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:
Art Yerkes
2006-09-12 05:09:41 +00:00
parent 5b6b2b681f
commit 32c139b3f3
7 changed files with 1219 additions and 283 deletions
+66
View File
@@ -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)&in;
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*/
-174
View File
@@ -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
+1
View File
@@ -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 \
+977
View File
@@ -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
View File
@@ -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))
+9 -9
View File
@@ -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:
+62
View File
@@ -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;
}