ReactOS 0.4.15-dev-5664-g3bf4ef6
rsym.c File Reference
#include "../../dll/win32/dbghelp/compat.h"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <assert.h>
#include <wchar.h>
#include "rsym.h"
Include dependency graph for rsym.c:

Go to the source code of this file.

Classes

struct  StringEntry
 
struct  StringHashTable
 
struct  DbgHelpLineEntry
 
struct  DbgHelpStringTab
 

Macros

#define MAX_PATH   260
 
#define MAX_SYM_NAME   2000
 

Functions

static unsigned int ComputeDJBHash (const char *name)
 
static void AddStringToHash (struct StringHashTable *StringTable, unsigned int hash, ULONG Offset, char *StringPtr)
 
static void StringHashTableInit (struct StringHashTable *StringTable, ULONG StringsLength, char *StringsBase)
 
static void StringHashTableFree (struct StringHashTable *StringTable)
 
static int CompareSymEntry (const PROSSYM_ENTRY SymEntry1, const PROSSYM_ENTRY SymEntry2)
 
static int GetStabInfo (void *FileData, PIMAGE_FILE_HEADER PEFileHeader, PIMAGE_SECTION_HEADER PESectionHeaders, ULONG *StabSymbolsLength, void **StabSymbolsBase, ULONG *StabStringsLength, void **StabStringsBase)
 
static int GetCoffInfo (void *FileData, PIMAGE_FILE_HEADER PEFileHeader, PIMAGE_SECTION_HEADER PESectionHeaders, ULONG *CoffSymbolsLength, void **CoffSymbolsBase, ULONG *CoffStringsLength, void **CoffStringsBase)
 
static ULONG FindOrAddString (struct StringHashTable *StringTable, char *StringToFind, ULONG *StringsLength, void *StringsBase)
 
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)
 
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)
 
static struct DbgHelpLineEntryDbgHelpAddLineEntry (struct DbgHelpStringTab *tab)
 
static int DbgHelpAddStringToTable (struct DbgHelpStringTab *tab, char *name)
 
const charDbgHelpGetString (struct DbgHelpStringTab *tab, int id)
 
static charStrDupShortenPath (char *PathChop, char *FilePath)
 
static BOOL DbgHelpAddLineNumber (PSRCCODEINFO LineInfo, void *UserContext)
 
static int ConvertDbgHelp (void *process, DWORD module_base, char *SourcePath, ULONG *SymbolsCount, PROSSYM_ENTRY *SymbolsBase, ULONG *StringsLength, void **StringsBase)
 
static int MergeStabsAndCoffs (ULONG *MergedSymbolCount, PROSSYM_ENTRY *MergedSymbols, ULONG StabSymbolsCount, PROSSYM_ENTRY StabSymbols, ULONG CoffSymbolsCount, PROSSYM_ENTRY CoffSymbols)
 
static PIMAGE_SECTION_HEADER FindSectionForRVA (DWORD RVA, unsigned NumberOfSections, PIMAGE_SECTION_HEADER SectionHeaders)
 
static int ProcessRelocations (ULONG *ProcessedRelocsLength, void **ProcessedRelocs, void *RawData, PIMAGE_OPTIONAL_HEADER OptHeader, unsigned NumberOfSections, PIMAGE_SECTION_HEADER SectionHeaders)
 
static const BYTEGetSectionName (void *StringsBase, const BYTE *SectionTitle)
 
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)
 
int main (int argc, char *argv[])
 

Macro Definition Documentation

◆ MAX_PATH

#define MAX_PATH   260

Definition at line 33 of file rsym.c.

◆ MAX_SYM_NAME

#define MAX_SYM_NAME   2000

Definition at line 34 of file rsym.c.

Function Documentation

◆ AddStringToHash()

static void AddStringToHash ( struct StringHashTable StringTable,
unsigned int  hash,
ULONG  Offset,
char StringPtr 
)
static

Definition at line 65 of file rsym.c.

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}
uint32_t entry
Definition: isohybrid.c:63
_In_ ULONG _In_ ULONG Offset
Definition: ntddpcm.h:101
#define calloc
Definition: rosglue.h:14
struct StringEntry ** Table
Definition: rsym.c:46
Definition: _hash_fun.h:40

Referenced by FindOrAddString(), and StringHashTableInit().

◆ CompareSymEntry()

static int CompareSymEntry ( const PROSSYM_ENTRY  SymEntry1,
const PROSSYM_ENTRY  SymEntry2 
)
static

Definition at line 114 of file rsym.c.

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}
ULONG SourceLine
Definition: rossym.h:30
ULONG_PTR Address
Definition: rossym.h:27

Referenced by ConvertCoffs(), ConvertDbgHelp(), ConvertStabs(), and MergeStabsAndCoffs().

◆ ComputeDJBHash()

static unsigned int ComputeDJBHash ( const char name)
static

Definition at line 51 of file rsym.c.

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}
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 i
Definition: glfuncs.h:248
Definition: name.c:39

Referenced by DbgHelpAddStringToTable(), FindOrAddString(), and StringHashTableInit().

◆ ConvertCoffs()

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 
)
static

Definition at line 371 of file rsym.c.

