ReactOS  0.4.12-dev-418-g3df31a8
raddr2line.c
Go to the documentation of this file.
1 /*
2  * Usage: raddr2line input-file address/offset
3  *
4  * This is a tool and is compiled using the host compiler,
5  * i.e. on Linux gcc and not mingw-gcc (cross-compiler).
6  * Therefore we can't include SDK headers and we have to
7  * duplicate some definitions here.
8  * Also note that the internal functions are "old C-style",
9  * returning an int, where a return of 0 means success and
10  * non-zero is failure.
11  */
12 
13 #include <stdio.h>
14 #include <string.h>
15 #include <stdlib.h>
16 
17 #include "rsym.h"
18 
19 /* Assume if an offset > ABS_TRESHOLD, then it must be absolute */
20 #define ABS_TRESHOLD 0x00400000L
21 
22 size_t fixup_offset ( size_t ImageBase, size_t offset )
23 {
24  if (offset > ABS_TRESHOLD)
25  offset -= ImageBase;
26 
27  return offset;
28 }
29 
30 long
31 my_atoi ( const char* a )
32 {
33  int i = 0;
34  const char* fmt = "%x";
35 
36  if ( *a == '0' )
37  {
38  switch ( *++a )
39  {
40  case 'x':
41  fmt = "%x";
42  ++a;
43  break;
44  case 'd':
45  fmt = "%d";
46  ++a;
47  break;
48  default:
49  fmt = "%o";
50  break;
51  }
52  }
53  sscanf ( a, fmt, &i );
54  return i;
55 }
56 
59  PIMAGE_SECTION_HEADER PESectionHeaders )
60 {
61  size_t i;
62  for ( i = 0; i < PEFileHeader->NumberOfSections; i++ )
63  {
64  if ( 0 == strcmp ( (char*)PESectionHeaders[i].Name, ".rossym" ) )
65  return &PESectionHeaders[i];
66  }
67  return NULL;
68 }
69 
70 int
72  void* data,
73  size_t offset )
74 {
76  PROSSYM_ENTRY Entries = (PROSSYM_ENTRY)((char*)data + RosSymHeader->SymbolsOffset);
77  char* Strings = (char*)data + RosSymHeader->StringsOffset;
78  size_t symbols = RosSymHeader->SymbolsLength / sizeof(ROSSYM_ENTRY);
79  size_t i;
80 
81  //if ( RosSymHeader->SymbolsOffset )
82 
83  for ( i = 0; i < symbols; i++ )
84  {
85  if ( Entries[i].Address > offset )
86  {
87  if ( !i-- )
88  return 1;
89  else
90  {
92  printf ( "%s:%u (%s)\n",
93  &Strings[e->FileOffset],
94  (unsigned int)e->SourceLine,
95  &Strings[e->FunctionOffset] );
96  return 0;
97  }
98  }
99  }
100  return 1;
101 }
102 
103 int
104 process_data ( const void* FileData, size_t offset )
105 {
106  PIMAGE_DOS_HEADER PEDosHeader;
107  PIMAGE_FILE_HEADER PEFileHeader;
108  PIMAGE_OPTIONAL_HEADER PEOptHeader;
109  PIMAGE_SECTION_HEADER PESectionHeaders;
110  PIMAGE_SECTION_HEADER PERosSymSectionHeader;
111  size_t ImageBase;
112  int res;
113 
114  /* Check if MZ header exists */
115  PEDosHeader = (PIMAGE_DOS_HEADER)FileData;
116  if (PEDosHeader->e_magic != IMAGE_DOS_MAGIC || PEDosHeader->e_lfanew == 0L)
117  {
118  perror("Input file is not a PE image.\n");
119  return 1;
120  }
121 
122  /* Locate PE file header */
123  /* sizeof(ULONG) = sizeof(MAGIC) */
124  PEFileHeader = (PIMAGE_FILE_HEADER)((char *)FileData + PEDosHeader->e_lfanew + sizeof(ULONG));
125 
126  /* Locate optional header */
127  PEOptHeader = (PIMAGE_OPTIONAL_HEADER)(PEFileHeader + 1);
128  ImageBase = PEOptHeader->ImageBase;
129 
130  /* Locate PE section headers */
131  PESectionHeaders = (PIMAGE_SECTION_HEADER)((char *) PEOptHeader + PEFileHeader->SizeOfOptionalHeader);
132 
133  /* make sure offset is what we want */
134  offset = fixup_offset ( ImageBase, offset );
135 
136  /* find rossym section */
137  PERosSymSectionHeader = find_rossym_section (
138  PEFileHeader, PESectionHeaders );
139  if ( !PERosSymSectionHeader )
140  {
141  fprintf ( stderr, "Couldn't find rossym section in executable\n" );
142  return 1;
143  }
144  res = find_and_print_offset ( (char*)FileData + PERosSymSectionHeader->PointerToRawData,
145  offset );
146  if ( res )
147  printf ( "??:0\n" );
148  return res;
149 }
150 
151 int
152 process_file ( const char* file_name, size_t offset )
153 {
154  void* FileData;
155  size_t FileSize;
156  int res = 1;
157 
159  if ( !FileData )
160  {
161  fprintf ( stderr, "An error occured loading '%s'\n", file_name );
162  }
163  else
164  {
166  free ( FileData );
167  }
168 
169  return res;
170 }
171 
172 int main ( int argc, const char** argv )
173 {
174  char* path;
175  size_t offset;
176  int res;
177 
178  if ( argc != 3 )
179  {
180  fprintf(stderr, "Usage: raddr2line <exefile> <offset>\n");
181  exit(1);
182  }
183 
184  path = convert_path ( argv[1] );
185  offset = my_atoi ( argv[2] );
186 
187  res = process_file ( path, offset );
188 
189  free ( path );
190 
191  return res;
192 }
static int argc
Definition: ServiceArgs.c:12
static FILEDATA FileData[MAX_FDS]
Definition: fs.c:52
int process_data(const void *FileData, size_t offset)
Definition: raddr2line.c:104
GLsizei const GLchar ** path
Definition: glext.h:7234
#define free
Definition: debug_ros.c:5
GLintptr offset
Definition: glext.h:5920
ULONG StringsOffset
Definition: rsym.h:34
int find_and_print_offset(void *data, size_t offset)
Definition: raddr2line.c:71
Definition: rossym.h:26
DWORD PointerToRawData
Definition: pedump.c:290
#define argv
Definition: mplay32.c:18
struct _SYMBOLFILE_HEADER * PSYMBOLFILE_HEADER
struct _ROSSYM_ENTRY * PROSSYM_ENTRY
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
_CRTIMP void __cdecl perror(_In_opt_z_ const char *_ErrMsg)
_Check_return_opt_ _CRTIMP int __cdecl fprintf(_Inout_ FILE *_File, _In_z_ _Printf_format_string_ const char *_Format,...)
#define a
Definition: ke_i.h:78
#define e
Definition: ke_i.h:82
smooth NULL
Definition: ftsmooth.c:416
static WCHAR Address[46]
Definition: ping.c:68
struct _IMAGE_DOS_HEADER * PIMAGE_DOS_HEADER
struct _IMAGE_OPTIONAL_HEADER * PIMAGE_OPTIONAL_HEADER
WORD SizeOfOptionalHeader
Definition: ntddk_ex.h:127
_Check_return_ _CRTIMP int __cdecl sscanf(_In_z_ const char *_Src, _In_z_ _Scanf_format_string_ const char *_Format,...)
#define IMAGE_DOS_MAGIC
Definition: pecoff.h:6
struct _IMAGE_FILE_HEADER * PIMAGE_FILE_HEADER
PIMAGE_SECTION_HEADER find_rossym_section(PIMAGE_FILE_HEADER PEFileHeader, PIMAGE_SECTION_HEADER PESectionHeaders)
Definition: raddr2line.c:58
#define ABS_TRESHOLD
Definition: raddr2line.c:20
static const WCHAR Strings[]
Definition: reg.c:35
long my_atoi(const char *a)
Definition: raddr2line.c:31
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
size_t fixup_offset(size_t ImageBase, size_t offset)
Definition: raddr2line.c:22
static const WCHAR L[]
Definition: oid.c:1087
static UINT load_file(MSIRECORD *row, LPVOID param)
Definition: action.c:1202
_Must_inspect_result_ _Out_ PLARGE_INTEGER FileSize
Definition: fsrtlfuncs.h:108
int process_file(const char *file_name, size_t offset)
Definition: raddr2line.c:152
ULONG SymbolsOffset
Definition: rsym.h:32
struct _IMAGE_SECTION_HEADER * PIMAGE_SECTION_HEADER
LIST_ENTRY Entries[5]
Definition: ExDoubleList.c:8
Definition: services.c:325
char * convert_path(char *origpath)
Definition: rcopy.c:11
static LPCWSTR file_name
Definition: protocol.c:146
ULONG SymbolsLength
Definition: rsym.h:33
GLuint res
Definition: glext.h:9613
unsigned int ULONG
Definition: retypes.h:1
FILE * stderr
int strcmp(const char *String1, const char *String2)
Definition: utclib.c:469
int main(int argc, const char **argv)
Definition: raddr2line.c:172
GLboolean GLboolean GLboolean GLboolean a
Definition: glext.h:6204
void exit(int exitcode)
Definition: _exit.c:33
Definition: dsound.c:943
#define printf
Definition: config.h:203