ReactOS  0.4.13-dev-259-g5ca9c9c
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 {
38  struct StringEntry *Next;
40  char *String;
41 };
42 
44 {
46  struct StringEntry **Table;
47 };
48 
49 /* This is the famous DJB hash */
50 static unsigned int
51 ComputeDJBHash(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 
64 static void
65 AddStringToHash(struct StringHashTable *StringTable,
66  unsigned int hash,
67  ULONG Offset,
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 
77 static 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 
96 static 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 
113 static int
114 CompareSymEntry(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 
139 static 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 
177 static 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 
201 static ULONG
202 FindOrAddString(struct StringHashTable *StringTable,
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 
230 static int
231 ConvertStabs(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 
370 static int
371 ConvertCoffs(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);
409  fprintf(stderr,
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;
477  char *SourcePath;
479 };
480 
481 static 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 
501 static 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 
538 const char*
539 DbgHelpGetString(struct DbgHelpStringTab *tab, int id)
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. */
547 static char *
548 StrDupShortenPath(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 
561 static BOOL
562 DbgHelpAddLineNumber(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 
639 static 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 
715 static int
716 MergeStabsAndCoffs(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;
724 
725  *MergedSymbolCount = 0;
726  if (StabSymbolsCount == 0)
727  {
728  *MergedSymbols = NULL;
729  return 0;
730  }
731  *MergedSymbols = malloc((StabSymbolsCount + CoffSymbolsCount) * sizeof(ROSSYM_ENTRY));
732  if (*MergedSymbols == NULL)
733  {
734  fprintf(stderr, "Unable to allocate memory for merged symbols\n");
735  return 1;
736  }
737 
738  StabFunctionStartAddress = 0;
739  StabFunctionStringOffset = 0;
740  CoffIndex = 0;
741  for (StabIndex = 0; StabIndex < StabSymbolsCount; StabIndex++)
742  {
743  (*MergedSymbols)[*MergedSymbolCount] = StabSymbols[StabIndex];
744  for (j = StabIndex + 1;
745  j < StabSymbolsCount && StabSymbols[j].Address == StabSymbols[StabIndex].Address;
746  j++)
747  {
748  if (StabSymbols[j].FileOffset != 0 && (*MergedSymbols)[*MergedSymbolCount].FileOffset == 0)
749  {
750  (*MergedSymbols)[*MergedSymbolCount].FileOffset = StabSymbols[j].FileOffset;
751  }
752  if (StabSymbols[j].FunctionOffset != 0 && (*MergedSymbols)[*MergedSymbolCount].FunctionOffset == 0)
753  {
754  (*MergedSymbols)[*MergedSymbolCount].FunctionOffset = StabSymbols[j].FunctionOffset;
755  }
756  if (StabSymbols[j].SourceLine != 0 && (*MergedSymbols)[*MergedSymbolCount].SourceLine == 0)
757  {
758  (*MergedSymbols)[*MergedSymbolCount].SourceLine = StabSymbols[j].SourceLine;
759  }
760  }
761  StabIndex = j - 1;
762 
763  while (CoffIndex < CoffSymbolsCount &&
764  CoffSymbols[CoffIndex + 1].Address <= (*MergedSymbols)[*MergedSymbolCount].Address)
765  {
766  CoffIndex++;
767  }
768  NewStabFunctionStringOffset = (*MergedSymbols)[*MergedSymbolCount].FunctionOffset;
769  if (CoffSymbolsCount > 0 &&
770  CoffSymbols[CoffIndex].Address < (*MergedSymbols)[*MergedSymbolCount].Address &&
771  StabFunctionStartAddress < CoffSymbols[CoffIndex].Address &&
772  CoffSymbols[CoffIndex].FunctionOffset != 0)
773  {
774  (*MergedSymbols)[*MergedSymbolCount].FunctionOffset = CoffSymbols[CoffIndex].FunctionOffset;
775  CoffSymbols[CoffIndex].FileOffset = CoffSymbols[CoffIndex].FunctionOffset = 0;
776  }
777  if (StabFunctionStringOffset != NewStabFunctionStringOffset)
778  {
779  StabFunctionStartAddress = (*MergedSymbols)[*MergedSymbolCount].Address;
780  }
781  StabFunctionStringOffset = NewStabFunctionStringOffset;
782  (*MergedSymbolCount)++;
783  }
784  /* Handle functions that have no analog in the upstream data */
785  for (CoffIndex = 0; CoffIndex < CoffSymbolsCount; CoffIndex++)
786  {
787  if (CoffSymbols[CoffIndex].Address &&
788  CoffSymbols[CoffIndex].FunctionOffset)
789  {
790  (*MergedSymbols)[*MergedSymbolCount] = CoffSymbols[CoffIndex];
791  (*MergedSymbolCount)++;
792  }
793  }
794 
795  qsort(*MergedSymbols, *MergedSymbolCount, sizeof(ROSSYM_ENTRY), (int (*)(const void *, const void *)) CompareSymEntry);
796 
797  return 0;
798 }
799 
801 FindSectionForRVA(DWORD RVA, unsigned NumberOfSections, PIMAGE_SECTION_HEADER SectionHeaders)
802 {
803  unsigned Section;
804 
805  for (Section = 0; Section < NumberOfSections; Section++)
806  {
807  if (SectionHeaders[Section].VirtualAddress <= RVA &&
808  RVA < SectionHeaders[Section].VirtualAddress + SectionHeaders[Section].Misc.VirtualSize)
809  {
810  return SectionHeaders + Section;
811  }
812  }
813 
814  return NULL;
815 }
816 
817 static int
818 ProcessRelocations(ULONG *ProcessedRelocsLength, void **ProcessedRelocs,
819  void *RawData, PIMAGE_OPTIONAL_HEADER OptHeader,
820  unsigned NumberOfSections, PIMAGE_SECTION_HEADER SectionHeaders)
821 {
822  PIMAGE_SECTION_HEADER RelocSectionHeader, TargetSectionHeader;
823  PIMAGE_BASE_RELOCATION BaseReloc, End, AcceptedRelocs;
824  int Found;
825 
828  {
829  /* No relocation entries */
830  *ProcessedRelocsLength = 0;
831  *ProcessedRelocs = NULL;
832  return 0;
833  }
834 
836  NumberOfSections, SectionHeaders);
837  if (RelocSectionHeader == NULL)
838  {
839  fprintf(stderr, "Can't find section header for relocation data\n");
840  return 1;
841  }
842 
843  *ProcessedRelocs = malloc(RelocSectionHeader->SizeOfRawData);
844  if (*ProcessedRelocs == NULL)
845  {
846  fprintf(stderr,
847  "Failed to allocate %u bytes for relocations\n",
848  (unsigned int)RelocSectionHeader->SizeOfRawData);
849  return 1;
850  }
851  *ProcessedRelocsLength = 0;
852 
853  BaseReloc = (PIMAGE_BASE_RELOCATION) ((char *) RawData +
854  RelocSectionHeader->PointerToRawData +
856  RelocSectionHeader->VirtualAddress));
857  End = (PIMAGE_BASE_RELOCATION) ((char *) BaseReloc +
859 
860  while (BaseReloc < End && BaseReloc->SizeOfBlock > 0)
861  {
862  TargetSectionHeader = FindSectionForRVA(BaseReloc->VirtualAddress,
863  NumberOfSections,
864  SectionHeaders);
865  if (TargetSectionHeader != NULL)
866  {
867  AcceptedRelocs = *ProcessedRelocs;
868  Found = 0;
869  while (AcceptedRelocs < (PIMAGE_BASE_RELOCATION) ((char *) *ProcessedRelocs +
870  *ProcessedRelocsLength)
871  && !Found)
872  {
873  Found = BaseReloc->SizeOfBlock == AcceptedRelocs->SizeOfBlock &&
874  memcmp(BaseReloc, AcceptedRelocs, AcceptedRelocs->SizeOfBlock) == 0;
875  AcceptedRelocs = (PIMAGE_BASE_RELOCATION) ((char *) AcceptedRelocs +
876  AcceptedRelocs->SizeOfBlock);
877  }
878  if (!Found)
879  {
880  memcpy((char *) *ProcessedRelocs + *ProcessedRelocsLength,
881  BaseReloc,
882  BaseReloc->SizeOfBlock);
883  *ProcessedRelocsLength += BaseReloc->SizeOfBlock;
884  }
885  }
886  BaseReloc = (PIMAGE_BASE_RELOCATION)((char *) BaseReloc + BaseReloc->SizeOfBlock);
887  }
888 
889  return 0;
890 }
891 
892 static const BYTE*
893 GetSectionName(void *StringsBase, const BYTE *SectionTitle)
894 {
895  if (SectionTitle[0] == '/')
896  {
897  int offset = atoi((char*)SectionTitle+1);
898  return ((BYTE *)StringsBase) + offset;
899  }
900  else
901  return SectionTitle;
902 }
903 
904 static int
905 CreateOutputFile(FILE *OutFile, void *InData,
906  PIMAGE_DOS_HEADER InDosHeader, PIMAGE_FILE_HEADER InFileHeader,
907  PIMAGE_OPTIONAL_HEADER InOptHeader, PIMAGE_SECTION_HEADER InSectionHeaders,
908  ULONG RosSymLength, void *RosSymSection)
909 {
910  ULONG StartOfRawData;
911  unsigned Section;
912  void *OutHeader, *ProcessedRelocs, *PaddedRosSym, *Data;
913  unsigned char *PaddedStringTable;
914  PIMAGE_DOS_HEADER OutDosHeader;
915  PIMAGE_FILE_HEADER OutFileHeader;
916  PIMAGE_OPTIONAL_HEADER OutOptHeader;
917  PIMAGE_SECTION_HEADER OutSectionHeaders, CurrentSectionHeader;
918  DWORD CheckSum;
919  ULONG Length, i;
920  ULONG ProcessedRelocsLength;
921  ULONG RosSymOffset, RosSymFileLength;
922  ULONG PaddedStringTableLength;
923  int InRelocSectionIndex;
924  PIMAGE_SECTION_HEADER OutRelocSection;
925  /* Each coff symbol is 18 bytes and the string table follows */
926  char *StringTable = (char *)InData +
927  InFileHeader->PointerToSymbolTable + 18 * InFileHeader->NumberOfSymbols;
928  ULONG StringTableLength = 0;
929  ULONG StringTableLocation;
930 
931  StartOfRawData = 0;
932  for (Section = 0; Section < InFileHeader->NumberOfSections; Section++)
933  {
934  const BYTE *SectionName = GetSectionName(StringTable,
935  InSectionHeaders[Section].Name);
936  if (InSectionHeaders[Section].Name[0] == '/')
937  {
938  StringTableLength = atoi((const char *)InSectionHeaders[Section].Name + 1) +
939  strlen((const char *)SectionName) + 1;
940  }
941  if ((StartOfRawData == 0 || InSectionHeaders[Section].PointerToRawData < StartOfRawData)
942  && InSectionHeaders[Section].PointerToRawData != 0
943  && (strncmp((char *) SectionName, ".stab", 5)) != 0
944  && (strncmp((char *) SectionName, ".debug_", 7)) != 0)
945  {
946  StartOfRawData = InSectionHeaders[Section].PointerToRawData;
947  }
948  }
949  OutHeader = malloc(StartOfRawData);
950  if (OutHeader == NULL)
951  {
952  fprintf(stderr,
953  "Failed to allocate %u bytes for output file header\n",
954  (unsigned int)StartOfRawData);
955  return 1;
956  }
957  memset(OutHeader, '\0', StartOfRawData);
958 
959  OutDosHeader = (PIMAGE_DOS_HEADER) OutHeader;
960  memcpy(OutDosHeader, InDosHeader, InDosHeader->e_lfanew + sizeof(ULONG));
961 
962  OutFileHeader = (PIMAGE_FILE_HEADER)((char *) OutHeader + OutDosHeader->e_lfanew + sizeof(ULONG));
963  memcpy(OutFileHeader, InFileHeader, sizeof(IMAGE_FILE_HEADER));
964  OutFileHeader->PointerToSymbolTable = 0;
965  OutFileHeader->NumberOfSymbols = 0;
968 
969  OutOptHeader = (PIMAGE_OPTIONAL_HEADER)(OutFileHeader + 1);
970  memcpy(OutOptHeader, InOptHeader, sizeof(IMAGE_OPTIONAL_HEADER));
971  OutOptHeader->CheckSum = 0;
972 
973  OutSectionHeaders = (PIMAGE_SECTION_HEADER)((char *) OutOptHeader + OutFileHeader->SizeOfOptionalHeader);
974 
975  if (ProcessRelocations(&ProcessedRelocsLength,
976  &ProcessedRelocs,
977  InData,
978  InOptHeader,
979  InFileHeader->NumberOfSections,
980  InSectionHeaders))
981  {
982  return 1;
983  }
986  {
987  InRelocSectionIndex = -1;
988  }
989  else
990  {
992  InFileHeader->NumberOfSections, InSectionHeaders) - InSectionHeaders;
993  }
994 
995  OutFileHeader->NumberOfSections = 0;
996  CurrentSectionHeader = OutSectionHeaders;
997  OutOptHeader->SizeOfImage = 0;
998  RosSymOffset = 0;
999  OutRelocSection = NULL;
1000 
1001  StringTableLocation = StartOfRawData;
1002 
1003  for (Section = 0; Section < InFileHeader->NumberOfSections; Section++)
1004  {
1005  const BYTE *SectionName = GetSectionName(StringTable,
1006  InSectionHeaders[Section].Name);
1007  if ((strncmp((char *) SectionName, ".stab", 5) != 0) &&
1008  (strncmp((char *) SectionName, ".debug_", 7)) != 0)
1009  {
1010  *CurrentSectionHeader = InSectionHeaders[Section];
1011  CurrentSectionHeader->PointerToLinenumbers = 0;
1012  CurrentSectionHeader->NumberOfLinenumbers = 0;
1013  if (OutOptHeader->SizeOfImage < CurrentSectionHeader->VirtualAddress +
1014  CurrentSectionHeader->Misc.VirtualSize)
1015  {
1016  OutOptHeader->SizeOfImage = ROUND_UP(CurrentSectionHeader->VirtualAddress +
1017  CurrentSectionHeader->Misc.VirtualSize,
1018  OutOptHeader->SectionAlignment);
1019  }
1020  if (RosSymOffset < CurrentSectionHeader->PointerToRawData + CurrentSectionHeader->SizeOfRawData)
1021  {
1022  RosSymOffset = CurrentSectionHeader->PointerToRawData + CurrentSectionHeader->SizeOfRawData;
1023  }
1024  if (Section == (ULONG)InRelocSectionIndex)
1025  {
1026  OutRelocSection = CurrentSectionHeader;
1027  }
1028  StringTableLocation = CurrentSectionHeader->PointerToRawData + CurrentSectionHeader->SizeOfRawData;
1029  OutFileHeader->NumberOfSections++;
1030  CurrentSectionHeader++;
1031  }
1032  }
1033 
1034  if (OutRelocSection == CurrentSectionHeader - 1)
1035  {
1036  OutOptHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].Size = ProcessedRelocsLength;
1037  if (OutOptHeader->SizeOfImage == OutRelocSection->VirtualAddress +
1038  ROUND_UP(OutRelocSection->Misc.VirtualSize,
1039  OutOptHeader->SectionAlignment))
1040  {
1041  OutOptHeader->SizeOfImage = OutRelocSection->VirtualAddress +
1042  ROUND_UP(ProcessedRelocsLength,
1043  OutOptHeader->SectionAlignment);
1044  }
1045  OutRelocSection->Misc.VirtualSize = ProcessedRelocsLength;
1046  if (RosSymOffset == OutRelocSection->PointerToRawData +
1047  OutRelocSection->SizeOfRawData)
1048  {
1049  RosSymOffset = OutRelocSection->PointerToRawData +
1050  ROUND_UP(ProcessedRelocsLength,
1051  OutOptHeader->FileAlignment);
1052  }
1053  OutRelocSection->SizeOfRawData = ROUND_UP(ProcessedRelocsLength,
1054  OutOptHeader->FileAlignment);
1055  }
1056 
1057  if (RosSymLength > 0)
1058  {
1059  RosSymFileLength = ROUND_UP(RosSymLength, OutOptHeader->FileAlignment);
1060  memcpy(CurrentSectionHeader->Name, ".rossym", 8); /* We're lucky: string is exactly 8 bytes long */
1061  CurrentSectionHeader->Misc.VirtualSize = RosSymLength;
1062  CurrentSectionHeader->VirtualAddress = OutOptHeader->SizeOfImage;
1063  CurrentSectionHeader->SizeOfRawData = RosSymFileLength;
1064  CurrentSectionHeader->PointerToRawData = RosSymOffset;
1065  CurrentSectionHeader->PointerToRelocations = 0;
1066  CurrentSectionHeader->PointerToLinenumbers = 0;
1067  CurrentSectionHeader->NumberOfRelocations = 0;
1068  CurrentSectionHeader->NumberOfLinenumbers = 0;
1071  OutOptHeader->SizeOfImage = ROUND_UP(CurrentSectionHeader->VirtualAddress + CurrentSectionHeader->Misc.VirtualSize,
1072  OutOptHeader->SectionAlignment);
1073  OutFileHeader->NumberOfSections++;
1074 
1075  PaddedRosSym = malloc(RosSymFileLength);
1076  if (PaddedRosSym == NULL)
1077  {
1078  fprintf(stderr,
1079  "Failed to allocate %u bytes for padded .rossym\n",
1080  (unsigned int)RosSymFileLength);
1081  return 1;
1082  }
1083  memcpy(PaddedRosSym, RosSymSection, RosSymLength);
1084  memset((char *) PaddedRosSym + RosSymLength,
1085  '\0',
1086  RosSymFileLength - RosSymLength);
1087 
1088  /* Position the string table after our new section */
1089  StringTableLocation = RosSymOffset + RosSymFileLength;
1090  }
1091  else
1092  {
1093  PaddedRosSym = NULL;
1094  }
1095 
1096  /* Set the string table area in the header if we need it */
1097  if (StringTableLength)
1098  {
1099  OutFileHeader->PointerToSymbolTable = StringTableLocation;
1100  OutFileHeader->NumberOfSymbols = 0;
1101  }
1102 
1103  CheckSum = 0;
1104  for (i = 0; i < StartOfRawData / 2; i++)
1105  {
1106  CheckSum += ((unsigned short*) OutHeader)[i];
1107  CheckSum = 0xffff & (CheckSum + (CheckSum >> 16));
1108  }
1109  Length = StartOfRawData;
1110  for (Section = 0; Section < OutFileHeader->NumberOfSections; Section++)
1111  {
1112  DWORD SizeOfRawData;
1113  if (OutRelocSection == OutSectionHeaders + Section)
1114  {
1115  Data = (void *) ProcessedRelocs;
1116  SizeOfRawData = ProcessedRelocsLength;
1117  }
1118  else if (RosSymLength > 0 && Section + 1 == OutFileHeader->NumberOfSections)
1119  {
1120  Data = (void *) PaddedRosSym;
1121  SizeOfRawData = OutSectionHeaders[Section].SizeOfRawData;
1122  }
1123  else
1124  {
1125  Data = (void *) ((char *) InData + OutSectionHeaders[Section].PointerToRawData);
1126  SizeOfRawData = OutSectionHeaders[Section].SizeOfRawData;
1127  }
1128  for (i = 0; i < SizeOfRawData / 2; i++)
1129  {
1130  CheckSum += ((unsigned short*) Data)[i];
1131  CheckSum = 0xffff & (CheckSum + (CheckSum >> 16));
1132  }
1133  Length += OutSectionHeaders[Section].SizeOfRawData;
1134  }
1135 
1136  if (OutFileHeader->PointerToSymbolTable)
1137  {
1138  int PaddingFrom = (OutFileHeader->PointerToSymbolTable + StringTableLength) %
1139  OutOptHeader->FileAlignment;
1140  int PaddingSize = PaddingFrom ? OutOptHeader->FileAlignment - PaddingFrom : 0;
1141 
1142  PaddedStringTableLength = StringTableLength + PaddingSize;
1143  PaddedStringTable = malloc(PaddedStringTableLength);
1144  /* COFF string section is preceeded by a length */
1145  assert(sizeof(StringTableLength) == 4);
1146  memcpy(PaddedStringTable, &StringTableLength, sizeof(StringTableLength));
1147  /* We just copy enough of the string table to contain the strings we want
1148  The string table length technically counts as part of the string table
1149  space itself. */
1150  memcpy(PaddedStringTable + 4, StringTable + 4, StringTableLength - 4);
1151  memset(PaddedStringTable + StringTableLength, 0, PaddingSize);
1152 
1153  assert(OutFileHeader->PointerToSymbolTable % 2 == 0);
1154  for (i = 0; i < PaddedStringTableLength / 2; i++)
1155  {
1156  CheckSum += ((unsigned short*)PaddedStringTable)[i];
1157  CheckSum = 0xffff & (CheckSum + (CheckSum >> 16));
1158  }
1159  Length += PaddedStringTableLength;
1160  }
1161  else
1162  {
1163  PaddedStringTable = NULL;
1164  }
1165 
1166  CheckSum += Length;
1167  OutOptHeader->CheckSum = CheckSum;
1168 
1169  if (fwrite(OutHeader, 1, StartOfRawData, OutFile) != StartOfRawData)
1170  {
1171  perror("Error writing output header\n");
1172  free(OutHeader);
1173  return 1;
1174  }
1175 
1176  for (Section = 0; Section < OutFileHeader->NumberOfSections; Section++)
1177  {
1178  if (OutSectionHeaders[Section].SizeOfRawData != 0)
1179  {
1180  DWORD SizeOfRawData;
1181  fseek(OutFile, OutSectionHeaders[Section].PointerToRawData, SEEK_SET);
1182  if (OutRelocSection == OutSectionHeaders + Section)
1183  {
1184  Data = (void *) ProcessedRelocs;
1185  SizeOfRawData = ProcessedRelocsLength;
1186  }
1187  else if (RosSymLength > 0 && Section + 1 == OutFileHeader->NumberOfSections)
1188  {
1189  Data = (void *) PaddedRosSym;
1190  SizeOfRawData = OutSectionHeaders[Section].SizeOfRawData;
1191  }
1192  else
1193  {
1194  Data = (void *) ((char *) InData + OutSectionHeaders[Section].PointerToRawData);
1195  SizeOfRawData = OutSectionHeaders[Section].SizeOfRawData;
1196  }
1197  if (fwrite(Data, 1, SizeOfRawData, OutFile) != SizeOfRawData)
1198  {
1199  perror("Error writing section data\n");
1200  free(PaddedRosSym);
1201  free(OutHeader);
1202  return 1;
1203  }
1204  }
1205  }
1206 
1207  if (PaddedStringTable)
1208  {
1209  fseek(OutFile, OutFileHeader->PointerToSymbolTable, SEEK_SET);
1210  fwrite(PaddedStringTable, 1, PaddedStringTableLength, OutFile);
1211  free(PaddedStringTable);
1212  }
1213 
1214  if (PaddedRosSym)
1215  {
1216  free(PaddedRosSym);
1217  }
1218  free(OutHeader);
1219 
1220  return 0;
1221 }
1222 
1223 int main(int argc, char* argv[])
1224 {
1225  PSYMBOLFILE_HEADER SymbolFileHeader;
1226  PIMAGE_DOS_HEADER PEDosHeader;
1227  PIMAGE_FILE_HEADER PEFileHeader;
1228  PIMAGE_OPTIONAL_HEADER PEOptHeader;
1229  PIMAGE_SECTION_HEADER PESectionHeaders;
1230  ULONG ImageBase;
1231  void *StabBase;
1232  ULONG StabsLength;
1233  void *StabStringBase;
1234  ULONG StabStringsLength;
1235  void *CoffBase = NULL;
1236  ULONG CoffsLength;
1237  void *CoffStringBase = NULL;
1238  ULONG CoffStringsLength;
1239  char* path1;
1240  char* path2;
1241  FILE* out;
1242  void *StringBase = NULL;
1243  ULONG StringsLength = 0;
1244  ULONG StabSymbolsCount = 0;
1245  PROSSYM_ENTRY StabSymbols = NULL;
1246  ULONG CoffSymbolsCount = 0;
1247  PROSSYM_ENTRY CoffSymbols = NULL;
1248  ULONG MergedSymbolsCount = 0;
1249  PROSSYM_ENTRY MergedSymbols = NULL;
1250  size_t FileSize;
1251  void *FileData;
1252  ULONG RosSymLength;
1253  void *RosSymSection;
1255  void *file;
1256  char elfhdr[4] = { '\177', 'E', 'L', 'F' };
1257  BOOLEAN UseDbgHelp = FALSE;
1258  int arg, argstate = 0;
1259  char *SourcePath = NULL;
1260 
1261  for (arg = 1; arg < argc; arg++)
1262  {
1263  switch (argstate)
1264  {
1265  default:
1266  argstate = -1;
1267  break;
1268 
1269  case 0:
1270  if (!strcmp(argv[arg], "-s"))
1271  {
1272  argstate = 1;
1273  }
1274  else
1275  {
1276  argstate = 2;
1277  path1 = convert_path(argv[arg]);
1278  }
1279  break;
1280 
1281  case 1:
1282  free(SourcePath);
1283  SourcePath = strdup(argv[arg]);
1284  argstate = 0;
1285  break;
1286 
1287  case 2:
1288  path2 = convert_path(argv[arg]);
1289  argstate = 3;
1290  break;
1291  }
1292  }
1293 
1294  if (argstate != 3)
1295  {
1296  fprintf(stderr, "Usage: rsym [-s <sources>] <input> <output>\n");
1297  exit(1);
1298  }
1299 
1301  if (!FileData)
1302  {
1303  fprintf(stderr, "An error occured loading '%s'\n", path1);
1304  exit(1);
1305  }
1306 
1307  file = fopen(path1, "rb");
1308 
1309  /* Check if MZ header exists */
1310  PEDosHeader = (PIMAGE_DOS_HEADER) FileData;
1311  if (PEDosHeader->e_magic != IMAGE_DOS_MAGIC ||
1312  PEDosHeader->e_lfanew == 0L)
1313  {
1314  /* Ignore elf */
1315  if (!memcmp(PEDosHeader, elfhdr, sizeof(elfhdr)))
1316  exit(0);
1317  perror("Input file is not a PE image.\n");
1318  free(FileData);
1319  exit(1);
1320  }
1321 
1322  /* Locate PE file header */
1323  /* sizeof(ULONG) = sizeof(MAGIC) */
1324  PEFileHeader = (PIMAGE_FILE_HEADER)((char *) FileData + PEDosHeader->e_lfanew + sizeof(ULONG));
1325 
1326  /* Locate optional header */
1327  assert(sizeof(ULONG) == 4);
1328  PEOptHeader = (PIMAGE_OPTIONAL_HEADER)(PEFileHeader + 1);
1329  ImageBase = PEOptHeader->ImageBase;
1330 
1331  /* Locate PE section headers */
1332  PESectionHeaders = (PIMAGE_SECTION_HEADER)((char *) PEOptHeader + PEFileHeader->SizeOfOptionalHeader);
1333 
1334  if (GetStabInfo(FileData,
1335  PEFileHeader,
1336  PESectionHeaders,
1337  &StabsLength,
1338  &StabBase,
1339  &StabStringsLength,
1340  &StabStringBase))
1341  {
1342  free(FileData);
1343  exit(1);
1344  }
1345 
1346  if (StabsLength == 0)
1347  {
1348  // SYMOPT_AUTO_PUBLICS
1349  // SYMOPT_FAVOR_COMPRESSED
1350  // SYMOPT_LOAD_ANYTHING
1351  // SYMOPT_LOAD_LINES
1352  SymSetOptions(0x10000 | 0x800000 | 0x40 | 0x10);
1353  SymInitialize(FileData, ".", 0);
1354 
1355  module_base = SymLoadModule(FileData, file, path1, path1, 0, FileSize) & 0xffffffff;
1356 
1358  module_base,
1359  SourcePath,
1360  &StabSymbolsCount,
1361  &StabSymbols,
1362  &StringsLength,
1363  &StringBase))
1364  {
1365  free(FileData);
1366  exit(1);
1367  }
1368 
1369  UseDbgHelp = TRUE;
1372  }
1373 
1374  if (GetCoffInfo(FileData,
1375  PEFileHeader,
1376  PESectionHeaders,
1377  &CoffsLength,
1378  &CoffBase,
1379  &CoffStringsLength,
1380  &CoffStringBase))
1381  {
1382  free(FileData);
1383  exit(1);
1384  }
1385 
1386  if (!UseDbgHelp)
1387  {
1388  StringBase = malloc(1 + StringsLength + CoffStringsLength +
1389  (CoffsLength / sizeof(ROSSYM_ENTRY)) * (E_SYMNMLEN + 1));
1390  if (StringBase == NULL)
1391  {
1392  free(FileData);
1393  fprintf(stderr, "Failed to allocate memory for strings table\n");
1394  exit(1);
1395  }
1396  /* Make offset 0 into an empty string */
1397  *((char *) StringBase) = '\0';
1398  StringsLength = 1;
1399 
1400  if (ConvertStabs(&StabSymbolsCount,
1401  &StabSymbols,
1402  &StringsLength,
1403  StringBase,
1404  StabsLength,
1405  StabBase,
1406  StabStringsLength,
1407  StabStringBase,
1408  ImageBase,
1409  PEFileHeader,
1410  PESectionHeaders))
1411  {
1412  free(StringBase);
1413  free(FileData);
1414  fprintf(stderr, "Failed to allocate memory for strings table\n");
1415  exit(1);
1416  }
1417  }
1418  else
1419  {
1420  StringBase = realloc(StringBase, StringsLength + CoffStringsLength);
1421  if (!StringBase)
1422  {
1423  free(FileData);
1424  fprintf(stderr, "Failed to allocate memory for strings table\n");
1425  exit(1);
1426  }
1427  }
1428 
1429  if (ConvertCoffs(&CoffSymbolsCount,
1430  &CoffSymbols,
1431  &StringsLength,
1432  StringBase,
1433  CoffsLength,
1434  CoffBase,
1435  CoffStringsLength,
1436  CoffStringBase,
1437  ImageBase,
1438  PEFileHeader,
1439  PESectionHeaders))
1440  {
1441  if (StabSymbols)
1442  {
1443  free(StabSymbols);
1444  }
1445  free(StringBase);
1446  free(FileData);
1447  exit(1);
1448  }
1449 
1450  if (MergeStabsAndCoffs(&MergedSymbolsCount,
1451  &MergedSymbols,
1452  StabSymbolsCount,
1453  StabSymbols,
1454  CoffSymbolsCount,
1455  CoffSymbols))
1456  {
1457  if (CoffSymbols)
1458  {
1459  free(CoffSymbols);
1460  }
1461  if (StabSymbols)
1462  {
1463  free(StabSymbols);
1464  }
1465  free(StringBase);
1466  free(FileData);
1467  exit(1);
1468  }
1469 
1470  if (CoffSymbols)
1471  {
1472  free(CoffSymbols);
1473  }
1474  if (StabSymbols)
1475  {
1476  free(StabSymbols);
1477  }
1478  if (MergedSymbolsCount == 0)
1479  {
1480  RosSymLength = 0;
1481  RosSymSection = NULL;
1482  }
1483  else
1484  {
1485  RosSymLength = sizeof(SYMBOLFILE_HEADER) +
1486  MergedSymbolsCount * sizeof(ROSSYM_ENTRY) +
1487  StringsLength;
1488 
1489  RosSymSection = malloc(RosSymLength);
1490  if (RosSymSection == NULL)
1491  {
1492  free(MergedSymbols);
1493  free(StringBase);
1494  free(FileData);
1495  fprintf(stderr, "Unable to allocate memory for .rossym section\n");
1496  exit(1);
1497  }
1498  memset(RosSymSection, '\0', RosSymLength);
1499 
1500  SymbolFileHeader = (PSYMBOLFILE_HEADER)RosSymSection;
1501  SymbolFileHeader->SymbolsOffset = sizeof(SYMBOLFILE_HEADER);
1502  SymbolFileHeader->SymbolsLength = MergedSymbolsCount * sizeof(ROSSYM_ENTRY);
1503  SymbolFileHeader->StringsOffset = SymbolFileHeader->SymbolsOffset +
1504  SymbolFileHeader->SymbolsLength;
1505  SymbolFileHeader->StringsLength = StringsLength;
1506 
1507  memcpy((char *) RosSymSection + SymbolFileHeader->SymbolsOffset,
1508  MergedSymbols,
1509  SymbolFileHeader->SymbolsLength);
1510 
1511  memcpy((char *) RosSymSection + SymbolFileHeader->StringsOffset,
1512  StringBase,
1513  SymbolFileHeader->StringsLength);
1514 
1515  free(MergedSymbols);
1516  }
1517 
1518  free(StringBase);
1519  out = fopen(path2, "wb");
1520  if (out == NULL)
1521  {
1522  perror("Cannot open output file");
1523  free(RosSymSection);
1524  free(FileData);
1525  exit(1);
1526  }
1527 
1528  if (CreateOutputFile(out,
1529  FileData,
1530  PEDosHeader,
1531  PEFileHeader,
1532  PEOptHeader,
1533  PESectionHeaders,
1534  RosSymLength,
1535  RosSymSection))
1536  {
1537  fclose(out);
1538  if (RosSymSection)
1539  {
1540  free(RosSymSection);
1541  }
1542  free(FileData);
1543  exit(1);
1544  }
1545 
1546  fclose(out);
1547  if (RosSymSection)
1548  {
1549  free(RosSymSection);
1550  }
1551  free(FileData);
1552 
1553  return 0;
1554 }
1555 
1556 /* EOF */
#define realloc
Definition: debug_ros.c:6
BOOL WINAPI SymCleanup(HANDLE hProcess)
Definition: dbghelp.c:416
static const WCHAR path2[]
Definition: path.c:29
disp
Definition: i386-dis.c:3181
static int argc
Definition: ServiceArgs.c:12
static FILEDATA FileData[MAX_FDS]
Definition: fs.c:52
ULONG SourceLine
Definition: rossym.h:30
CHAR Name[1]
Definition: compat.h:701
#define TRUE
Definition: types.h:120
struct _IMAGE_BASE_RELOCATION * PIMAGE_BASE_RELOCATION
#define ISFCN(x)
Definition: winnt_old.h:1095
static ULONG FindOrAddString(struct StringHashTable *StringTable, char *StringToFind, ULONG *StringsLength, void *StringsBase)
Definition: rsym.c:202
IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES]
Definition: ntddk_ex.h:178
ULONG LineEntries
Definition: rsym.c:472
#define N_BINCL
Definition: stabs.c:108
int memcmp(void *Buffer1, void *Buffer2, ACPI_SIZE Count)
Definition: utclib.c:112
#define ROUND_UP(n, align)
Definition: eventvwr.h:31
ULONG MaxNameLen
Definition: compat.h:700
DWORD WINAPI SymLoadModule(HANDLE hProcess, HANDLE hFile, PCSTR ImageName, PCSTR ModuleName, DWORD BaseOfDll, DWORD SizeOfDll)
Definition: module.c:531
WORD NumberOfRelocations
Definition: pedump.c:293
char * strcat(char *DstString, const char *SrcString)
Definition: utclib.c:568
const char * DbgHelpGetString(struct DbgHelpStringTab *tab, int id)
Definition: rsym.c:539
ULONG functionId
Definition: rsym.c:464
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
DWORD WINAPI SymSetOptions(DWORD opts)
Definition: dbghelp.c:443
_Check_return_ _CRTIMP size_t __cdecl strcspn(_In_z_ const char *_Str, _In_z_ const char *_Control)
#define free
Definition: debug_ros.c:5
GLintptr offset
Definition: glext.h:5920
#define MAX_SYM_NAME
Definition: rsym.c:34
struct StringEntry * Next
Definition: rsym.c:38
#define IMAGE_SCN_MEM_READ
Definition: ntimage.h:240
ULONG StringsOffset
Definition: rsym.h:34
static int DbgHelpAddStringToTable(struct DbgHelpStringTab *tab, char *name)
Definition: rsym.c:502
static HANDLE process
Definition: process.c:76
struct _COFF_SYMENT COFF_SYMENT
#define assert(x)
Definition: debug.h:53
#define E_SYMNMLEN
Definition: pe.h:27
_Inout_ __drv_aliasesMem PSLIST_ENTRY _Inout_ PSLIST_ENTRY _In_ ULONG Count
Definition: exfuncs.h:1015
void * arg
Definition: msvc.h:12
ULONG Offset
Definition: rsym.c:39
GLuint GLuint end
Definition: gl.h:1545
#define IMAGE_SCN_LNK_REMOVE
Definition: pecoff.h:27
_Check_return_ _CRTIMP _CONST_RETURN char *__cdecl strrchr(_In_z_ const char *_Str, _In_ int _Ch)
Definition: rossym.h:26
DWORD PointerToRawData
Definition: pedump.c:290
CHAR FileName[MAX_PATH+1]
Definition: compat.h:756
_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)
#define argv
Definition: mplay32.c:18
static int CompareSymEntry(const PROSSYM_ENTRY SymEntry1, const PROSSYM_ENTRY SymEntry2)
Definition: rsym.c:114
void * process
Definition: rsym.c:474
struct _SYMBOLFILE_HEADER * PSYMBOLFILE_HEADER
PCWSTR FilePath
#define N_FUN
Definition: stabs.c:95
static struct DbgHelpLineEntry * DbgHelpAddLineEntry(struct DbgHelpStringTab *tab)
Definition: rsym.c:482
uint32_t ULONG_PTR
Definition: typedefs.h:63
#define C_EXT
Definition: pe.h:45
WCHAR First[]
Definition: FormatMessage.c:11
char *** Table
Definition: rsym.c:471
BOOL WINAPI SymEnumLines(HANDLE hProcess, ULONG64 base, PCSTR compiland, PCSTR srcfile, PSYM_ENUMLINES_CALLBACK cb, PVOID user)
Definition: symbol.c:2174
#define N_SOL
Definition: stabs.c:109
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
ULONG FileOffset
Definition: rossym.h:29
char * PathChop
Definition: rsym.c:476
_In_ ULONG _In_ ULONG Offset
Definition: ntddpcm.h:101
struct _STAB_ENTRY STAB_ENTRY
int hash
Definition: main.c:58
_CRTIMP void __cdecl perror(_In_opt_z_ const char *_ErrMsg)
unsigned int BOOL
Definition: ntddk_ex.h:94
static char * StrDupShortenPath(char *PathChop, char *FilePath)
Definition: rsym.c:548
_Check_return_opt_ _CRTIMP int __cdecl fprintf(_Inout_ FILE *_File, _In_z_ _Printf_format_string_ const char *_Format,...)
#define e
Definition: ke_i.h:82
_Check_return_ _CRTIMP char *__cdecl strdup(_In_opt_z_ const char *_Src)
static BOOL DbgHelpAddLineNumber(PSRCCODEINFO LineInfo, void *UserContext)
Definition: rsym.c:562
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 *))
struct NameRec_ * Name
Definition: cdprocs.h:464
union _IMAGE_SECTION_HEADER::@1519 Misc
DWORD64 ModBase
Definition: compat.h:754
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
BOOL WINAPI SymInitialize(HANDLE hProcess, PCSTR UserSearchPath, BOOL fInvadeProcess)
Definition: dbghelp.c:393
ULONG fileId
Definition: rsym.c:463
static WCHAR Address[46]
Definition: ping.c:68
static void StringHashTableFree(struct StringHashTable *StringTable)
Definition: rsym.c:97
_Check_return_opt_ _CRTIMP int __cdecl fseek(_Inout_ FILE *_File, _In_ long _Offset, _In_ int _Origin)
struct _IMAGE_DOS_HEADER * PIMAGE_DOS_HEADER
_In_ LPGUID _In_ PVOID Data
Definition: classpnp.h:778
struct _IMAGE_OPTIONAL_HEADER * PIMAGE_OPTIONAL_HEADER
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
ULONG CurLineEntries
Definition: rsym.c:472
WORD SizeOfOptionalHeader
Definition: ntddk_ex.h:127
static DWORD StringHash(const WCHAR *str)
return Found
Definition: dirsup.c:1270
#define IMAGE_FILE_DEBUG_STRIPPED
Definition: pedump.c:165
ULONG vma
Definition: rsym.c:462
#define IMAGE_FILE_LINE_NUMS_STRIPPED
Definition: pedump.c:161
GLuint GLfloat * val
Definition: glext.h:7180
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
struct _SYMBOLFILE_HEADER SYMBOLFILE_HEADER
static const WCHAR path1[]
Definition: path.c:28
#define IMAGE_DOS_MAGIC
Definition: pecoff.h:6
#define SEEK_SET
Definition: jmemansi.c:26
WORD NumberOfLinenumbers
Definition: pedump.c:294
struct _ROSSYM_ENTRY ROSSYM_ENTRY
GLfloat f
Definition: glext.h:7540
struct DbgHelpLineEntry * LineEntryData
Definition: rsym.c:473
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:185
DWORD NumberOfSymbols
Definition: ntddk_ex.h:126
DWORD PointerToLinenumbers
Definition: pedump.c:292
static unsigned int ComputeDJBHash(const char *name)
Definition: rsym.c:51
struct _IMAGE_FILE_HEADER * PIMAGE_FILE_HEADER
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
DWORD LineNumber
Definition: compat.h:757
const char file[]
Definition: icontest.c:11
#define N_SLINE
Definition: stabs.c:103
int strncmp(const char *String1, const char *String2, ACPI_SIZE Count)
Definition: utclib.c:534
struct _SYMBOL_INFO SYMBOL_INFO
struct _COFF_SYMENT * PCOFF_SYMENT
static FILE * out
Definition: regtests2xml.c:44
#define for
Definition: utility.h:88
unsigned long DWORD
Definition: ntddk_ex.h:95
UCHAR CheckSum(LPSTR p, ULONG Len)
Definition: serial.c:197
ULONG Length
Definition: rsym.c:469
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
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:905
Definition: partlist.h:33
GLsizei const GLchar *const * strings
Definition: glext.h:7622
DWORD64 Address
Definition: compat.h:758
static const WCHAR L[]
Definition: oid.c:1250
static UINT load_file(MSIRECORD *row, LPVOID param)
Definition: action.c:1202
static int ProcessRelocations(ULONG *ProcessedRelocsLength, void **ProcessedRelocs, void *RawData, PIMAGE_OPTIONAL_HEADER OptHeader, unsigned NumberOfSections, PIMAGE_SECTION_HEADER SectionHeaders)
Definition: rsym.c:818
uint32_t entry
Definition: isohybrid.c:63
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
ULONG SizeOfStruct
Definition: compat.h:687
_Must_inspect_result_ _Out_ PLARGE_INTEGER FileSize
Definition: fsrtlfuncs.h:108
unsigned char BYTE
Definition: mem.h:68
#define IMAGE_FILE_LOCAL_SYMS_STRIPPED
Definition: pedump.c:162
DWORD module_base
Definition: rsym.c:475
_Check_return_opt_ _CRTIMP int __cdecl fclose(_Inout_ FILE *_File)
_Check_return_ _CRTIMP FILE *__cdecl fopen(_In_z_ const char *_Filename, _In_z_ const char *_Mode)
_In_ ULONG _In_ BOOLEAN _Must_inspect_result_ PVOID * VirtualAddress
Definition: ndis.h:3791
static int MergeStabsAndCoffs(ULONG *MergedSymbolCount, PROSSYM_ENTRY *MergedSymbols, ULONG StabSymbolsCount, PROSSYM_ENTRY StabSymbols, ULONG CoffSymbolsCount, PROSSYM_ENTRY CoffSymbols)
Definition: rsym.c:716
BOOL WINAPI SymFromAddr(HANDLE hProcess, DWORD64 Address, DWORD64 *Displacement, PSYMBOL_INFO Symbol)
Definition: symbol.c:1271
char * String
Definition: rsym.c:40
Definition: shared.h:92
ULONG line
Definition: rsym.c:465
#define IMAGE_SCN_TYPE_NOLOAD
Definition: pecoff.h:20
ULONG SymbolsOffset
Definition: rsym.h:32
struct _IMAGE_SECTION_HEADER * PIMAGE_SECTION_HEADER
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
#define N_SO
Definition: stabs.c:105
ULONG StringsLength
Definition: rsym.h:35
ULONG TableSize
Definition: rsym.c:45
uint64_t DWORD64
Definition: typedefs.h:65
static int ConvertDbgHelp(void *process, DWORD module_base, char *SourcePath, ULONG *SymbolsCount, PROSSYM_ENTRY *SymbolsBase, ULONG *StringsLength, void **StringsBase)
Definition: rsym.c:640
int main(int argc, char *argv[])
Definition: rsym.c:1223
_In_ PFCB _In_ LONGLONG FileOffset
Definition: cdprocs.h:151
DWORD PointerToSymbolTable
Definition: ntddk_ex.h:125
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:254
#define IMAGE_DIRECTORY_ENTRY_BASERELOC
Definition: pedump.c:264
struct StringEntry ** Table
Definition: rsym.c:46
char * SourcePath
Definition: rsym.c:477
char * convert_path(char *origpath)
Definition: rcopy.c:11
BYTE Name[IMAGE_SIZEOF_SHORT_NAME]
Definition: pedump.c:281
ULONG SymbolsLength
Definition: rsym.h:33
_Check_return_ int __cdecl atoi(_In_z_ const char *_Str)
static const BYTE * GetSectionName(void *StringsBase, const BYTE *SectionTitle)
Definition: rsym.c:893
Definition: name.c:36
#define calloc
Definition: rosglue.h:14
DWORD RVA
Definition: compat.h:903
ULONG Bytes
Definition: rsym.c:470
char * strcpy(char *DstString, const char *SrcString)
Definition: utclib.c:388
unsigned int ULONG
Definition: retypes.h:1
struct DbgHelpLineEntry * lastLineEntry
Definition: rsym.c:478
FILE * stderr
int strcmp(const char *String1, const char *String2)
Definition: utclib.c:469
#define malloc
Definition: debug_ros.c:4
static void AddStringToHash(struct StringHashTable *StringTable, unsigned int hash, ULONG Offset, char *StringPtr)
Definition: rsym.c:65
static PIMAGE_SECTION_HEADER FindSectionForRVA(DWORD RVA, unsigned NumberOfSections, PIMAGE_SECTION_HEADER SectionHeaders)
Definition: rsym.c:801
void exit(int exitcode)
Definition: _exit.c:33
GLfloat GLfloat p
Definition: glext.h:8902
ULONG FunctionOffset
Definition: rossym.h:28
Definition: _hash_fun.h:40
#define memset(x, y, z)
Definition: compat.h:39
ULONG_PTR Address
Definition: rossym.h:27
BOOL WINAPI SymUnloadModule(HANDLE hProcess, DWORD BaseOfDll)
Definition: module.c:722
DWORD PointerToRelocations
Definition: pedump.c:291
static void StringHashTableInit(struct StringHashTable *StringTable, ULONG StringsLength, char *StringsBase)
Definition: rsym.c:78
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
Definition: fci.c:126
#define IMAGE_SCN_MEM_DISCARDABLE
Definition: ntimage.h:235
GLuint const GLchar * name
Definition: glext.h:6031