ReactOS 0.4.15-dev-5669-g09dde2c
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>
13
14
15typedef struct rsym_file_entry_s
16{
17 const char* File;
18 unsigned Source;
20
21typedef 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 */
38{
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
58static 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
64static 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
79BOOL 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
179
180 return TRUE;
181}
182
WCHAR First[]
Definition: FormatMessage.c:11
int strcmp(const char *String1, const char *String2)
Definition: utclib.c:469
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
#define WINE_DEFAULT_DEBUG_CHANNEL(t)
Definition: precomp.h:23
#define WARN(fmt,...)
Definition: debug.h:112
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:452
struct symt_function * symt_new_function(struct module *module, struct symt_compiland *parent, const char *name, ULONG_PTR addr, ULONG_PTR size, struct symt *type) DECLSPEC_HIDDEN
Definition: symbol.c:293
void sparse_array_init(struct sparse_array *sa, unsigned elt_sz, unsigned bucket_sz) DECLSPEC_HIDDEN
Definition: storage.c:213
void pool_init(struct pool *a, size_t arena_size) DECLSPEC_HIDDEN
Definition: storage.c:43
void pool_destroy(struct pool *a) DECLSPEC_HIDDEN
Definition: storage.c:50
unsigned source_new(struct module *module, const char *basedir, const char *source) DECLSPEC_HIDDEN
Definition: source.c:66
struct symt_public * symt_new_public(struct module *module, struct symt_compiland *parent, const char *typename, BOOL is_function, ULONG_PTR address, unsigned size) DECLSPEC_HIDDEN
Definition: symbol.c:224
void * sparse_array_add(struct sparse_array *sa, ULONG_PTR key, struct pool *pool) DECLSPEC_HIDDEN
Definition: storage.c:281
void * sparse_array_find(const struct sparse_array *sa, ULONG_PTR idx) DECLSPEC_HIDDEN
Definition: storage.c:271
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:1480
@ loc_absolute
void symt_add_func_line(struct module *module, struct symt_function *func, unsigned source_idx, int line_num, ULONG_PTR offset) DECLSPEC_HIDDEN
Definition: symbol.c:326
BOOL symt_normalize_function(struct module *module, const struct symt_function *func) DECLSPEC_HIDDEN
Definition: symbol.c:473
BOOL symt_get_func_line_next(const struct module *module, PIMAGEHLP_LINE64 line) DECLSPEC_HIDDEN
Definition: symbol.c:1734
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
static const WCHAR Strings[]
Definition: reg.c:35
@ SymDia
Definition: compat.h:1063
@ SymTagFuncDebugStart
Definition: compat.h:1602
struct rsym_func_entry_s rsym_func_entry_t
struct rsym_file_entry_s rsym_file_entry_t
static int use_raw_address(const char *name)
Definition: rsym.c:64
static int is_metadata_sym(const char *name)
Definition: rsym.c:58
BOOL rsym_parse(struct module *module, unsigned long load_offset, const void *rsym_ptr, int rsymlen)
Definition: rsym.c:79
static void rsym_finalize_function(struct module *module, struct symt_function *func)
Definition: rsym.c:37
unsigned int BOOL
Definition: ntddk_ex.h:94
GLenum func
Definition: glext.h:6028
GLenum GLsizei len
Definition: glext.h:6722
static WCHAR Address[46]
Definition: ping.c:68
struct _ROSSYM_ENTRY ROSSYM_ENTRY
base of all file and directory entries
Definition: entries.h:83
DWORD64 Address
Definition: compat.h:1099
SYM_TYPE SymType
Definition: compat.h:1075
Definition: rossym.h:26
unsigned long SymbolsOffset
Definition: rossym.h:20
unsigned long SymbolsLength
Definition: rossym.h:21
unsigned long StringsLength
Definition: rossym.h:23
unsigned long StringsOffset
Definition: rossym.h:22
Definition: fci.c:127
ULONG_PTR offset
unsigned kind
IMAGEHLP_MODULEW64 module
Definition: name.c:39
Definition: rsym.c:16
const char * File
Definition: rsym.c:17
unsigned Source
Definition: rsym.c:18
Definition: rsym.c:22
struct rsym_func_entry_s * next
Definition: rsym.c:25
ULONG_PTR Address
Definition: rsym.c:23
struct symt_function * func
Definition: rsym.c:24
uint32_t ULONG_PTR
Definition: typedefs.h:65
uint32_t ULONG
Definition: typedefs.h:59
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_DEVICE_PROPERTY_DATA _In_ DEVPROPTYPE _In_ ULONG Size
Definition: wdfdevice.h:4533
char CHAR
Definition: xmlstorage.h:175