ReactOS  0.4.14-dev-77-gd9e7c48
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, 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 
808 FindSectionForRVA(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 
824 static int
825 ProcessRelocations(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  {
853  fprintf(stderr,
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 
899 static const BYTE*
900 GetSectionName(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 
911 static int
912 CreateOutputFile(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  {
959  fprintf(stderr,
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  {
1085  fprintf(stderr,
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 
1230 int 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;
1284  path1 = convert_path(argv[arg]);
1285  }
1286  break;
1287 
1288  case 1:
1289  free(SourcePath);
1290  SourcePath = strdup(argv[arg]);
1291  argstate = 0;
1292  break;
1293 
1294  case 2:
1295  path2 = convert_path(argv[arg]);
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 
1341  if (GetStabInfo(FileData,
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);
1360  SymInitialize(FileData, ".", 0);
1361 
1362  module_base = SymLoadModule(FileData, file, path1, path1, 0, FileSize) & 0xffffffff;
1363 
1365  module_base,
1366  SourcePath,
1367  &StabSymbolsCount,
1368  &StabSymbols,
1369  &StringsLength,
1370  &StringBase))
1371  {
1372  free(FileData);
1373  exit(1);
1374  }
1375 
1376  UseDbgHelp = TRUE;
1379  }
1380 
1381  if (GetCoffInfo(FileData,
1382  PEFileHeader,
1383  PESectionHeaders,
1384  &CoffsLength,
1385  &CoffBase,
1386  &CoffStringsLength,
1387  &CoffStringBase))
1388  {
1389  free(FileData);
1390  exit(1);
1391  }
1392 
1393  if (!UseDbgHelp)
1394  {
1395  StringBase = malloc(1 + StringsLength + CoffStringsLength +
1396  (CoffsLength / sizeof(ROSSYM_ENTRY)) * (E_SYMNMLEN + 1));
1397  if (StringBase == NULL)
1398  {
1399  free(FileData);
1400  fprintf(stderr, "Failed to allocate memory for strings table\n");
1401  exit(1);
1402  }
1403  /* Make offset 0 into an empty string */
1404  *((char *) StringBase) = '\0';
1405  StringsLength = 1;
1406 
1407  if (ConvertStabs(&StabSymbolsCount,
1408  &StabSymbols,
1409  &StringsLength,
1410  StringBase,
1411  StabsLength,
1412  StabBase,
1413  StabStringsLength,
1414  StabStringBase,
1415  ImageBase,
1416  PEFileHeader,
1417  PESectionHeaders))
1418  {
1419  free(StringBase);
1420  free(FileData);
1421  fprintf(stderr, "Failed to allocate memory for strings table\n");
1422  exit(1);
1423  }
1424  }
1425  else
1426  {
1427  StringBase = realloc(StringBase, StringsLength + CoffStringsLength);
1428  if (!StringBase)
1429  {
1430  free(FileData);
1431  fprintf(stderr, "Failed to allocate memory for strings table\n");
1432  exit(1);
1433  }
1434  }
1435 
1436  if (ConvertCoffs(&CoffSymbolsCount,
1437  &CoffSymbols,
1438  &StringsLength,
1439  StringBase,
1440  CoffsLength,
1441  CoffBase,
1442  CoffStringsLength,
1443  CoffStringBase,
1444  ImageBase,
1445  PEFileHeader,
1446  PESectionHeaders))
1447  {
1448  if (StabSymbols)
1449  {
1450  free(StabSymbols);
1451  }
1452  free(StringBase);
1453  free(FileData);
1454  exit(1);
1455  }
1456 
1457  if (MergeStabsAndCoffs(&MergedSymbolsCount,
1458  &MergedSymbols,
1459  StabSymbolsCount,
1460  StabSymbols,
1461  CoffSymbolsCount,
1462  CoffSymbols))
1463  {
1464  if (CoffSymbols)
1465  {
1466  free(CoffSymbols);
1467  }
1468  if (StabSymbols)
1469  {
1470  free(StabSymbols);
1471  }
1472  free(StringBase);
1473  free(FileData);
1474  exit(1);
1475  }
1476 
1477  if (CoffSymbols)
1478  {
1479  free(CoffSymbols);
1480  }
1481  if (StabSymbols)
1482  {
1483  free(StabSymbols);
1484  }
1485  if (MergedSymbolsCount == 0)
1486  {
1487  RosSymLength = 0;
1488  RosSymSection = NULL;
1489  }
1490  else
1491  {
1492  RosSymLength = sizeof(SYMBOLFILE_HEADER) +
1493  MergedSymbolsCount * sizeof(ROSSYM_ENTRY) +
1494  StringsLength;
1495 
1496  RosSymSection = malloc(RosSymLength);
1497  if (RosSymSection == NULL)
1498  {
1499  free(MergedSymbols);
1500  free(StringBase);
1501  free(FileData);
1502  fprintf(stderr, "Unable to allocate memory for .rossym section\n");
1503  exit(1);
1504  }
1505  memset(RosSymSection, '\0', RosSymLength);
1506 
1507  SymbolFileHeader = (PSYMBOLFILE_HEADER)RosSymSection;
1508  SymbolFileHeader->SymbolsOffset = sizeof(SYMBOLFILE_HEADER);
1509  SymbolFileHeader->SymbolsLength = MergedSymbolsCount * sizeof(ROSSYM_ENTRY);
1510  SymbolFileHeader->StringsOffset = SymbolFileHeader->SymbolsOffset +
1511  SymbolFileHeader->SymbolsLength;
1512  SymbolFileHeader->StringsLength = StringsLength;
1513 
1514  memcpy((char *) RosSymSection + SymbolFileHeader->SymbolsOffset,
1515  MergedSymbols,
1516  SymbolFileHeader->SymbolsLength);
1517 
1518  memcpy((char *) RosSymSection + SymbolFileHeader->StringsOffset,
1519  StringBase,
1520  SymbolFileHeader->StringsLength);
1521 
1522  free(MergedSymbols);
1523  }
1524 
1525  free(StringBase);
1526  out = fopen(path2, "wb");
1527  if (out == NULL)
1528  {
1529  perror("Cannot open output file");
1530  free(RosSymSection);
1531  free(FileData);
1532  exit(1);
1533  }
1534 
1535  if (CreateOutputFile(out,
1536  FileData,
1537  PEDosHeader,
1538  PEFileHeader,
1539  PEOptHeader,
1540  PESectionHeaders,
1541  RosSymLength,
1542  RosSymSection))
1543  {
1544  fclose(out);
1545  if (RosSymSection)
1546  {
1547  free(RosSymSection);
1548  }
1549  free(FileData);
1550  exit(1);
1551  }
1552 
1553  fclose(out);
1554  if (RosSymSection)
1555  {
1556  free(RosSymSection);
1557  }
1558  free(FileData);
1559 
1560  return 0;
1561 }
1562 
1563 /* 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:51
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
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:912
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:825
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:1230
_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:900
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:808
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
union _IMAGE_SECTION_HEADER::@1528 Misc
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