diff --git a/reactos/tools/bytesex.h b/reactos/tools/bytesex.h new file mode 100644 index 00000000000..68eb702eb1d --- /dev/null +++ b/reactos/tools/bytesex.h @@ -0,0 +1,66 @@ +#ifndef BYTESEX_H +#define BYTESEX_H + +namespace { +static inline WORD dtohs(WORD in) +{ + PBYTE in_ptr = (PBYTE)∈ + return in_ptr[0] | (in_ptr[1] << 8); +} + +static inline WORD htods(WORD in) +{ + WORD out; + PBYTE out_ptr = (PBYTE)&out; + out_ptr[0] = in; out_ptr[1] = in >> 8; + return out; +} + +static inline DWORD dtohl(DWORD in) +{ + PBYTE in_ptr = (PBYTE)∈ + return in_ptr[0] | (in_ptr[1] << 8) | (in_ptr[2] << 16) | (in_ptr[3] << 24); +} + +static inline DWORD htodl(DWORD in) +{ + DWORD out; + PBYTE out_ptr = (PBYTE)&out; + out_ptr[0] = in ; out_ptr[1] = in >> 8; + out_ptr[2] = in >> 16; out_ptr[3] = in >> 24; + return out; +} + +template T toHost( T value ); +template T toDest( T value ); +template <> WORD toHost( WORD value ) { return dtohs(value); } +template <> DWORD toHost( DWORD value ) { return dtohl(value); } +template <> int toHost( int value ) { return dtohl(value); } +template <> WORD toDest( WORD value ) { return htods(value); } +template <> DWORD toDest( DWORD value ) { return htodl(value); } +template <> int toDest( int value ) { return htodl(value); } +} + +namespace ReactosBytesex { +template +struct LENumber { +public: + operator T () const { return toHost(value); } + LENumber &operator = (T other) { value = toDest(other); return *this; } + T operator ++ () { (*this) += 1; return *this; } + LENumber &operator ++ (int) { (*this) += 1; return *this; } + T operator -- () { (*this) -= 1; return *this; } + LENumber &operator -- (int) { (*this) -= 1; return *this; } + LENumber &operator += (T other) { value = toDest(toHost(value) + other); return *this; } + LENumber &operator -= (T other) { return (*this) += -other; } + LENumber &operator &= (T other) { value = toDest(toHost(value) & other); return *this; } + LENumber &operator |= (T other) { value = toDest(toHost(value) | other); return *this; } +private: + T value; +}; + +typedef LENumber LEWord; +typedef LENumber LEDWord; +} + +#endif/*BYTESEX_H*/ diff --git a/reactos/tools/ppc.lost+found/link-ntoskrnl b/reactos/tools/ppc.lost+found/link-ntoskrnl deleted file mode 100755 index eeacb95ef8d..00000000000 --- a/reactos/tools/ppc.lost+found/link-ntoskrnl +++ /dev/null @@ -1,174 +0,0 @@ -#!/bin/sh -xv - -reactos-powerpc-ld \ - -v \ - --subsystem native \ - --entry NtProcessStartup \ - --image-base 0x80000000 \ - --file-alignment 0x1000 \ - --section-alignment 0x1000 \ - -nostartfiles -shared \ - ntoskrnl.temp.exp -o output-ppc/ntoskrnl/ntoskrnl.exe \ - obj-ppc/ntoskrnl/ke/powerpc/main_asm.o \ - obj-ppc/ntoskrnl/ke/apc.o \ - obj-ppc/ntoskrnl/ke/bug.o \ - obj-ppc/ntoskrnl/ke/clock.o \ - obj-ppc/ntoskrnl/ke/device.o \ - obj-ppc/ntoskrnl/ke/dpc.o \ - obj-ppc/ntoskrnl/ke/event.o \ - obj-ppc/ntoskrnl/ke/exception.o \ - obj-ppc/ntoskrnl/ke/gate.o \ - obj-ppc/ntoskrnl/ke/gmutex.o \ - obj-ppc/ntoskrnl/ke/ipi.o \ - obj-ppc/ntoskrnl/ke/kqueue.o \ - obj-ppc/ntoskrnl/ke/kthread.o \ - obj-ppc/ntoskrnl/ke/mutex.o \ - obj-ppc/ntoskrnl/ke/process.o \ - obj-ppc/ntoskrnl/ke/profile.o \ - obj-ppc/ntoskrnl/ke/queue.o \ - obj-ppc/ntoskrnl/ke/sem.o \ - obj-ppc/ntoskrnl/ke/spinlock.o \ - obj-ppc/ntoskrnl/ke/timer.o \ - obj-ppc/ntoskrnl/ke/usercall.o \ - obj-ppc/ntoskrnl/ke/wait.o \ - obj-ppc/ntoskrnl/cc/cacheman.o \ - obj-ppc/ntoskrnl/cc/copy.o \ - obj-ppc/ntoskrnl/cc/fs.o \ - obj-ppc/ntoskrnl/cc/mdl.o \ - obj-ppc/ntoskrnl/cc/pin.o \ - obj-ppc/ntoskrnl/cc/view.o \ - obj-ppc/ntoskrnl/cm/import.o \ - obj-ppc/ntoskrnl/cm/ntfunc.o \ - obj-ppc/ntoskrnl/cm/regfile.o \ - obj-ppc/ntoskrnl/cm/registry.o \ - obj-ppc/ntoskrnl/cm/regobj.o \ - obj-ppc/ntoskrnl/dbgk/dbgkutil.o \ - obj-ppc/ntoskrnl/dbgk/debug.o \ - obj-ppc/ntoskrnl/ex/atom.o \ - obj-ppc/ntoskrnl/ex/callback.o \ - obj-ppc/ntoskrnl/ex/dbgctrl.o \ - obj-ppc/ntoskrnl/ex/error.o \ - obj-ppc/ntoskrnl/ex/event.o \ - obj-ppc/ntoskrnl/ex/evtpair.o \ - obj-ppc/ntoskrnl/ex/fmutex.o \ - obj-ppc/ntoskrnl/ex/handle.o \ - obj-ppc/ntoskrnl/ex/init.o \ - obj-ppc/ntoskrnl/ex/lookas.o \ - obj-ppc/ntoskrnl/ex/mutant.o \ - obj-ppc/ntoskrnl/ex/power.o \ - obj-ppc/ntoskrnl/ex/pushlock.o \ - obj-ppc/ntoskrnl/ex/profile.o \ - obj-ppc/ntoskrnl/ex/resource.o \ - obj-ppc/ntoskrnl/ex/rundown.o \ - obj-ppc/ntoskrnl/ex/sem.o \ - obj-ppc/ntoskrnl/ex/sysinfo.o \ - obj-ppc/ntoskrnl/ex/time.o \ - obj-ppc/ntoskrnl/ex/timer.o \ - obj-ppc/ntoskrnl/ex/uuid.o \ - obj-ppc/ntoskrnl/ex/win32k.o \ - obj-ppc/ntoskrnl/ex/work.o \ - obj-ppc/ntoskrnl/ex/zone.o \ - obj-ppc/ntoskrnl/ex/zw.o \ - obj-ppc/ntoskrnl/fs/context.o \ - obj-ppc/ntoskrnl/fs/fastio.o \ - obj-ppc/ntoskrnl/fs/filelock.o \ - obj-ppc/ntoskrnl/fs/mcb.o \ - obj-ppc/ntoskrnl/fs/name.o \ - obj-ppc/ntoskrnl/fs/notify.o \ - obj-ppc/ntoskrnl/fs/oplock.o \ - obj-ppc/ntoskrnl/fs/pool.o \ - obj-ppc/ntoskrnl/fs/tunnel.o \ - obj-ppc/ntoskrnl/fs/unc.o \ - obj-ppc/ntoskrnl/fs/util.o \ - obj-ppc/ntoskrnl/inbv/inbv.o \ - obj-ppc/ntoskrnl/io/iomgr/*.o \ - obj-ppc/ntoskrnl/io/pnpmgr/*.o \ - obj-ppc/ntoskrnl/kd/wrappers/bochs.o \ - obj-ppc/ntoskrnl/kd/wrappers/gdbstub.o \ - obj-ppc/ntoskrnl/kd/kdinit.o \ - obj-ppc/ntoskrnl/kd/kdio.o \ - obj-ppc/ntoskrnl/kd/kdmain.o \ - obj-ppc/ntoskrnl/ldr/loader.o \ - obj-ppc/ntoskrnl/ldr/rtl.o \ - obj-ppc/ntoskrnl/lpc/close.o \ - obj-ppc/ntoskrnl/lpc/complete.o \ - obj-ppc/ntoskrnl/lpc/connect.o \ - obj-ppc/ntoskrnl/lpc/create.o \ - obj-ppc/ntoskrnl/lpc/listen.o \ - obj-ppc/ntoskrnl/lpc/port.o \ - obj-ppc/ntoskrnl/lpc/query.o \ - obj-ppc/ntoskrnl/lpc/queue.o \ - obj-ppc/ntoskrnl/lpc/receive.o \ - obj-ppc/ntoskrnl/lpc/reply.o \ - obj-ppc/ntoskrnl/lpc/send.o \ - obj-ppc/ntoskrnl/mm/anonmem.o \ - obj-ppc/ntoskrnl/mm/aspace.o \ - obj-ppc/ntoskrnl/mm/balance.o \ - obj-ppc/ntoskrnl/mm/cont.o \ - obj-ppc/ntoskrnl/mm/drvlck.o \ - obj-ppc/ntoskrnl/mm/freelist.o \ - obj-ppc/ntoskrnl/mm/iospace.o \ - obj-ppc/ntoskrnl/mm/kmap.o \ - obj-ppc/ntoskrnl/mm/marea.o \ - obj-ppc/ntoskrnl/mm/mdl.o \ - obj-ppc/ntoskrnl/mm/mm.o \ - obj-ppc/ntoskrnl/mm/process.o \ - obj-ppc/ntoskrnl/mm/mminit.o \ - obj-ppc/ntoskrnl/mm/mpw.o \ - obj-ppc/ntoskrnl/mm/ncache.o \ - obj-ppc/ntoskrnl/mm/npool.o \ - obj-ppc/ntoskrnl/mm/pagefile.o \ - obj-ppc/ntoskrnl/mm/pageop.o \ - obj-ppc/ntoskrnl/mm/pager.o \ - obj-ppc/ntoskrnl/mm/pagfault.o \ - obj-ppc/ntoskrnl/mm/paging.o \ - obj-ppc/ntoskrnl/mm/pe.o \ - obj-ppc/ntoskrnl/mm/physical.o \ - obj-ppc/ntoskrnl/mm/pool.o \ - obj-ppc/ntoskrnl/mm/ppool.o \ - obj-ppc/ntoskrnl/mm/region.o \ - obj-ppc/ntoskrnl/mm/rmap.o \ - obj-ppc/ntoskrnl/mm/section.o \ - obj-ppc/ntoskrnl/mm/verifier.o \ - obj-ppc/ntoskrnl/mm/virtual.o \ - obj-ppc/ntoskrnl/mm/wset.o \ - obj-ppc/ntoskrnl/mm/elf32.o \ - obj-ppc/ntoskrnl/mm/elf64.o \ - obj-ppc/ntoskrnl/ob/obdir.o \ - obj-ppc/ntoskrnl/ob/obinit.o \ - obj-ppc/ntoskrnl/ob/obhandle.o \ - obj-ppc/ntoskrnl/ob/obname.o \ - obj-ppc/ntoskrnl/ob/oblife.o \ - obj-ppc/ntoskrnl/ob/obref.o \ - obj-ppc/ntoskrnl/ob/sdcache.o \ - obj-ppc/ntoskrnl/ob/symlink.o \ - obj-ppc/ntoskrnl/po/power.o \ - obj-ppc/ntoskrnl/ps/*.o \ - obj-ppc/ntoskrnl/rtl/libsupp.o \ - obj-ppc/ntoskrnl/rtl/misc.o \ - obj-ppc/ntoskrnl/rtl/nls.o \ - obj-ppc/ntoskrnl/rtl/regio.o \ - obj-ppc/ntoskrnl/rtl/strtok.o \ - obj-ppc/ntoskrnl/se/access.o \ - obj-ppc/ntoskrnl/se/acl.o \ - obj-ppc/ntoskrnl/se/audit.o \ - obj-ppc/ntoskrnl/se/lsa.o \ - obj-ppc/ntoskrnl/se/luid.o \ - obj-ppc/ntoskrnl/se/priv.o \ - obj-ppc/ntoskrnl/se/sd.o \ - obj-ppc/ntoskrnl/se/semgr.o \ - obj-ppc/ntoskrnl/se/sid.o \ - obj-ppc/ntoskrnl/se/token.o \ - obj-ppc/ntoskrnl/ntoskrnl.coff \ - obj-ppc/ntoskrnl/kdbg/kdb_symbols.o \ - obj-ppc/lib/drivers/csq/csq.a \ - obj-ppc/hal/hal/libhal.a \ - obj-ppc/lib/kjs/kjs.a \ - obj-ppc/lib/pseh/pseh.a \ - obj-ppc/lib/rtl/rtl.a \ - obj-ppc/lib/rossym/rossym.a \ - obj-ppc/lib/string/string.a \ - obj-ppc/lib/wdmguid/wdmguid.a \ - -nostartfiles \ - -nostdlib \ - -lgcc -g diff --git a/reactos/tools/ppc.lost+found/pmake b/reactos/tools/ppc.lost+found/pmake index 942a1f2d7ca..988f524e55c 100755 --- a/reactos/tools/ppc.lost+found/pmake +++ b/reactos/tools/ppc.lost+found/pmake @@ -4,6 +4,7 @@ export PATH=$PATH:/usr/local/pkg/reactos-powerpc/bin make \ ARCH=powerpc \ HOST=mingw32-linux \ + PREFIX=reactos-powerpc \ ROS_INTERMEDIATE=obj-ppc \ ROS_OUTPUT=output-ppc \ ROS_PREFIX=reactos-powerpc \ diff --git a/reactos/tools/rsym.cpp b/reactos/tools/rsym.cpp new file mode 100644 index 00000000000..b4399ad7846 --- /dev/null +++ b/reactos/tools/rsym.cpp @@ -0,0 +1,977 @@ +/* + * Usage: rsym input-file output-file + * + * There are two sources of information: the .stab/.stabstr + * sections of the executable and the COFF symbol table. Most + * of the information is in the .stab/.stabstr sections. + * However, most of our asm files don't contain .stab directives, + * so routines implemented in assembler won't show up in the + * .stab section. They are present in the COFF symbol table. + * So, we mostly use the .stab/.stabstr sections, but we augment + * the info there with info from the COFF symbol table when + * possible. + * + * This is a tool and is compiled using the host compiler, + * i.e. on Linux gcc and not mingw-gcc (cross-compiler). + * Therefore we can't include SDK headers and we have to + * duplicate some definitions here. + * Also note that the internal functions are "old C-style", + * returning an int, where a return of 0 means success and + * non-zero is failure. + */ + +#include +#include +#include +#include + +#include "rsym.h" + +static int +CompareSymEntry(const PROSSYM_ENTRY SymEntry1, const PROSSYM_ENTRY SymEntry2) +{ + if (SymEntry1->Address < SymEntry2->Address) + { + return -1; + } + + if (SymEntry2->Address < SymEntry1->Address) + { + return +1; + } + + return 0; +} + +static int +GetStabInfo(void *FileData, PIMAGE_FILE_HEADER PEFileHeader, + PIMAGE_SECTION_HEADER PESectionHeaders, + ULONG *StabSymbolsLength, void **StabSymbolsBase, + ULONG *StabStringsLength, void **StabStringsBase) +{ + ULONG Idx; + + /* Load .stab and .stabstr sections if available */ + *StabSymbolsBase = NULL; + *StabSymbolsLength = 0; + *StabStringsBase = NULL; + *StabStringsLength = 0; + + for (Idx = 0; Idx < PEFileHeader->NumberOfSections; Idx++) + { + /* printf("section: '%.08s'\n", PESectionHeaders[Idx].Name); */ + if ((strncmp((char*)PESectionHeaders[Idx].Name, ".stab", 5) == 0) + && (PESectionHeaders[Idx].Name[5] == 0)) + { + /* printf(".stab section found. Size %d\n", + PESectionHeaders[Idx].SizeOfRawData); */ + + *StabSymbolsLength = PESectionHeaders[Idx].SizeOfRawData; + *StabSymbolsBase = (void *)((char *) FileData + PESectionHeaders[Idx].PointerToRawData); + } + + if (strncmp((char*)PESectionHeaders[Idx].Name, ".stabstr", 8) == 0) + { + /* printf(".stabstr section found. Size %d\n", + PESectionHeaders[Idx].SizeOfRawData); */ + + *StabStringsLength = PESectionHeaders[Idx].SizeOfRawData; + *StabStringsBase = (void *)((char *) FileData + PESectionHeaders[Idx].PointerToRawData); + } + } + + return 0; +} + +static int +GetCoffInfo(void *FileData, PIMAGE_FILE_HEADER PEFileHeader, + PIMAGE_SECTION_HEADER PESectionHeaders, + ULONG *CoffSymbolsLength, void **CoffSymbolsBase, + ULONG *CoffStringsLength, void **CoffStringsBase) +{ + + if (0 == PEFileHeader->PointerToSymbolTable || 0 == PEFileHeader->NumberOfSymbols) + { + /* No COFF symbol table */ + *CoffSymbolsLength = 0; + *CoffStringsLength = 0; + } + else + { + *CoffSymbolsLength = PEFileHeader->NumberOfSymbols * sizeof(COFF_SYMENT); + *CoffSymbolsBase = (void *)((char *) FileData + PEFileHeader->PointerToSymbolTable); + *CoffStringsLength = *((ULONG *) ((char *) *CoffSymbolsBase + *CoffSymbolsLength)); + *CoffStringsBase = (void *)((char *) *CoffSymbolsBase + *CoffSymbolsLength); + } + + return 0; +} + +static ULONG +FindOrAddString(char *StringToFind, ULONG *StringsLength, void *StringsBase) +{ + char *Search, *End; + + Search = (char *) StringsBase; + End = Search + *StringsLength; + + while (Search < End) + { + if (0 == strcmp(Search, StringToFind)) + { + return Search - (char *) StringsBase; + } + Search += strlen(Search) + 1; + } + + strcpy(Search, StringToFind); + *StringsLength += strlen(StringToFind) + 1; + + return Search - (char *) 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) +{ + PSTAB_ENTRY StabEntry; + ULONG Count, i; + ULONG_PTR Address, LastFunctionAddress; + int First = 1; + char *Name; + char FuncName[256]; + PROSSYM_ENTRY Current; + + StabEntry = (PSTAB_ENTRY)StabSymbolsBase; + Count = StabSymbolsLength / sizeof(STAB_ENTRY); + *SymbolsCount = 0; + if (Count == 0) + { + /* No symbol info */ + *SymbolsBase = NULL; + return 0; + } + + *SymbolsBase = (PROSSYM_ENTRY)malloc(Count * sizeof(ROSSYM_ENTRY)); + if (NULL == *SymbolsBase) + { + fprintf(stderr, "Failed to allocate memory for converted .stab symbols\n"); + return 1; + } + Current = *SymbolsBase; + memset ( Current, 0, sizeof(*Current) ); + + LastFunctionAddress = 0; + for (i = 0; i < Count; i++) + { + if ( 0 == LastFunctionAddress ) + { + Address = StabEntry[i].n_value - ImageBase; + } + else + { + Address = LastFunctionAddress + StabEntry[i].n_value; + } + switch (StabEntry[i].n_type) + { + case N_SO: + case N_SOL: + case N_BINCL: + Name = (char *) StabStringsBase + StabEntry[i].n_strx; + if (StabStringsLength < StabEntry[i].n_strx + ||'\0' == *Name || '/' == Name[strlen(Name) - 1] + || '\\' == Name[strlen(Name) - 1] + || StabEntry[i].n_value < ImageBase) + { + continue; + } + if ( First || Address != Current->Address ) + { + if ( !First ) + { + memset ( ++Current, 0, sizeof(*Current) ); + Current->FunctionOffset = Current[-1].FunctionOffset; + } + else + First = 0; + Current->Address = Address; + } + Current->FileOffset = FindOrAddString((char *)StabStringsBase + + StabEntry[i].n_strx, + StringsLength, + StringsBase); + break; + case N_FUN: + if (0 == StabEntry[i].n_desc || StabEntry[i].n_value < ImageBase) + { + LastFunctionAddress = 0; /* line # 0 = end of function */ + continue; + } + if ( First || Address != Current->Address ) + { + if ( !First ) + memset ( ++Current, 0, sizeof(*Current) ); + else + First = 0; + Current->Address = Address; + Current->FileOffset = Current[-1].FileOffset; + } + if (sizeof(FuncName) <= strlen((char *) StabStringsBase + StabEntry[i].n_strx)) + { + free(*SymbolsBase); + fprintf(stderr, "Function name too long\n"); + return 1; + } + strcpy(FuncName, (char *) StabStringsBase + StabEntry[i].n_strx); + Name = strchr(FuncName, ':'); + if (NULL != Name) + { + *Name = '\0'; + } + Current->FunctionOffset = FindOrAddString(FuncName, + StringsLength, + StringsBase); + Current->SourceLine = 0; + LastFunctionAddress = Address; + break; + case N_SLINE: + if ( First || Address != Current->Address ) + { + if ( !First ) + { + memset ( ++Current, 0, sizeof(*Current) ); + Current->FileOffset = Current[-1].FileOffset; + Current->FunctionOffset = Current[-1].FunctionOffset; + } + else + First = 0; + Current->Address = Address; + } + Current->SourceLine = StabEntry[i].n_desc; + break; + default: + continue; + } + } + *SymbolsCount = (Current - *SymbolsBase + 1); + + qsort(*SymbolsBase, *SymbolsCount, sizeof(ROSSYM_ENTRY), (int (*)(const void *, const void *)) CompareSymEntry); + + return 0; +} + +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) +{ + ULONG Count, i; + PCOFF_SYMENT CoffEntry; + char FuncName[256]; + char *p; + PROSSYM_ENTRY Current; + + CoffEntry = (PCOFF_SYMENT) CoffSymbolsBase; + Count = CoffSymbolsLength / sizeof(COFF_SYMENT); + *SymbolsBase = (PROSSYM_ENTRY)malloc(Count * sizeof(ROSSYM_ENTRY)); + if (NULL == *SymbolsBase) + { + fprintf(stderr, "Unable to allocate memory for converted COFF symbols\n"); + return 1; + } + *SymbolsCount = 0; + Current = *SymbolsBase; + + for (i = 0; i < Count; i++) + { + if (ISFCN(CoffEntry[i].e_type) || C_EXT == CoffEntry[i].e_sclass) + { + Current->Address = CoffEntry[i].e_value; + if (0 < CoffEntry[i].e_scnum) + { + if (PEFileHeader->NumberOfSections < CoffEntry[i].e_scnum) + { + free(*SymbolsBase); + fprintf(stderr, "Invalid section number %d in COFF symbols (only %d sections present)\n", + (DWORD)CoffEntry[i].e_scnum, (DWORD)PEFileHeader->NumberOfSections); + return 1; + } + Current->Address += PESectionHeaders[CoffEntry[i].e_scnum - 1].VirtualAddress; + } + Current->FileOffset = 0; + if (0 == CoffEntry[i].e.e.e_zeroes) + { + if (sizeof(FuncName) <= strlen((char *) CoffStringsBase + CoffEntry[i].e.e.e_offset)) + { + free(*SymbolsBase); + fprintf(stderr, "Function name too long\n"); + return 1; + } + strcpy(FuncName, (char *) CoffStringsBase + CoffEntry[i].e.e.e_offset); + } + else + { + memcpy(FuncName, CoffEntry[i].e.e_name, E_SYMNMLEN); + FuncName[E_SYMNMLEN] = '\0'; + } + + /* Name demangling: stdcall */ + p = strrchr(FuncName, '@'); + if (NULL != p) + { + *p = '\0'; + } + p = ('_' == FuncName[0] || '@' == FuncName[0] ? FuncName + 1 : FuncName); + Current->FunctionOffset = FindOrAddString(p, + StringsLength, + StringsBase); + Current->SourceLine = 0; + memset ( ++Current, 0, sizeof(*Current) ); + } + i += CoffEntry[i].e_numaux; + } + + *SymbolsCount = (Current - *SymbolsBase + 1); + qsort(*SymbolsBase, *SymbolsCount, sizeof(ROSSYM_ENTRY), (int (*)(const void *, const void *)) CompareSymEntry); + + return 0; +} + +static int +MergeStabsAndCoffs(ULONG *MergedSymbolCount, PROSSYM_ENTRY *MergedSymbols, + ULONG StabSymbolsCount, PROSSYM_ENTRY StabSymbols, + ULONG CoffSymbolsCount, PROSSYM_ENTRY CoffSymbols) +{ + ULONG StabIndex, j; + ULONG CoffIndex; + ULONG_PTR StabFunctionStartAddress; + ULONG StabFunctionStringOffset, NewStabFunctionStringOffset; + + *MergedSymbolCount = 0; + if (StabSymbolsCount == 0) + { + *MergedSymbols = NULL; + return 0; + } + *MergedSymbols = (PROSSYM_ENTRY)malloc(StabSymbolsCount * sizeof(ROSSYM_ENTRY)); + if (NULL == *MergedSymbols) + { + fprintf(stderr, "Unable to allocate memory for merged symbols\n"); + return 1; + } + + StabFunctionStartAddress = 0; + StabFunctionStringOffset = 0; + CoffIndex = 0; + for (StabIndex = 0; StabIndex < StabSymbolsCount; StabIndex++) + { + (*MergedSymbols)[*MergedSymbolCount] = StabSymbols[StabIndex]; + for (j = StabIndex + 1; + j < StabSymbolsCount && StabSymbols[j].Address == StabSymbols[StabIndex].Address; + j++) + { + if (0 != StabSymbols[j].FileOffset && 0 == (*MergedSymbols)[*MergedSymbolCount].FileOffset) + { + (*MergedSymbols)[*MergedSymbolCount].FileOffset = StabSymbols[j].FileOffset; + } + if (0 != StabSymbols[j].FunctionOffset && 0 == (*MergedSymbols)[*MergedSymbolCount].FunctionOffset) + { + (*MergedSymbols)[*MergedSymbolCount].FunctionOffset = StabSymbols[j].FunctionOffset; + } + if (0 != StabSymbols[j].SourceLine && 0 == (*MergedSymbols)[*MergedSymbolCount].SourceLine) + { + (*MergedSymbols)[*MergedSymbolCount].SourceLine = StabSymbols[j].SourceLine; + } + } + StabIndex = j - 1; + while (CoffIndex < CoffSymbolsCount + && CoffSymbols[CoffIndex + 1].Address <= (*MergedSymbols)[*MergedSymbolCount].Address) + { + CoffIndex++; + } + NewStabFunctionStringOffset = (*MergedSymbols)[*MergedSymbolCount].FunctionOffset; + if (CoffSymbolsCount > 0 && + CoffSymbols[CoffIndex].Address < (*MergedSymbols)[*MergedSymbolCount].Address + && StabFunctionStartAddress < CoffSymbols[CoffIndex].Address + && 0 != CoffSymbols[CoffIndex].FunctionOffset) + { + (*MergedSymbols)[*MergedSymbolCount].FunctionOffset = CoffSymbols[CoffIndex].FunctionOffset; + } + if (StabFunctionStringOffset != NewStabFunctionStringOffset) + { + StabFunctionStartAddress = (*MergedSymbols)[*MergedSymbolCount].Address; + } + StabFunctionStringOffset = NewStabFunctionStringOffset; + (*MergedSymbolCount)++; + } + + return 0; +} + +static PIMAGE_SECTION_HEADER +FindSectionForRVA(DWORD RVA, unsigned NumberOfSections, PIMAGE_SECTION_HEADER SectionHeaders) +{ + unsigned Section; + + for (Section = 0; Section < NumberOfSections; Section++) + { + if (SectionHeaders[Section].VirtualAddress <= RVA && + RVA < SectionHeaders[Section].VirtualAddress + SectionHeaders[Section].Misc.VirtualSize) + { + return SectionHeaders + Section; + } + } + + return NULL; +} + +static int +IncludeRelocationsForSection(PIMAGE_SECTION_HEADER SectionHeader) +{ + static char *BlacklistedSections[] = + { + ".edata", + ".idata", + ".reloc" + }; + char SectionName[IMAGE_SIZEOF_SHORT_NAME]; + unsigned i; + + if (0 != (SectionHeader->Characteristics & IMAGE_SCN_LNK_REMOVE)) + { + return 0; + } + + for (i = 0; i < sizeof(BlacklistedSections) / sizeof(BlacklistedSections[0]); i++) + { + strncpy(SectionName, BlacklistedSections[i], IMAGE_SIZEOF_SHORT_NAME); + if (0 == memcmp(SectionName, SectionHeader->Name, IMAGE_SIZEOF_SHORT_NAME)) + { + return 0; + } + } + + return 1; +} + +static int +ProcessRelocations(ULONG *ProcessedRelocsLength, void **ProcessedRelocs, + void *RawData, PIMAGE_OPTIONAL_HEADER OptHeader, + unsigned NumberOfSections, PIMAGE_SECTION_HEADER SectionHeaders) +{ + PIMAGE_SECTION_HEADER RelocSectionHeader, TargetSectionHeader; + PIMAGE_BASE_RELOCATION BaseReloc, End, AcceptedRelocs; + int Found; + + if (OptHeader->NumberOfRvaAndSizes < IMAGE_DIRECTORY_ENTRY_BASERELOC + || 0 == OptHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress) + { + /* No relocation entries */ + *ProcessedRelocsLength = 0; + *ProcessedRelocs = NULL; + return 0; + } + + RelocSectionHeader = FindSectionForRVA(OptHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress, + NumberOfSections, SectionHeaders); + if (NULL == RelocSectionHeader) + { + fprintf(stderr, "Can't find section header for relocation data\n"); + return 1; + } + + *ProcessedRelocs = malloc(RelocSectionHeader->SizeOfRawData); + if (NULL == *ProcessedRelocs) + { + fprintf(stderr, "Failed to allocate %lu bytes for relocations\n", (DWORD)RelocSectionHeader->SizeOfRawData); + return 1; + } + *ProcessedRelocsLength = 0; + + BaseReloc = (PIMAGE_BASE_RELOCATION) ((char *) RawData + + RelocSectionHeader->PointerToRawData + + (OptHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress - + RelocSectionHeader->VirtualAddress)); + End = (PIMAGE_BASE_RELOCATION) ((char *) BaseReloc + + OptHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].Size); + + while (BaseReloc < End && 0 < BaseReloc->SizeOfBlock) + { + TargetSectionHeader = FindSectionForRVA(BaseReloc->VirtualAddress, NumberOfSections, + SectionHeaders); + if (NULL != TargetSectionHeader && IncludeRelocationsForSection(TargetSectionHeader)) + { + AcceptedRelocs = (PIMAGE_BASE_RELOCATION)*ProcessedRelocs; + Found = 0; + while (AcceptedRelocs < (PIMAGE_BASE_RELOCATION) ((char *) *ProcessedRelocs + + *ProcessedRelocsLength) + && ! Found) + { + Found = BaseReloc->SizeOfBlock == AcceptedRelocs->SizeOfBlock + && 0 == memcmp(BaseReloc, AcceptedRelocs, AcceptedRelocs->SizeOfBlock); + AcceptedRelocs= (PIMAGE_BASE_RELOCATION) ((char *) AcceptedRelocs + + AcceptedRelocs->SizeOfBlock); + } + if (! Found) + { + memcpy((char *) *ProcessedRelocs + *ProcessedRelocsLength, + BaseReloc, BaseReloc->SizeOfBlock); + *ProcessedRelocsLength += BaseReloc->SizeOfBlock; + } + } + BaseReloc = (PIMAGE_BASE_RELOCATION)((char *) BaseReloc + BaseReloc->SizeOfBlock); + } + + return 0; +} + +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) +{ + ULONG StartOfRawData; + unsigned Section; + void *OutHeader, *ProcessedRelocs, *PaddedRosSym, *Data; + PIMAGE_DOS_HEADER OutDosHeader; + PIMAGE_FILE_HEADER OutFileHeader; + PIMAGE_OPTIONAL_HEADER OutOptHeader; + PIMAGE_SECTION_HEADER OutSectionHeaders, CurrentSectionHeader; + DWORD CheckSum; + ULONG Length, i; + ULONG ProcessedRelocsLength; + ULONG RosSymOffset, RosSymFileLength; + int InRelocSectionIndex; + PIMAGE_SECTION_HEADER OutRelocSection; + + StartOfRawData = 0; + for (Section = 0; Section < InFileHeader->NumberOfSections; Section++) + { + if ((0 == StartOfRawData + || InSectionHeaders[Section].PointerToRawData < StartOfRawData) + && 0 != InSectionHeaders[Section].PointerToRawData + && 0 == (InSectionHeaders[Section].Characteristics & IMAGE_SCN_LNK_REMOVE)) + { + StartOfRawData = InSectionHeaders[Section].PointerToRawData; + } + } + OutHeader = malloc(StartOfRawData); + if (NULL == OutHeader) + { + fprintf(stderr, "Failed to allocate %lu bytes for output file header\n", StartOfRawData); + return 1; + } + memset(OutHeader, '\0', StartOfRawData); + + OutDosHeader = (PIMAGE_DOS_HEADER) OutHeader; + memcpy(OutDosHeader, InDosHeader, InDosHeader->e_lfanew + sizeof(ULONG)); + + OutFileHeader = (PIMAGE_FILE_HEADER)((char *) OutHeader + OutDosHeader->e_lfanew + sizeof(ULONG)); + memcpy(OutFileHeader, InFileHeader, sizeof(IMAGE_FILE_HEADER)); + OutFileHeader->PointerToSymbolTable = 0; + OutFileHeader->NumberOfSymbols = 0; + OutFileHeader->Characteristics &= ~(IMAGE_FILE_LINE_NUMS_STRIPPED | IMAGE_FILE_LOCAL_SYMS_STRIPPED | + IMAGE_FILE_DEBUG_STRIPPED); + + OutOptHeader = (PIMAGE_OPTIONAL_HEADER)(OutFileHeader + 1); + memcpy(OutOptHeader, InOptHeader, sizeof(IMAGE_OPTIONAL_HEADER)); + OutOptHeader->CheckSum = 0; + + OutSectionHeaders = (PIMAGE_SECTION_HEADER)((char *) OutOptHeader + OutFileHeader->SizeOfOptionalHeader); + + if (ProcessRelocations(&ProcessedRelocsLength, &ProcessedRelocs, InData, InOptHeader, + InFileHeader->NumberOfSections, InSectionHeaders)) + { + return 1; + } + if (InOptHeader->NumberOfRvaAndSizes < IMAGE_DIRECTORY_ENTRY_BASERELOC + || 0 == InOptHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress) + { + InRelocSectionIndex = -1; + } + else + { + InRelocSectionIndex = FindSectionForRVA(InOptHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress, + InFileHeader->NumberOfSections, InSectionHeaders) - InSectionHeaders; + } + + OutFileHeader->NumberOfSections = 0; + CurrentSectionHeader = OutSectionHeaders; + OutOptHeader->SizeOfImage = 0; + RosSymOffset = 0; + OutRelocSection = NULL; + for (Section = 0; Section < InFileHeader->NumberOfSections; Section++) + { + if (0 == (InSectionHeaders[Section].Characteristics & IMAGE_SCN_LNK_REMOVE)) + { + *CurrentSectionHeader = InSectionHeaders[Section]; + CurrentSectionHeader->PointerToLinenumbers = 0; + CurrentSectionHeader->NumberOfLinenumbers = 0; + if (OutOptHeader->SizeOfImage < CurrentSectionHeader->VirtualAddress + + CurrentSectionHeader->Misc.VirtualSize) + { + OutOptHeader->SizeOfImage = ROUND_UP(CurrentSectionHeader->VirtualAddress + + CurrentSectionHeader->Misc.VirtualSize, + OutOptHeader->SectionAlignment); + } + if (RosSymOffset < CurrentSectionHeader->PointerToRawData + CurrentSectionHeader->SizeOfRawData) + { + RosSymOffset = CurrentSectionHeader->PointerToRawData + CurrentSectionHeader->SizeOfRawData; + } + if (Section == (ULONG)InRelocSectionIndex) + { + OutRelocSection = CurrentSectionHeader; + } + (OutFileHeader->NumberOfSections) ++; + CurrentSectionHeader++; + } + } + + if (OutRelocSection == CurrentSectionHeader - 1) + { + OutOptHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].Size = ProcessedRelocsLength; + if (OutOptHeader->SizeOfImage == OutRelocSection->VirtualAddress + + ROUND_UP(OutRelocSection->Misc.VirtualSize, + OutOptHeader->SectionAlignment)) + { + OutOptHeader->SizeOfImage = OutRelocSection->VirtualAddress + + ROUND_UP(ProcessedRelocsLength, + OutOptHeader->SectionAlignment); + } + OutRelocSection->Misc.VirtualSize = ProcessedRelocsLength; + if (RosSymOffset == OutRelocSection->PointerToRawData + + OutRelocSection->SizeOfRawData) + { + RosSymOffset = OutRelocSection->PointerToRawData + + ROUND_UP(ProcessedRelocsLength, OutOptHeader->FileAlignment); + } + OutRelocSection->SizeOfRawData = ROUND_UP(ProcessedRelocsLength, + OutOptHeader->FileAlignment); + } + + if (RosSymLength > 0) + { + RosSymFileLength = ROUND_UP(RosSymLength, OutOptHeader->FileAlignment); + memcpy(CurrentSectionHeader->Name, ".rossym", 8); /* We're lucky: string is exactly 8 bytes long */ + CurrentSectionHeader->Misc.VirtualSize = RosSymLength; + CurrentSectionHeader->VirtualAddress = OutOptHeader->SizeOfImage; + CurrentSectionHeader->SizeOfRawData = RosSymFileLength; + CurrentSectionHeader->PointerToRawData = RosSymOffset; + CurrentSectionHeader->PointerToRelocations = 0; + CurrentSectionHeader->PointerToLinenumbers = 0; + CurrentSectionHeader->NumberOfRelocations = 0; + CurrentSectionHeader->NumberOfLinenumbers = 0; + CurrentSectionHeader->Characteristics = IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_DISCARDABLE + | IMAGE_SCN_LNK_REMOVE | IMAGE_SCN_TYPE_NOLOAD; + OutOptHeader->SizeOfImage = ROUND_UP(CurrentSectionHeader->VirtualAddress + + CurrentSectionHeader->Misc.VirtualSize, + OutOptHeader->SectionAlignment); + (OutFileHeader->NumberOfSections)++; + + PaddedRosSym = malloc(RosSymFileLength); + if (NULL == PaddedRosSym) + { + fprintf(stderr, "Failed to allocate %lu bytes for padded .rossym\n", RosSymFileLength); + return 1; + } + memcpy(PaddedRosSym, RosSymSection, RosSymLength); + memset((char *) PaddedRosSym + RosSymLength, '\0', RosSymFileLength - RosSymLength); + } + else + { + PaddedRosSym = NULL; + } + CheckSum = 0; + for (i = 0; i < StartOfRawData / 2; i++) + { + CheckSum += ((unsigned short*) OutHeader)[i]; + CheckSum = 0xffff & (CheckSum + (CheckSum >> 16)); + } + Length = StartOfRawData; + for (Section = 0; Section < OutFileHeader->NumberOfSections; Section++) + { + if (OutRelocSection == OutSectionHeaders + Section) + { + Data = (void *) ProcessedRelocs; + } + else if (RosSymLength > 0 && Section + 1 == OutFileHeader->NumberOfSections) + { + Data = (void *) PaddedRosSym; + } + else + { + Data = (void *) ((char *) InData + OutSectionHeaders[Section].PointerToRawData); + } + for (i = 0; i < OutSectionHeaders[Section].SizeOfRawData / 2; i++) + { + CheckSum += ((unsigned short*) Data)[i]; + CheckSum = 0xffff & (CheckSum + (CheckSum >> 16)); + } + Length += OutSectionHeaders[Section].SizeOfRawData; + } + CheckSum += Length; + OutOptHeader->CheckSum = CheckSum; + + if (fwrite(OutHeader, 1, StartOfRawData, OutFile) != StartOfRawData) + { + perror("Error writing output header\n"); + free(OutHeader); + return 1; + } + + for (Section = 0; Section < OutFileHeader->NumberOfSections; Section++) + { + if (0 != OutSectionHeaders[Section].SizeOfRawData) + { + fseek(OutFile, OutSectionHeaders[Section].PointerToRawData, SEEK_SET); + if (OutRelocSection == OutSectionHeaders + Section) + { + Data = (void *) ProcessedRelocs; + } + else if (RosSymLength > 0 && Section + 1 == OutFileHeader->NumberOfSections) + { + Data = (void *) PaddedRosSym; + } + else + { + Data = (void *) ((char *) InData + OutSectionHeaders[Section].PointerToRawData); + } + if (fwrite(Data, 1, OutSectionHeaders[Section].SizeOfRawData, OutFile) != + OutSectionHeaders[Section].SizeOfRawData) + { + perror("Error writing section data\n"); + free(PaddedRosSym); + free(OutHeader); + return 1; + } + } + } + + if (PaddedRosSym) + { + free(PaddedRosSym); + } + free(OutHeader); + + return 0; +} + +int main(int argc, char* argv[]) +{ + PSYMBOLFILE_HEADER SymbolFileHeader; + PIMAGE_DOS_HEADER PEDosHeader; + PIMAGE_FILE_HEADER PEFileHeader; + PIMAGE_OPTIONAL_HEADER PEOptHeader; + PIMAGE_SECTION_HEADER PESectionHeaders; + ULONG ImageBase; + void *StabBase; + ULONG StabsLength; + void *StabStringBase; + ULONG StabStringsLength; + void *CoffBase = NULL; + ULONG CoffsLength; + void *CoffStringBase = NULL; + ULONG CoffStringsLength; + char* path1; + char* path2; + FILE* out; + void *StringBase; + ULONG StringsLength; + ULONG StabSymbolsCount; + PROSSYM_ENTRY StabSymbols; + ULONG CoffSymbolsCount; + PROSSYM_ENTRY CoffSymbols; + ULONG MergedSymbolsCount; + PROSSYM_ENTRY MergedSymbols; + size_t FileSize; + void *FileData; + ULONG RosSymLength; + void *RosSymSection; + + if (3 != argc) + { + fprintf(stderr, "Usage: rsym \n"); + exit(1); + } + + path1 = convert_path(argv[1]); + path2 = convert_path(argv[2]); + + FileData = load_file ( path1, &FileSize ); + if ( !FileData ) + { + fprintf ( stderr, "An error occured loading '%s'\n", path1 ); + exit(1); + } + + /* Check if MZ header exists */ + PEDosHeader = (PIMAGE_DOS_HEADER) FileData; + + if ((WORD)PEDosHeader->e_magic != IMAGE_DOS_MAGIC || + (DWORD)PEDosHeader->e_lfanew == 0L) + { + perror("Input file is not a PE image.\n"); + free(FileData); + exit(1); + } + + /* Locate PE file header */ + /* sizeof(ULONG) = sizeof(MAGIC) */ + PEFileHeader = (PIMAGE_FILE_HEADER)((char *) FileData + PEDosHeader->e_lfanew + sizeof(ULONG)); + + /* Locate optional header */ + assert(sizeof(ULONG) == 4); + PEOptHeader = (PIMAGE_OPTIONAL_HEADER)(PEFileHeader + 1); + ImageBase = PEOptHeader->ImageBase; + + /* Locate PE section headers */ + PESectionHeaders = (PIMAGE_SECTION_HEADER)((char *) PEOptHeader + PEFileHeader->SizeOfOptionalHeader); + + if (GetStabInfo(FileData, PEFileHeader, PESectionHeaders, &StabsLength, &StabBase, + &StabStringsLength, &StabStringBase)) + { + free(FileData); + exit(1); + } + + if (GetCoffInfo(FileData, PEFileHeader, PESectionHeaders, &CoffsLength, &CoffBase, + &CoffStringsLength, &CoffStringBase)) + { + free(FileData); + exit(1); + } + + StringBase = malloc(1 + StabStringsLength + CoffStringsLength + + (CoffsLength / sizeof(ROSSYM_ENTRY)) * (E_SYMNMLEN + 1)); + if (NULL == StringBase) + { + free(FileData); + fprintf(stderr, "Failed to allocate memory for strings table\n"); + exit(1); + } + /* Make offset 0 into an empty string */ + *((char *) StringBase) = '\0'; + StringsLength = 1; + + if (ConvertStabs(&StabSymbolsCount, &StabSymbols, &StringsLength, StringBase, + StabsLength, StabBase, StabStringsLength, StabStringBase, + ImageBase, PEFileHeader, PESectionHeaders)) + { + free(StringBase); + free(FileData); + fprintf(stderr, "Failed to allocate memory for strings table\n"); + exit(1); + } + + if (ConvertCoffs(&CoffSymbolsCount, &CoffSymbols, &StringsLength, StringBase, + CoffsLength, CoffBase, CoffStringsLength, CoffStringBase, + ImageBase, PEFileHeader, PESectionHeaders)) + { + if (StabSymbols) + { + free(StabSymbols); + } + free(StringBase); + free(FileData); + exit(1); + } + + if (MergeStabsAndCoffs(&MergedSymbolsCount, &MergedSymbols, + StabSymbolsCount, StabSymbols, + CoffSymbolsCount, CoffSymbols)) + { + if (CoffSymbols) + { + free(CoffSymbols); + } + if (StabSymbols) + { + free(StabSymbols); + } + free(StringBase); + free(FileData); + exit(1); + } + + if (CoffSymbols) + { + free(CoffSymbols); + } + if (StabSymbols) + { + free(StabSymbols); + } + if (MergedSymbolsCount == 0) + { + RosSymLength = 0; + RosSymSection = NULL; + } + else + { + RosSymLength = sizeof(SYMBOLFILE_HEADER) + MergedSymbolsCount * sizeof(ROSSYM_ENTRY) + + StringsLength; + RosSymSection = malloc(RosSymLength); + if (NULL == RosSymSection) + { + free(MergedSymbols); + free(StringBase); + free(FileData); + fprintf(stderr, "Unable to allocate memory for .rossym section\n"); + exit(1); + } + memset(RosSymSection, '\0', RosSymLength); + + SymbolFileHeader = (PSYMBOLFILE_HEADER) RosSymSection; + SymbolFileHeader->SymbolsOffset = sizeof(SYMBOLFILE_HEADER); + SymbolFileHeader->SymbolsLength = MergedSymbolsCount * sizeof(ROSSYM_ENTRY); + SymbolFileHeader->StringsOffset = SymbolFileHeader->SymbolsOffset + SymbolFileHeader->SymbolsLength; + SymbolFileHeader->StringsLength = StringsLength; + + memcpy((char *) RosSymSection + SymbolFileHeader->SymbolsOffset, MergedSymbols, + SymbolFileHeader->SymbolsLength); + memcpy((char *) RosSymSection + SymbolFileHeader->StringsOffset, StringBase, + SymbolFileHeader->StringsLength); + + free(MergedSymbols); + } + free(StringBase); + out = fopen(path2, "wb"); + if (out == NULL) + { + perror("Cannot open output file"); + free(RosSymSection); + free(FileData); + exit(1); + } + + if (CreateOutputFile(out, FileData, PEDosHeader, PEFileHeader, PEOptHeader, + PESectionHeaders, RosSymLength, RosSymSection)) + { + fclose(out); + if (RosSymSection) + { + free(RosSymSection); + } + free(FileData); + exit(1); + } + + fclose(out); + if (RosSymSection) + { + free(RosSymSection); + } + free(FileData); + + return 0; +} + +/* EOF */ diff --git a/reactos/tools/rsym.h b/reactos/tools/rsym.h index 6c68fe91f86..7bbcbc20b2b 100644 --- a/reactos/tools/rsym.h +++ b/reactos/tools/rsym.h @@ -33,27 +33,31 @@ typedef unsigned long ULONG_PTR; #endif #endif +#include "bytesex.h" + +using namespace ReactosBytesex; + #pragma pack(2) typedef struct _IMAGE_DOS_HEADER { - WORD e_magic; - WORD e_cblp; - WORD e_cp; - WORD e_crlc; - WORD e_cparhdr; - WORD e_minalloc; - WORD e_maxalloc; - WORD e_ss; - WORD e_sp; - WORD e_csum; - WORD e_ip; - WORD e_cs; - WORD e_lfarlc; - WORD e_ovno; - WORD e_res[4]; - WORD e_oemid; - WORD e_oeminfo; - WORD e_res2[10]; - LONG e_lfanew; + LEWord e_magic; + LEWord e_cblp; + LEWord e_cp; + LEWord e_crlc; + LEWord e_cparhdr; + LEWord e_minalloc; + LEWord e_maxalloc; + LEWord e_ss; + LEWord e_sp; + LEWord e_csum; + LEWord e_ip; + LEWord e_cs; + LEWord e_lfarlc; + LEWord e_ovno; + LEWord e_res[4]; + LEWord e_oemid; + LEWord e_oeminfo; + LEWord e_res2[10]; + LEDWord e_lfanew; } IMAGE_DOS_HEADER,*PIMAGE_DOS_HEADER; #pragma pack(4) @@ -63,53 +67,53 @@ typedef struct _IMAGE_DOS_HEADER { #pragma pack(4) typedef struct _IMAGE_FILE_HEADER { - WORD Machine; - WORD NumberOfSections; - DWORD TimeDateStamp; - DWORD PointerToSymbolTable; - DWORD NumberOfSymbols; - WORD SizeOfOptionalHeader; - WORD Characteristics; + LEWord Machine; + LEWord NumberOfSections; + LEDWord TimeDateStamp; + LEDWord PointerToSymbolTable; + LEDWord NumberOfSymbols; + LEWord SizeOfOptionalHeader; + LEWord Characteristics; } IMAGE_FILE_HEADER, *PIMAGE_FILE_HEADER; typedef struct _IMAGE_DATA_DIRECTORY { - DWORD VirtualAddress; - DWORD Size; + LEDWord VirtualAddress; + LEDWord Size; } IMAGE_DATA_DIRECTORY,*PIMAGE_DATA_DIRECTORY; #define IMAGE_DIRECTORY_ENTRY_BASERELOC 5 typedef struct _IMAGE_OPTIONAL_HEADER { - WORD Magic; + LEWord Magic; BYTE MajorLinkerVersion; BYTE MinorLinkerVersion; - DWORD SizeOfCode; - DWORD SizeOfInitializedData; - DWORD SizeOfUninitializedData; - DWORD AddressOfEntryPoint; - DWORD BaseOfCode; - DWORD BaseOfData; - DWORD ImageBase; - DWORD SectionAlignment; - DWORD FileAlignment; - WORD MajorOperatingSystemVersion; - WORD MinorOperatingSystemVersion; - WORD MajorImageVersion; - WORD MinorImageVersion; - WORD MajorSubsystemVersion; - WORD MinorSubsystemVersion; - DWORD Reserved1; - DWORD SizeOfImage; - DWORD SizeOfHeaders; - DWORD CheckSum; - WORD Subsystem; - WORD DllCharacteristics; - DWORD SizeOfStackReserve; - DWORD SizeOfStackCommit; - DWORD SizeOfHeapReserve; - DWORD SizeOfHeapCommit; - DWORD LoaderFlags; - DWORD NumberOfRvaAndSizes; + LEDWord SizeOfCode; + LEDWord SizeOfInitializedData; + LEDWord SizeOfUninitializedData; + LEDWord AddressOfEntryPoint; + LEDWord BaseOfCode; + LEDWord BaseOfData; + LEDWord ImageBase; + LEDWord SectionAlignment; + LEDWord FileAlignment; + LEWord MajorOperatingSystemVersion; + LEWord MinorOperatingSystemVersion; + LEWord MajorImageVersion; + LEWord MinorImageVersion; + LEWord MajorSubsystemVersion; + LEWord MinorSubsystemVersion; + LEDWord Reserved1; + LEDWord SizeOfImage; + LEDWord SizeOfHeaders; + LEDWord CheckSum; + LEWord Subsystem; + LEWord DllCharacteristics; + LEDWord SizeOfStackReserve; + LEDWord SizeOfStackCommit; + LEDWord SizeOfHeapReserve; + LEDWord SizeOfHeapCommit; + LEDWord LoaderFlags; + LEDWord NumberOfRvaAndSizes; IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES]; } IMAGE_OPTIONAL_HEADER,*PIMAGE_OPTIONAL_HEADER; @@ -121,62 +125,62 @@ typedef struct _IMAGE_OPTIONAL_HEADER { typedef struct _IMAGE_SECTION_HEADER { BYTE Name[IMAGE_SIZEOF_SHORT_NAME]; union { - DWORD PhysicalAddress; - DWORD VirtualSize; + LEDWord PhysicalAddress; + LEDWord VirtualSize; } Misc; - DWORD VirtualAddress; - DWORD SizeOfRawData; - DWORD PointerToRawData; - DWORD PointerToRelocations; - DWORD PointerToLinenumbers; - WORD NumberOfRelocations; - WORD NumberOfLinenumbers; - DWORD Characteristics; + LEDWord VirtualAddress; + LEDWord SizeOfRawData; + LEDWord PointerToRawData; + LEDWord PointerToRelocations; + LEDWord PointerToLinenumbers; + LEWord NumberOfRelocations; + LEWord NumberOfLinenumbers; + LEDWord Characteristics; } IMAGE_SECTION_HEADER,*PIMAGE_SECTION_HEADER; typedef struct _IMAGE_BASE_RELOCATION { - DWORD VirtualAddress; - DWORD SizeOfBlock; + LEDWord VirtualAddress; + LEDWord SizeOfBlock; } IMAGE_BASE_RELOCATION,*PIMAGE_BASE_RELOCATION; typedef struct { - USHORT f_magic; /* magic number */ - USHORT f_nscns; /* number of sections */ - ULONG f_timdat; /* time & date stamp */ - ULONG f_symptr; /* file pointer to symtab */ - ULONG f_nsyms; /* number of symtab entries */ - USHORT f_opthdr; /* sizeof(optional hdr) */ - USHORT f_flags; /* flags */ + LEWord f_magic; /* magic number */ + LEWord f_nscns; /* number of sections */ + LEDWord f_timdat; /* time & date stamp */ + LEDWord f_symptr; /* file pointer to symtab */ + LEDWord f_nsyms; /* number of symtab entries */ + LEWord f_opthdr; /* sizeof(optional hdr) */ + LEWord f_flags; /* flags */ } FILHDR; typedef struct { char s_name[8]; /* section name */ - ULONG s_paddr; /* physical address, aliased s_nlib */ - ULONG s_vaddr; /* virtual address */ - ULONG s_size; /* section size */ - ULONG s_scnptr; /* file ptr to raw data for section */ - ULONG s_relptr; /* file ptr to relocation */ - ULONG s_lnnoptr; /* file ptr to line numbers */ - USHORT s_nreloc; /* number of relocation entries */ - USHORT s_nlnno; /* number of line number entries */ - ULONG s_flags; /* flags */ + LEDWord s_paddr; /* physical address, aliased s_nlib */ + LEDWord s_vaddr; /* virtual address */ + LEDWord s_size; /* section size */ + LEDWord s_scnptr; /* file ptr to raw data for section */ + LEDWord s_relptr; /* file ptr to relocation */ + LEDWord s_lnnoptr; /* file ptr to line numbers */ + LEWord s_nreloc; /* number of relocation entries */ + LEWord s_nlnno; /* number of line number entries */ + LEDWord s_flags; /* flags */ } SCNHDR; #pragma pack(4) typedef struct _SYMBOLFILE_HEADER { - ULONG SymbolsOffset; - ULONG SymbolsLength; - ULONG StringsOffset; - ULONG StringsLength; + LEDWord SymbolsOffset; + LEDWord SymbolsLength; + LEDWord StringsOffset; + LEDWord StringsLength; } SYMBOLFILE_HEADER, *PSYMBOLFILE_HEADER; typedef struct _STAB_ENTRY { - ULONG n_strx; /* index into string table of name */ + LEDWord n_strx; /* index into string table of name */ UCHAR n_type; /* type of symbol */ UCHAR n_other; /* misc info (usually empty) */ - USHORT n_desc; /* description field */ - ULONG n_value; /* value of symbol */ + LEWord n_desc; /* description field */ + LEDWord n_value; /* value of symbol */ } STAB_ENTRY, *PSTAB_ENTRY; /* http://www.math.utah.edu/docs/info/stabs_12.html */ @@ -279,25 +283,25 @@ typedef struct _COFF_SYMENT char e_name[E_SYMNMLEN]; struct { - ULONG e_zeroes; - ULONG e_offset; + LEDWord e_zeroes; + LEDWord e_offset; } e; } e; - ULONG e_value; - short e_scnum; - USHORT e_type; + LEDWord e_value; + LEWord e_scnum; + LEWord e_type; UCHAR e_sclass; UCHAR e_numaux; } COFF_SYMENT, *PCOFF_SYMENT; #pragma pack(4) typedef struct _ROSSYM_ENTRY { - ULONG_PTR Address; - ULONG FunctionOffset; - ULONG FileOffset; - ULONG SourceLine; + LEDWord Address; + LEDWord FunctionOffset; + LEDWord FileOffset; + LEDWord SourceLine; } ROSSYM_ENTRY, *PROSSYM_ENTRY; #define ROUND_UP(N, S) (((N) + (S) - 1) & ~((S) - 1)) diff --git a/reactos/tools/rsym.mak b/reactos/tools/rsym.mak index ad6b383de87..5f057c66f43 100644 --- a/reactos/tools/rsym.mak +++ b/reactos/tools/rsym.mak @@ -10,13 +10,13 @@ RSYM_TARGET = \ $(EXEPREFIX)$(RSYM_OUT_)rsym$(EXEPOSTFIX) RSYM_SOURCES = \ - $(RSYM_BASE_)rsym.c \ - $(RSYM_BASE_)rsym_common.c + $(RSYM_BASE_)rsym.cpp \ + $(RSYM_BASE_)rsym_common.cpp RSYM_OBJECTS = \ - $(addprefix $(INTERMEDIATE_), $(RSYM_SOURCES:.c=.o)) + $(addprefix $(INTERMEDIATE_), $(RSYM_SOURCES:.cpp=.o)) -RSYM_HOST_CFLAGS = $(TOOLS_CFLAGS) +RSYM_HOST_CFLAGS = $(TOOLS_CFLAGS) -g -xc++ RSYM_HOST_LFLAGS = $(TOOLS_LFLAGS) @@ -25,15 +25,15 @@ rsym: $(RSYM_TARGET) $(RSYM_TARGET): $(RSYM_OBJECTS) | $(RSYM_OUT) $(ECHO_LD) - ${host_gcc} $(RSYM_OBJECTS) $(RSYM_HOST_LFLAGS) -o $@ + ${host_gpp} $(RSYM_OBJECTS) $(RSYM_HOST_LFLAGS) -o $@ -$(RSYM_INT_)rsym.o: $(RSYM_BASE_)rsym.c | $(RSYM_INT) +$(RSYM_INT_)rsym.o: $(RSYM_BASE_)rsym.cpp | $(RSYM_INT) $(ECHO_CC) - ${host_gcc} $(RSYM_HOST_CFLAGS) -c $< -o $@ + ${host_gpp} $(RSYM_HOST_CFLAGS) -c $< -o $@ -$(RSYM_INT_)rsym_common.o: $(RSYM_BASE_)rsym_common.c | $(RSYM_INT) +$(RSYM_INT_)rsym_common.o: $(RSYM_BASE_)rsym_common.cpp | $(RSYM_INT) $(ECHO_CC) - ${host_gcc} $(RSYM_HOST_CFLAGS) -c $< -o $@ + ${host_gpp} $(RSYM_HOST_CFLAGS) -c $< -o $@ .PHONY: rsym_clean rsym_clean: diff --git a/reactos/tools/rsym_common.cpp b/reactos/tools/rsym_common.cpp new file mode 100644 index 00000000000..875463fe920 --- /dev/null +++ b/reactos/tools/rsym_common.cpp @@ -0,0 +1,62 @@ +/* rsym_common.c */ + +#include +#include +#include + +#include "rsym.h" + +char* +convert_path ( const char* origpath ) +{ + char* newpath; + int i; + + newpath = strdup(origpath); + + i = 0; + while (newpath[i] != 0) + { +#ifdef UNIX_PATHS + if (newpath[i] == '\\') + { + newpath[i] = '/'; + } +#else +#ifdef DOS_PATHS + if (newpath[i] == '/') + { + newpath[i] = '\\'; + } +#endif +#endif + i++; + } + return(newpath); +} + +void* +load_file ( const char* file_name, size_t* file_size ) +{ + FILE* f; + void* FileData = NULL; + + f = fopen ( file_name, "rb" ); + if (f != NULL) + { + fseek(f, 0L, SEEK_END); + *file_size = ftell(f); + fseek(f, 0L, SEEK_SET); + FileData = malloc(*file_size); + if (FileData != NULL) + { + if ( *file_size != fread(FileData, 1, *file_size, f) ) + { + free(FileData); + FileData = NULL; + } + } + fclose(f); + } + return FileData; +}