mirror of
https://github.com/ApfelTeeSaft/reactos.git
synced 2026-08-31 12:23:31 +00:00
rsym working right on ppc. Use a template (horror) to emulate an off-endian
field in a struct. We'll reconcile this code later. remove link-ntoskrnl. I'm gonna split off the ppc ldscript. svn path=/branches/powerpc/; revision=24077
This commit is contained in:
@@ -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 <class T> T toHost( T value );
|
||||
template <class T> T toDest( T value );
|
||||
template <> WORD toHost<WORD>( WORD value ) { return dtohs(value); }
|
||||
template <> DWORD toHost<DWORD>( DWORD value ) { return dtohl(value); }
|
||||
template <> int toHost<int>( int value ) { return dtohl(value); }
|
||||
template <> WORD toDest<WORD>( WORD value ) { return htods(value); }
|
||||
template <> DWORD toDest<DWORD>( DWORD value ) { return htodl(value); }
|
||||
template <> int toDest<int>( int value ) { return htodl(value); }
|
||||
}
|
||||
|
||||
namespace ReactosBytesex {
|
||||
template <class T>
|
||||
struct LENumber {
|
||||
public:
|
||||
operator T () const { return toHost<T>(value); }
|
||||
LENumber &operator = (T other) { value = toDest<T>(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<T>(toHost<T>(value) + other); return *this; }
|
||||
LENumber &operator -= (T other) { return (*this) += -other; }
|
||||
LENumber &operator &= (T other) { value = toDest<T>(toHost<T>(value) & other); return *this; }
|
||||
LENumber &operator |= (T other) { value = toDest<T>(toHost<T>(value) | other); return *this; }
|
||||
private:
|
||||
T value;
|
||||
};
|
||||
|
||||
typedef LENumber<WORD> LEWord;
|
||||
typedef LENumber<DWORD> LEDWord;
|
||||
}
|
||||
|
||||
#endif/*BYTESEX_H*/
|
||||
@@ -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
|
||||
@@ -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 \
|
||||
|
||||
@@ -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 <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
|
||||
#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 <exefile> <symfile>\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 */
|
||||
+104
-100
@@ -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))
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -0,0 +1,62 @@
|
||||
/* rsym_common.c */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#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;
|
||||
}
|
||||
Reference in New Issue
Block a user