Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-winehq
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wine
wine-winehq
Commits
52097fd7
Commit
52097fd7
authored
Sep 11, 2002
by
Andreas Mohr
Committed by
Alexandre Julliard
Sep 11, 2002
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
- Implement dumping of COFF debug symbol table.
- Fix winedump syntax description. - Spelling fixes.
parent
025b52d9
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
150 additions
and
41 deletions
+150
-41
README
tools/winedump/README
+13
-10
debug.c
tools/winedump/debug.c
+103
-0
pe.c
tools/winedump/pe.c
+32
-30
pe.h
tools/winedump/pe.h
+2
-1
No files found.
tools/winedump/README
View file @
52097fd7
...
...
@@ -59,7 +59,7 @@ Winedump can be used for different usages:
- demangling MSVC C++ symbol names
- dumping the 'PE' files contents
Usage: winedump [-h
sym <sym> spec <dll>
dump <dll>] [mode options]
Usage: winedump [-h
| sym <sym> | spec <dll> |
dump <dll>] [mode options]
When used in -h mode
-h Display this help message
When used in sym mode
...
...
@@ -436,7 +436,7 @@ The definition for the _complex struct needs to be given. Since it is passed
by value, its size also needs to be correct in order to forward the call
correctly to a native DLL. In this case the structure is 8 bytes in size, which
means that the gcc compile flag -freg-struct-return must be given when
compiling the function in order to be compatable with the native DLL. (In
compiling the function in order to be compatable with the native DLL. (In
general this is not an issue, but you need to be aware of such issues if you
encounter problems with your forwarding DLL).
...
...
@@ -472,7 +472,7 @@ struct foobar { int _FIXME; };
The output should be piped through 'sort' and 'uniq' to remove multiple
declarations, e.g:
winedump
-d
foo -c -I "inc/*.h" -v | grep FIXME | sort | uniq > fixup.h
winedump foo -c -I "inc/*.h" -v | grep FIXME | sort | uniq > fixup.h
By adding '#include "fixup.h"' to foobar_dll.h your compile errors will be
greatly reduced.
...
...
@@ -481,7 +481,7 @@ If winedump encounters a type it doesnt know that is passed by value (as in
the _cabs example above), it also prints a FIXME message like:
/* FIXME: By value type: Assumed 'int' */ typedef int ldiv_t;
If the type is not an int, you will need to change the code and possibly
the .spec entry in order to forward correctly. Otherwise, include the typedef
in your fixup header to avoid compile errors.
...
...
@@ -582,10 +582,13 @@ Which is enough information to begin implementing the function.
Dumping
-------
Another tool might be helpful digging into a 32bit DLL (and any PE image file):
Another tool might be helpful
for
digging into a 32bit DLL (and any PE image file):
pedump.
Usage:
winedump [-h | sym <sym> | spec <dll> | dump <dll> ] [switches]
winedump switches:
-h Display this help message
-d <dll> Use dll for input file and generate implementation code
-C Turns on symbol demangling
...
...
@@ -593,13 +596,13 @@ Usage:
-j dir_name Dumps only the content of directory dir_name (import, export, debug)
-x Dumps everything
The basic usage, to look everything in a file is:
winedump dump
-d
mydll.dll -x
The basic usage, to look
at
everything in a file is:
winedump dump mydll.dll -x
It'll print any available information on the file. This information can be splitted
into sub-categories:
- file he
daers (request by -f or -x) are made of the standard PE header structures,
- file he
aders (request by -f or -x) are made of the standard PE header structures,
plus the COFF sections
- directories: you can print them one after the other using the -j switch.
Currently,
only the import, export and debug directories are implemented.
- directories: you can print them one after the other using the -j switch.
Currently,
only the import, export and debug directories are implemented.
- -x displays the file headers and any available directory.
tools/winedump/debug.c
View file @
52097fd7
...
...
@@ -97,6 +97,10 @@
* (OMFDirHeader.cDir)
*/
extern
void
*
PE_base
;
extern
IMAGE_NT_HEADERS
*
PE_nt_headers
;
static
void
*
cv_base
/* = 0 */
;
static
int
dump_cv_sst_module
(
OMFDirEntry
*
omfde
)
...
...
@@ -482,7 +486,106 @@ static void dump_codeview_headers(unsigned long base, unsigned long len)
dump_codeview_all_modules
(
dirHeader
);
}
static
const
char
*
get_coff_name
(
PIMAGE_SYMBOL
coff_sym
,
const
char
*
coff_strtab
)
{
static
char
namebuff
[
9
];
const
char
*
nampnt
;
if
(
coff_sym
->
N
.
Name
.
Short
)
{
memcpy
(
namebuff
,
coff_sym
->
N
.
ShortName
,
8
);
namebuff
[
8
]
=
'\0'
;
nampnt
=
&
namebuff
[
0
];
}
else
{
nampnt
=
coff_strtab
+
coff_sym
->
N
.
Name
.
Long
;
}
if
(
nampnt
[
0
]
==
'_'
)
nampnt
++
;
return
nampnt
;
}
void
dump_coff
(
unsigned
long
coffbase
,
unsigned
long
len
)
{
PIMAGE_COFF_SYMBOLS_HEADER
coff
;
PIMAGE_SYMBOL
coff_sym
;
PIMAGE_SYMBOL
coff_symbols
;
PIMAGE_LINENUMBER
coff_linetab
;
char
*
coff_strtab
;
IMAGE_SECTION_HEADER
*
sectHead
=
(
IMAGE_SECTION_HEADER
*
)((
char
*
)
PE_nt_headers
+
sizeof
(
DWORD
)
+
sizeof
(
IMAGE_FILE_HEADER
)
+
PE_nt_headers
->
FileHeader
.
SizeOfOptionalHeader
);
unsigned
int
i
;
const
char
*
nampnt
;
int
naux
;
coff
=
(
PIMAGE_COFF_SYMBOLS_HEADER
)
PRD
(
coffbase
,
len
);
coff_symbols
=
(
PIMAGE_SYMBOL
)
((
unsigned
int
)
coff
+
coff
->
LvaToFirstSymbol
);
coff_linetab
=
(
PIMAGE_LINENUMBER
)
((
unsigned
int
)
coff
+
coff
->
LvaToFirstLinenumber
);
coff_strtab
=
(
char
*
)
(
coff_symbols
+
coff
->
NumberOfSymbols
);
printf
(
"
\n
Debug table: COFF format. modbase %p, coffbase %p
\n
"
,
PE_base
,
coff
);
printf
(
" ID | seg:offs [ abs ] | symbol/function name
\n
"
);
for
(
i
=
0
;
i
<
coff
->
NumberOfSymbols
;
i
++
)
{
coff_sym
=
coff_symbols
+
i
;
naux
=
coff_sym
->
NumberOfAuxSymbols
;
if
(
coff_sym
->
StorageClass
==
IMAGE_SYM_CLASS_FILE
)
{
printf
(
"file %s
\n
"
,
(
char
*
)
(
coff_sym
+
1
));
i
+=
naux
;
continue
;
}
if
(
(
coff_sym
->
StorageClass
==
IMAGE_SYM_CLASS_STATIC
)
&&
(
naux
==
0
)
&&
(
coff_sym
->
SectionNumber
==
1
)
)
{
DWORD
base
=
sectHead
[
coff_sym
->
SectionNumber
-
1
].
VirtualAddress
;
/*
* This is a normal static function when naux == 0.
* Just register it. The current file is the correct
* one in this instance.
*/
nampnt
=
get_coff_name
(
coff_sym
,
coff_strtab
);
printf
(
"%05d | %02d:%08lx [%08lx] | %s
\n
"
,
i
,
coff_sym
->
SectionNumber
-
1
,
coff_sym
->
Value
-
base
,
coff_sym
->
Value
,
nampnt
);
i
+=
naux
;
continue
;
}
if
(
(
coff_sym
->
StorageClass
==
IMAGE_SYM_CLASS_EXTERNAL
)
&&
ISFCN
(
coff_sym
->
Type
)
&&
(
coff_sym
->
SectionNumber
>
0
)
)
{
DWORD
base
=
sectHead
[
coff_sym
->
SectionNumber
-
1
].
VirtualAddress
;
nampnt
=
get_coff_name
(
coff_sym
,
coff_strtab
);
/* FIXME: add code to find out the file this symbol belongs to,
* see winedbg */
printf
(
"%05d | %02d:%08lx [%08lx] | %s
\n
"
,
i
,
coff_sym
->
SectionNumber
-
1
,
coff_sym
->
Value
-
base
,
coff_sym
->
Value
,
nampnt
);
i
+=
naux
;
continue
;
}
/*
* For now, skip past the aux entries.
*/
i
+=
naux
;
}
}
void
dump_codeview
(
unsigned
long
base
,
unsigned
long
len
)
{
dump_codeview_headers
(
base
,
len
);
}
void
dump_frame_pointer_omission
(
unsigned
long
base
,
unsigned
long
len
)
{
/* FPO is used to describe nonstandard stack frames */
printf
(
"FIXME: FPO (frame pointer omission) debug symbol dumping not implemented yet.
\n
"
);
}
tools/winedump/pe.c
View file @
52097fd7
...
...
@@ -46,9 +46,9 @@
# define O_BINARY 0
#endif
static
void
*
base
;
static
unsigned
long
total_len
;
static
IMAGE_NT_HEADERS
*
nt_headers
;
void
*
PE_
base
;
unsigned
long
PE_
total_len
;
IMAGE_NT_HEADERS
*
PE_
nt_headers
;
enum
FileSig
{
SIG_UNKNOWN
,
SIG_DOS
,
SIG_PE
,
SIG_DBG
};
...
...
@@ -85,14 +85,14 @@ static const char* get_machine_str(DWORD mach)
void
*
PRD
(
unsigned
long
prd
,
unsigned
long
len
)
{
return
(
prd
+
len
>
total_len
)
?
NULL
:
(
char
*
)
base
+
prd
;
return
(
prd
+
len
>
PE_total_len
)
?
NULL
:
(
char
*
)
PE_
base
+
prd
;
}
unsigned
long
Offset
(
void
*
ptr
)
{
if
(
ptr
<
base
)
{
printf
(
"<<<<<ptr below
\n
"
);
return
0
;}
if
((
char
*
)
ptr
>=
(
char
*
)
base
+
total_len
)
{
printf
(
"<<<<<ptr above
\n
"
);
return
0
;}
return
(
char
*
)
ptr
-
(
char
*
)
base
;
if
(
ptr
<
PE_
base
)
{
printf
(
"<<<<<ptr below
\n
"
);
return
0
;}
if
((
char
*
)
ptr
>=
(
char
*
)
PE_base
+
PE_
total_len
)
{
printf
(
"<<<<<ptr above
\n
"
);
return
0
;}
return
(
char
*
)
ptr
-
(
char
*
)
PE_
base
;
}
void
*
RVA
(
unsigned
long
rva
,
unsigned
long
len
)
...
...
@@ -100,13 +100,13 @@ void* RVA(unsigned long rva, unsigned long len)
IMAGE_SECTION_HEADER
*
sectHead
;
int
i
;
sectHead
=
(
IMAGE_SECTION_HEADER
*
)((
char
*
)
nt_headers
+
sizeof
(
DWORD
)
+
sectHead
=
(
IMAGE_SECTION_HEADER
*
)((
char
*
)
PE_
nt_headers
+
sizeof
(
DWORD
)
+
sizeof
(
IMAGE_FILE_HEADER
)
+
nt_headers
->
FileHeader
.
SizeOfOptionalHeader
);
PE_
nt_headers
->
FileHeader
.
SizeOfOptionalHeader
);
if
(
rva
==
0
)
return
NULL
;
for
(
i
=
nt_headers
->
FileHeader
.
NumberOfSections
-
1
;
i
>=
0
;
i
--
)
for
(
i
=
PE_
nt_headers
->
FileHeader
.
NumberOfSections
-
1
;
i
>=
0
;
i
--
)
{
if
(
sectHead
[
i
].
VirtualAddress
<=
rva
&&
rva
+
len
<=
(
DWORD
)
sectHead
[
i
].
VirtualAddress
+
sectHead
[
i
].
SizeOfRawData
)
...
...
@@ -125,10 +125,10 @@ void* RVA(unsigned long rva, unsigned long len)
static
void
*
get_dir
(
unsigned
idx
)
{
if
(
idx
>=
nt_headers
->
OptionalHeader
.
NumberOfRvaAndSizes
)
if
(
idx
>=
PE_
nt_headers
->
OptionalHeader
.
NumberOfRvaAndSizes
)
return
NULL
;
return
RVA
(
nt_headers
->
OptionalHeader
.
DataDirectory
[
idx
].
VirtualAddress
,
nt_headers
->
OptionalHeader
.
DataDirectory
[
idx
].
Size
);
return
RVA
(
PE_
nt_headers
->
OptionalHeader
.
DataDirectory
[
idx
].
VirtualAddress
,
PE_
nt_headers
->
OptionalHeader
.
DataDirectory
[
idx
].
Size
);
}
static
const
char
*
DirectoryNames
[
16
]
=
{
...
...
@@ -146,7 +146,7 @@ static void dump_pe_header(void)
unsigned
i
;
printf
(
"File Header
\n
"
);
fileHeader
=
&
nt_headers
->
FileHeader
;
fileHeader
=
&
PE_
nt_headers
->
FileHeader
;
printf
(
" Machine: %04X (%s)
\n
"
,
fileHeader
->
Machine
,
get_machine_str
(
fileHeader
->
Machine
));
...
...
@@ -175,7 +175,7 @@ static void dump_pe_header(void)
/* hope we have the right size */
printf
(
"Optional Header
\n
"
);
optionalHeader
=
&
nt_headers
->
OptionalHeader
;
optionalHeader
=
&
PE_
nt_headers
->
OptionalHeader
;
printf
(
" Magic 0x%-4X %u
\n
"
,
optionalHeader
->
Magic
,
optionalHeader
->
Magic
);
printf
(
" linker version %u.%02u
\n
"
,
...
...
@@ -401,12 +401,12 @@ static void dump_dir_imported_functions(void)
unsigned
nb_imp
,
i
;
if
(
!
importDesc
)
return
;
nb_imp
=
nt_headers
->
OptionalHeader
.
DataDirectory
[
IMAGE_FILE_IMPORT_DIRECTORY
].
Size
/
nb_imp
=
PE_
nt_headers
->
OptionalHeader
.
DataDirectory
[
IMAGE_FILE_IMPORT_DIRECTORY
].
Size
/
sizeof
(
*
importDesc
);
if
(
!
nb_imp
)
return
;
printf
(
"Import Table size: %lu
\n
"
,
nt_headers
->
OptionalHeader
.
DataDirectory
[
IMAGE_FILE_IMPORT_DIRECTORY
].
Size
);
/* FIXME */
PE_
nt_headers
->
OptionalHeader
.
DataDirectory
[
IMAGE_FILE_IMPORT_DIRECTORY
].
Size
);
/* FIXME */
for
(
i
=
0
;
i
<
nb_imp
-
1
;
i
++
)
/* the last descr is set as 0 as a sentinel */
{
...
...
@@ -495,11 +495,13 @@ static void dump_dir_debug_dir(IMAGE_DEBUG_DIRECTORY* idd, int idx)
case
IMAGE_DEBUG_TYPE_UNKNOWN
:
break
;
case
IMAGE_DEBUG_TYPE_COFF
:
dump_coff
(
idd
->
PointerToRawData
,
idd
->
SizeOfData
);
break
;
case
IMAGE_DEBUG_TYPE_CODEVIEW
:
dump_codeview
(
idd
->
PointerToRawData
,
idd
->
SizeOfData
);
break
;
case
IMAGE_DEBUG_TYPE_FPO
:
dump_frame_pointer_omission
(
idd
->
PointerToRawData
,
idd
->
SizeOfData
);
break
;
case
IMAGE_DEBUG_TYPE_MISC
:
{
...
...
@@ -535,7 +537,7 @@ static void dump_dir_debug(void)
unsigned
nb_dbg
,
i
;
if
(
!
debugDir
)
return
;
nb_dbg
=
nt_headers
->
OptionalHeader
.
DataDirectory
[
IMAGE_FILE_DEBUG_DIRECTORY
].
Size
/
nb_dbg
=
PE_
nt_headers
->
OptionalHeader
.
DataDirectory
[
IMAGE_FILE_DEBUG_DIRECTORY
].
Size
/
sizeof
(
*
debugDir
);
if
(
!
nb_dbg
)
return
;
...
...
@@ -740,10 +742,10 @@ static void do_dump(void)
if
(
globals
.
do_dumpheader
)
{
dump_pe_header
();
/* FIX
%
E: should check ptr */
dump_sections
((
char
*
)
nt_headers
+
sizeof
(
DWORD
)
+
sizeof
(
IMAGE_FILE_HEADER
)
+
nt_headers
->
FileHeader
.
SizeOfOptionalHeader
,
nt_headers
->
FileHeader
.
NumberOfSections
);
/* FIX
M
E: should check ptr */
dump_sections
((
char
*
)
PE_
nt_headers
+
sizeof
(
DWORD
)
+
sizeof
(
IMAGE_FILE_HEADER
)
+
PE_
nt_headers
->
FileHeader
.
SizeOfOptionalHeader
,
PE_
nt_headers
->
FileHeader
.
NumberOfSections
);
}
else
if
(
!
globals
.
dumpsect
)
{
...
...
@@ -792,7 +794,7 @@ static enum FileSig check_headers(void)
{
if
(
*
pdw
==
IMAGE_NT_SIGNATURE
)
{
nt_headers
=
PRD
(
dh
->
e_lfanew
,
sizeof
(
DWORD
));
PE_
nt_headers
=
PRD
(
dh
->
e_lfanew
,
sizeof
(
DWORD
));
sig
=
SIG_PE
;
}
else
...
...
@@ -830,14 +832,14 @@ int pe_analysis(const char* name, void (*fn)(void), enum FileSig wanted_sig)
if
(
fd
==
-
1
)
fatal
(
"Can't open file"
);
if
(
fstat
(
fd
,
&
s
)
<
0
)
fatal
(
"Can't get size"
);
total_len
=
s
.
st_size
;
PE_
total_len
=
s
.
st_size
;
#ifdef HAVE_MMAP
if
((
base
=
mmap
(
NULL
,
total_len
,
PROT_READ
,
MAP_PRIVATE
,
fd
,
0
))
==
(
void
*
)
-
1
)
if
((
PE_base
=
mmap
(
NULL
,
PE_
total_len
,
PROT_READ
,
MAP_PRIVATE
,
fd
,
0
))
==
(
void
*
)
-
1
)
#endif
{
if
(
!
(
base
=
malloc
(
total_len
)))
fatal
(
"Out of memory"
);
if
(
read
(
fd
,
base
,
total_len
)
!=
total_len
)
fatal
(
"Cannot read file"
);
if
(
!
(
PE_base
=
malloc
(
PE_
total_len
)))
fatal
(
"Out of memory"
);
if
(
read
(
fd
,
PE_base
,
PE_total_len
)
!=
PE_
total_len
)
fatal
(
"Cannot read file"
);
}
effective_sig
=
check_headers
();
...
...
@@ -854,7 +856,7 @@ int pe_analysis(const char* name, void (*fn)(void), enum FileSig wanted_sig)
case
SIG_UNKNOWN
:
/* shouldn't happen... */
ret
=
0
;
break
;
case
SIG_PE
:
printf
(
"Contents of
\"
%s
\"
: %ld bytes
\n\n
"
,
name
,
total_len
);
printf
(
"Contents of
\"
%s
\"
: %ld bytes
\n\n
"
,
name
,
PE_
total_len
);
(
*
fn
)();
break
;
case
SIG_DBG
:
...
...
@@ -872,10 +874,10 @@ int pe_analysis(const char* name, void (*fn)(void), enum FileSig wanted_sig)
if
(
ret
)
printf
(
"Done dumping %s
\n
"
,
name
);
#ifdef HAVE_MMAP
if
(
munmap
(
base
,
total_len
)
==
-
1
)
if
(
munmap
(
PE_base
,
PE_
total_len
)
==
-
1
)
#endif
{
free
(
base
);
free
(
PE_
base
);
}
close
(
fd
);
...
...
tools/winedump/pe.h
View file @
52097fd7
...
...
@@ -19,7 +19,8 @@
*/
extern
void
dump_codeview
(
unsigned
long
ptr
,
unsigned
long
len
);
extern
void
dump_coff
(
unsigned
long
coffbase
,
unsigned
long
len
);
extern
void
dump_frame_pointer_omission
(
unsigned
long
base
,
unsigned
long
len
);
extern
void
*
PRD
(
unsigned
long
prd
,
unsigned
long
len
);
extern
unsigned
long
Offset
(
void
*
ptr
);
extern
char
*
get_time_str
(
DWORD
_t
);
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment