Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenraddr2line.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
1.7.6.1
|