377{
378 ULONG Count, i;
379 PCOFF_SYMENT CoffEntry;
380 char FuncName[256], FileName[1024];
381 char *p;
382 PROSSYM_ENTRY Current;
384
385 CoffEntry = (PCOFF_SYMENT) CoffSymbolsBase;
386 Count = CoffSymbolsLength / sizeof(COFF_SYMENT);
387
388 *SymbolsBase = malloc(Count * sizeof(ROSSYM_ENTRY));
389 if (*SymbolsBase == NULL)
390 {
391 fprintf(stderr, "Unable to allocate memory for converted COFF symbols\n");
392 return 1;
393 }
394 *SymbolsCount = 0;
395 Current = *SymbolsBase;
396
397 StringHashTableInit(&StringHash, *StringsLength, (char*)StringsBase);
398
399 for (i = 0; i < Count; i++)
400 {
401 if (ISFCN(CoffEntry[i].e_type) || C_EXT == CoffEntry[i].e_sclass)
402 {
403 Current->Address = CoffEntry[i].e_value;
404 if (CoffEntry[i].e_scnum > 0)
405 {
406 if (PEFileHeader->NumberOfSections < CoffEntry[i].e_scnum)
407 {
408 free(*SymbolsBase);
410 "Invalid section number %d in COFF symbols (only %d sections present)\n",
411 CoffEntry[i].e_scnum,
412 PEFileHeader->NumberOfSections);
413 return 1;
414 }
415 Current->Address += PESectionHeaders[CoffEntry[i].e_scnum - 1].VirtualAddress;
416 }
417 Current->FileOffset = 0;
418 if (CoffEntry[i].e.e.e_zeroes == 0)
419 {
420 if (sizeof(FuncName) <= strlen((char *) CoffStringsBase + CoffEntry[i].e.e.e_offset))
421 {
422 free(*SymbolsBase);
423 fprintf(stderr, "Function name too long\n");
425 return 1;
426 }
427 strcpy(FuncName, (char *) CoffStringsBase + CoffEntry[i].e.e.e_offset);
428 }
429 else
430 {
431 memcpy(FuncName, CoffEntry[i].e.e_name, E_SYMNMLEN);
432 FuncName[E_SYMNMLEN] = '\0';
433 }
434
435 /* Name demangling: stdcall */
436 p = strrchr(FuncName, '@');
437 if (p != NULL)
438 {
439 *p = '\0';
440 }
441 p = ('_' == FuncName[0] || '@' == FuncName[0] ? FuncName + 1 : FuncName);
443 p,
444 StringsLength,
445 StringsBase);
446 Current->SourceLine = 0;
447 memset(++Current, 0, sizeof(*Current));
448 }
449
450 i += CoffEntry[i].e_numaux;
451 }
452
453 *SymbolsCount = (Current - *SymbolsBase + 1);
454 qsort(*SymbolsBase, *SymbolsCount, sizeof(ROSSYM_ENTRY), (int (*)(const void *, const void *)) CompareSymEntry);
455
457
458 return 0;
459}
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
char * strcpy(char *DstString, const char *SrcString)
Definition: utclib.c:388
#define free
Definition: debug_ros.c:5
#define malloc
Definition: debug_ros.c:4
#define NULL
Definition: types.h:112
GLfloat GLfloat p
Definition: glext.h:8902
#define stderr
Definition: stdio.h:100
_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
macro IMPORT Name endm macro EXPORT Name global &Name endm macro TEXTAREA section rx align endm macro DATAAREA section rw endm macro RODATAAREA section rw endm macro NESTED_ENTRY Name FuncName equ &Name PrologName equ &Name &_Prolog FuncEndName equ &Name &_end global &FuncName align func &FuncName & FuncName
Definition: kxarm.h:221
unsigned int ULONG
Definition: retypes.h:1
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
int Count
Definition: noreturn.cpp:7
#define C_EXT
Definition: pe.h:45
#define E_SYMNMLEN
Definition: pe.h:27
struct _COFF_SYMENT COFF_SYMENT
struct _COFF_SYMENT * PCOFF_SYMENT
static DWORD StringHash(const WCHAR *str)
_Check_return_ _CRTIMP _CONST_RETURN char *__cdecl strrchr(_In_z_ const char *_Str, _In_ int _Ch)
#define memset(x, y, z)
Definition: compat.h:39
static void StringHashTableFree(struct StringHashTable *StringTable)
Definition: rsym.c:97
static ULONG FindOrAddString(struct StringHashTable *StringTable, char *StringToFind, ULONG *StringsLength, void *StringsBase)
Definition: rsym.c:202
static void StringHashTableInit(struct StringHashTable *StringTable, ULONG StringsLength, char *StringsBase)
Definition: rsym.c:78
static int CompareSymEntry(const PROSSYM_ENTRY SymEntry1, const PROSSYM_ENTRY SymEntry2)
Definition: rsym.c:114
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 *))
ULONG e_value
Definition: rsym.h:152
UCHAR e_numaux
Definition: rsym.h:156
short e_scnum
Definition: rsym.h:153
Definition: rossym.h:26
ULONG FileOffset
Definition: rossym.h:29
ULONG FunctionOffset
Definition: rossym.h:28
#define ISFCN(x)
Definition: winnt_old.h:1098

Referenced by main().

◆ ConvertDbgHelp()

static int ConvertDbgHelp ( void process,
DWORD  module_base,
char SourcePath,
ULONG SymbolsCount,
PROSSYM_ENTRY SymbolsBase,
ULONG StringsLength,
void **  StringsBase 
)
static

Definition at line 640 of file rsym.c.

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}
BOOL WINAPI SymEnumLines(HANDLE hProcess, ULONG64 base, PCSTR compiland, PCSTR srcfile, PSYM_ENUMLINES_CALLBACK cb, PVOID user)
Definition: symbol.c:2177
#define assert(x)
Definition: debug.h:53
GLsizei const GLchar *const * strings
Definition: glext.h:7622
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
_Check_return_ _CRTIMP char *__cdecl strdup(_In_opt_z_ const char *_Src)
static BOOL DbgHelpAddLineNumber(PSRCCODEINFO LineInfo, void *UserContext)
Definition: rsym.c:562
void * process
Definition: rsym.c:474
ULONG CurLineEntries
Definition: rsym.c:472
char * SourcePath
Definition: rsym.c:477
DWORD module_base
Definition: rsym.c:475
char * PathChop
Definition: rsym.c:476
ULONG Bytes
Definition: rsym.c:470
ULONG LineEntries
Definition: rsym.c:472
char *** Table
Definition: rsym.c:471
ULONG Length
Definition: rsym.c:469
struct DbgHelpLineEntry * LineEntryData
Definition: rsym.c:473

Referenced by main().

◆ ConvertStabs()

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 
)
static

Definition at line 231 of file rsym.c.

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}
WCHAR First[]
Definition: FormatMessage.c:11
struct NameRec_ * Name
Definition: cdprocs.h:460
struct _STAB_ENTRY STAB_ENTRY
static WCHAR Address[46]
Definition: ping.c:68
_Check_return_ _CRTIMP size_t __cdecl strcspn(_In_z_ const char *_Str, _In_z_ const char *_Control)
#define N_SOL
Definition: stabs.c:88
#define N_BINCL
Definition: stabs.c:87
#define N_SO
Definition: stabs.c:84
#define N_SLINE
Definition: stabs.c:82
#define N_FUN
Definition: stabs.c:74
Definition: shared.h:93
unsigned short n_desc
Definition: shared.h:97
unsigned long n_value
Definition: shared.h:98
uint32_t ULONG_PTR
Definition: typedefs.h:65

Referenced by main().

◆ CreateOutputFile()

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 
)
static

