ReactOS  0.4.14-dev-358-gbef841c
rsym.c
Go to the documentation of this file.
1 /*
2  * PROJECT: ReactOS dbghelp extension
3  * LICENSE: GPLv2+ - See COPYING in the top level directory
4  * PURPOSE: Parse rsym information for use with dbghelp
5  * PROGRAMMER: Mark Jansen
6  */
7 
8 #include "dbghelp_private.h"
9 #include <reactos/rossym.h>
10 
11 #include <wine/debug.h>
12 WINE_DEFAULT_DEBUG_CHANNEL(dbghelp_rsym);
13 
14 
15 typedef struct rsym_file_entry_s
16 {
17  const char* File;
18  unsigned Source;
20 
21 typedef struct rsym_func_entry_s
22 {
27 
28 
29 
30 /******************************************************************
31  * rsym_finalize_function (copied from stabs_finalize_function)
32  *
33  * Ends function creation: mainly:
34  * - cleans up line number information
35  * - tries to set up a debug-start tag (FIXME: heuristic to be enhanced)
36  */
37 static void rsym_finalize_function(struct module* module, struct symt_function* func)
38 {
39  IMAGEHLP_LINE64 il;
40  struct location loc;
41 
42  if (!func) return;
44  /* To define the debug-start of the function, we use the second line number.
45  * Not 100% bullet proof, but better than nothing
46  */
47  if (symt_fill_func_line_info(module, func, func->address, &il) &&
49  {
50  loc.kind = loc_absolute;
51  loc.offset = il.Address - func->address;
53  &loc, NULL);
54  }
55 }
56 
57 
58 static int is_metadata_sym(const char* name)
59 {
60  ULONG len = name ? strlen(name) : 0;
61  return len > 3 && name[0] == '_' && name[1] != '_' && name[len-1] == '_' && name[len-2] == '_';
62 };
63 
64 static int use_raw_address(const char* name)
65 {
66  if (!name)
67  return 0;
68 
69  if (!strcmp(name, "__ImageBase"))
70  return 1;
71 
72  if (!strcmp(name, "__RUNTIME_PSEUDO_RELOC_LIST__"))
73  return 1;
74 
75  return 0;
76 }
77 
78 
79 BOOL rsym_parse(struct module* module, unsigned long load_offset,
80  const void* rsym_ptr, int rsymlen)
81 {
82  const ROSSYM_HEADER* RosSymHeader;
83  const ROSSYM_ENTRY* First, *Last, *Entry;
84  const CHAR* Strings;
85 
86  struct pool pool;
87  struct sparse_array file_table, func_table;
88  rsym_func_entry_t* first_func = NULL;
89 
90 
91  RosSymHeader = rsym_ptr;
92 
93  if (RosSymHeader->SymbolsOffset < sizeof(ROSSYM_HEADER)
94  || RosSymHeader->StringsOffset < RosSymHeader->SymbolsOffset + RosSymHeader->SymbolsLength
95  || rsymlen < RosSymHeader->StringsOffset + RosSymHeader->StringsLength
96  || 0 != (RosSymHeader->SymbolsLength % sizeof(ROSSYM_ENTRY)))
97  {
98  WARN("Invalid ROSSYM_HEADER\n");
99  return FALSE;
100  }
101 
102  First = (const ROSSYM_ENTRY *)((const char*)rsym_ptr + RosSymHeader->SymbolsOffset);
103  Last = First + RosSymHeader->SymbolsLength / sizeof(ROSSYM_ENTRY);
104  Strings = (const CHAR*)rsym_ptr + RosSymHeader->StringsOffset;
105 
106  pool_init(&pool, 65536);
107  sparse_array_init(&file_table, sizeof(rsym_file_entry_t), 64);
108  sparse_array_init(&func_table, sizeof(rsym_func_entry_t), 128);
109 
110  for (Entry = First; Entry != Last; Entry++)
111  {
112  ULONG Address = load_offset + Entry->Address;
113  if (!Entry->FileOffset)
114  {
115  rsym_func_entry_t* func = sparse_array_find(&func_table, Entry->FunctionOffset);
116 
117  /* We do not want to define a data point where there is already a function! */
118  if (!func || func->Address != Address)
119  {
120  const char* SymbolName = Strings + Entry->FunctionOffset;
121  if (!is_metadata_sym(SymbolName))
122  {
123  /* TODO: How should we determine the size? */
124  ULONG Size = sizeof(ULONG);
125  if (use_raw_address(SymbolName))
126  Address = Entry->Address;
127 
128  symt_new_public(module, NULL, SymbolName, FALSE, Address, Size);
129  }
130  else
131  {
132  /* Maybe use it to fill some metadata? */
133  }
134  }
135  }
136  else
137  {
138  rsym_file_entry_t* file = sparse_array_find(&file_table, Entry->FileOffset);
139  rsym_func_entry_t* func = sparse_array_find(&func_table, Entry->FunctionOffset);
140 
141  if (!file)
142  {
143  file = sparse_array_add(&file_table, Entry->FileOffset, &pool);
144  file->File = Strings + Entry->FileOffset;
145  file->Source = source_new(module, NULL, Strings + Entry->FileOffset);
146  }
147 
148  if (!func)
149  {
150  func = sparse_array_add(&func_table, Entry->FunctionOffset, &pool);
151  func->func = symt_new_function(module, NULL, Strings + Entry->FunctionOffset,
152  Address, 0, NULL);
153  func->Address = Address;
154  func->next = first_func;
155  first_func = func;
156  }
157 
158  /* TODO: What if we have multiple chunks scattered around? */
159  symt_add_func_line(module, func->func, file->Source, Entry->SourceLine, Address - func->Address);
160  }
161  }
162 
163  while (first_func)
164  {
165  /* TODO: Size of function? */
166  rsym_finalize_function(module, first_func->func);
167  first_func = first_func->next;
168  }
169 
171  module->module.CVSig = 'R' | ('S' << 8) | ('Y' << 16) | ('M' << 24);
177 
178  pool_destroy(&pool);
179 
180  return TRUE;
181 }
182 
GLenum func
Definition: glext.h:6028
static void rsym_finalize_function(struct module *module, struct symt_function *func)
Definition: rsym.c:37
#define TRUE
Definition: types.h:120
struct rsym_func_entry_s rsym_func_entry_t
Definition: compat.h:720
struct _Entry Entry
Definition: kefuncs.h:640
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
BOOL symt_fill_func_line_info(const struct module *module, const struct symt_function *func, DWORD64 addr, IMAGEHLP_LINE64 *line) DECLSPEC_HIDDEN
Definition: symbol.c:1488
struct rsym_func_entry_s * next
Definition: rsym.c:25
char CHAR
Definition: xmlstorage.h:175
#define WARN(fmt,...)
Definition: debug.h:111
Definition: rsym.c:15
Definition: rossym.h:26
unsigned long StringsOffset
Definition: rossym.h:22
BOOL rsym_parse(struct module *module, unsigned long load_offset, const void *rsym_ptr, int rsymlen)
Definition: rsym.c:79
unsigned Source
Definition: rsym.c:18
uint32_t ULONG_PTR
Definition: typedefs.h:63
WCHAR First[]
Definition: FormatMessage.c:11
unsigned int BOOL
Definition: ntddk_ex.h:94
struct symt_public * symt_new_public(struct module *module, struct symt_compiland *parent, const char *typename, BOOL is_function, unsigned long address, unsigned size) DECLSPEC_HIDDEN
Definition: symbol.c:226
void symt_add_func_line(struct module *module, struct symt_function *func, unsigned source_idx, int line_num, unsigned long offset) DECLSPEC_HIDDEN
Definition: symbol.c:328
struct symt_function * func
Definition: rsym.c:24
smooth NULL
Definition: ftsmooth.c:416
static WCHAR Address[46]
Definition: ping.c:68
struct _ROSSYM_ENTRY ROSSYM_ENTRY
BOOL symt_get_func_line_next(const struct module *module, PIMAGEHLP_LINE64 line) DECLSPEC_HIDDEN
Definition: symbol.c:1730
static int is_metadata_sym(const char *name)
Definition: rsym.c:58
ULONG_PTR Address
Definition: rsym.c:23
struct rsym_file_entry_s rsym_file_entry_t
void sparse_array_init(struct sparse_array *sa, unsigned elt_sz, unsigned bucket_sz) DECLSPEC_HIDDEN
Definition: storage.c:214
const char * File
Definition: rsym.c:17
static const WCHAR Strings[]
Definition: reg.c:35
void pool_init(struct pool *a, size_t arena_size) DECLSPEC_HIDDEN
Definition: storage.c:44
struct symt_hierarchy_point * symt_add_function_point(struct module *module, struct symt_function *func, enum SymTagEnum point, const struct location *loc, const char *name) DECLSPEC_HIDDEN
Definition: symbol.c:454
SYM_TYPE SymType
Definition: compat.h:732
GLenum GLsizei len
Definition: glext.h:6722
static int use_raw_address(const char *name)
Definition: rsym.c:64
IN PVOID IN PVOID IN USHORT IN USHORT Size
Definition: pci.h:359
WINE_DEFAULT_DEBUG_CHANNEL(dbghelp_rsym)
unsigned kind
BOOL symt_normalize_function(struct module *module, const struct symt_function *func) DECLSPEC_HIDDEN
Definition: symbol.c:475
unsigned long StringsLength
Definition: rossym.h:23
void pool_destroy(struct pool *a) DECLSPEC_HIDDEN
Definition: storage.c:51
struct symt_function * symt_new_function(struct module *module, struct symt_compiland *parent, const char *name, unsigned long addr, unsigned long size, struct symt *type) DECLSPEC_HIDDEN
Definition: symbol.c:295
unsigned source_new(struct module *module, const char *basedir, const char *source) DECLSPEC_HIDDEN
Definition: source.c:67
Definition: name.c:36
unsigned long offset
unsigned long SymbolsLength
Definition: rossym.h:21
unsigned int ULONG
Definition: retypes.h:1
int strcmp(const char *String1, const char *String2)
Definition: utclib.c:469
void * sparse_array_add(struct sparse_array *sa, unsigned long key, struct pool *pool) DECLSPEC_HIDDEN
Definition: storage.c:282
unsigned long SymbolsOffset
Definition: rossym.h:20
DWORD64 Address
Definition: compat.h:756
IMAGEHLP_MODULEW64 module
Definition: rsym.c:21
base of all file and directory entries
Definition: entries.h:82
void * sparse_array_find(const struct sparse_array *sa, unsigned long idx) DECLSPEC_HIDDEN
Definition: storage.c:272
Definition: fci.c:126