ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

raddr2line.c
Go to the documentation of this file.
00001 /*
00002  * Usage: raddr2line input-file address/offset
00003  *
00004  * This is a tool and is compiled using the host compiler,
00005  * i.e. on Linux gcc and not mingw-gcc (cross-compiler).
00006  * Therefore we can't include SDK headers and we have to
00007  * duplicate some definitions here.
00008  * Also note that the internal functions are "old C-style",
00009  * returning an int, where a return of 0 means success and
00010  * non-zero is failure.
00011  */
00012 
00013 #include <stdio.h>
00014 #include <string.h>
00015 #include <stdlib.h>
00016 
00017 #include "rsym.h"
00018 
00019 /* Assume if an offset > ABS_TRESHOLD, then it must be absolute */
00020 #define ABS_TRESHOLD    0x00400000L
00021 
00022 size_t fixup_offset ( size_t ImageBase, size_t offset )
00023 {
00024     if (offset > ABS_TRESHOLD)
00025         offset -= ImageBase;
00026 
00027     return offset;
00028 }
00029 
00030 long
00031 my_atoi ( const char* a )
00032 {
00033     int i = 0;
00034     const char* fmt = "%x";
00035 
00036     if ( *a == '0' )
00037     {
00038         switch ( *++a )
00039         {
00040         case 'x':
00041             fmt = "%x";
00042             ++a;
00043             break;
00044         case 'd':
00045             fmt = "%d";
00046             ++a;
00047             break;
00048         default:
00049             fmt = "%o";
00050             break;
00051         }
00052     }
00053     sscanf ( a, fmt, &i );
00054     return i;
00055 }
00056 
00057 PIMAGE_SECTION_HEADER
00058 find_rossym_section ( PIMAGE_FILE_HEADER PEFileHeader,
00059     PIMAGE_SECTION_HEADER PESectionHeaders )
00060 {
00061     size_t i;
00062     for ( i = 0; i < PEFileHeader->NumberOfSections; i++ )
00063     {
00064         if ( 0 == strcmp ( (char*)PESectionHeaders[i].Name, ".rossym" ) )
00065             return &PESectionHeaders[i];
00066     }
00067     return NULL;
00068 }
00069 
00070 int
00071 find_and_print_offset (
00072     void* data,
00073     size_t offset )
00074 {
00075     PSYMBOLFILE_HEADER RosSymHeader = (PSYMBOLFILE_HEADER)data;
00076     PROSSYM_ENTRY Entries = (PROSSYM_ENTRY)((char*)data + RosSymHeader->SymbolsOffset);
00077     char* Strings = (char*)data + RosSymHeader->StringsOffset;
00078     size_t symbols = RosSymHeader->SymbolsLength / sizeof(ROSSYM_ENTRY);
00079     size_t i;
00080 
00081     //if ( RosSymHeader->SymbolsOffset )
00082 
00083     for ( i = 0; i < symbols; i++ )
00084     {
00085         if ( Entries[i].Address > offset )
00086         {
00087             if ( !i-- )
00088                 return 1;
00089             else
00090             {
00091                 PROSSYM_ENTRY e = &Entries[i];
00092                 printf ( "%s:%u (%s)\n",
00093                     &Strings[e->FileOffset],
00094                     (unsigned int)e->SourceLine,
00095                     &Strings[e->FunctionOffset] );
00096                 return 0;
00097             }
00098         }
00099     }
00100     return 1;
00101 }
00102 
00103 int
00104 process_data ( const void* FileData, size_t offset )
00105 {
00106     PIMAGE_DOS_HEADER PEDosHeader;
00107     PIMAGE_FILE_HEADER PEFileHeader;
00108     PIMAGE_OPTIONAL_HEADER PEOptHeader;
00109     PIMAGE_SECTION_HEADER PESectionHeaders;
00110     PIMAGE_SECTION_HEADER PERosSymSectionHeader;
00111     size_t ImageBase;
00112     int res;
00113 
00114     /* Check if MZ header exists  */
00115     PEDosHeader = (PIMAGE_DOS_HEADER)FileData;
00116     if (PEDosHeader->e_magic != IMAGE_DOS_MAGIC || PEDosHeader->e_lfanew == 0L)
00117     {
00118         perror("Input file is not a PE image.\n");
00119         return 1;
00120     }
00121 
00122     /* Locate PE file header  */
00123     /* sizeof(ULONG) = sizeof(MAGIC) */
00124     PEFileHeader = (PIMAGE_FILE_HEADER)((char *)FileData + PEDosHeader->e_lfanew + sizeof(ULONG));
00125 
00126     /* Locate optional header */
00127     PEOptHeader = (PIMAGE_OPTIONAL_HEADER)(PEFileHeader + 1);
00128     ImageBase = PEOptHeader->ImageBase;
00129 
00130     /* Locate PE section headers  */
00131     PESectionHeaders = (PIMAGE_SECTION_HEADER)((char *) PEOptHeader + PEFileHeader->SizeOfOptionalHeader);
00132 
00133     /* make sure offset is what we want */
00134     offset = fixup_offset ( ImageBase, offset );
00135 
00136     /* find rossym section */
00137     PERosSymSectionHeader = find_rossym_section (
00138         PEFileHeader, PESectionHeaders );
00139     if ( !PERosSymSectionHeader )
00140     {
00141         fprintf ( stderr, "Couldn't find rossym section in executable\n" );
00142         return 1;
00143     }
00144     res = find_and_print_offset ( (char*)FileData + PERosSymSectionHeader->PointerToRawData,
00145         offset );
00146     if ( res )
00147         printf ( "??:0\n" );
00148     return res;
00149 }
00150 
00151 int
00152 process_file ( const char* file_name, size_t offset )
00153 {
00154     void* FileData;
00155     size_t FileSize;
00156     int res = 1;
00157 
00158     FileData = load_file ( file_name, &FileSize );
00159     if ( !FileData )
00160     {
00161         fprintf ( stderr, "An error occured loading '%s'\n", file_name );
00162     }
00163     else
00164     {
00165         res = process_data ( FileData, offset );
00166         free ( FileData );
00167     }
00168 
00169     return res;
00170 }
00171 
00172 int main ( int argc, const char** argv )
00173 {
00174     char* path;
00175     size_t offset;
00176     int res;
00177 
00178     if ( argc != 3 )
00179     {
00180         fprintf(stderr, "Usage: raddr2line <exefile> <offset>\n");
00181         exit(1);
00182     }
00183 
00184     path = convert_path ( argv[1] );
00185     offset = my_atoi ( argv[2] );
00186 
00187     res = process_file ( path, offset );
00188 
00189     free ( path );
00190 
00191     return res;
00192 }

Generated on Sun May 27 2012 04:37:47 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.