Definition at line 912 of file rsym.c.

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;
926 ULONG Length, i;
927 ULONG ProcessedRelocsLength;
928 ULONG RosSymOffset, RosSymFileLength;
929 ULONG PaddedStringTableLength;
930 int InRelocSectionIndex;
931 PIMAGE_SECTION_HEADER OutRelocSection;
932 /* Each coff symbol is 18 bytes and the string table follows */
933 char *StringTable = (char *)InData +
934 InFileHeader->PointerToSymbolTable + 18 * InFileHeader->NumberOfSymbols;
935 ULONG StringTableLength = 0;
936 ULONG StringTableLocation;
937
938 StartOfRawData = 0;
939 for (Section = 0; Section < InFileHeader->NumberOfSections; Section++)
940 {
941 const BYTE *SectionName = GetSectionName(StringTable,
942 InSectionHeaders[Section].Name);
943 if (InSectionHeaders[Section].Name[0] == '/')
944 {
945 StringTableLength = atoi((const char *)InSectionHeaders[Section].Name + 1) +
946 strlen((const char *)SectionName) + 1;
947 }
948 if ((StartOfRawData == 0 || InSectionHeaders[Section].PointerToRawData < StartOfRawData)
949 && InSectionHeaders[Section].PointerToRawData != 0
950 && (strncmp((char *) SectionName, ".stab", 5)) != 0
951 && (strncmp((char *) SectionName, ".debug_", 7)) != 0)
952 {
953 StartOfRawData = InSectionHeaders[Section].PointerToRawData;
954 }
955 }
956 OutHeader = malloc(StartOfRawData);
957 if (OutHeader == NULL)
958 {
960 "Failed to allocate %u bytes for output file header\n",
961 (unsigned int)StartOfRawData);
962 return 1;
963 }
964 memset(OutHeader, '\0', StartOfRawData);
965
966 OutDosHeader = (PIMAGE_DOS_HEADER) OutHeader;
967 memcpy(OutDosHeader, InDosHeader, InDosHeader->e_lfanew + sizeof(ULONG));
968
969 OutFileHeader = (PIMAGE_FILE_HEADER)((char *) OutHeader + OutDosHeader->e_lfanew + sizeof(ULONG));
970 memcpy(OutFileHeader, InFileHeader, sizeof(IMAGE_FILE_HEADER));
971 OutFileHeader->PointerToSymbolTable = 0;
972 OutFileHeader->NumberOfSymbols = 0;
975
976 OutOptHeader = (PIMAGE_OPTIONAL_HEADER)(OutFileHeader + 1);
977 memcpy(OutOptHeader, InOptHeader, sizeof(IMAGE_OPTIONAL_HEADER));
978 OutOptHeader->CheckSum = 0;
979
980 OutSectionHeaders = (PIMAGE_SECTION_HEADER)((char *) OutOptHeader + OutFileHeader->SizeOfOptionalHeader);
981
982 if (ProcessRelocations(&ProcessedRelocsLength,
983 &ProcessedRelocs,
984 InData,
985 InOptHeader,
986 InFileHeader->NumberOfSections,
987 InSectionHeaders))
988 {
989 return 1;
990 }
993 {
994 InRelocSectionIndex = -1;
995 }
996 else
997 {
999 InFileHeader->NumberOfSections, InSectionHeaders) - InSectionHeaders;
1000 }
1001
1002 OutFileHeader->NumberOfSections = 0;
1003 CurrentSectionHeader = OutSectionHeaders;
1004 OutOptHeader->SizeOfImage = 0;
1005 RosSymOffset = 0;
1006 OutRelocSection = NULL;
1007
1008 StringTableLocation = StartOfRawData;
1009
1010 for (Section = 0; Section < InFileHeader->NumberOfSections; Section++)
1011 {
1012 const BYTE *SectionName = GetSectionName(StringTable,
1013 InSectionHeaders[Section].Name);
1014 if ((strncmp((char *) SectionName, ".stab", 5) != 0) &&
1015 (strncmp((char *) SectionName, ".debug_", 7)) != 0)
1016 {
1017 *CurrentSectionHeader = InSectionHeaders[Section];
1018 CurrentSectionHeader->PointerToLinenumbers = 0;
1019 CurrentSectionHeader->NumberOfLinenumbers = 0;
1020 if (OutOptHeader->SizeOfImage < CurrentSectionHeader->VirtualAddress +
1021 CurrentSectionHeader->Misc.VirtualSize)
1022 {
1023 OutOptHeader->SizeOfImage = ROUND_UP(CurrentSectionHeader->VirtualAddress +
1024 CurrentSectionHeader->Misc.VirtualSize,
1025 OutOptHeader->SectionAlignment);
1026 }
1027 if (RosSymOffset < CurrentSectionHeader->PointerToRawData + CurrentSectionHeader->SizeOfRawData)
1028 {
1029 RosSymOffset = CurrentSectionHeader->PointerToRawData + CurrentSectionHeader->SizeOfRawData;
1030 }
1031 if (Section == (ULONG)InRelocSectionIndex)
1032 {
1033 OutRelocSection = CurrentSectionHeader;
1034 }
1035 StringTableLocation = CurrentSectionHeader->PointerToRawData + CurrentSectionHeader->SizeOfRawData;
1036 OutFileHeader->NumberOfSections++;
1037 CurrentSectionHeader++;
1038 }
1039 }
1040
1041 if (OutRelocSection == CurrentSectionHeader - 1)
1042 {
1043 OutOptHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].Size = ProcessedRelocsLength;
1044 if (OutOptHeader->SizeOfImage == OutRelocSection->VirtualAddress +
1045 ROUND_UP(OutRelocSection->Misc.VirtualSize,
1046 OutOptHeader->SectionAlignment))
1047 {
1048 OutOptHeader->SizeOfImage = OutRelocSection->VirtualAddress +
1049 ROUND_UP(ProcessedRelocsLength,
1050 OutOptHeader->SectionAlignment);
1051 }
1052 OutRelocSection->Misc.VirtualSize = ProcessedRelocsLength;
1053 if (RosSymOffset == OutRelocSection->PointerToRawData +
1054 OutRelocSection->SizeOfRawData)
1055 {
1056 RosSymOffset = OutRelocSection->PointerToRawData +
1057 ROUND_UP(ProcessedRelocsLength,
1058 OutOptHeader->FileAlignment);
1059 }
1060 OutRelocSection->SizeOfRawData = ROUND_UP(ProcessedRelocsLength,
1061 OutOptHeader->FileAlignment);
1062 }
1063
1064 if (RosSymLength > 0)
1065 {
1066 RosSymFileLength = ROUND_UP(RosSymLength, OutOptHeader->FileAlignment);
1067 memcpy(CurrentSectionHeader->Name, ".rossym", 8); /* We're lucky: string is exactly 8 bytes long */
1068 CurrentSectionHeader->Misc.VirtualSize = RosSymLength;
1069 CurrentSectionHeader->VirtualAddress = OutOptHeader->SizeOfImage;
1070 CurrentSectionHeader->SizeOfRawData = RosSymFileLength;
1071 CurrentSectionHeader->PointerToRawData = RosSymOffset;
1072 CurrentSectionHeader->PointerToRelocations = 0;
1073 CurrentSectionHeader->PointerToLinenumbers = 0;
1074 CurrentSectionHeader->NumberOfRelocations = 0;
1075 CurrentSectionHeader->NumberOfLinenumbers = 0;
1078 OutOptHeader->SizeOfImage = ROUND_UP(CurrentSectionHeader->VirtualAddress + CurrentSectionHeader->Misc.VirtualSize,
1079 OutOptHeader->SectionAlignment);
1080 OutFileHeader->NumberOfSections++;
1081
1082 PaddedRosSym = malloc(RosSymFileLength);
1083 if (PaddedRosSym == NULL)
1084 {
1086 "Failed to allocate %u bytes for padded .rossym\n",
1087 (unsigned int)RosSymFileLength);
1088 return 1;
1089 }
1090 memcpy(PaddedRosSym, RosSymSection, RosSymLength);
1091 memset((char *) PaddedRosSym + RosSymLength,
1092 '\0',
1093 RosSymFileLength - RosSymLength);
1094
1095 /* Position the string table after our new section */
1096 StringTableLocation = RosSymOffset + RosSymFileLength;
1097 }
1098 else
1099 {
1100 PaddedRosSym = NULL;
1101 }
1102
1103 /* Set the string table area in the header if we need it */
1104 if (StringTableLength)
1105 {
1106 OutFileHeader->PointerToSymbolTable = StringTableLocation;
1107 OutFileHeader->NumberOfSymbols = 0;
1108 }
1109
1110 CheckSum = 0;
1111 for (i = 0; i < StartOfRawData / 2; i++)
1112 {
1113 CheckSum += ((unsigned short*) OutHeader)[i];
1114 CheckSum = 0xffff & (CheckSum + (CheckSum >> 16));
1115 }
1116 Length = StartOfRawData;
1117 for (Section = 0; Section < OutFileHeader->NumberOfSections; Section++)
1118 {
1119 DWORD SizeOfRawData;
1120 if (OutRelocSection == OutSectionHeaders + Section)
1121 {
1122 Data = (void *) ProcessedRelocs;
1123 SizeOfRawData = ProcessedRelocsLength;
1124 }
1125 else if (RosSymLength > 0 && Section + 1 == OutFileHeader->NumberOfSections)
1126 {
1127 Data = (void *) PaddedRosSym;
1128 SizeOfRawData = OutSectionHeaders[Section].SizeOfRawData;
1129 }
1130 else
1131 {
1132 Data = (void *) ((char *) InData + OutSectionHeaders[Section].PointerToRawData);
1133 SizeOfRawData = OutSectionHeaders[Section].SizeOfRawData;
1134 }
1135 for (i = 0; i < SizeOfRawData / 2; i++)
1136 {
1137 CheckSum += ((unsigned short*) Data)[i];
1138 CheckSum = 0xffff & (CheckSum + (CheckSum >> 16));
1139 }
1140 Length += OutSectionHeaders[Section].SizeOfRawData;
1141 }
1142
1143 if (OutFileHeader->PointerToSymbolTable)
1144 {
1145 int PaddingFrom = (OutFileHeader->PointerToSymbolTable + StringTableLength) %
1146 OutOptHeader->FileAlignment;
1147 int PaddingSize = PaddingFrom ? OutOptHeader->FileAlignment - PaddingFrom : 0;
1148
1149 PaddedStringTableLength = StringTableLength + PaddingSize;
1150 PaddedStringTable = malloc(PaddedStringTableLength);
1151 /* COFF string section is preceeded by a length */
1152 assert(sizeof(StringTableLength) == 4);
1153 memcpy(PaddedStringTable, &StringTableLength, sizeof(StringTableLength));
1154 /* We just copy enough of the string table to contain the strings we want
1155 The string table length technically counts as part of the string table
1156 space itself. */
1157 memcpy(PaddedStringTable + 4, StringTable + 4, StringTableLength - 4);
1158 memset(PaddedStringTable + StringTableLength, 0, PaddingSize);
1159
1160 assert(OutFileHeader->PointerToSymbolTable % 2 == 0);
1161 for (i = 0; i < PaddedStringTableLength / 2; i++)
1162 {
1163 CheckSum += ((unsigned short*)PaddedStringTable)[i];
1164 CheckSum = 0xffff & (CheckSum + (CheckSum >> 16));
1165 }
1166 Length += PaddedStringTableLength;
1167 }
1168 else
1169 {
1170 PaddedStringTable = NULL;
1171 }
1172
1173 CheckSum += Length;
1174 OutOptHeader->CheckSum = CheckSum;
1175
1176 if (fwrite(OutHeader, 1, StartOfRawData, OutFile) != StartOfRawData)
1177 {
1178 perror("Error writing output header\n");
1179 free(OutHeader);
1180 return 1;
1181 }
1182
1183 for (Section = 0; Section < OutFileHeader->NumberOfSections; Section++)
1184 {
1185 if (OutSectionHeaders[Section].SizeOfRawData != 0)
1186 {
1187 DWORD SizeOfRawData;
1188 fseek(OutFile, OutSectionHeaders[Section].PointerToRawData, SEEK_SET);
1189 if (OutRelocSection == OutSectionHeaders + Section)
1190 {
1191 Data = (void *) ProcessedRelocs;
1192 SizeOfRawData = ProcessedRelocsLength;
1193 }
1194 else if (RosSymLength > 0 && Section + 1 == OutFileHeader->NumberOfSections)
1195 {
1196 Data = (void *) PaddedRosSym;
1197 SizeOfRawData = OutSectionHeaders[Section].SizeOfRawData;
1198 }
1199 else
1200 {
1201 Data = (void *) ((char *) InData + OutSectionHeaders[Section].PointerToRawData);
1202 SizeOfRawData = OutSectionHeaders[Section].SizeOfRawData;
1203 }
1204 if (fwrite(Data, 1, SizeOfRawData, OutFile) != SizeOfRawData)
1205 {
1206 perror("Error writing section data\n");
1207 free(PaddedRosSym);
1208 free(OutHeader);
1209 return 1;
1210 }
1211 }
1212 }
1213
1214 if (PaddedStringTable)
1215 {
1216 fseek(OutFile, OutFileHeader->PointerToSymbolTable, SEEK_SET);
1217 fwrite(PaddedStringTable, 1, PaddedStringTableLength, OutFile);
1218 free(PaddedStringTable);
1219 }
1220
1221 if (PaddedRosSym)
1222 {
1223 free(PaddedRosSym);
1224 }
1225 free(OutHeader);
1226
1227 return 0;
1228}
int strncmp(const char *String1, const char *String2, ACPI_SIZE Count)
Definition: utclib.c:534
#define ROUND_UP(n, align)
Definition: eventvwr.h:34
unsigned long DWORD
Definition: ntddk_ex.h:95
struct _IMAGE_DOS_HEADER * PIMAGE_DOS_HEADER
struct _IMAGE_FILE_HEADER * PIMAGE_FILE_HEADER
_CRTIMP void __cdecl perror(_In_opt_z_ const char *_ErrMsg)
_Check_return_opt_ _CRTIMP int __cdecl fseek(_Inout_ FILE *_File, _In_ long _Offset, _In_ int _Origin)
_Check_return_opt_ _CRTIMP size_t __cdecl fwrite(_In_reads_bytes_(_Size *_Count) const void *_Str, _In_ size_t _Size, _In_ size_t _Count, _Inout_ FILE *_File)
_Check_return_ int __cdecl atoi(_In_z_ const char *_Str)
#define SEEK_SET
Definition: jmemansi.c:26
#define for
Definition: utility.h:88
UCHAR CheckSum(LPSTR p, ULONG Len)
Definition: serial.c:197
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:102
#define IMAGE_SCN_MEM_DISCARDABLE
Definition: ntimage.h:235
#define IMAGE_SCN_MEM_READ
Definition: ntimage.h:240
#define IMAGE_SCN_TYPE_NOLOAD
Definition: pecoff.h:20
#define IMAGE_SCN_LNK_REMOVE
Definition: pecoff.h:27
#define IMAGE_FILE_LOCAL_SYMS_STRIPPED
Definition: pedump.c:162
struct _IMAGE_SECTION_HEADER * PIMAGE_SECTION_HEADER
#define IMAGE_DIRECTORY_ENTRY_BASERELOC
Definition: pedump.c:264
#define IMAGE_FILE_DEBUG_STRIPPED
Definition: pedump.c:165
struct _IMAGE_OPTIONAL_HEADER * PIMAGE_OPTIONAL_HEADER
#define IMAGE_FILE_LINE_NUMS_STRIPPED
Definition: pedump.c:161
static int ProcessRelocations(ULONG *ProcessedRelocsLength, void **ProcessedRelocs, void *RawData, PIMAGE_OPTIONAL_HEADER OptHeader, unsigned NumberOfSections, PIMAGE_SECTION_HEADER SectionHeaders)
Definition: rsym.c:825
static PIMAGE_SECTION_HEADER FindSectionForRVA(DWORD RVA, unsigned NumberOfSections, PIMAGE_SECTION_HEADER SectionHeaders)
Definition: rsym.c:808
static const BYTE * GetSectionName(void *StringsBase, const BYTE *SectionTitle)
Definition: rsym.c:900
DWORD NumberOfSymbols
Definition: ntddk_ex.h:126
DWORD PointerToSymbolTable
Definition: ntddk_ex.h:125
WORD SizeOfOptionalHeader
Definition: ntddk_ex.h:127
IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES]
Definition: ntddk_ex.h:178
DWORD PointerToLinenumbers
Definition: pedump.c:292
DWORD PointerToRelocations
Definition: pedump.c:291
union _IMAGE_SECTION_HEADER::@1538 Misc
DWORD PointerToRawData
Definition: pedump.c:290
BYTE Name[IMAGE_SIZEOF_SHORT_NAME]
Definition: pedump.c:281
WORD NumberOfLinenumbers
Definition: pedump.c:294
WORD NumberOfRelocations
Definition: pedump.c:293
unsigned char BYTE
Definition: xxhash.c:193

