From e2303991a6c5493033f6468b7298a3fd5ec64051 Mon Sep 17 00:00:00 2001 From: Royce Mitchell III Date: Fri, 8 Apr 2005 05:35:20 +0000 Subject: [PATCH] raddr2line utility moved code common betw rsym and raddr2line to rsym_common.c simplified tools/Makefile svn path=/trunk/; revision=14542 --- reactos/tools/Makefile | 126 +++++--------- reactos/tools/raddr2line.c | 188 +++++++++++++++++++++ reactos/tools/rsym.c | 329 ++---------------------------------- reactos/tools/rsym.h | 266 +++++++++++++++++++++++++++++ reactos/tools/rsym_common.c | 62 +++++++ 5 files changed, 569 insertions(+), 402 deletions(-) create mode 100644 reactos/tools/raddr2line.c create mode 100644 reactos/tools/rsym.h create mode 100644 reactos/tools/rsym_common.c diff --git a/reactos/tools/Makefile b/reactos/tools/Makefile index 5602a9c5f10..da89ae71c83 100644 --- a/reactos/tools/Makefile +++ b/reactos/tools/Makefile @@ -3,6 +3,14 @@ PATH_TO_TOP = .. include $(PATH_TO_TOP)/rules.mak CFLAGS += -Wall -Werror +ifeq ($(HOST),mingw32-linux) +CFLAGS += -DUNIX_PATHS +rm := @rm +endif +ifeq ($(HOST),mingw32-windows) +CFLAGS += -DDOS_PATHS +rm := -@del +endif TOOLS = \ regtests$(EXE_POSTFIX) \ @@ -12,6 +20,7 @@ TOOLS = \ rmkdir$(EXE_POSTFIX) \ rrmdir$(EXE_POSTFIX) \ rsym$(EXE_POSTFIX) \ + raddr2line$(EXE_POSTFIX) \ rtouch$(EXE_POSTFIX) \ mkflpimg$(EXE_POSTFIX) \ ppc-le2be$(EXE_POSTFIX) \ @@ -30,94 +39,55 @@ tools_check: $(MAKE) -f tools-check.mak regtests$(EXE_POSTFIX): regtests.c - @$(HOST_CC) $(CFLAGS) -o regtests$(EXE_POSTFIX) regtests.c + @$(HOST_CC) $(CFLAGS) -o $@ $< -ifeq ($(HOST),mingw32-linux) rcopy$(EXE_POSTFIX): rcopy.c - @$(HOST_CC) $(CFLAGS) -DUNIX_PATHS rcopy.c -o rcopy$(EXE_POSTFIX) -endif -ifeq ($(HOST),mingw32-windows) -rcopy$(EXE_POSTFIX): rcopy.c - @$(HOST_CC) $(CFLAGS) -DDOS_PATHS rcopy.c -o rcopy$(EXE_POSTFIX) -endif + @$(HOST_CC) $(CFLAGS) $< -o $@ rdel$(EXE_POSTFIX): rdel.c - @$(HOST_CC) $(CFLAGS) rdel.c -o rdel$(EXE_POSTFIX) + @$(HOST_CC) $(CFLAGS) $< -o $@ -ifeq ($(HOST),mingw32-linux) rline$(EXE_POSTFIX): rline.c - @$(HOST_CC) $(CFLAGS) -DUNIX_PATHS rline.c -o rline$(EXE_POSTFIX) -endif -ifeq ($(HOST),mingw32-windows) -rline$(EXE_POSTFIX): rline.c - @$(HOST_CC) $(CFLAGS) -DDOS_PATHS rline.c -o rline$(EXE_POSTFIX) -endif + @$(HOST_CC) $(CFLAGS) $< -o $@ -ifeq ($(HOST),mingw32-linux) rmkdir$(EXE_POSTFIX): rmkdir.c - @$(HOST_CC) $(CFLAGS) -DUNIX_PATHS rmkdir.c -o rmkdir$(EXE_POSTFIX) -endif -ifeq ($(HOST),mingw32-windows) -rmkdir$(EXE_POSTFIX): rmkdir.c - @$(HOST_CC) $(CFLAGS) -DDOS_PATHS rmkdir.c -o rmkdir$(EXE_POSTFIX) -endif + @$(HOST_CC) $(CFLAGS) $< -o $@ -ifeq ($(HOST),mingw32-linux) rrmdir$(EXE_POSTFIX): rrmdir.c - @$(HOST_CC) $(CFLAGS) -DUNIX_PATHS rrmdir.c -o rrmdir$(EXE_POSTFIX) -endif -ifeq ($(HOST),mingw32-windows) -rrmdir$(EXE_POSTFIX): rrmdir.c - @$(HOST_CC) $(CFLAGS) -DDOS_PATHS rrmdir.c -o rrmdir$(EXE_POSTFIX) -endif + @$(HOST_CC) $(CFLAGS) $< -o $@ -ifeq ($(HOST),mingw32-linux) -rsym$(EXE_POSTFIX): rsym.c - @$(HOST_CC) $(CFLAGS) -DUNIX_PATHS rsym.c -o rsym$(EXE_POSTFIX) -endif -ifeq ($(HOST),mingw32-windows) -rsym$(EXE_POSTFIX): rsym.c - @$(HOST_CC) $(CFLAGS) -DDOS_PATHS rsym.c -o rsym$(EXE_POSTFIX) -endif +rsym_common.o: rsym_common.c rsym.h + @$(HOST_CC) $(CFLAGS) -c $< -o $@ + +rsym.o: rsym.c rsym.h + @$(HOST_CC) $(CFLAGS) -c $< -o $@ + +rsym$(EXE_POSTFIX): rsym.o rsym_common.o + @$(HOST_CC) $(CFLAGS) $^ -o $@ + +raddr2line.o: raddr2line.c rsym.h + @$(HOST_CC) $(CFLAGS) -c $< -o $@ + +raddr2line$(EXE_POSTFIX): raddr2line.o rsym_common.o + @$(HOST_CC) $(CFLAGS) $^ -o $@ -ifeq ($(HOST),mingw32-linux) rtouch$(EXE_POSTFIX): rtouch.c - @$(HOST_CC) $(CFLAGS) -DUNIX_PATHS rtouch.c -o rtouch$(EXE_POSTFIX) -endif -ifeq ($(HOST),mingw32-windows) -rtouch$(EXE_POSTFIX): rtouch.c - @$(HOST_CC) $(CFLAGS) -DDOS_PATHS rtouch.c -o rtouch$(EXE_POSTFIX) -endif + @$(HOST_CC) $(CFLAGS) $< -o $@ -ifeq ($(HOST),mingw32-linux) mkflpimg$(EXE_POSTFIX): mkflpimg.c - @$(HOST_CC) $(CFLAGS) -DUNIX_PATHS mkflpimg.c -o mkflpimg$(EXE_POSTFIX) -endif -ifeq ($(HOST),mingw32-windows) -mkflpimg$(EXE_POSTFIX): mkflpimg.c - @$(HOST_CC) $(CFLAGS) -DDOS_PATHS mkflpimg.c -o mkflpimg$(EXE_POSTFIX) -endif + @$(HOST_CC) $(CFLAGS) $< -o $@ -ifeq ($(HOST),mingw32-linux) hack-coff$(EXE_POSTFIX): hack-coff.c - @$(HOST_CC) $(CFLAGS) hack-coff.c -o hack-coff$(EXE_POSTFIX) -endif -ifeq ($(HOST),mingw32-windows) -hack-coff$(EXE_POSTFIX): hack-coff.c - @$(HOST_CC) $(CFLAGS) hack-coff.c -o hack-coff$(EXE_POSTFIX) -endif + @$(HOST_CC) $(CFLAGS) $< -o $@ -ifeq ($(HOST),mingw32-linux) ppc-le2be$(EXE_POSTFIX): ppc-le2be.c - @$(HOST_CC) $(CFLAGS) ppc-le2be.c -o ppc-le2be$(EXE_POSTFIX) -endif -ifeq ($(HOST),mingw32-windows) -ppc-le2be$(EXE_POSTFIX): ppc-le2be.c - @$(HOST_CC) $(CFLAGS) ppc-le2be.c -o ppc-le2be$(EXE_POSTFIX) -endif + @$(HOST_CC) $(CFLAGS) $< -o $@ depends$(EXE_POSTFIX): depends.c - @$(HOST_CC) $(CFLAGS) depends.c -o depends$(EXE_POSTFIX) + @$(HOST_CC) $(CFLAGS) $< -o $@ + +.PHONY: zlib_target wmc_target cdmake_target mkhive_target rgenstat_target pipetools_target wrc_target \ + widl_target buildno_target lib_unicode lib_wpp zlib_target: $(MAKE) --silent -C ../lib/zlib -f Makefile.host @@ -166,11 +136,7 @@ lib_unicode: lib_wpp: $(MAKE) -C wpp -.PHONY: wmc_target cdmake_target mkhive_target rgenstat_target pipetools_target wrc_target \ - widl_target buildno_target lib_unicode lib_wpp - -ifeq ($(HOST),mingw32-linux) clean: $(MAKE) --silent -C buildno clean $(MAKE) --silent -C widl clean @@ -186,27 +152,13 @@ clean: $(MAKE) --silent -C ../lib/zlib -f Makefile.host clean $(MAKE) -C wpp clean $(MAKE) -C unicode clean +ifeq ($(HOST),mingw32-linux) @rm mkconfig @rm $(TOOLS) endif ifeq ($(HOST),mingw32-windows) -clean: - $(MAKE) --silent -C buildno clean - $(MAKE) --silent -C widl clean - $(MAKE) --silent -C wrc clean - $(MAKE) --silent -C cabman clean - $(MAKE) --silent -C cdmake clean - $(MAKE) --silent -C mkhive clean - $(MAKE) --silent -C wmc clean - $(MAKE) --silent -C rgenstat clean $(MAKE) --silent -C pipetools clean - $(MAKE) --silent -C wine2ros clean - $(MAKE) --silent -C winebuild clean - $(MAKE) --silent -C bin2res clean - $(MAKE) --silent -C ../lib/zlib -f Makefile.host clean - $(MAKE) -C wpp clean - $(MAKE) -C unicode clean - -@del *$(EXE_POSTFIX) + $(rm) *$(EXE_POSTFIX) endif .PHONY: all clean diff --git a/reactos/tools/raddr2line.c b/reactos/tools/raddr2line.c new file mode 100644 index 00000000000..fa0bdec2851 --- /dev/null +++ b/reactos/tools/raddr2line.c @@ -0,0 +1,188 @@ +/* + * Usage: raddr2line input-file address/offset + * + * This is a tool and is compiled using the host compiler, + * i.e. on Linux gcc and not mingw-gcc (cross-compiler). + * Therefore we can't include SDK headers and we have to + * duplicate some definitions here. + * Also note that the internal functions are "old C-style", + * returning an int, where a return of 0 means success and + * non-zero is failure. + */ + +#include +#include +#include + +#include "rsym.h" + +size_t fixup_offset ( size_t ImageBase, size_t offset ) +{ + if ( offset >= ImageBase ) + offset -= ImageBase; + return offset; +} + +long +my_atoi ( const char* a ) +{ + int i = 0; + const char* fmt = "%x"; + + if ( *a == '0' ) + { + switch ( *++a ) + { + case 'x': + fmt = "%x"; + ++a; + break; + case 'd': + fmt = "%d"; + ++a; + break; + default: + fmt = "%o"; + break; + } + } + sscanf ( a, fmt, &i ); + return i; +} + +PIMAGE_SECTION_HEADER +find_rossym_section ( PIMAGE_FILE_HEADER PEFileHeader, + PIMAGE_SECTION_HEADER PESectionHeaders ) +{ + size_t i; + for ( i = 0; i < PEFileHeader->NumberOfSections; i++ ) + { + if ( 0 == strcmp ( PESectionHeaders[i].Name, ".rossym" ) ) + return &PESectionHeaders[i]; + } + return NULL; +} + +int +find_and_print_offset ( + void* data, + size_t offset ) +{ + PSYMBOLFILE_HEADER RosSymHeader = (PSYMBOLFILE_HEADER)data; + PROSSYM_ENTRY Entries = (PROSSYM_ENTRY)((char*)data + RosSymHeader->SymbolsOffset); + char* Strings = (char*)data + RosSymHeader->StringsOffset; + size_t symbols = RosSymHeader->SymbolsLength / sizeof(ROSSYM_ENTRY); + size_t i; + + //if ( RosSymHeader->SymbolsOffset ) + + for ( i = 0; i < symbols; i++ ) + { + if ( Entries[i].Address > offset ) + { + if ( !i-- ) + return 1; + else + { + PROSSYM_ENTRY e = &Entries[i]; + printf ( "%s:%lu (%s)", + &Strings[e->FileOffset], + e->SourceLine, + &Strings[e->FunctionOffset] ); + return 0; + } + } + } + return 1; +} + +int +process_data ( const void* FileData, size_t FileSize, size_t offset ) +{ + PIMAGE_DOS_HEADER PEDosHeader; + PIMAGE_FILE_HEADER PEFileHeader; + PIMAGE_OPTIONAL_HEADER PEOptHeader; + PIMAGE_SECTION_HEADER PESectionHeaders; + PIMAGE_SECTION_HEADER PERosSymSectionHeader; + size_t ImageBase; + int res; + + /* Check if MZ header exists */ + PEDosHeader = (PIMAGE_DOS_HEADER)FileData; + if (PEDosHeader->e_magic != IMAGE_DOS_MAGIC || PEDosHeader->e_lfanew == 0L) + { + perror("Input file is not a PE image.\n"); + return 1; + } + + /* Locate PE file header */ + /* sizeof(ULONG) = sizeof(MAGIC) */ + PEFileHeader = (PIMAGE_FILE_HEADER)((char *)FileData + PEDosHeader->e_lfanew + sizeof(ULONG)); + + /* Locate optional header */ + PEOptHeader = (PIMAGE_OPTIONAL_HEADER)(PEFileHeader + 1); + ImageBase = PEOptHeader->ImageBase; + + /* Locate PE section headers */ + PESectionHeaders = (PIMAGE_SECTION_HEADER)((char *) PEOptHeader + PEFileHeader->SizeOfOptionalHeader); + + /* make sure offset is what we want */ + offset = fixup_offset ( ImageBase, offset ); + + /* find rossym section */ + PERosSymSectionHeader = find_rossym_section ( + PEFileHeader, PESectionHeaders ); + if ( !PERosSymSectionHeader ) + { + fprintf ( stderr, "Couldn't find rossym section in executable\n" ); + return 1; + } + res = find_and_print_offset ( (char*)FileData + PERosSymSectionHeader->PointerToRawData, + offset ); + if ( res ) + printf ( "??:0\n" ); + return res; +} + +int +process_file ( const char* file_name, size_t offset ) +{ + void* FileData; + size_t FileSize; + int res = 1; + + FileData = load_file ( file_name, &FileSize ); + if ( !FileData ) + { + fprintf ( stderr, "An error occured loading '%s'\n", file_name ); + } + else + { + res = process_data ( FileData, FileSize, offset ); + free ( FileData ); + } + + return res; +} + +int main ( int argc, const char** argv ) +{ + char* path; + size_t offset; + int res; + + if ( argc != 3 ) + { + fprintf(stderr, "Usage: raddr2line \n"); + exit(1); + } + + path = convert_path ( argv[1] ); + offset = my_atoi ( argv[2] ); + + res = process_file ( path, offset ); + + free ( path ); + + return res; +} diff --git a/reactos/tools/rsym.c b/reactos/tools/rsym.c index 21885b4e985..46405bf0921 100644 --- a/reactos/tools/rsym.c +++ b/reactos/tools/rsym.c @@ -24,287 +24,7 @@ #include #include -#define IMAGE_DOS_MAGIC 0x5a4d -#define IMAGE_PE_MAGIC 0x00004550 - -#define IMAGE_SIZEOF_SHORT_NAME 8 - -#define IMAGE_NUMBEROF_DIRECTORY_ENTRIES 16 - -typedef unsigned char BYTE; -typedef unsigned short WORD; -typedef unsigned long DWORD; -typedef signed long LONG; -typedef unsigned long ULONG; -#if defined(_WIN64) -typedef unsigned __int64 ULONG_PTR; -#else -typedef unsigned long ULONG_PTR; -#endif - -#pragma pack(push,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; -} IMAGE_DOS_HEADER,*PIMAGE_DOS_HEADER; -#pragma pack(pop) - -#define IMAGE_FILE_LINE_NUMS_STRIPPED 4 -#define IMAGE_FILE_LOCAL_SYMS_STRIPPED 8 -#define IMAGE_FILE_DEBUG_STRIPPED 512 - -#pragma pack(push,4) -typedef struct _IMAGE_FILE_HEADER { - WORD Machine; - WORD NumberOfSections; - DWORD TimeDateStamp; - DWORD PointerToSymbolTable; - DWORD NumberOfSymbols; - WORD SizeOfOptionalHeader; - WORD Characteristics; -} IMAGE_FILE_HEADER, *PIMAGE_FILE_HEADER; - -typedef struct _IMAGE_DATA_DIRECTORY { - DWORD VirtualAddress; - DWORD Size; -} IMAGE_DATA_DIRECTORY,*PIMAGE_DATA_DIRECTORY; - -#define IMAGE_DIRECTORY_ENTRY_BASERELOC 5 - -typedef struct _IMAGE_OPTIONAL_HEADER { - WORD 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; - IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES]; -} IMAGE_OPTIONAL_HEADER,*PIMAGE_OPTIONAL_HEADER; - -#define IMAGE_SCN_TYPE_NOLOAD 0x00000002 -#define IMAGE_SCN_LNK_REMOVE 0x00000800 -#define IMAGE_SCN_MEM_READ 0x40000000 -#define IMAGE_SCN_MEM_DISCARDABLE 0x02000000 - -typedef struct _IMAGE_SECTION_HEADER { - BYTE Name[IMAGE_SIZEOF_SHORT_NAME]; - union { - DWORD PhysicalAddress; - DWORD VirtualSize; - } Misc; - DWORD VirtualAddress; - DWORD SizeOfRawData; - DWORD PointerToRawData; - DWORD PointerToRelocations; - DWORD PointerToLinenumbers; - WORD NumberOfRelocations; - WORD NumberOfLinenumbers; - DWORD Characteristics; -} IMAGE_SECTION_HEADER,*PIMAGE_SECTION_HEADER; - -typedef struct _IMAGE_BASE_RELOCATION { - DWORD VirtualAddress; - DWORD SizeOfBlock; -} IMAGE_BASE_RELOCATION,*PIMAGE_BASE_RELOCATION; - - -typedef struct { - unsigned short f_magic; /* magic number */ - unsigned short f_nscns; /* number of sections */ - unsigned long f_timdat; /* time & date stamp */ - unsigned long f_symptr; /* file pointer to symtab */ - unsigned long f_nsyms; /* number of symtab entries */ - unsigned short f_opthdr; /* sizeof(optional hdr) */ - unsigned short f_flags; /* flags */ -} FILHDR; - -typedef struct { - char s_name[8]; /* section name */ - unsigned long s_paddr; /* physical address, aliased s_nlib */ - unsigned long s_vaddr; /* virtual address */ - unsigned long s_size; /* section size */ - unsigned long s_scnptr; /* file ptr to raw data for section */ - unsigned long s_relptr; /* file ptr to relocation */ - unsigned long s_lnnoptr; /* file ptr to line numbers */ - unsigned short s_nreloc; /* number of relocation entries */ - unsigned short s_nlnno; /* number of line number entries */ - unsigned long s_flags; /* flags */ -} SCNHDR; -#pragma pack(pop) - -typedef struct _SYMBOLFILE_HEADER { - unsigned long SymbolsOffset; - unsigned long SymbolsLength; - unsigned long StringsOffset; - unsigned long StringsLength; -} SYMBOLFILE_HEADER, *PSYMBOLFILE_HEADER; - -typedef struct _STAB_ENTRY { - unsigned long n_strx; /* index into string table of name */ - unsigned char n_type; /* type of symbol */ - unsigned char n_other; /* misc info (usually empty) */ - unsigned short n_desc; /* description field */ - unsigned long n_value; /* value of symbol */ -} STAB_ENTRY, *PSTAB_ENTRY; - -#define N_FUN 0x24 -#define N_SLINE 0x44 -#define N_SO 0x64 - -/* COFF symbol table */ - -#define E_SYMNMLEN 8 /* # characters in a symbol name */ -#define E_FILNMLEN 14 /* # characters in a file name */ -#define E_DIMNUM 4 /* # array dimensions in auxiliary entry */ - -#define N_BTMASK (0xf) -#define N_TMASK (0x30) -#define N_BTSHFT (4) -#define N_TSHIFT (2) - -/* derived types, in e_type */ -#define DT_NON (0) /* no derived type */ -#define DT_PTR (1) /* pointer */ -#define DT_FCN (2) /* function */ -#define DT_ARY (3) /* array */ - -#define BTYPE(x) ((x) & N_BTMASK) - -#define ISPTR(x) (((x) & N_TMASK) == (DT_PTR << N_BTSHFT)) -#define ISFCN(x) (((x) & N_TMASK) == (DT_FCN << N_BTSHFT)) -#define ISARY(x) (((x) & N_TMASK) == (DT_ARY << N_BTSHFT)) -#define ISTAG(x) ((x)==C_STRTAG||(x)==C_UNTAG||(x)==C_ENTAG) -#define DECREF(x) ((((x)>>N_TSHIFT)&~N_BTMASK)|((x)&N_BTMASK)) - -#define C_EFCN 0xff /* physical end of function */ -#define C_NULL 0 -#define C_AUTO 1 /* automatic variable */ -#define C_EXT 2 /* external symbol */ -#define C_STAT 3 /* static */ -#define C_REG 4 /* register variable */ -#define C_EXTDEF 5 /* external definition */ -#define C_LABEL 6 /* label */ -#define C_ULABEL 7 /* undefined label */ -#define C_MOS 8 /* member of structure */ -#define C_ARG 9 /* function argument */ -#define C_STRTAG 10 /* structure tag */ -#define C_MOU 11 /* member of union */ -#define C_UNTAG 12 /* union tag */ -#define C_TPDEF 13 /* type definition */ -#define C_USTATIC 14 /* undefined static */ -#define C_ENTAG 15 /* enumeration tag */ -#define C_MOE 16 /* member of enumeration */ -#define C_REGPARM 17 /* register parameter */ -#define C_FIELD 18 /* bit field */ -#define C_AUTOARG 19 /* auto argument */ -#define C_LASTENT 20 /* dummy entry (end of block) */ -#define C_BLOCK 100 /* ".bb" or ".eb" */ -#define C_FCN 101 /* ".bf" or ".ef" */ -#define C_EOS 102 /* end of structure */ -#define C_FILE 103 /* file name */ -#define C_LINE 104 /* line # reformatted as symbol table entry */ -#define C_ALIAS 105 /* duplicate tag */ -#define C_HIDDEN 106 /* ext symbol in dmert public lib */ - -#pragma pack(push,1) -typedef struct _COFF_SYMENT -{ - union - { - char e_name[E_SYMNMLEN]; - struct - { - unsigned long e_zeroes; - unsigned long e_offset; - } - e; - } - e; - unsigned long e_value; - short e_scnum; - unsigned short e_type; - unsigned char e_sclass; - unsigned char e_numaux; -} COFF_SYMENT, *PCOFF_SYMENT; -#pragma pack(pop) - -typedef struct _ROSSYM_ENTRY { - ULONG_PTR Address; - ULONG FunctionOffset; - ULONG FileOffset; - ULONG SourceLine; -} ROSSYM_ENTRY, *PROSSYM_ENTRY; - -#define ROUND_UP(N, S) (((N) + (S) - 1) & ~((S) - 1)) - -char* convert_path(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); -} +#include "rsym.h" static int CompareSymEntry(const PROSSYM_ENTRY SymEntry1, const PROSSYM_ENTRY SymEntry2) @@ -342,7 +62,7 @@ GetStabInfo(void *FileData, PIMAGE_FILE_HEADER PEFileHeader, if ((strncmp((char*)PESectionHeaders[Idx].Name, ".stab", 5) == 0) && (PESectionHeaders[Idx].Name[5] == 0)) { - /* printf(".stab section found. Size %d\n", + /* printf(".stab section found. Size %d\n", PESectionHeaders[Idx].SizeOfRawData); */ *StabSymbolsLength = PESectionHeaders[Idx].SizeOfRawData; @@ -351,7 +71,7 @@ GetStabInfo(void *FileData, PIMAGE_FILE_HEADER PEFileHeader, if (strncmp((char*)PESectionHeaders[Idx].Name, ".stabstr", 8) == 0) { - /* printf(".stabstr section found. Size %d\n", + /* printf(".stabstr section found. Size %d\n", PESectionHeaders[Idx].SizeOfRawData); */ *StabStringsLength = PESectionHeaders[Idx].SizeOfRawData; @@ -462,9 +182,9 @@ ConvertStabs(ULONG *SymbolsCount, PROSSYM_ENTRY *SymbolsBase, (*SymbolsBase)[*SymbolsCount].FunctionOffset = 0; (*SymbolsBase)[*SymbolsCount].SourceLine = 0; LastFunctionAddress = 0; - break; + break; case N_FUN: - if (0 == StabEntry[i].n_desc || StabEntry[i].n_value < ImageBase) /* line # 0 isn't valid */ + if (0 == StabEntry[i].n_desc || StabEntry[i].n_value < ImageBase) /* line # 0 isn't valid */ { continue; } @@ -492,7 +212,7 @@ ConvertStabs(ULONG *SymbolsCount, PROSSYM_ENTRY *SymbolsBase, StringsBase); (*SymbolsBase)[*SymbolsCount].SourceLine = 0; LastFunctionAddress = Address; - break; + break; case N_SLINE: if (0 == LastFunctionAddress) { @@ -512,7 +232,7 @@ ConvertStabs(ULONG *SymbolsCount, PROSSYM_ENTRY *SymbolsBase, (*SymbolsBase)[*SymbolsCount].SourceLine = StabEntry[i].n_desc; break; default: - continue; + continue; } First = 0; } @@ -1022,9 +742,7 @@ int main(int argc, char* argv[]) ULONG CoffStringsLength; char* path1; char* path2; - FILE* in; FILE* out; - int n_in; void *StringBase; ULONG StringsLength; ULONG StabSymbolsCount; @@ -1033,7 +751,7 @@ int main(int argc, char* argv[]) PROSSYM_ENTRY CoffSymbols; ULONG MergedSymbolsCount; PROSSYM_ENTRY MergedSymbols; - long FileSize; + size_t FileSize; void *FileData; ULONG RosSymLength; void *RosSymSection; @@ -1047,31 +765,12 @@ int main(int argc, char* argv[]) path1 = convert_path(argv[1]); path2 = convert_path(argv[2]); - in = fopen(path1, "rb"); - if (in == NULL) - { - perror("Cannot open input file"); - exit(1); - } - fseek(in, 0L, SEEK_END); - FileSize = ftell(in); - fseek(in, 0L, SEEK_SET); - FileData = malloc(FileSize); - if (NULL == FileData) - { - fclose(in); - fprintf(stderr, "Can't allocate %ld bytes to read input file\n", FileSize); - exit(1); - } - n_in = fread(FileData, 1, FileSize, in); - if (n_in != FileSize) - { - perror("Error reading from input file"); - free(FileData); - fclose(in); - exit(1); - } - fclose(in); + 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; diff --git a/reactos/tools/rsym.h b/reactos/tools/rsym.h new file mode 100644 index 00000000000..a282c2b22b9 --- /dev/null +++ b/reactos/tools/rsym.h @@ -0,0 +1,266 @@ +/* rsym.h */ + +#ifndef RSYM_H +#define RSYM_H + +#define IMAGE_DOS_MAGIC 0x5a4d +#define IMAGE_PE_MAGIC 0x00004550 + +#define IMAGE_SIZEOF_SHORT_NAME 8 + +#define IMAGE_NUMBEROF_DIRECTORY_ENTRIES 16 + +typedef unsigned char BYTE; +typedef unsigned short WORD; +typedef unsigned long DWORD; +typedef signed long LONG; +typedef unsigned long ULONG; +#if defined(_WIN64) +typedef unsigned __int64 ULONG_PTR; +#else +typedef unsigned long ULONG_PTR; +#endif + +#pragma pack(push,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; +} IMAGE_DOS_HEADER,*PIMAGE_DOS_HEADER; +#pragma pack(pop) + +#define IMAGE_FILE_LINE_NUMS_STRIPPED 4 +#define IMAGE_FILE_LOCAL_SYMS_STRIPPED 8 +#define IMAGE_FILE_DEBUG_STRIPPED 512 + +#pragma pack(push,4) +typedef struct _IMAGE_FILE_HEADER { + WORD Machine; + WORD NumberOfSections; + DWORD TimeDateStamp; + DWORD PointerToSymbolTable; + DWORD NumberOfSymbols; + WORD SizeOfOptionalHeader; + WORD Characteristics; +} IMAGE_FILE_HEADER, *PIMAGE_FILE_HEADER; + +typedef struct _IMAGE_DATA_DIRECTORY { + DWORD VirtualAddress; + DWORD Size; +} IMAGE_DATA_DIRECTORY,*PIMAGE_DATA_DIRECTORY; + +#define IMAGE_DIRECTORY_ENTRY_BASERELOC 5 + +typedef struct _IMAGE_OPTIONAL_HEADER { + WORD 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; + IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES]; +} IMAGE_OPTIONAL_HEADER,*PIMAGE_OPTIONAL_HEADER; + +#define IMAGE_SCN_TYPE_NOLOAD 0x00000002 +#define IMAGE_SCN_LNK_REMOVE 0x00000800 +#define IMAGE_SCN_MEM_READ 0x40000000 +#define IMAGE_SCN_MEM_DISCARDABLE 0x02000000 + +typedef struct _IMAGE_SECTION_HEADER { + BYTE Name[IMAGE_SIZEOF_SHORT_NAME]; + union { + DWORD PhysicalAddress; + DWORD VirtualSize; + } Misc; + DWORD VirtualAddress; + DWORD SizeOfRawData; + DWORD PointerToRawData; + DWORD PointerToRelocations; + DWORD PointerToLinenumbers; + WORD NumberOfRelocations; + WORD NumberOfLinenumbers; + DWORD Characteristics; +} IMAGE_SECTION_HEADER,*PIMAGE_SECTION_HEADER; + +typedef struct _IMAGE_BASE_RELOCATION { + DWORD VirtualAddress; + DWORD SizeOfBlock; +} IMAGE_BASE_RELOCATION,*PIMAGE_BASE_RELOCATION; + + +typedef struct { + unsigned short f_magic; /* magic number */ + unsigned short f_nscns; /* number of sections */ + unsigned long f_timdat; /* time & date stamp */ + unsigned long f_symptr; /* file pointer to symtab */ + unsigned long f_nsyms; /* number of symtab entries */ + unsigned short f_opthdr; /* sizeof(optional hdr) */ + unsigned short f_flags; /* flags */ +} FILHDR; + +typedef struct { + char s_name[8]; /* section name */ + unsigned long s_paddr; /* physical address, aliased s_nlib */ + unsigned long s_vaddr; /* virtual address */ + unsigned long s_size; /* section size */ + unsigned long s_scnptr; /* file ptr to raw data for section */ + unsigned long s_relptr; /* file ptr to relocation */ + unsigned long s_lnnoptr; /* file ptr to line numbers */ + unsigned short s_nreloc; /* number of relocation entries */ + unsigned short s_nlnno; /* number of line number entries */ + unsigned long s_flags; /* flags */ +} SCNHDR; +#pragma pack(pop) + +typedef struct _SYMBOLFILE_HEADER { + unsigned long SymbolsOffset; + unsigned long SymbolsLength; + unsigned long StringsOffset; + unsigned long StringsLength; +} SYMBOLFILE_HEADER, *PSYMBOLFILE_HEADER; + +typedef struct _STAB_ENTRY { + unsigned long n_strx; /* index into string table of name */ + unsigned char n_type; /* type of symbol */ + unsigned char n_other; /* misc info (usually empty) */ + unsigned short n_desc; /* description field */ + unsigned long n_value; /* value of symbol */ +} STAB_ENTRY, *PSTAB_ENTRY; + +#define N_FUN 0x24 +#define N_SLINE 0x44 +#define N_SO 0x64 + +/* COFF symbol table */ + +#define E_SYMNMLEN 8 /* # characters in a symbol name */ +#define E_FILNMLEN 14 /* # characters in a file name */ +#define E_DIMNUM 4 /* # array dimensions in auxiliary entry */ + +#define N_BTMASK (0xf) +#define N_TMASK (0x30) +#define N_BTSHFT (4) +#define N_TSHIFT (2) + +/* derived types, in e_type */ +#define DT_NON (0) /* no derived type */ +#define DT_PTR (1) /* pointer */ +#define DT_FCN (2) /* function */ +#define DT_ARY (3) /* array */ + +#define BTYPE(x) ((x) & N_BTMASK) + +#define ISPTR(x) (((x) & N_TMASK) == (DT_PTR << N_BTSHFT)) +#define ISFCN(x) (((x) & N_TMASK) == (DT_FCN << N_BTSHFT)) +#define ISARY(x) (((x) & N_TMASK) == (DT_ARY << N_BTSHFT)) +#define ISTAG(x) ((x)==C_STRTAG||(x)==C_UNTAG||(x)==C_ENTAG) +#define DECREF(x) ((((x)>>N_TSHIFT)&~N_BTMASK)|((x)&N_BTMASK)) + +#define C_EFCN 0xff /* physical end of function */ +#define C_NULL 0 +#define C_AUTO 1 /* automatic variable */ +#define C_EXT 2 /* external symbol */ +#define C_STAT 3 /* static */ +#define C_REG 4 /* register variable */ +#define C_EXTDEF 5 /* external definition */ +#define C_LABEL 6 /* label */ +#define C_ULABEL 7 /* undefined label */ +#define C_MOS 8 /* member of structure */ +#define C_ARG 9 /* function argument */ +#define C_STRTAG 10 /* structure tag */ +#define C_MOU 11 /* member of union */ +#define C_UNTAG 12 /* union tag */ +#define C_TPDEF 13 /* type definition */ +#define C_USTATIC 14 /* undefined static */ +#define C_ENTAG 15 /* enumeration tag */ +#define C_MOE 16 /* member of enumeration */ +#define C_REGPARM 17 /* register parameter */ +#define C_FIELD 18 /* bit field */ +#define C_AUTOARG 19 /* auto argument */ +#define C_LASTENT 20 /* dummy entry (end of block) */ +#define C_BLOCK 100 /* ".bb" or ".eb" */ +#define C_FCN 101 /* ".bf" or ".ef" */ +#define C_EOS 102 /* end of structure */ +#define C_FILE 103 /* file name */ +#define C_LINE 104 /* line # reformatted as symbol table entry */ +#define C_ALIAS 105 /* duplicate tag */ +#define C_HIDDEN 106 /* ext symbol in dmert public lib */ + +#pragma pack(push,1) +typedef struct _COFF_SYMENT +{ + union + { + char e_name[E_SYMNMLEN]; + struct + { + unsigned long e_zeroes; + unsigned long e_offset; + } + e; + } + e; + unsigned long e_value; + short e_scnum; + unsigned short e_type; + unsigned char e_sclass; + unsigned char e_numaux; +} COFF_SYMENT, *PCOFF_SYMENT; +#pragma pack(pop) + +typedef struct _ROSSYM_ENTRY { + ULONG_PTR Address; + ULONG FunctionOffset; + ULONG FileOffset; + ULONG SourceLine; +} ROSSYM_ENTRY, *PROSSYM_ENTRY; + +#define ROUND_UP(N, S) (((N) + (S) - 1) & ~((S) - 1)) + +extern char* +convert_path(const char* origpath); + +extern void* +load_file ( const char* file_name, size_t* file_size ); + +#endif/*RSYM_H*/ diff --git a/reactos/tools/rsym_common.c b/reactos/tools/rsym_common.c new file mode 100644 index 00000000000..875463fe920 --- /dev/null +++ b/reactos/tools/rsym_common.c @@ -0,0 +1,62 @@ +/* rsym_common.c */ + +#include +#include +#include + +#include "rsym.h" + +char* +convert_path ( const char* origpath ) +{ + char* newpath; + int i; + + newpath = strdup(origpath); + + i = 0; + while (newpath[i] != 0) + { +#ifdef UNIX_PATHS + if (newpath[i] == '\\') + { + newpath[i] = '/'; + } +#else +#ifdef DOS_PATHS + if (newpath[i] == '/') + { + newpath[i] = '\\'; + } +#endif +#endif + i++; + } + return(newpath); +} + +void* +load_file ( const char* file_name, size_t* file_size ) +{ + FILE* f; + void* FileData = NULL; + + f = fopen ( file_name, "rb" ); + if (f != NULL) + { + fseek(f, 0L, SEEK_END); + *file_size = ftell(f); + fseek(f, 0L, SEEK_SET); + FileData = malloc(*file_size); + if (FileData != NULL) + { + if ( *file_size != fread(FileData, 1, *file_size, f) ) + { + free(FileData); + FileData = NULL; + } + } + fclose(f); + } + return FileData; +}