raddr2line utility
authorRoyce Mitchell III <royce3@ev1.net>
Fri, 8 Apr 2005 05:35:20 +0000 (05:35 +0000)
committerRoyce Mitchell III <royce3@ev1.net>
Fri, 8 Apr 2005 05:35:20 +0000 (05:35 +0000)
moved code common betw rsym and raddr2line to rsym_common.c
simplified tools/Makefile

svn path=/trunk/; revision=14542

reactos/tools/Makefile
reactos/tools/raddr2line.c [new file with mode: 0644]
reactos/tools/rsym.c
reactos/tools/rsym.h [new file with mode: 0644]
reactos/tools/rsym_common.c [new file with mode: 0644]

index 5602a9c..da89ae7 100644 (file)
@@ -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 (file)
index 0000000..fa0bdec
--- /dev/null
@@ -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 <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#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 <exefile> <offset>\n");
+               exit(1);
+       }
+
+       path = convert_path ( argv[1] );
+       offset = my_atoi ( argv[2] );
+
+       res = process_file ( path, offset );
+
+       free ( path );
+
+       return res;
+}
index 21885b4..46405bf 100644 (file)
 #include <string.h>
 #include <stdlib.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))
-
-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 (file)
index 0000000..a282c2b
--- /dev/null
@@ -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 (file)
index 0000000..875463f
--- /dev/null
@@ -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;
+}