Referenced by main().

◆ DbgHelpAddLineEntry()

static struct DbgHelpLineEntry * DbgHelpAddLineEntry ( struct DbgHelpStringTab tab)
static

Definition at line 482 of file rsym.c.

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}
#define realloc
Definition: debug_ros.c:6

Referenced by DbgHelpAddLineNumber().

◆ DbgHelpAddLineNumber()

static BOOL DbgHelpAddLineNumber ( PSRCCODEINFO  LineInfo,
void UserContext 
)
static

Definition at line 562 of file rsym.c.

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}
char * strcat(char *DstString, const char *SrcString)
Definition: utclib.c:568
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
BOOL WINAPI SymFromAddr(HANDLE hProcess, DWORD64 Address, DWORD64 *Displacement, PSYMBOL_INFO Symbol)
Definition: symbol.c:1263
#define MAX_SYM_NAME
Definition: compat.h:975
struct _SYMBOL_INFO SYMBOL_INFO
GLuint GLuint end
Definition: gl.h:1545
GLfloat f
Definition: glext.h:7540
_Check_return_ _CRTIMP FILE *__cdecl fopen(_In_z_ const char *_Filename, _In_z_ const char *_Mode)
_Check_return_opt_ _CRTIMP int __cdecl fclose(_Inout_ FILE *_File)
static int DbgHelpAddStringToTable(struct DbgHelpStringTab *tab, char *name)
Definition: rsym.c:502
static char * StrDupShortenPath(char *PathChop, char *FilePath)
Definition: rsym.c:548
static struct DbgHelpLineEntry * DbgHelpAddLineEntry(struct DbgHelpStringTab *tab)
Definition: rsym.c:482
struct DbgHelpLineEntry * lastLineEntry
Definition: rsym.c:478
DWORD LineNumber
Definition: compat.h:1115
CHAR FileName[MAX_PATH+1]
Definition: compat.h:1114
DWORD64 ModBase
Definition: compat.h:1112
DWORD64 Address
Definition: compat.h:1116
ULONG SizeOfStruct
Definition: compat.h:1038
CHAR Name[1]
Definition: compat.h:1052
ULONG MaxNameLen
Definition: compat.h:1051
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
uint64_t DWORD64
Definition: typedefs.h:67

