2 * Usage: dumpstab input-file
4 * There are two sources of information: the .stab/.stabstr
5 * sections of the executable and the COFF symbol table. Most
6 * of the information is in the .stab/.stabstr sections.
7 * However, most of our asm files don't contain .stab directives,
8 * so routines implemented in assembler won't show up in the
9 * .stab section. They are present in the COFF symbol table.
10 * So, we mostly use the .stab/.stabstr sections, but we augment
11 * the info there with info from the COFF symbol table when
14 * This is a tool and is compiled using the host compiler,
15 * i.e. on Linux gcc and not mingw-gcc (cross-compiler).
16 * Therefore we can't include SDK headers and we have to
17 * duplicate some definitions here.
18 * Also note that the internal functions are "old C-style",
19 * returning an int, where a return of 0 means success and
20 * non-zero is failure.
31 stab_type_name ( int stab_type
)
36 #define X(n) case n: return #n;
73 sprintf ( buf
, "%lu", stab_type
);
78 GetStabInfo(void *FileData
, PIMAGE_FILE_HEADER PEFileHeader
,
79 PIMAGE_SECTION_HEADER PESectionHeaders
,
80 ULONG
*StabSymbolsLength
, void **StabSymbolsBase
,
81 ULONG
*StabStringsLength
, void **StabStringsBase
)
85 /* Load .stab and .stabstr sections if available */
86 *StabSymbolsBase
= NULL
;
87 *StabSymbolsLength
= 0;
88 *StabStringsBase
= NULL
;
89 *StabStringsLength
= 0;
91 for (Idx
= 0; Idx
< PEFileHeader
->NumberOfSections
; Idx
++)
93 /* printf("section: '%.08s'\n", PESectionHeaders[Idx].Name); */
94 if ((strncmp((char*)PESectionHeaders
[Idx
].Name
, ".stab", 5) == 0)
95 && (PESectionHeaders
[Idx
].Name
[5] == 0))
97 /* printf(".stab section found. Size %d\n",
98 PESectionHeaders[Idx].SizeOfRawData); */
100 *StabSymbolsLength
= PESectionHeaders
[Idx
].SizeOfRawData
;
101 *StabSymbolsBase
= (void *)((char *) FileData
+ PESectionHeaders
[Idx
].PointerToRawData
);
104 if (strncmp((char*)PESectionHeaders
[Idx
].Name
, ".stabstr", 8) == 0)
106 /* printf(".stabstr section found. Size %d\n",
107 PESectionHeaders[Idx].SizeOfRawData); */
109 *StabStringsLength
= PESectionHeaders
[Idx
].SizeOfRawData
;
110 *StabStringsBase
= (void *)((char *) FileData
+ PESectionHeaders
[Idx
].PointerToRawData
);
118 IterateStabs(ULONG StabSymbolsLength
, void *StabSymbolsBase
,
119 ULONG StabStringsLength
, void *StabStringsBase
,
120 ULONG_PTR ImageBase
, PIMAGE_FILE_HEADER PEFileHeader
,
121 PIMAGE_SECTION_HEADER PESectionHeaders
)
127 Count
= StabSymbolsLength
/ sizeof(STAB_ENTRY
);
128 if (Count
== 0) /* No symbol info */
131 printf ( "type,other,desc,value,str\n" );
132 for (i
= 0; i
< Count
; i
++)
134 printf ( "%s,%lu(0x%x),%lu(0x%x),%lu(0x%x),%s\n",
135 stab_type_name(e
[i
].n_type
),
142 (char *) StabStringsBase
+ e
[i
].n_strx
);
146 int main(int argc
, char* argv
[])
148 PIMAGE_DOS_HEADER PEDosHeader
;
149 PIMAGE_FILE_HEADER PEFileHeader
;
150 PIMAGE_OPTIONAL_HEADER PEOptHeader
;
151 PIMAGE_SECTION_HEADER PESectionHeaders
;
155 void *StabStringBase
;
156 ULONG StabStringsLength
;
163 fprintf(stderr
, "Usage: dumpstabs <exefile>\n");
167 path1
= convert_path(argv
[1]);
169 FileData
= load_file ( path1
, &FileSize
);
172 fprintf ( stderr
, "An error occured loading '%s'\n", path1
);
176 /* Check if MZ header exists */
177 PEDosHeader
= (PIMAGE_DOS_HEADER
) FileData
;
178 if (PEDosHeader
->e_magic
!= IMAGE_DOS_MAGIC
|| PEDosHeader
->e_lfanew
== 0L)
180 perror("Input file is not a PE image.\n");
185 /* Locate PE file header */
186 /* sizeof(ULONG) = sizeof(MAGIC) */
187 PEFileHeader
= (PIMAGE_FILE_HEADER
)((char *) FileData
+ PEDosHeader
->e_lfanew
+ sizeof(ULONG
));
189 /* Locate optional header */
190 assert(sizeof(ULONG
) == 4);
191 PEOptHeader
= (PIMAGE_OPTIONAL_HEADER
)(PEFileHeader
+ 1);
192 ImageBase
= PEOptHeader
->ImageBase
;
194 /* Locate PE section headers */
195 PESectionHeaders
= (PIMAGE_SECTION_HEADER
)((char *) PEOptHeader
+ PEFileHeader
->SizeOfOptionalHeader
);
197 if (GetStabInfo(FileData
, PEFileHeader
, PESectionHeaders
, &StabsLength
, &StabBase
,
198 &StabStringsLength
, &StabStringBase
))
204 IterateStabs( StabsLength
, StabBase
, StabStringsLength
, StabStringBase
,
205 ImageBase
, PEFileHeader
, PESectionHeaders
);