ReactOS 0.4.16-dev-336-gb667d82
rsym.c
Go to the documentation of this file.
1/*
2 * Usage: rsym input-file output-file
3 *
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
12 * possible.
13 *
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.
21 */
22
23#include "../../dll/win32/dbghelp/compat.h"
24
25#include <stdio.h>
26#include <string.h>
27#include <stdlib.h>
28#include <assert.h>
29#include <wchar.h>
30
31#include "rsym.h"
32
33#define MAX_PATH 260
34#define MAX_SYM_NAME 2000
35
37{
40 char *String;
41};
42
44{
47};
48
49/* This is the famous DJB hash */
50static unsigned int
51ComputeDJBHash(const char *name)
52{
53 unsigned int val = 5381;
54 int i = 0;
55
56 for (i = 0; name[i]; i++)
57 {
58 val = (33 * val) + name[i];
59 }
60
61 return val;
62}
63
64static void
65AddStringToHash(struct StringHashTable *StringTable,
66 unsigned int hash,
68 char *StringPtr)
69{
70 struct StringEntry *entry = calloc(1, sizeof(struct StringEntry));
71 entry->Offset = Offset;
72 entry->String = StringPtr;
73 entry->Next = StringTable->Table[hash];
74 StringTable->Table[hash] = entry;
75}
76
77static void
79 ULONG StringsLength,
80 char *StringsBase)
81{
82 char *Start = StringsBase;
83 char *End = StringsBase + StringsLength;
84 StringTable->TableSize = 1024;
85 StringTable->Table = calloc(1024, sizeof(struct StringEntry *));
86 while (Start < End)
87 {
88 AddStringToHash(StringTable,
89 ComputeDJBHash(Start) % StringTable->TableSize,
90 Start - StringsBase,
91 Start);
92 Start += strlen(Start) + 1;
93 }
94}
95
96static void
98{
99 int i;
100 struct StringEntry *entry;
101 for (i = 0; i < StringTable->TableSize; i++)
102 {
103 while ((entry = StringTable->Table[i]))
104 {
105 entry = entry->Next;
106 free(StringTable->Table[i]);
107 StringTable->Table[i] = entry;
108 }
109 }
110 free(StringTable->Table);
111}
112
113static int
114CompareSymEntry(const PROSSYM_ENTRY SymEntry1, const PROSSYM_ENTRY SymEntry2)
115{
116 if (SymEntry1->Address < SymEntry2->Address)
117 {
118 return -1;
119 }
120
121 if (SymEntry2->Address < SymEntry1->Address)
122 {
123 return +1;
124 }
125
126 if (SymEntry2->SourceLine == 0)
127 {
128 return -1;
129 }
130
131 if (SymEntry1->SourceLine == 0)
132 {
133 return +1;
134 }
135
136 return 0;
137}
138
139static int
141 PIMAGE_SECTION_HEADER PESectionHeaders,
142 ULONG *StabSymbolsLength, void **StabSymbolsBase,
143 ULONG *StabStringsLength, void **StabStringsBase)
144{
145 ULONG Idx;
146
147 /* Load .stab and .stabstr sections if available */
148 *StabSymbolsBase = NULL;
149 *StabSymbolsLength = 0;
150 *StabStringsBase = NULL;
151 *StabStringsLength = 0;
152
153 for (Idx = 0; Idx < PEFileHeader->NumberOfSections; Idx++)
154 {
155 /* printf("section: '%.08s'\n", PESectionHeaders[Idx].Name); */
156 if ((strncmp((char *) PESectionHeaders[Idx].Name, ".stab", 5) == 0)
157 && (PESectionHeaders[Idx].Name[5] == 0))
158 {
159 /* printf(".stab section found. Size %d\n", PESectionHeaders[Idx].SizeOfRawData); */
160
161 *StabSymbolsLength = PESectionHeaders[Idx].SizeOfRawData;
162 *StabSymbolsBase = (void *)((char *) FileData + PESectionHeaders[Idx].PointerToRawData);
163 }
164
165 if (strncmp((char *) PESectionHeaders[Idx].Name, ".stabstr", 8) == 0)
166 {
167 /* printf(".stabstr section found. Size %d\n", PESectionHeaders[Idx].SizeOfRawData); */
168
169 *StabStringsLength = PESectionHeaders[Idx].SizeOfRawData;
170 *StabStringsBase = (void *)((char *) FileData + PESectionHeaders[Idx].PointerToRawData);
171 }
172 }
173
174 return 0;
175}
176
177static int
179 PIMAGE_SECTION_HEADER PESectionHeaders,
180 ULONG *CoffSymbolsLength, void **CoffSymbolsBase,
181 ULONG *CoffStringsLength, void **CoffStringsBase)
182{
183
184 if (PEFileHeader->PointerToSymbolTable == 0 || PEFileHeader->NumberOfSymbols == 0)
185 {
186 /* No COFF symbol table */
187 *CoffSymbolsLength = 0;
188 *CoffStringsLength = 0;
189 }
190 else
191 {
192 *CoffSymbolsLength = PEFileHeader->NumberOfSymbols * sizeof(COFF_SYMENT);
193 *CoffSymbolsBase = (void *)((char *) FileData + PEFileHeader->PointerToSymbolTable);
194 *CoffStringsLength = *((ULONG *) ((char *) *CoffSymbolsBase + *CoffSymbolsLength));
195 *CoffStringsBase = (void *)((char *) *CoffSymbolsBase + *CoffSymbolsLength);
196 }
197
198 return 0;
199}
200
201static ULONG
203 char *StringToFind,
204 ULONG *StringsLength,
205 void *StringsBase)
206{
207 unsigned int hash = ComputeDJBHash(StringToFind) % StringTable->TableSize;
208 struct StringEntry *entry = StringTable->Table[hash];
209
210 while (entry && strcmp(entry->String, StringToFind))
211 entry = entry->Next;
212
213 if (entry)
214 {
215 return entry->Offset;
216 }
217 else
218 {
219 char *End = (char *)StringsBase + *StringsLength;
220
221 strcpy(End, StringToFind);
222 *StringsLength += strlen(StringToFind) + 1;
223
224 AddStringToHash(StringTable, hash, End - (char *)StringsBase, End);
225
226 return End - (char *)StringsBase;
227 }
228}
229
230static int
231ConvertStabs(ULONG *SymbolsCount, PROSSYM_ENTRY *SymbolsBase,
232 ULONG *StringsLength, void *StringsBase,
233 ULONG StabSymbolsLength, void *StabSymbolsBase,
234 ULONG StabStringsLength, void *StabStringsBase,
235 ULONG_PTR ImageBase, PIMAGE_FILE_HEADER PEFileHeader,
236 PIMAGE_SECTION_HEADER PESectionHeaders)
237{
238 PSTAB_ENTRY StabEntry;
239 ULONG Count, i;
240 ULONG_PTR Address, LastFunctionAddress;
241 int First = 1;
242 char *Name;
243 ULONG NameLen;
244 char FuncName[256];
245 PROSSYM_ENTRY Current;
247
248 StabEntry = StabSymbolsBase;
249 Count = StabSymbolsLength / sizeof(STAB_ENTRY);
250 *SymbolsCount = 0;
251
252 if (Count == 0)
253 {
254 /* No symbol info */
255 *SymbolsBase = NULL;
256 return 0;
257 }
258
259 *SymbolsBase = malloc(Count * sizeof(ROSSYM_ENTRY));
260 if (*SymbolsBase == NULL)
261 {
262 fprintf(stderr, "Failed to allocate memory for converted .stab symbols\n");
263 return 1;
264 }
265 Current = *SymbolsBase;
266 memset(Current, 0, sizeof(*Current));
267
268 StringHashTableInit(&StringHash, *StringsLength, (char *)StringsBase);
269
270 LastFunctionAddress = 0;
271 for (i = 0; i < Count; i++)
272 {
273 if (LastFunctionAddress == 0)
274 {
275 Address = StabEntry[i].n_value - ImageBase;
276 }
277 else
278 {
279 Address = LastFunctionAddress + StabEntry[i].n_value;
280 }
281 switch (StabEntry[i].n_type)
282 {
283 case N_SO:
284 case N_SOL:
285 case N_BINCL:
286 Name = (char *) StabStringsBase + StabEntry[i].n_strx;
287 if (StabStringsLength < StabEntry[i].n_strx
288 || *Name == '\0' || Name[strlen(Name) - 1] == '/'
289 || Name[strlen(Name) - 1] == '\\'
290 || StabEntry[i].n_value < ImageBase)
291 {
292 continue;
293 }
294 if (First || Address != Current->Address)
295 {
296 if (!First)
297 {
298 memset(++Current, 0, sizeof(*Current));
299 Current->FunctionOffset = Current[-1].FunctionOffset;
300 }
301 else
302 First = 0;
303 Current->Address = Address;
304 }
306 (char *)StabStringsBase + StabEntry[i].n_strx,
307 StringsLength,
308 StringsBase);
309 break;
310 case N_FUN:
311 if (StabEntry[i].n_desc == 0 || StabEntry[i].n_value < ImageBase)
312 {
313 LastFunctionAddress = 0; /* line # 0 = end of function */
314 continue;
315 }
316 if (First || Address != Current->Address)
317 {
318 if (!First)
319 memset(++Current, 0, sizeof(*Current));
320 else
321 First = 0;
322 Current->Address = Address;
323 Current->FileOffset = Current[-1].FileOffset;
324 }
325 Name = (char *)StabStringsBase + StabEntry[i].n_strx;
326 NameLen = strcspn(Name, ":");
327 if (sizeof(FuncName) <= NameLen)
328 {
329 free(*SymbolsBase);
330 fprintf(stderr, "Function name too long\n");
331 return 1;
332 }
333 memcpy(FuncName, Name, NameLen);
334 FuncName[NameLen] = '\0';
336 FuncName,
337 StringsLength,
338 StringsBase);
339 Current->SourceLine = 0;
340 LastFunctionAddress = Address;
341 break;
342 case N_SLINE:
343 if (First || Address != Current->Address)
344 {
345 if (!First)
346 {
347 memset(++Current, 0, sizeof(*Current));
348 Current->FileOffset = Current[-1].FileOffset;
349 Current->FunctionOffset = Current[-1].FunctionOffset;
350 }
351 else
352 First = 0;
353 Current->Address = Address;
354 }
355 Current->SourceLine = StabEntry[i].n_desc;
356 break;
357 default:
358 continue;
359 }
360 }
361 *SymbolsCount = (Current - *SymbolsBase + 1);
362
363 qsort(*SymbolsBase, *SymbolsCount, sizeof(ROSSYM_ENTRY), (int (*)(const void *, const void *)) CompareSymEntry);
364
366
367 return 0;
368}
369
370static int
371ConvertCoffs(ULONG *SymbolsCount, PROSSYM_ENTRY *SymbolsBase,
372 ULONG *StringsLength, void *StringsBase,
373 ULONG CoffSymbolsLength, void *CoffSymbolsBase,
374 ULONG CoffStringsLength, void *CoffStringsBase,
375 ULONG_PTR ImageBase, PIMAGE_FILE_HEADER PEFileHeader,
376 PIMAGE_SECTION_HEADER PESectionHeaders)
377{
378 ULONG Count, i;
379 PCOFF_SYMENT CoffEntry;
380 char FuncName[256], FileName[1024];
381 char *p;
382 PROSSYM_ENTRY Current;
384
385 CoffEntry = (PCOFF_SYMENT) CoffSymbolsBase;
386 Count = CoffSymbolsLength / sizeof(COFF_SYMENT);
387
388 *SymbolsBase = malloc(Count * sizeof(ROSSYM_ENTRY));
389 if (*SymbolsBase == NULL)
390 {
391 fprintf(stderr, "Unable to allocate memory for converted COFF symbols\n");
392 return 1;
393 }
394 *SymbolsCount = 0;
395 Current = *SymbolsBase;
396
397 StringHashTableInit(&StringHash, *StringsLength, (char*)StringsBase);
398
399 for (i = 0; i < Count; i++)
400 {
401 if (ISFCN(CoffEntry[i].e_type) || C_EXT == CoffEntry[i].e_sclass)
402 {
403 Current->Address = CoffEntry[i].e_value;
404 if (CoffEntry[i].e_scnum > 0)
405 {
406 if (PEFileHeader->NumberOfSections < CoffEntry[i].e_scnum)
407 {
408 free(*SymbolsBase);
410 "Invalid section number %d in COFF symbols (only %d sections present)\n",
411 CoffEntry[i].e_scnum,
412 PEFileHeader->NumberOfSections);
413 return 1;
414 }
415 Current->Address += PESectionHeaders[CoffEntry[i].e_scnum - 1].VirtualAddress;
416 }
417 Current->FileOffset = 0;
418 if (CoffEntry[i].e.e.e_zeroes == 0)
419 {
420 if (sizeof(FuncName) <= strlen((char *) CoffStringsBase + CoffEntry[i].e.e.e_offset))
421 {
422 free(*SymbolsBase);
423 fprintf(stderr, "Function name too long\n");
425 return 1;
426 }
427 strcpy(FuncName, (char *) CoffStringsBase + CoffEntry[i].e.e.e_offset);
428 }
429 else
430 {
431 memcpy(FuncName, CoffEntry[i].e.e_name, E_SYMNMLEN);
432 FuncName[E_SYMNMLEN] = '\0';
433 }
434
435 /* Name demangling: stdcall */
436 p = strrchr(FuncName, '@');
437 if (p != NULL)
438 {
439 *p = '\0';
440 }
441 p = ('_' == FuncName[0] || '@' == FuncName[0] ? FuncName + 1 : FuncName);
443 p,
444 StringsLength,
445 StringsBase);
446 Current->SourceLine = 0;
447 memset(++Current, 0, sizeof(*Current));
448 }
449
450 i += CoffEntry[i].e_numaux;
451 }
452
453 *SymbolsCount = (Current - *SymbolsBase + 1);
454 qsort(*SymbolsBase, *SymbolsCount, sizeof(ROSSYM_ENTRY), (int (*)(const void *, const void *)) CompareSymEntry);
455
457
458 return 0;
459}
460
466};
467
471 char ***Table;
474 void *process;
476 char *PathChop;
479};
480
481static struct DbgHelpLineEntry*
483{
484 if (tab->CurLineEntries == tab->LineEntries)
485 {
486 struct DbgHelpLineEntry *newEntries = realloc(tab->LineEntryData,
487 tab->LineEntries * 2 * sizeof(struct DbgHelpLineEntry));
488
489 if (!newEntries)
490 return 0;
491
492 tab->LineEntryData = newEntries;
493
494 memset(tab->LineEntryData + tab->LineEntries, 0, sizeof(struct DbgHelpLineEntry) * tab->LineEntries);
495 tab->LineEntries *= 2;
496 }
497
498 return &tab->LineEntryData[tab->CurLineEntries++];
499}
500
501static int
503{
504 unsigned int bucket = ComputeDJBHash(name) % tab->Length;
505 char **tabEnt = tab->Table[bucket];
506 int i;
507 char **newBucket;
508
509 if (tabEnt)
510 {
511 for (i = 0; tabEnt[i] && strcmp(tabEnt[i], name); i++);
512 if (tabEnt[i])
513 {
514 free(name);
515 return (i << 10) | bucket;
516 }
517 }
518 else
519 i = 0;
520
521 /* At this point, we need to insert */
522 tab->Bytes += strlen(name) + 1;
523
524 newBucket = realloc(tab->Table[bucket], (i+2) * sizeof(char *));
525
526 if (!newBucket)
527 {
528 fprintf(stderr, "realloc failed!\n");
529 return -1;
530 }
531
532 tab->Table[bucket] = newBucket;
533 tab->Table[bucket][i+1] = 0;
534 tab->Table[bucket][i] = name;
535 return (i << 10) | bucket;
536}
537
538const char*
540{
541 int i = id >> 10;
542 int bucket = id & 0x3ff;
543 return tab->Table[bucket][i];
544}
545
546/* Remove a prefix of PathChop if it exists and return a copy of the tail. */
547static char *
548StrDupShortenPath(char *PathChop, char *FilePath)
549{
550 int pclen = strlen(PathChop);
551 if (!strncmp(FilePath, PathChop, pclen))
552 {
553 return strdup(FilePath+pclen);
554 }
555 else
556 {
557 return strdup(FilePath);
558 }
559}
560
561static BOOL
562DbgHelpAddLineNumber(PSRCCODEINFO LineInfo, void *UserContext)
563{
564 struct DbgHelpStringTab *tab = (struct DbgHelpStringTab *)UserContext;
565 DWORD64 disp;
566 int fileId, functionId;
568 if (!pSymbol) return FALSE;
570
571 /* If any file can be opened by relative path up to a certain level, then
572 record that path. */
573 if (!tab->PathChop)
574 {
575 int i, endLen;
576 char *end = strrchr(LineInfo->FileName, '/');
577
578 if (!end)
579 end = strrchr(LineInfo->FileName, '\\');
580
581 if (end)
582 {
583 for (i = (end - LineInfo->FileName) - 1; i >= 0; i--)
584 {
585 if (LineInfo->FileName[i] == '/' || LineInfo->FileName[i] == '\\')
586 {
587 char *synthname = malloc(strlen(tab->SourcePath) +
588 strlen(LineInfo->FileName + i + 1)
589 + 2);
590 strcpy(synthname, tab->SourcePath);
591 strcat(synthname, "/");
592 strcat(synthname, LineInfo->FileName + i + 1);
593 FILE *f = fopen(synthname, "r");
594 free(synthname);
595 if (f)
596 {
597 fclose(f);
598 break;
599 }
600 }
601 }
602
603 i++; /* Be in the string or past the next slash */
604 tab->PathChop = malloc(i + 1);
605 memcpy(tab->PathChop, LineInfo->FileName, i);
606 tab->PathChop[i] = 0;
607 }
608 }
609
610 fileId = DbgHelpAddStringToTable(tab,
612 LineInfo->FileName));
613
614 pSymbol->SizeOfStruct = sizeof(SYMBOL_INFO);
615 pSymbol->MaxNameLen = MAX_SYM_NAME;
616
617 if (!SymFromAddr(tab->process, LineInfo->Address, &disp, pSymbol))
618 {
619 //fprintf(stderr, "SymFromAddr failed.\n");
620 free(pSymbol);
621 return FALSE;
622 }
623
624 functionId = DbgHelpAddStringToTable(tab, strdup(pSymbol->Name));
625
626 if (LineInfo->Address == 0)
627 fprintf(stderr, "Address is 0.\n");
628
630 tab->lastLineEntry->vma = LineInfo->Address - LineInfo->ModBase;
631 tab->lastLineEntry->functionId = functionId;
632 tab->lastLineEntry->fileId = fileId;
633 tab->lastLineEntry->line = LineInfo->LineNumber;
634
635 free(pSymbol);
636 return TRUE;
637}
638
639static int
641 ULONG *SymbolsCount, PROSSYM_ENTRY *SymbolsBase,
642 ULONG *StringsLength, void **StringsBase)
643{
644 char *strings, *strings_copy;
645 int i, j, bucket, entry;
646 PROSSYM_ENTRY rossym;
647 struct DbgHelpStringTab strtab = { 0 };
648
649 strtab.process = process;
650 strtab.module_base = module_base;
651 strtab.Bytes = 1;
652 strtab.Length = 1024;
653 strtab.Table = calloc(1024, sizeof(const char **));
654 strtab.Table[0] = calloc(2, sizeof(const char *));
655 strtab.Table[0][0] = strdup(""); // The zero string
656 strtab.CurLineEntries = 0;
657 strtab.LineEntries = 16384;
658 strtab.LineEntryData = calloc(strtab.LineEntries, sizeof(struct DbgHelpLineEntry));
659 strtab.PathChop = NULL;
660 strtab.SourcePath = SourcePath ? SourcePath : "";
661
663
664 /* Transcribe necessary strings */
665 *StringsLength = strtab.Bytes;
666 strings = strings_copy = ((char *)(*StringsBase = malloc(strtab.Bytes)));
667
668 /* Copy in strings */
669 for (i = 0; i < strtab.Length; i++)
670 {
671 for (j = 0; strtab.Table[i] && strtab.Table[i][j]; j++)
672 {
673 /* Each entry is replaced by its corresponding entry in our string
674 section. We can substract the strings origin to get an offset. */
675 char *toFree = strtab.Table[i][j];
676 strtab.Table[i][j] = strcpy(strings_copy, strtab.Table[i][j]);
677 free(toFree);
678 strings_copy += strlen(strings_copy) + 1;
679 }
680 }
681
682 assert(strings_copy == strings + strtab.Bytes);
683
684 *SymbolsBase = calloc(strtab.CurLineEntries, sizeof(ROSSYM_ENTRY));
685 *SymbolsCount = strtab.CurLineEntries;
686
687 /* Copy symbols into rossym entries */
688 for (i = 0; i < strtab.CurLineEntries; i++)
689 {
690 rossym = &(*SymbolsBase)[i];
691 rossym->Address = strtab.LineEntryData[i].vma;
692 bucket = strtab.LineEntryData[i].fileId & 0x3ff;
693 entry = strtab.LineEntryData[i].fileId >> 10;
694 rossym->FileOffset = strtab.Table[bucket][entry] - strings;
695 bucket = strtab.LineEntryData[i].functionId & 0x3ff;
696 entry = strtab.LineEntryData[i].functionId >> 10;
697 rossym->FunctionOffset = strtab.Table[bucket][entry] - strings;
698 rossym->SourceLine = strtab.LineEntryData[i].line;
699 }
700
701 /* Free stringtab */
702 for (i = 0; i < strtab.Length; i++)
703 {
704 free(strtab.Table[i]);
705 }
706
707 free(strtab.LineEntryData);
708 free(strtab.PathChop);
709
710 qsort(*SymbolsBase, *SymbolsCount, sizeof(ROSSYM_ENTRY), (int (*)(const void *, const void *))CompareSymEntry);
711
712 return 0;
713}
714
715static int
716MergeStabsAndCoffs(ULONG *MergedSymbolCount, PROSSYM_ENTRY *MergedSymbols,
717 ULONG StabSymbolsCount, PROSSYM_ENTRY StabSymbols,
718 ULONG CoffSymbolsCount, PROSSYM_ENTRY CoffSymbols)
719{
720 ULONG StabIndex, j;
721 ULONG CoffIndex;
722 ULONG_PTR StabFunctionStartAddress;
723 ULONG StabFunctionStringOffset, NewStabFunctionStringOffset, CoffFunctionStringOffset;
724 PROSSYM_ENTRY CoffFunctionSymbol;
725
726 *MergedSymbolCount = 0;
727 if (StabSymbolsCount == 0)
728 {
729 *MergedSymbols = NULL;
730 return 0;
731 }
732 *MergedSymbols = malloc((StabSymbolsCount + CoffSymbolsCount) * sizeof(ROSSYM_ENTRY));
733 if (*MergedSymbols == NULL)
734 {
735 fprintf(stderr, "Unable to allocate memory for merged symbols\n");
736 return 1;
737 }
738
739 StabFunctionStartAddress = 0;
740 StabFunctionStringOffset = 0;
741 CoffFunctionStringOffset = 0;
742 CoffFunctionSymbol = NULL;
743 CoffIndex = 0;
744 for (StabIndex = 0; StabIndex < StabSymbolsCount; StabIndex++)
745 {
746 (*MergedSymbols)[*MergedSymbolCount] = StabSymbols[StabIndex];
747 for (j = StabIndex + 1;
748 j < StabSymbolsCount && StabSymbols[j].Address == StabSymbols[StabIndex].Address;
749 j++)
750 {
751 if (StabSymbols[j].FileOffset != 0 && (*MergedSymbols)[*MergedSymbolCount].FileOffset == 0)
752 {
753 (*MergedSymbols)[*MergedSymbolCount].FileOffset = StabSymbols[j].FileOffset;
754 }
755 if (StabSymbols[j].FunctionOffset != 0 && (*MergedSymbols)[*MergedSymbolCount].FunctionOffset == 0)
756 {
757 (*MergedSymbols)[*MergedSymbolCount].FunctionOffset = StabSymbols[j].FunctionOffset;
758 }
759 if (StabSymbols[j].SourceLine != 0 && (*MergedSymbols)[*MergedSymbolCount].SourceLine == 0)
760 {
761 (*MergedSymbols)[*MergedSymbolCount].SourceLine = StabSymbols[j].SourceLine;
762 }
763 }
764 StabIndex = j - 1;
765
766 while (CoffIndex < CoffSymbolsCount &&
767 CoffSymbols[CoffIndex].Address <= (*MergedSymbols)[*MergedSymbolCount].Address)
768 {
769 if (CoffSymbols[CoffIndex].FunctionOffset != 0)
770 {
771 CoffFunctionSymbol = &CoffSymbols[CoffIndex];
772 CoffFunctionStringOffset = CoffFunctionSymbol->FunctionOffset;
773 }
774 CoffIndex++;
775 }
776 NewStabFunctionStringOffset = (*MergedSymbols)[*MergedSymbolCount].FunctionOffset;
777 if (CoffFunctionSymbol &&
778 CoffFunctionSymbol->Address <= (*MergedSymbols)[*MergedSymbolCount].Address &&
779 StabFunctionStartAddress < CoffFunctionSymbol->Address)
780 {
781 (*MergedSymbols)[*MergedSymbolCount].FunctionOffset = CoffFunctionStringOffset;
782 CoffFunctionSymbol->FunctionOffset = 0;
783 }
784 if (StabFunctionStringOffset != NewStabFunctionStringOffset)
785 {
786 StabFunctionStartAddress = (*MergedSymbols)[*MergedSymbolCount].Address;
787 }
788 StabFunctionStringOffset = NewStabFunctionStringOffset;
789 (*MergedSymbolCount)++;
790 }
791 /* Handle functions that have no analog in the upstream data */
792 for (CoffIndex = 0; CoffIndex < CoffSymbolsCount; CoffIndex++)
793 {
794 if (CoffSymbols[CoffIndex].Address &&
795 CoffSymbols[CoffIndex].FunctionOffset)
796 {
797 (*MergedSymbols)[*MergedSymbolCount] = CoffSymbols[CoffIndex];
798 (*MergedSymbolCount)++;
799 }
800 }
801
802 qsort(*MergedSymbols, *MergedSymbolCount, sizeof(ROSSYM_ENTRY), (int (*)(const void *, const void *)) CompareSymEntry);
803
804 return 0;
805}
806
808FindSectionForRVA(DWORD RVA, unsigned NumberOfSections, PIMAGE_SECTION_HEADER SectionHeaders)
809{
810 unsigned Section;
811
812 for (Section = 0; Section < NumberOfSections; Section++)
813 {
814 if (SectionHeaders[Section].VirtualAddress <= RVA &&
815 RVA < SectionHeaders[Section].VirtualAddress + SectionHeaders[Section].Misc.VirtualSize)
816 {
817 return SectionHeaders + Section;
818 }
819 }
820
821 return NULL;
822}
823
824static int
825ProcessRelocations(ULONG *ProcessedRelocsLength, void **ProcessedRelocs,
826 void *RawData, PIMAGE_OPTIONAL_HEADER OptHeader,
827 unsigned NumberOfSections, PIMAGE_SECTION_HEADER SectionHeaders)
828{
829 PIMAGE_SECTION_HEADER RelocSectionHeader, TargetSectionHeader;
830 PIMAGE_BASE_RELOCATION BaseReloc, End, AcceptedRelocs;
831 int Found;
832
835 {
836 /* No relocation entries */
837 *ProcessedRelocsLength = 0;
838 *ProcessedRelocs = NULL;
839 return 0;
840 }
841
843 NumberOfSections, SectionHeaders);
844 if (RelocSectionHeader == NULL)
845 {
846 fprintf(stderr, "Can't find section header for relocation data\n");
847 return 1;
848 }
849
850 *ProcessedRelocs = malloc(RelocSectionHeader->SizeOfRawData);
851 if (*ProcessedRelocs == NULL)
852 {
854 "Failed to allocate %u bytes for relocations\n",
855 (unsigned int)RelocSectionHeader->SizeOfRawData);
856 return 1;
857 }
858 *ProcessedRelocsLength = 0;
859
860 BaseReloc = (PIMAGE_BASE_RELOCATION) ((char *) RawData +
861 RelocSectionHeader->PointerToRawData +
863 RelocSectionHeader->VirtualAddress));
864 End = (PIMAGE_BASE_RELOCATION) ((char *) BaseReloc +
866
867 while (BaseReloc < End && BaseReloc->SizeOfBlock > 0)
868 {
869 TargetSectionHeader = FindSectionForRVA(BaseReloc->VirtualAddress,
870 NumberOfSections,
871 SectionHeaders);
872 if (TargetSectionHeader != NULL)
873 {
874 AcceptedRelocs = *ProcessedRelocs;
875 Found = 0;
876 while (AcceptedRelocs < (PIMAGE_BASE_RELOCATION) ((char *) *ProcessedRelocs +
877 *ProcessedRelocsLength)
878 && !Found)
879 {
880 Found = BaseReloc->SizeOfBlock == AcceptedRelocs->SizeOfBlock &&
881 memcmp(BaseReloc, AcceptedRelocs, AcceptedRelocs->SizeOfBlock) == 0;
882 AcceptedRelocs = (PIMAGE_BASE_RELOCATION) ((char *) AcceptedRelocs +
883 AcceptedRelocs->SizeOfBlock);
884 }
885 if (!Found)
886 {
887 memcpy((char *) *ProcessedRelocs + *ProcessedRelocsLength,
888 BaseReloc,
889 BaseReloc->SizeOfBlock);
890 *ProcessedRelocsLength += BaseReloc->SizeOfBlock;
891 }
892 }
893 BaseReloc = (PIMAGE_BASE_RELOCATION)((char *) BaseReloc + BaseReloc->SizeOfBlock);
894 }
895
896 return 0;
897}
898
899static const BYTE*
900GetSectionName(void *StringsBase, const BYTE *SectionTitle)
901{
902 if (SectionTitle[0] == '/')
903 {
904 int offset = atoi((char*)SectionTitle+1);
905 return ((BYTE *)StringsBase) + offset;
906 }
907 else
908 return SectionTitle;
909}
910
911static int
912CreateOutputFile(FILE *OutFile, void *InData,
913 PIMAGE_DOS_HEADER InDosHeader, PIMAGE_FILE_HEADER InFileHeader,
914 PIMAGE_OPTIONAL_HEADER InOptHeader, PIMAGE_SECTION_HEADER InSectionHeaders,
915 ULONG RosSymLength, void *RosSymSection)
916{
917 ULONG StartOfRawData;
918 unsigned Section;
919 void *OutHeader, *ProcessedRelocs, *PaddedRosSym, *Data;
920 unsigned char *PaddedStringTable;
921 PIMAGE_DOS_HEADER OutDosHeader;
922 PIMAGE_FILE_HEADER OutFileHeader;
923 PIMAGE_OPTIONAL_HEADER OutOptHeader;
924 PIMAGE_SECTION_HEADER OutSectionHeaders, CurrentSectionHeader;
925 DWORD CheckSum;
926 ULONG Length, i;
927 ULONG ProcessedRelocsLength;
928 ULONG RosSymOffset, RosSymFileLength;
929 ULONG PaddedStringTableLength;
930 int InRelocSectionIndex;
931 PIMAGE_SECTION_HEADER OutRelocSection;
932 /* Each coff symbol is 18 bytes and the string table follows */
933 char *StringTable = (char *)InData +
934 InFileHeader->PointerToSymbolTable + 18 * InFileHeader->NumberOfSymbols;
935 ULONG StringTableLength = 0;
936 ULONG StringTableLocation;
937
938 StartOfRawData = 0;
939 for (Section = 0; Section < InFileHeader->NumberOfSections; Section++)
940 {
941 const BYTE *SectionName = GetSectionName(StringTable,
942 InSectionHeaders[Section].Name);
943 if (InSectionHeaders[Section].Name[0] == '/')
944 {
945 StringTableLength = atoi((const char *)InSectionHeaders[Section].Name + 1) +
946 strlen((const char *)SectionName) + 1;
947 }
948 if ((StartOfRawData == 0 || InSectionHeaders[Section].PointerToRawData < StartOfRawData)
949 && InSectionHeaders[Section].PointerToRawData != 0
950 && (strncmp((char *) SectionName, ".stab", 5)) != 0
951 && (strncmp((char *) SectionName, ".debug_", 7)) != 0)
952 {
953 StartOfRawData = InSectionHeaders[Section].PointerToRawData;
954 }
955 }
956 OutHeader = malloc(StartOfRawData);
957 if (OutHeader == NULL)
958 {
960 "Failed to allocate %u bytes for output file header\n",
961 (unsigned int)StartOfRawData);
962 return 1;
963 }
964 memset(OutHeader, '\0', StartOfRawData);
965
966 OutDosHeader = (PIMAGE_DOS_HEADER) OutHeader;
967 memcpy(OutDosHeader, InDosHeader, InDosHeader->e_lfanew + sizeof(ULONG));
968
969 OutFileHeader = (PIMAGE_FILE_HEADER)((char *) OutHeader + OutDosHeader->e_lfanew + sizeof(ULONG));
970 memcpy(OutFileHeader, InFileHeader, sizeof(IMAGE_FILE_HEADER));
971 OutFileHeader->PointerToSymbolTable = 0;
972 OutFileHeader->NumberOfSymbols = 0;
975
976 OutOptHeader = (PIMAGE_OPTIONAL_HEADER)(OutFileHeader + 1);
977 memcpy(OutOptHeader, InOptHeader, sizeof(IMAGE_OPTIONAL_HEADER));
978 OutOptHeader->CheckSum = 0;
979
980 OutSectionHeaders = (PIMAGE_SECTION_HEADER)((char *) OutOptHeader + OutFileHeader->SizeOfOptionalHeader);
981
982 if (ProcessRelocations(&ProcessedRelocsLength,
983 &ProcessedRelocs,
984 InData,
985 InOptHeader,
986 InFileHeader->NumberOfSections,
987 InSectionHeaders))
988 {
989 return 1;
990 }
993 {
994 InRelocSectionIndex = -1;
995 }
996 else
997 {
999 InFileHeader->NumberOfSections, InSectionHeaders) - InSectionHeaders;
1000 }
1001
1002 OutFileHeader->NumberOfSections = 0;
1003 CurrentSectionHeader = OutSectionHeaders;
1004 OutOptHeader->SizeOfImage = 0;
1005 RosSymOffset = 0;
1006 OutRelocSection = NULL;
1007
1008 StringTableLocation = StartOfRawData;
1009
1010 for (Section = 0; Section < InFileHeader->NumberOfSections; Section++)
1011 {
1012 const BYTE *SectionName = GetSectionName(StringTable,
1013 InSectionHeaders[Section].Name);
1014 if ((strncmp((char *) SectionName, ".stab", 5) != 0) &&
1015 (strncmp((char *) SectionName, ".debug_", 7)) != 0)
1016 {
1017 *CurrentSectionHeader = InSectionHeaders[Section];
1018 CurrentSectionHeader->PointerToLinenumbers = 0;
1019 CurrentSectionHeader->NumberOfLinenumbers = 0;
1020 if (OutOptHeader->SizeOfImage < CurrentSectionHeader->VirtualAddress +
1021 CurrentSectionHeader->Misc.VirtualSize)
1022 {
1023 OutOptHeader->SizeOfImage = ROUND_UP(CurrentSectionHeader->VirtualAddress +
1024 CurrentSectionHeader->Misc.VirtualSize,
1025 OutOptHeader->SectionAlignment);
1026 }
1027 if (RosSymOffset < CurrentSectionHeader->PointerToRawData + CurrentSectionHeader->SizeOfRawData)
1028 {
1029 RosSymOffset = CurrentSectionHeader->PointerToRawData + CurrentSectionHeader->SizeOfRawData;
1030 }
1031 if (Section == (ULONG)InRelocSectionIndex)
1032 {
1033 OutRelocSection = CurrentSectionHeader;
1034 }
1035 StringTableLocation = CurrentSectionHeader->PointerToRawData + CurrentSectionHeader->SizeOfRawData;
1036 OutFileHeader->NumberOfSections++;
1037 CurrentSectionHeader++;
1038 }
1039 }
1040
1041 if (OutRelocSection == CurrentSectionHeader - 1)
1042 {
1043 OutOptHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].Size = ProcessedRelocsLength;
1044 if (OutOptHeader->SizeOfImage == OutRelocSection->VirtualAddress +
1045 ROUND_UP(OutRelocSection->Misc.VirtualSize,
1046 OutOptHeader->SectionAlignment))
1047 {
1048 OutOptHeader->SizeOfImage = OutRelocSection->VirtualAddress +
1049 ROUND_UP(ProcessedRelocsLength,
1050 OutOptHeader->SectionAlignment);
1051 }
1052 OutRelocSection->Misc.VirtualSize = ProcessedRelocsLength;
1053 if (RosSymOffset == OutRelocSection->PointerToRawData +
1054 OutRelocSection->SizeOfRawData)
1055 {
1056 RosSymOffset = OutRelocSection->PointerToRawData +
1057 ROUND_UP(ProcessedRelocsLength,
1058 OutOptHeader->FileAlignment);
1059 }
1060 OutRelocSection->SizeOfRawData = ROUND_UP(ProcessedRelocsLength,
1061 OutOptHeader->FileAlignment);
1062 }
1063
1064 if (RosSymLength > 0)
1065 {
1066 RosSymFileLength = ROUND_UP(RosSymLength, OutOptHeader->FileAlignment);
1067 memcpy(CurrentSectionHeader->Name, ".rossym", 8); /* We're lucky: string is exactly 8 bytes long */
1068 CurrentSectionHeader->Misc.VirtualSize = RosSymLength;
1069 CurrentSectionHeader->VirtualAddress = OutOptHeader->SizeOfImage;
1070 CurrentSectionHeader->SizeOfRawData = RosSymFileLength;
1071 CurrentSectionHeader->PointerToRawData = RosSymOffset;
1072 CurrentSectionHeader->PointerToRelocations = 0;
1073 CurrentSectionHeader->PointerToLinenumbers = 0;
1074 CurrentSectionHeader->NumberOfRelocations = 0;
1075 CurrentSectionHeader->NumberOfLinenumbers = 0;
1078 OutOptHeader->SizeOfImage = ROUND_UP(CurrentSectionHeader->VirtualAddress + CurrentSectionHeader->Misc.VirtualSize,
1079 OutOptHeader->SectionAlignment);
1080 OutFileHeader->NumberOfSections++;
1081
1082 PaddedRosSym = malloc(RosSymFileLength);
1083 if (PaddedRosSym == NULL)
1084 {
1086 "Failed to allocate %u bytes for padded .rossym\n",
1087 (unsigned int)RosSymFileLength);
1088 return 1;
1089 }
1090 memcpy(PaddedRosSym, RosSymSection, RosSymLength);
1091 memset((char *) PaddedRosSym + RosSymLength,
1092 '\0',
1093 RosSymFileLength - RosSymLength);
1094
1095 /* Position the string table after our new section */
1096 StringTableLocation = RosSymOffset + RosSymFileLength;
1097 }
1098 else
1099 {
1100 PaddedRosSym = NULL;
1101 }
1102
1103 /* Set the string table area in the header if we need it */
1104 if (StringTableLength)
1105 {
1106 OutFileHeader->PointerToSymbolTable = StringTableLocation;
1107 OutFileHeader->NumberOfSymbols = 0;
1108 }
1109
1110 CheckSum = 0;
1111 for (i = 0; i < StartOfRawData / 2; i++)
1112 {
1113 CheckSum += ((unsigned short*) OutHeader)[i];
1114 CheckSum = 0xffff & (CheckSum + (CheckSum >> 16));
1115 }
1116 Length = StartOfRawData;
1117 for (Section = 0; Section < OutFileHeader->NumberOfSections; Section++)
1118 {
1119 DWORD SizeOfRawData;
1120 if (OutRelocSection == OutSectionHeaders + Section)
1121 {
1122 Data = (void *) ProcessedRelocs;
1123 SizeOfRawData = ProcessedRelocsLength;
1124 }
1125 else if (RosSymLength > 0 && Section + 1 == OutFileHeader->NumberOfSections)
1126 {
1127 Data = (void *) PaddedRosSym;
1128 SizeOfRawData = OutSectionHeaders[Section].SizeOfRawData;
1129 }
1130 else
1131 {
1132 Data = (void *) ((char *) InData + OutSectionHeaders[Section].PointerToRawData);
1133 SizeOfRawData = OutSectionHeaders[Section].SizeOfRawData;
1134 }
1135 for (i = 0; i < SizeOfRawData / 2; i++)
1136 {
1137 CheckSum += ((unsigned short*) Data)[i];
1138 CheckSum = 0xffff & (CheckSum + (CheckSum >> 16));
1139 }
1140 Length += OutSectionHeaders[Section].SizeOfRawData;
1141 }
1142
1143 if (OutFileHeader->PointerToSymbolTable)
1144 {
1145 int PaddingFrom = (OutFileHeader->PointerToSymbolTable + StringTableLength) %
1146 OutOptHeader->FileAlignment;
1147 int PaddingSize = PaddingFrom ? OutOptHeader->FileAlignment - PaddingFrom : 0;
1148
1149 PaddedStringTableLength = StringTableLength + PaddingSize;
1150 PaddedStringTable = malloc(PaddedStringTableLength);
1151 /* COFF string section is preceeded by a length */
1152 assert(sizeof(StringTableLength) == 4);
1153 memcpy(PaddedStringTable, &StringTableLength, sizeof(StringTableLength));
1154 /* We just copy enough of the string table to contain the strings we want
1155 The string table length technically counts as part of the string table
1156 space itself. */
1157 memcpy(PaddedStringTable + 4, StringTable + 4, StringTableLength - 4);
1158 memset(PaddedStringTable + StringTableLength, 0, PaddingSize);
1159
1160 assert(OutFileHeader->PointerToSymbolTable % 2 == 0);
1161 for (i = 0; i < PaddedStringTableLength / 2; i++)
1162 {
1163 CheckSum += ((unsigned short*)PaddedStringTable)[i];
1164 CheckSum = 0xffff & (CheckSum + (CheckSum >> 16));
1165 }
1166 Length += PaddedStringTableLength;
1167 }
1168 else
1169 {
1170 PaddedStringTable = NULL;
1171 }
1172
1173 CheckSum += Length;
1174 OutOptHeader->CheckSum = CheckSum;
1175
1176 if (fwrite(OutHeader, 1, StartOfRawData, OutFile) != StartOfRawData)
1177 {
1178 perror("Error writing output header\n");
1179 free(OutHeader);
1180 return 1;
1181 }
1182
1183 for (Section = 0; Section < OutFileHeader->NumberOfSections; Section++)
1184 {
1185 if (OutSectionHeaders[Section].SizeOfRawData != 0)
1186 {
1187 DWORD SizeOfRawData;
1188 fseek(OutFile, OutSectionHeaders[Section].PointerToRawData, SEEK_SET);
1189 if (OutRelocSection == OutSectionHeaders + Section)
1190 {
1191 Data = (void *) ProcessedRelocs;
1192 SizeOfRawData = ProcessedRelocsLength;
1193 }
1194 else if (RosSymLength > 0 && Section + 1 == OutFileHeader->NumberOfSections)
1195 {
1196 Data = (void *) PaddedRosSym;
1197 SizeOfRawData = OutSectionHeaders[Section].SizeOfRawData;
1198 }
1199 else
1200 {
1201 Data = (void *) ((char *) InData + OutSectionHeaders[Section].PointerToRawData);
1202 SizeOfRawData = OutSectionHeaders[Section].SizeOfRawData;
1203 }
1204 if (fwrite(Data, 1, SizeOfRawData, OutFile) != SizeOfRawData)
1205 {
1206 perror("Error writing section data\n");
1207 free(PaddedRosSym);
1208 free(OutHeader);
1209 return 1;
1210 }
1211 }
1212 }
1213
1214 if (PaddedStringTable)
1215 {
1216 fseek(OutFile, OutFileHeader->PointerToSymbolTable, SEEK_SET);
1217 fwrite(PaddedStringTable, 1, PaddedStringTableLength, OutFile);
1218 free(PaddedStringTable);
1219 }
1220
1221 if (PaddedRosSym)
1222 {
1223 free(PaddedRosSym);
1224 }
1225 free(OutHeader);
1226
1227 return 0;
1228}
1229
1230int main(int argc, char* argv[])
1231{
1232 PSYMBOLFILE_HEADER SymbolFileHeader;
1233 PIMAGE_DOS_HEADER PEDosHeader;
1234 PIMAGE_FILE_HEADER PEFileHeader;
1235 PIMAGE_OPTIONAL_HEADER PEOptHeader;
1236 PIMAGE_SECTION_HEADER PESectionHeaders;
1237 ULONG ImageBase;
1238 void *StabBase;
1239 ULONG StabsLength;
1240 void *StabStringBase;
1241 ULONG StabStringsLength;
1242 void *CoffBase = NULL;
1243 ULONG CoffsLength;
1244 void *CoffStringBase = NULL;
1245 ULONG CoffStringsLength;
1246 char* path1;
1247 char* path2;
1248 FILE* out;
1249 void *StringBase = NULL;
1250 ULONG StringsLength = 0;
1251 ULONG StabSymbolsCount = 0;
1252 PROSSYM_ENTRY StabSymbols = NULL;
1253 ULONG CoffSymbolsCount = 0;
1254 PROSSYM_ENTRY CoffSymbols = NULL;
1255 ULONG MergedSymbolsCount = 0;
1256 PROSSYM_ENTRY MergedSymbols = NULL;
1257 size_t FileSize;
1258 void *FileData;
1259 ULONG RosSymLength;
1260 void *RosSymSection;
1262 void *file;
1263 char elfhdr[4] = { '\177', 'E', 'L', 'F' };
1264 BOOLEAN UseDbgHelp = FALSE;
1265 int arg, argstate = 0;
1266 char *SourcePath = NULL;
1267
1268 for (arg = 1; arg < argc; arg++)
1269 {
1270 switch (argstate)
1271 {
1272 default:
1273 argstate = -1;
1274 break;
1275
1276 case 0:
1277 if (!strcmp(argv[arg], "-s"))
1278 {
1279 argstate = 1;
1280 }
1281 else
1282 {
1283 argstate = 2;
1285 }
1286 break;
1287
1288 case 1:
1291 argstate = 0;
1292 break;
1293
1294 case 2:
1296 argstate = 3;
1297 break;
1298 }
1299 }
1300
1301 if (argstate != 3)
1302 {
1303 fprintf(stderr, "Usage: rsym [-s <sources>] <input> <output>\n");
1304 exit(1);
1305 }
1306
1308 if (!FileData)
1309 {
1310 fprintf(stderr, "An error occured loading '%s'\n", path1);
1311 exit(1);
1312 }
1313
1314 file = fopen(path1, "rb");
1315
1316 /* Check if MZ header exists */
1317 PEDosHeader = (PIMAGE_DOS_HEADER) FileData;
1318 if (PEDosHeader->e_magic != IMAGE_DOS_MAGIC ||
1319 PEDosHeader->e_lfanew == 0L)
1320 {
1321 /* Ignore elf */
1322 if (!memcmp(PEDosHeader, elfhdr, sizeof(elfhdr)))
1323 exit(0);
1324 perror("Input file is not a PE image.\n");
1325 free(FileData);
1326 exit(1);
1327 }
1328
1329 /* Locate PE file header */
1330 /* sizeof(ULONG) = sizeof(MAGIC) */
1331 PEFileHeader = (PIMAGE_FILE_HEADER)((char *) FileData + PEDosHeader->e_lfanew + sizeof(ULONG));
1332
1333 /* Locate optional header */
1334 assert(sizeof(ULONG) == 4);
1335 PEOptHeader = (PIMAGE_OPTIONAL_HEADER)(PEFileHeader + 1);
1336 ImageBase = PEOptHeader->ImageBase;
1337
1338 /* Locate PE section headers */
1339 PESectionHeaders = (PIMAGE_SECTION_HEADER)((char *) PEOptHeader + PEFileHeader->SizeOfOptionalHeader);
1340
1342 PEFileHeader,
1343 PESectionHeaders,
1344 &StabsLength,
1345 &StabBase,
1346 &StabStringsLength,
1347 &StabStringBase))
1348 {
1349 free(FileData);
1350 exit(1);
1351 }
1352
1353 if (StabsLength == 0)
1354 {
1355 // SYMOPT_AUTO_PUBLICS
1356 // SYMOPT_FAVOR_COMPRESSED
1357 // SYMOPT_LOAD_ANYTHING
1358 // SYMOPT_LOAD_LINES
1359 SymSetOptions(0x10000 | 0x800000 | 0x40 | 0x10);
1361 SymInitialize(FileData, ".", 0);
1362
1363 module_base = SymLoadModule(FileData, file, path1, path1, 0, FileSize) & 0xffffffff;
1364
1367 SourcePath,
1368 &StabSymbolsCount,
1369 &StabSymbols,
1370 &StringsLength,
1371 &StringBase))
1372 {
1373 free(FileData);
1374 exit(1);
1375 }
1376
1377 UseDbgHelp = TRUE;
1380 }
1381
1383 PEFileHeader,
1384 PESectionHeaders,
1385 &CoffsLength,
1386 &CoffBase,
1387 &CoffStringsLength,
1388 &CoffStringBase))
1389 {
1390 free(FileData);
1391 exit(1);
1392 }
1393
1394 if (!UseDbgHelp)
1395 {
1396 StringBase = malloc(1 + StringsLength + CoffStringsLength +
1397 (CoffsLength / sizeof(ROSSYM_ENTRY)) * (E_SYMNMLEN + 1));
1398 if (StringBase == NULL)
1399 {
1400 free(FileData);
1401 fprintf(stderr, "Failed to allocate memory for strings table\n");
1402 exit(1);
1403 }
1404 /* Make offset 0 into an empty string */
1405 *((char *) StringBase) = '\0';
1406 StringsLength = 1;
1407
1408 if (ConvertStabs(&StabSymbolsCount,
1409 &StabSymbols,
1410 &StringsLength,
1411 StringBase,
1412 StabsLength,
1413 StabBase,
1414 StabStringsLength,
1415 StabStringBase,
1416 ImageBase,
1417 PEFileHeader,
1418 PESectionHeaders))
1419 {
1420 free(StringBase);
1421 free(FileData);
1422 fprintf(stderr, "Failed to allocate memory for strings table\n");
1423 exit(1);
1424 }
1425 }
1426 else
1427 {
1428 StringBase = realloc(StringBase, StringsLength + CoffStringsLength);
1429 if (!StringBase)
1430 {
1431 free(FileData);
1432 fprintf(stderr, "Failed to allocate memory for strings table\n");
1433 exit(1);
1434 }
1435 }
1436
1437 if (ConvertCoffs(&CoffSymbolsCount,
1438 &CoffSymbols,
1439 &StringsLength,
1440 StringBase,
1441 CoffsLength,
1442 CoffBase,
1443 CoffStringsLength,
1444 CoffStringBase,
1445 ImageBase,
1446 PEFileHeader,
1447 PESectionHeaders))
1448 {
1449 if (StabSymbols)
1450 {
1451 free(StabSymbols);
1452 }
1453 free(StringBase);
1454 free(FileData);
1455 exit(1);
1456 }
1457
1458 if (MergeStabsAndCoffs(&MergedSymbolsCount,
1459 &MergedSymbols,
1460 StabSymbolsCount,
1461 StabSymbols,
1462 CoffSymbolsCount,
1463 CoffSymbols))
1464 {
1465 if (CoffSymbols)
1466 {
1467 free(CoffSymbols);
1468 }
1469 if (StabSymbols)
1470 {
1471 free(StabSymbols);
1472 }
1473 free(StringBase);
1474 free(FileData);
1475 exit(1);
1476 }
1477
1478 if (CoffSymbols)
1479 {
1480 free(CoffSymbols);
1481 }
1482 if (StabSymbols)
1483 {
1484 free(StabSymbols);
1485 }
1486 if (MergedSymbolsCount == 0)
1487 {
1488 RosSymLength = 0;
1489 RosSymSection = NULL;
1490 }
1491 else
1492 {
1493 RosSymLength = sizeof(SYMBOLFILE_HEADER) +
1494 MergedSymbolsCount * sizeof(ROSSYM_ENTRY) +
1495 StringsLength;
1496
1497 RosSymSection = malloc(RosSymLength);
1498 if (RosSymSection == NULL)
1499 {
1500 free(MergedSymbols);
1501 free(StringBase);
1502 free(FileData);
1503 fprintf(stderr, "Unable to allocate memory for .rossym section\n");
1504 exit(1);
1505 }
1506 memset(RosSymSection, '\0', RosSymLength);
1507
1508 SymbolFileHeader = (PSYMBOLFILE_HEADER)RosSymSection;
1509 SymbolFileHeader->SymbolsOffset = sizeof(SYMBOLFILE_HEADER);
1510 SymbolFileHeader->SymbolsLength = MergedSymbolsCount * sizeof(ROSSYM_ENTRY);
1511 SymbolFileHeader->StringsOffset = SymbolFileHeader->SymbolsOffset +
1512 SymbolFileHeader->SymbolsLength;
1513 SymbolFileHeader->StringsLength = StringsLength;
1514
1515 memcpy((char *) RosSymSection + SymbolFileHeader->SymbolsOffset,
1516 MergedSymbols,
1517 SymbolFileHeader->SymbolsLength);
1518
1519 memcpy((char *) RosSymSection + SymbolFileHeader->StringsOffset,
1520 StringBase,
1521 SymbolFileHeader->StringsLength);
1522
1523 free(MergedSymbols);
1524 }
1525
1526 free(StringBase);
1527 out = fopen(path2, "wb");
1528 if (out == NULL)
1529 {
1530 perror("Cannot open output file");
1531 free(RosSymSection);
1532 free(FileData);
1533 exit(1);
1534 }
1535
1537 FileData,
1538 PEDosHeader,
1539 PEFileHeader,
1540 PEOptHeader,
1541 PESectionHeaders,
1542 RosSymLength,
1543 RosSymSection))
1544 {
1545 fclose(out);
1546 if (RosSymSection)
1547 {
1548 free(RosSymSection);
1549 }
1550 free(FileData);
1551 exit(1);
1552 }
1553
1554 fclose(out);
1555 if (RosSymSection)
1556 {
1557 free(RosSymSection);
1558 }
1559 free(FileData);
1560
1561 return 0;
1562}
1563
1564/* EOF */
WCHAR First[]
Definition: FormatMessage.c:11
PCWSTR FilePath
unsigned char BOOLEAN
static int argc
Definition: ServiceArgs.c:12
char * strcat(char *DstString, const char *SrcString)
Definition: utclib.c:568
int strcmp(const char *String1, const char *String2)
Definition: utclib.c:469
int memcmp(void *Buffer1, void *Buffer2, ACPI_SIZE Count)
Definition: utclib.c:112
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
int strncmp(const char *String1, const char *String2, ACPI_SIZE Count)
Definition: utclib.c:534
char * strcpy(char *DstString, const char *SrcString)
Definition: utclib.c:388
struct NameRec_ * Name
Definition: cdprocs.h:460
static FILEDATA FileData[MAX_FDS]
Definition: fs.c:51
return Found
Definition: dirsup.c:1270
_In_ PFCB _In_ LONGLONG FileOffset
Definition: cdprocs.h:160
#define realloc
Definition: debug_ros.c:6
#define free
Definition: debug_ros.c:5
#define malloc
Definition: debug_ros.c:4
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
BOOL WINAPI SymFromAddr(HANDLE hProcess, DWORD64 Address, DWORD64 *Displacement, PSYMBOL_INFO Symbol)
Definition: symbol.c:1263
BOOL WINAPI SymUnloadModule(HANDLE hProcess, DWORD BaseOfDll)
Definition: module.c:928
#define MAX_SYM_NAME
Definition: compat.h:975
BOOL WINAPI SymCleanup(HANDLE hProcess)
Definition: dbghelp.c:557
BOOL WINAPI SymInitialize(HANDLE hProcess, PCSTR UserSearchPath, BOOL fInvadeProcess)
Definition: dbghelp.c:534
@ SYMOPT_EX_WINE_NATIVE_MODULES
Definition: compat.h:1106
DWORD RVA
Definition: compat.h:1262
struct _SYMBOL_INFO SYMBOL_INFO
BOOL WINAPI SymSetExtendedOption(IMAGEHLP_EXTENDED_OPTIONS option, BOOL value)
Definition: dbghelp.c:609
BOOL WINAPI SymEnumLines(HANDLE hProcess, ULONG64 base, PCSTR compiland, PCSTR srcfile, PSYM_ENUMLINES_CALLBACK cb, PVOID user)
Definition: symbol.c:2177
DWORD WINAPI SymSetOptions(DWORD opts)
Definition: dbghelp.c:585
DWORD WINAPI SymLoadModule(HANDLE hProcess, HANDLE hFile, PCSTR ImageName, PCSTR ModuleName, DWORD BaseOfDll, DWORD SizeOfDll)
Definition: module.c:753
static UINT load_file(MSIRECORD *row, LPVOID param)
Definition: action.c:1031
#define assert(x)
Definition: debug.h:53
int main()
Definition: test.c:6
#define ROUND_UP(n, align)
Definition: eventvwr.h:34
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
struct _IMAGE_DOS_HEADER * PIMAGE_DOS_HEADER
struct _IMAGE_FILE_HEADER * PIMAGE_FILE_HEADER
_Must_inspect_result_ _Out_ PLARGE_INTEGER FileSize
Definition: fsrtlfuncs.h:108
return pTarget Start()
GLuint GLuint end
Definition: gl.h:1545
GLsizei const GLchar *const * strings
Definition: glext.h:7622
GLfloat f
Definition: glext.h:7540
GLuint GLfloat * val
Definition: glext.h:7180
GLfloat GLfloat p
Definition: glext.h:8902
GLintptr offset
Definition: glext.h:5920
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint GLint GLint j
Definition: glfuncs.h:250
_CRTIMP void __cdecl perror(_In_opt_z_ const char *_ErrMsg)
#define stderr
Definition: stdio.h:100
_Check_return_opt_ _CRTIMP int __cdecl fprintf(_Inout_ FILE *_File, _In_z_ _Printf_format_string_ const char *_Format,...)
_Check_return_ _CRTIMP FILE *__cdecl fopen(_In_z_ const char *_Filename, _In_z_ const char *_Mode)
_Check_return_opt_ _CRTIMP int __cdecl fseek(_Inout_ FILE *_File, _In_ long _Offset, _In_ int _Origin)
_Check_return_opt_ _CRTIMP int __cdecl fclose(_Inout_ FILE *_File)
_Check_return_opt_ _CRTIMP size_t __cdecl fwrite(_In_reads_bytes_(_Size *_Count) const void *_Str, _In_ size_t _Size, _In_ size_t _Count, _Inout_ FILE *_File)
_Check_return_ int __cdecl atoi(_In_z_ const char *_Str)
uint32_t entry
Definition: isohybrid.c:63
#define SEEK_SET
Definition: jmemansi.c:26
#define e
Definition: ke_i.h:82
macro IMPORT Name endm macro EXPORT Name global &Name endm macro TEXTAREA section rx align endm macro DATAAREA section rw endm macro RODATAAREA section rw endm macro NESTED_ENTRY Name FuncName equ &Name PrologName equ &Name &_Prolog FuncEndName equ &Name &_end global &FuncName align func &FuncName & FuncName
Definition: kxarm.h:221
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
#define for
Definition: utility.h:88
static const WCHAR path1[]
Definition: path.c:28
static const WCHAR path2[]
Definition: path.c:29
#define argv
Definition: mplay32.c:18
int Count
Definition: noreturn.cpp:7
_In_ ULONG _In_ ULONG Offset
Definition: ntddpcm.h:101
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:102
struct _IMAGE_BASE_RELOCATION * PIMAGE_BASE_RELOCATION
#define IMAGE_SCN_MEM_DISCARDABLE
Definition: ntimage.h:235
#define IMAGE_SCN_MEM_READ
Definition: ntimage.h:240
#define L(x)
Definition: ntvdm.h:50
#define IMAGE_SCN_TYPE_NOLOAD
Definition: pecoff.h:20
#define IMAGE_DOS_MAGIC
Definition: pecoff.h:6
#define IMAGE_SCN_LNK_REMOVE
Definition: pecoff.h:27
#define IMAGE_FILE_LOCAL_SYMS_STRIPPED
Definition: pedump.c:162
struct _IMAGE_SECTION_HEADER * PIMAGE_SECTION_HEADER
#define IMAGE_DIRECTORY_ENTRY_BASERELOC
Definition: pedump.c:264
#define IMAGE_FILE_DEBUG_STRIPPED
Definition: pedump.c:165
struct _IMAGE_OPTIONAL_HEADER * PIMAGE_OPTIONAL_HEADER
#define IMAGE_FILE_LINE_NUMS_STRIPPED
Definition: pedump.c:161
static WCHAR Address[46]
Definition: ping.c:68
char * convert_path(char *origpath)
Definition: rcopy.c:11
static FILE * out
Definition: regtests2xml.c:44
#define calloc
Definition: rosglue.h:14
#define C_EXT
Definition: pe.h:45
#define E_SYMNMLEN
Definition: pe.h:27
struct _ROSSYM_ENTRY ROSSYM_ENTRY
struct _SYMBOLFILE_HEADER * PSYMBOLFILE_HEADER
struct _SYMBOLFILE_HEADER SYMBOLFILE_HEADER
struct _COFF_SYMENT COFF_SYMENT
struct _COFF_SYMENT * PCOFF_SYMENT
struct _STAB_ENTRY STAB_ENTRY
static DWORD StringHash(const WCHAR *str)
_Check_return_ _CRTIMP char *__cdecl strdup(_In_opt_z_ const char *_Src)
_CRT_RESTORE_GCC_WARNINGS _CRT_DISABLE_GCC_WARNINGS _Check_return_ _CRTIMP _CONST_RETURN char *__cdecl strrchr(_In_z_ const char *_Str, _In_ int _Ch)
_Check_return_ _CRTIMP size_t __cdecl strcspn(_In_z_ const char *_Str, _In_z_ const char *_Control)
#define exit(n)
Definition: config.h:202
#define memset(x, y, z)
Definition: compat.h:39
static int DbgHelpAddStringToTable(struct DbgHelpStringTab *tab, char *name)
Definition: rsym.c:502
static void StringHashTableFree(struct StringHashTable *StringTable)
Definition: rsym.c:97
const char * DbgHelpGetString(struct DbgHelpStringTab *tab, int id)
Definition: rsym.c:539
static unsigned int ComputeDJBHash(const char *name)
Definition: rsym.c:51
static int ProcessRelocations(ULONG *ProcessedRelocsLength, void **ProcessedRelocs, void *RawData, PIMAGE_OPTIONAL_HEADER OptHeader, unsigned NumberOfSections, PIMAGE_SECTION_HEADER SectionHeaders)
Definition: rsym.c:825
static ULONG FindOrAddString(struct StringHashTable *StringTable, char *StringToFind, ULONG *StringsLength, void *StringsBase)
Definition: rsym.c:202
static int ConvertDbgHelp(void *process, DWORD module_base, char *SourcePath, ULONG *SymbolsCount, PROSSYM_ENTRY *SymbolsBase, ULONG *StringsLength, void **StringsBase)
Definition: rsym.c:640
static int CreateOutputFile(FILE *OutFile, void *InData, PIMAGE_DOS_HEADER InDosHeader, PIMAGE_FILE_HEADER InFileHeader, PIMAGE_OPTIONAL_HEADER InOptHeader, PIMAGE_SECTION_HEADER InSectionHeaders, ULONG RosSymLength, void *RosSymSection)
Definition: rsym.c:912
static BOOL DbgHelpAddLineNumber(PSRCCODEINFO LineInfo, void *UserContext)
Definition: rsym.c:562
static PIMAGE_SECTION_HEADER FindSectionForRVA(DWORD RVA, unsigned NumberOfSections, PIMAGE_SECTION_HEADER SectionHeaders)
Definition: rsym.c:808
static int MergeStabsAndCoffs(ULONG *MergedSymbolCount, PROSSYM_ENTRY *MergedSymbols, ULONG StabSymbolsCount, PROSSYM_ENTRY StabSymbols, ULONG CoffSymbolsCount, PROSSYM_ENTRY CoffSymbols)
Definition: rsym.c:716
static int GetCoffInfo(void *FileData, PIMAGE_FILE_HEADER PEFileHeader, PIMAGE_SECTION_HEADER PESectionHeaders, ULONG *CoffSymbolsLength, void **CoffSymbolsBase, ULONG *CoffStringsLength, void **CoffStringsBase)
Definition: rsym.c:178
static int ConvertStabs(ULONG *SymbolsCount, PROSSYM_ENTRY *SymbolsBase, ULONG *StringsLength, void *StringsBase, ULONG StabSymbolsLength, void *StabSymbolsBase, ULONG StabStringsLength, void *StabStringsBase, ULONG_PTR ImageBase, PIMAGE_FILE_HEADER PEFileHeader, PIMAGE_SECTION_HEADER PESectionHeaders)
Definition: rsym.c:231
static char * StrDupShortenPath(char *PathChop, char *FilePath)
Definition: rsym.c:548
static void StringHashTableInit(struct StringHashTable *StringTable, ULONG StringsLength, char *StringsBase)
Definition: rsym.c:78
static struct DbgHelpLineEntry * DbgHelpAddLineEntry(struct DbgHelpStringTab *tab)
Definition: rsym.c:482
static int GetStabInfo(void *FileData, PIMAGE_FILE_HEADER PEFileHeader, PIMAGE_SECTION_HEADER PESectionHeaders, ULONG *StabSymbolsLength, void **StabSymbolsBase, ULONG *StabStringsLength, void **StabStringsBase)
Definition: rsym.c:140
static const BYTE * GetSectionName(void *StringsBase, const BYTE *SectionTitle)
Definition: rsym.c:900
static int CompareSymEntry(const PROSSYM_ENTRY SymEntry1, const PROSSYM_ENTRY SymEntry2)
Definition: rsym.c:114
static int ConvertCoffs(ULONG *SymbolsCount, PROSSYM_ENTRY *SymbolsBase, ULONG *StringsLength, void *StringsBase, ULONG CoffSymbolsLength, void *CoffSymbolsBase, ULONG CoffStringsLength, void *CoffStringsBase, ULONG_PTR ImageBase, PIMAGE_FILE_HEADER PEFileHeader, PIMAGE_SECTION_HEADER PESectionHeaders)
Definition: rsym.c:371
static void AddStringToHash(struct StringHashTable *StringTable, unsigned int hash, ULONG Offset, char *StringPtr)
Definition: rsym.c:65
void __cdecl qsort(_Inout_updates_bytes_(_NumOfElements *_SizeOfElements) void *_Base, _In_ size_t _NumOfElements, _In_ size_t _SizeOfElements, _In_ int(__cdecl *_PtFuncCompare)(const void *, const void *))
#define N_SOL
Definition: stabs.c:88
#define N_BINCL
Definition: stabs.c:87
#define N_SO
Definition: stabs.c:84
#define N_SLINE
Definition: stabs.c:82
#define N_FUN
Definition: stabs.c:74
ULONG vma
Definition: rsym.c:462
ULONG functionId
Definition: rsym.c:464
ULONG fileId
Definition: rsym.c:463
ULONG line
Definition: rsym.c:465
void * process
Definition: rsym.c:474
ULONG CurLineEntries
Definition: rsym.c:472
char * SourcePath
Definition: rsym.c:477
DWORD module_base
Definition: rsym.c:475
char * PathChop
Definition: rsym.c:476
ULONG Bytes
Definition: rsym.c:470
ULONG LineEntries
Definition: rsym.c:472
char *** Table
Definition: rsym.c:471
ULONG Length
Definition: rsym.c:469
struct DbgHelpLineEntry * lastLineEntry
Definition: rsym.c:478
struct DbgHelpLineEntry * LineEntryData
Definition: rsym.c:473
struct StringEntry * Next
Definition: rsym.c:38
char * String
Definition: rsym.c:40
ULONG Offset
Definition: rsym.c:39
ULONG TableSize
Definition: rsym.c:45
struct StringEntry ** Table
Definition: rsym.c:46
ULONG e_value
Definition: rsym.h:152
UCHAR e_numaux
Definition: rsym.h:156
short e_scnum
Definition: rsym.h:153
DWORD NumberOfSymbols
Definition: ntddk_ex.h:126
DWORD PointerToSymbolTable
Definition: ntddk_ex.h:125
WORD SizeOfOptionalHeader
Definition: ntddk_ex.h:127
IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES]
Definition: ntddk_ex.h:178
DWORD PointerToLinenumbers
Definition: pedump.c:292
DWORD PointerToRelocations
Definition: pedump.c:291
DWORD PointerToRawData
Definition: pedump.c:290
BYTE Name[IMAGE_SIZEOF_SHORT_NAME]
Definition: pedump.c:281
WORD NumberOfLinenumbers
Definition: pedump.c:294
WORD NumberOfRelocations
Definition: pedump.c:293
union _IMAGE_SECTION_HEADER::@1573 Misc
Definition: rossym.h:26
ULONG SourceLine
Definition: rossym.h:30
ULONG FileOffset
Definition: rossym.h:29
ULONG_PTR Address
Definition: rossym.h:27
ULONG FunctionOffset
Definition: rossym.h:28
DWORD LineNumber
Definition: compat.h:1115
CHAR FileName[MAX_PATH+1]
Definition: compat.h:1114
DWORD64 ModBase
Definition: compat.h:1112
DWORD64 Address
Definition: compat.h:1116
Definition: rsym.h:38
USHORT n_desc
Definition: rsym.h:42
ULONG n_value
Definition: rsym.h:43
ULONG StringsOffset
Definition: rsym.h:34
ULONG StringsLength
Definition: rsym.h:35
ULONG SymbolsOffset
Definition: rsym.h:32
ULONG SymbolsLength
Definition: rsym.h:33
ULONG SizeOfStruct
Definition: compat.h:1038
CHAR Name[1]
Definition: compat.h:1052
ULONG MaxNameLen
Definition: compat.h:1051
Definition: fci.c:127
Definition: _hash_fun.h:40
Definition: name.c:39
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
uint64_t DWORD64
Definition: typedefs.h:67
uint32_t ULONG_PTR
Definition: typedefs.h:65
uint32_t ULONG
Definition: typedefs.h:59
_Must_inspect_result_ _In_ WDFDMATRANSACTION _In_ PFN_WDF_PROGRAM_DMA _In_ WDF_DMA_DIRECTION _In_ PMDL _In_ PVOID VirtualAddress
void * arg
Definition: msvc.h:10
#define ISFCN(x)
Definition: winnt_old.h:1093
unsigned char BYTE
Definition: xxhash.c:193