Referenced by ConvertDbgHelp().

◆ DbgHelpAddStringToTable()

static int DbgHelpAddStringToTable ( struct DbgHelpStringTab tab,
char name 
)
static

Definition at line 502 of file rsym.c.

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}
int strcmp(const char *String1, const char *String2)
Definition: utclib.c:469
static unsigned int ComputeDJBHash(const char *name)
Definition: rsym.c:51

Referenced by DbgHelpAddLineNumber().

◆ DbgHelpGetString()

const char * DbgHelpGetString ( struct DbgHelpStringTab tab,
int  id 
)

Definition at line 539 of file rsym.c.

540{
541 int i = id >> 10;
542 int bucket = id & 0x3ff;
543 return tab->Table[bucket][i];
544}

◆ FindOrAddString()

static ULONG FindOrAddString ( struct StringHashTable StringTable,
char StringToFind,
ULONG StringsLength,
void StringsBase 
)
static

Definition at line 202 of file rsym.c.

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}
static void AddStringToHash(struct StringHashTable *StringTable, unsigned int hash, ULONG Offset, char *StringPtr)
Definition: rsym.c:65
ULONG TableSize
Definition: rsym.c:45

Referenced by ConvertCoffs(), and ConvertStabs().

◆ FindSectionForRVA()

