home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 11 Util
/
11-Util.zip
/
WHATFN.ZIP
/
WHATFUNC.DOC
< prev
next >
Wrap
Text File
|
1989-01-22
|
5KB
|
128 lines
***** WHATFUNC.EXE *****
WHATFUNC is a utility for OS/2 programmers. Given one or more
hexadecimal function addresses on the command line, it will attempt to
provide the ASCIIZ name for each function.
Often when debugging code in CodeView (CVP), you are faced with
raw unassembled code like:
CALL 01B7:0C7C
Like, how are you supposed to know this is a call to VioGetMode?
CodeView may be called a symbolic debugger, but apparently that
doesn't extend to the symbolic names of dynamically-linked functions
even though, as WHATFUNC demonstrates, these names are readily
available under OS/2.
Even when you are debugging your own program, for which you
presumably have the source code, often the routines you call in turn
make calls to functions in DLL's. For instance, you're tracing
through fopen(), and you see
CALL 10AB:0000
How are you supposed to know this is a call to DosQHandType?
WHATFUNC.EXE, that's how. From the CVP command-line, you could
type:
> ! whatfunc 01b7:0c7c 10ab
and WHATFUNC.EXE (which you might rename WF.EXE to save typing) will
reply:
01B7:0C7C VIOGETMODE
10AB:0000 DOSQHANDTYPE
WHATFUNC doesn't have to be run from the CVP command-line, of
course. It can of course be run from"straight" CMD.EXE. It is known
to run within an Epsilon process buffer. It's been linked with the
WINDOWCOMPAT statement, so it should run in a PM window.
In the example above, note that if the offset of the function
you're looking for is zero, then you can just type the selector (which
is probably a DOSCALLS call gate).
Wait a minute! You're in one process, you have a function pointer
like 01B7:0C7C, and you expect WHATFUNC.EXE, which is running in an
entirely separate process, to also know about 01B7:0C7C? This works
because OS/2 maps dynamic-link routines into the same selectors for
each process. (This isn't a very good explanation, but it'll have to
do for now. For further details, read Gordon Letwin's book INSIDE OS/2.)
Theory of Operation
-------------------
WHATFUNC.C is just a rehash of some code I'd already written in
ENUMDLL.LSP and ENUMPROC.C. The way WHATFUNC tries to match an ASCIIZ
string against an address is:
for each module in system (ENUMDLL)
for each function in module (ENUMPROC)
does procaddr(function) == procaddr we're looking for?
We can rely on the OS/2 function DosGetModName to provide us with
the ASCIIZ names of all DLL's currently loaded. We then open each of
these files and read through its name table. For each ASCIIZ
function name we find in the DLL, we call DosGetProcAddr. If the
resulting function pointer is equal to the one we're looking for, we're
done.
Notice how OS/2 makes it easy to do this sort of thing, since
practically everything in OS/2 has an ASCIIZ name attached to it: a
very powerful concept.
Unfortunately, there's one special case: the OS/2 kernel, whose
exported functions masquerade under the name DOSCALLS.DLL. This isn't
really a DLL, and the ASCIIZ names for its functions are not
available through normal OS/2 channels. For this reason, the names
of all DOSCALLS routines through version 1.1 are hard-wired into
WHATFUNC.C. Yuk!
Speaking of special cases, before entering the ENUMDLL loop, we
first check the most common cases: DOSCALLS, VIOCALLS, KBDCALLS, and
MOUCALLS.
WHATFUNC.EXE has one command-line option: the -v verbose switch.
This will print out the mod.func names (e.g., VIOCALLS.VIOGETMODE)
and addresses of all functions found until WHATFUNC succeeds. Therefore,
passing WHATFUNC a bogus address:
C>whatfunc -v 1
will print out _all_ DLL routines currently loaded in your system.
This is either exciting or incredibly stupid, depending on how you
look at it.
A few things remain to be done with WHATFUNC:
Because ploughing through each DLL is kinda slow, WHATFUNC ought
to maintain some kind of in-memory tables when there is more than one
command-line argument, and/or it ought to launch a separate thread for
each command-line argument. Separate threads seems like a good idea:
assuming each thread proceeds through each DLL at more or less the same
rate, each thread should find that the file blocks it's looking for
are already in memory.
Secondly, WHATFUNC ought to be rewritten as a monitor (an OS/2
"TSR"). In that case, there would be a great benefit to maintaining
in-memory symbol tables for each DLL.
Please feel free to send comments, criticisms, or suggestions.
-- Andrew Schulman
32 Andrews St. #2
Cambridge MA 02139
(617) 876-2102 (h)
(617) 577-8500 x7148 (w)
CIS 76320,302
14 January 1989
p.s. Thanks for Charles Petzold for finding a bug in enumproc() (22jan89).