static PIMAGE_SECTION_HEADER FindSectionForRVA ( DWORD  RVA,
unsigned  NumberOfSections,
PIMAGE_SECTION_HEADER  SectionHeaders 
)
static

Definition at line 808 of file rsym.c.

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}
DWORD RVA
Definition: compat.h:1262
_Must_inspect_result_ _In_ WDFDMATRANSACTION _In_ PFN_WDF_PROGRAM_DMA _In_ WDF_DMA_DIRECTION _In_ PMDL _In_ PVOID VirtualAddress

Referenced by CreateOutputFile(), and ProcessRelocations().

◆ GetCoffInfo()

static int GetCoffInfo ( void FileData,
PIMAGE_FILE_HEADER  PEFileHeader,
PIMAGE_SECTION_HEADER  PESectionHeaders,
ULONG CoffSymbolsLength,
void **  CoffSymbolsBase,
ULONG CoffStringsLength,
void **  CoffStringsBase 
)
static

Definition at line 178 of file rsym.c.

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}
static FILEDATA FileData[MAX_FDS]
Definition: fs.c:51

Referenced by main().

◆ GetSectionName()

static const BYTE * GetSectionName ( void StringsBase,
const BYTE SectionTitle 
)
static

Definition at line 900 of file rsym.c.

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}
GLintptr offset
Definition: glext.h:5920

Referenced by CreateOutputFile().

◆ GetStabInfo()

static int GetStabInfo ( void FileData,
PIMAGE_FILE_HEADER  PEFileHeader,
PIMAGE_SECTION_HEADER  PESectionHeaders,
ULONG StabSymbolsLength,
void **  StabSymbolsBase,
ULONG StabStringsLength,
void **  StabStringsBase 
)
static

Definition at line 140 of file rsym.c.

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}

Referenced by main().

◆ main()

int main ( int argc  ,
char argv[] 
)

Definition at line 1230 of file rsym.c.

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;
1261 DWORD module_base;
1262 void *file;
1263 char elfhdr[4] = { '\177', 'E', 'L', 'F' };
1264 BOOLEAN UseDbgHelp = FALSE;
1265 int arg, argstate = 0;
1266 char *SourcePath = NULL;
1267
1268 for (arg = 1; arg < argc; arg++)
1269 {
1270 switch (argstate)
1271 {
1272 default:
1273 argstate = -1;
1274 break;
1275
1276 case 0:
1277 if (!strcmp(argv[arg], "-s"))
1278 {
1279 argstate = 1;
1280 }
1281 else
1282 {
1283 argstate = 2;
1285 }
1286 break;
1287
1288 case 1:
1289 free(SourcePath);
1290 SourcePath = strdup(argv[arg]);
1291 argstate = 0;
1292 break;
1293
1294 case 2:
1296 argstate = 3;
1297 break;
1298 }
1299 }
1300
1301 if (argstate != 3)
1302 {
1303 fprintf(stderr, "Usage: rsym [-s <sources>] <input> <output>\n");
1304 exit(1);
1305 }
1306
1308 if (!FileData)
1309 {
1310 fprintf(stderr, "An error occured loading '%s'\n", path1);
1311 exit(1);
1312 }
1313
1314 file = fopen(path1, "rb");
1315
1316 /* Check if MZ header exists */
1317 PEDosHeader = (PIMAGE_DOS_HEADER) FileData;
1318 if (PEDosHeader->e_magic != IMAGE_DOS_MAGIC ||
1319 PEDosHeader->e_lfanew == 0L)
1320 {
1321 /* Ignore elf */
1322 if (!memcmp(PEDosHeader, elfhdr, sizeof(elfhdr)))
1323 exit(0);
1324 perror("Input file is not a PE image.\n");
1325 free(FileData);
1326 exit(1);
1327 }
1328
1329 /* Locate PE file header */
1330 /* sizeof(ULONG) = sizeof(MAGIC) */
1331 PEFileHeader = (PIMAGE_FILE_HEADER)((char *) FileData + PEDosHeader->e_lfanew + sizeof(ULONG));
1332
1333 /* Locate optional header */
1334 assert(sizeof(ULONG) == 4);
1335 PEOptHeader = (PIMAGE_OPTIONAL_HEADER)(PEFileHeader + 1);
1336 ImageBase = PEOptHeader->ImageBase;
1337
1338 /* Locate PE section headers */
1339 PESectionHeaders = (PIMAGE_SECTION_HEADER)((char *) PEOptHeader + PEFileHeader->SizeOfOptionalHeader);
1340
1342 PEFileHeader,
1343 PESectionHeaders,
1344 &StabsLength,
1345 &StabBase,
1346 &StabStringsLength,
1347 &StabStringBase))
1348 {
1349 free(FileData);
1350 exit(1);
1351 }
1352
1353 if (StabsLength == 0)
1354 {
1355 // SYMOPT_AUTO_PUBLICS
1356 // SYMOPT_FAVOR_COMPRESSED
1357 // SYMOPT_LOAD_ANYTHING
1358 // SYMOPT_LOAD_LINES
1359 SymSetOptions(0x10000 | 0x800000 | 0x40 | 0x10);
1361 SymInitialize(FileData, ".", 0);
1362
1363 module_base = SymLoadModule(FileData, file, path1, path1, 0, FileSize) & 0xffffffff;
1364
1366 module_base,
1367 SourcePath,
1368 &StabSymbolsCount,
1369 &StabSymbols,
1370 &StringsLength,
1371 &StringBase))
1372 {
1373 free(FileData);
1374 exit(1);
1375 }
1376
1377 UseDbgHelp = TRUE;
1378 SymUnloadModule(FileData, module_base);
1380 }
1381
1383 PEFileHeader,
1384 PESectionHeaders,
1385 &CoffsLength,
1386 &CoffBase,
1387 &CoffStringsLength,
1388 &CoffStringBase))
1389 {
1390 free(FileData);
1391 exit(1);
1392 }
1393
1394 if (!UseDbgHelp)
1395 {
1396 StringBase = malloc(1 + StringsLength + CoffStringsLength +
1397 (CoffsLength / sizeof(ROSSYM_ENTRY)) * (E_SYMNMLEN + 1));
1398 if (StringBase == NULL)
1399 {
1400 free(FileData);
1401 fprintf(stderr, "Failed to allocate memory for strings table\n");
1402 exit(1);
1403 }
1404 /* Make offset 0 into an empty string */
1405 *((char *) StringBase) = '\0';
1406 StringsLength = 1;
1407
1408 if (ConvertStabs(&StabSymbolsCount,
1409 &StabSymbols,
1410 &StringsLength,
1411 StringBase,
1412 StabsLength,
1413 StabBase,
1414 StabStringsLength,
1415 StabStringBase,
1416 ImageBase,
1417 PEFileHeader,
1418 PESectionHeaders))
1419 {
1420 free(StringBase);
1421 free(FileData);
1422 fprintf(stderr, "Failed to allocate memory for strings table\n");
1423 exit(1);
1424 }
1425 }
1426 else
1427 {
1428 StringBase = realloc(StringBase, StringsLength + CoffStringsLength);
1429 if (!StringBase)
1430 {
1431 free(FileData);
1432 fprintf(stderr, "Failed to allocate memory for strings table\n");
1433 exit(1);
1434 }
1435 }
1436
1437 if (ConvertCoffs(&CoffSymbolsCount,
1438 &CoffSymbols,
1439 &StringsLength,
1440 StringBase,
1441 CoffsLength,
1442 CoffBase,
1443 CoffStringsLength,
1444 CoffStringBase,
1445 ImageBase,
1446 PEFileHeader,
1447 PESectionHeaders))
1448 {
1449 if (StabSymbols)
1450 {
1451 free(StabSymbols);
1452 }
1453 free(StringBase);
1454 free(FileData);
1455 exit(1);
1456 }
1457
1458 if (MergeStabsAndCoffs(&MergedSymbolsCount,
1459 &MergedSymbols,
1460 StabSymbolsCount,
1461 StabSymbols,
1462 CoffSymbolsCount,
1463 CoffSymbols))
1464 {
1465 if (CoffSymbols)
1466 {
1467 free(CoffSymbols);
1468 }
1469 if (StabSymbols)
1470 {
1471 free(StabSymbols);
1472 }
1473 free(StringBase);
1474 free(FileData);
1475 exit(1);
1476 }
1477
1478 if (CoffSymbols)
1479 {
1480 free(CoffSymbols);
1481 }
1482 if (StabSymbols)
1483 {
1484 free(StabSymbols);
1485 }
1486 if (MergedSymbolsCount == 0)
1487 {
1488 RosSymLength = 0;
1489 RosSymSection = NULL;
1490 }
1491 else
1492 {
1493 RosSymLength = sizeof(SYMBOLFILE_HEADER) +
1494 MergedSymbolsCount * sizeof(ROSSYM_ENTRY) +
1495 StringsLength;
1496
1497 RosSymSection = malloc(RosSymLength);
1498 if (RosSymSection == NULL)
1499 {
1500 free(MergedSymbols);
1501 free(StringBase);
1502 free(FileData);
1503 fprintf(stderr, "Unable to allocate memory for .rossym section\n");
1504 exit(1);
1505 }
1506 memset(RosSymSection, '\0', RosSymLength);
1507
1508 SymbolFileHeader = (PSYMBOLFILE_HEADER)RosSymSection;
1509 SymbolFileHeader->SymbolsOffset = sizeof(SYMBOLFILE_HEADER);
1510 SymbolFileHeader->SymbolsLength = MergedSymbolsCount * sizeof(ROSSYM_ENTRY);
1511 SymbolFileHeader->StringsOffset = SymbolFileHeader->SymbolsOffset +
1512 SymbolFileHeader->SymbolsLength;
1513 SymbolFileHeader->StringsLength = StringsLength;
1514
1515 memcpy((char *) RosSymSection + SymbolFileHeader->SymbolsOffset,
1516 MergedSymbols,
1517 SymbolFileHeader->SymbolsLength);
1518
1519 memcpy((char *) RosSymSection + SymbolFileHeader->StringsOffset,
1520 StringBase,
1521 SymbolFileHeader->StringsLength);
1522
1523 free(MergedSymbols);
1524 }
1525
1526 free(StringBase);
1527 out = fopen(path2, "wb");
1528 if (out == NULL)
1529 {
1530 perror("Cannot open output file");
1531 free(RosSymSection);
1532 free(FileData);
1533 exit(1);
1534 }
1535
1537 FileData,
1538 PEDosHeader,
1539 PEFileHeader,
1540 PEOptHeader,
1541 PESectionHeaders,
1542 RosSymLength,
1543 RosSymSection))
1544 {
1545 fclose(out);
1546 if (RosSymSection)
1547 {
1548 free(RosSymSection);
1549 }
1550 free(FileData);
1551 exit(1);
1552 }
1553
1554 fclose(out);
1555 if (RosSymSection)
1556 {
1557 free(RosSymSection);
1558 }
1559 free(FileData);
1560
1561 return 0;
1562}
unsigned char BOOLEAN
static int argc
Definition: ServiceArgs.c:12
int memcmp(void *Buffer1, void *Buffer2, ACPI_SIZE Count)
Definition: utclib.c:112
BOOL WINAPI SymUnloadModule(HANDLE hProcess, DWORD BaseOfDll)
Definition: module.c:928
BOOL WINAPI SymCleanup(HANDLE hProcess)
Definition: dbghelp.c:557
BOOL WINAPI SymInitialize(HANDLE hProcess, PCSTR UserSearchPath, BOOL fInvadeProcess)
Definition: dbghelp.c:534
@ SYMOPT_EX_WINE_NATIVE_MODULES
Definition: compat.h:1106
BOOL WINAPI SymSetExtendedOption(IMAGEHLP_EXTENDED_OPTIONS option, BOOL value)
Definition: dbghelp.c:609
DWORD WINAPI SymSetOptions(DWORD opts)
Definition: dbghelp.c:585
DWORD WINAPI SymLoadModule(HANDLE hProcess, HANDLE hFile, PCSTR ImageName, PCSTR ModuleName, DWORD BaseOfDll, DWORD SizeOfDll)
Definition: module.c:753
static UINT load_file(MSIRECORD *row, LPVOID param)
Definition: action.c:1032
_Must_inspect_result_ _Out_ PLARGE_INTEGER FileSize
Definition: fsrtlfuncs.h:108
static const WCHAR path1[]
Definition: path.c:28
static const WCHAR path2[]
Definition: path.c:29
#define argv
Definition: mplay32.c:18
#define L(x)
Definition: ntvdm.h:50
#define IMAGE_DOS_MAGIC
Definition: pecoff.h:6
char * convert_path(char *origpath)
Definition: rcopy.c:11
static FILE * out
Definition: regtests2xml.c:44
struct _ROSSYM_ENTRY ROSSYM_ENTRY
struct _SYMBOLFILE_HEADER * PSYMBOLFILE_HEADER
struct _SYMBOLFILE_HEADER SYMBOLFILE_HEADER
#define exit(n)
Definition: config.h:202
static int ConvertDbgHelp(void *process, DWORD module_base, char *SourcePath, ULONG *SymbolsCount, PROSSYM_ENTRY *SymbolsBase, ULONG *StringsLength, void **StringsBase)
Definition: rsym.c:640
static int CreateOutputFile(FILE *OutFile, void *InData, PIMAGE_DOS_HEADER InDosHeader, PIMAGE_FILE_HEADER InFileHeader, PIMAGE_OPTIONAL_HEADER InOptHeader, PIMAGE_SECTION_HEADER InSectionHeaders, ULONG RosSymLength, void *RosSymSection)
Definition: rsym.c:912
static int MergeStabsAndCoffs(ULONG *MergedSymbolCount, PROSSYM_ENTRY *MergedSymbols, ULONG StabSymbolsCount, PROSSYM_ENTRY StabSymbols, ULONG CoffSymbolsCount, PROSSYM_ENTRY CoffSymbols)
Definition: rsym.c:716
static int GetCoffInfo(void *FileData, PIMAGE_FILE_HEADER PEFileHeader, PIMAGE_SECTION_HEADER PESectionHeaders, ULONG *CoffSymbolsLength, void **CoffSymbolsBase, ULONG *CoffStringsLength, void **CoffStringsBase)
Definition: rsym.c:178
static int ConvertStabs(ULONG *SymbolsCount, PROSSYM_ENTRY *SymbolsBase, ULONG *StringsLength, void *StringsBase, ULONG StabSymbolsLength, void *StabSymbolsBase, ULONG StabStringsLength, void *StabStringsBase, ULONG_PTR ImageBase, PIMAGE_FILE_HEADER PEFileHeader, PIMAGE_SECTION_HEADER PESectionHeaders)
Definition: rsym.c:231
static int GetStabInfo(void *FileData, PIMAGE_FILE_HEADER PEFileHeader, PIMAGE_SECTION_HEADER PESectionHeaders, ULONG *StabSymbolsLength, void **StabSymbolsBase, ULONG *StabStringsLength, void **StabStringsBase)
Definition: rsym.c:140
static 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 StringsOffset
Definition: rsym.h:34
ULONG StringsLength
Definition: rsym.h:35
ULONG SymbolsOffset
Definition: rsym.h:32
ULONG SymbolsLength
Definition: rsym.h:33
Definition: fci.c:127
void * arg
Definition: msvc.h:10

◆ MergeStabsAndCoffs()

static int MergeStabsAndCoffs ( ULONG MergedSymbolCount,
PROSSYM_ENTRY MergedSymbols,
ULONG  StabSymbolsCount,
PROSSYM_ENTRY  StabSymbols,
ULONG  CoffSymbolsCount,
PROSSYM_ENTRY  CoffSymbols 
)
static

Definition at line 716 of file rsym.c.

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}
_In_ PFCB _In_ LONGLONG FileOffset
Definition: cdprocs.h:160

Referenced by main().

◆ ProcessRelocations()

static int ProcessRelocations ( ULONG ProcessedRelocsLength,
void **  ProcessedRelocs,
void RawData,
PIMAGE_OPTIONAL_HEADER  OptHeader,
unsigned  NumberOfSections,
PIMAGE_SECTION_HEADER  SectionHeaders 
)
static

Definition at line 825 of file rsym.c.

828{
829 PIMAGE_SECTION_HEADER RelocSectionHeader, TargetSectionHeader;
830 PIMAGE_BASE_RELOCATION BaseReloc, End, AcceptedRelocs;
831 int Found;
832
835 {
836 /* No relocation entries */
837 *ProcessedRelocsLength = 0;
838 *ProcessedRelocs = NULL;
839 return 0;
840 }
841
843 NumberOfSections, SectionHeaders);
844 if (RelocSectionHeader == NULL)
845 {
846 fprintf(stderr, "Can't find section header for relocation data\n");
847 return 1;
848 }
849
850 *ProcessedRelocs = malloc(RelocSectionHeader->SizeOfRawData);
851 if (*ProcessedRelocs == NULL)
852 {
854 "Failed to allocate %u bytes for relocations\n",
855 (unsigned int)RelocSectionHeader->SizeOfRawData);
856 return 1;
857 }
858 *ProcessedRelocsLength = 0;
859
860 BaseReloc = (PIMAGE_BASE_RELOCATION) ((char *) RawData +
861 RelocSectionHeader->PointerToRawData +
863 RelocSectionHeader->VirtualAddress));
864 End = (PIMAGE_BASE_RELOCATION) ((char *) BaseReloc +
866
867 while (BaseReloc < End && BaseReloc->SizeOfBlock > 0)
868 {
869 TargetSectionHeader = FindSectionForRVA(BaseReloc->VirtualAddress,
870 NumberOfSections,
871 SectionHeaders);
872 if (TargetSectionHeader != NULL)
873 {
874 AcceptedRelocs = *ProcessedRelocs;
875 Found = 0;
876 while (AcceptedRelocs < (PIMAGE_BASE_RELOCATION) ((char *) *ProcessedRelocs +
877 *ProcessedRelocsLength)
878 && !Found)
879 {
880 Found = BaseReloc->SizeOfBlock == AcceptedRelocs->SizeOfBlock &&
881 memcmp(BaseReloc, AcceptedRelocs, AcceptedRelocs->SizeOfBlock) == 0;
882 AcceptedRelocs = (PIMAGE_BASE_RELOCATION) ((char *) AcceptedRelocs +
883 AcceptedRelocs->SizeOfBlock);
884 }
885 if (!Found)
886 {
887 memcpy((char *) *ProcessedRelocs + *ProcessedRelocsLength,
888 BaseReloc,
889 BaseReloc->SizeOfBlock);
890 *ProcessedRelocsLength += BaseReloc->SizeOfBlock;
891 }
892 }
893 BaseReloc = (PIMAGE_BASE_RELOCATION)((char *) BaseReloc + BaseReloc->SizeOfBlock);
894 }
895
896 return 0;
897}
return Found
Definition: dirsup.c:1270
struct _IMAGE_BASE_RELOCATION * PIMAGE_BASE_RELOCATION

Referenced by CreateOutputFile().

◆ StrDupShortenPath()

static char * StrDupShortenPath ( char PathChop,
char FilePath 
)
static

Definition at line 548 of file rsym.c.

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}
PCWSTR FilePath

Referenced by DbgHelpAddLineNumber().

◆ StringHashTableFree()

static void StringHashTableFree ( struct StringHashTable StringTable)
static

Definition at line 97 of file rsym.c.

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}

Referenced by ConvertCoffs(), and ConvertStabs().

◆ StringHashTableInit()

static void StringHashTableInit ( struct StringHashTable StringTable,
ULONG  StringsLength,
char StringsBase 
)
static

Definition at line 78 of file rsym.c.

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}
@ Start
Definition: partlist.h:33

Referenced by ConvertCoffs(), and ConvertStabs().