mirror of
https://github.com/reactos/reactos.git
synced 2024-12-31 19:42:51 +00:00
[DBGHELP] Add experimental rsym support. CORE-12773
svn path=/trunk/; revision=73817
This commit is contained in:
parent
e2c97e602f
commit
b742e89b01
4 changed files with 216 additions and 0 deletions
|
@ -63,6 +63,7 @@ else()
|
|||
path.c
|
||||
pe_module.c
|
||||
rosstubs.c
|
||||
rsym.c
|
||||
source.c
|
||||
stabs.c
|
||||
stack.c
|
||||
|
|
|
@ -714,6 +714,12 @@ extern BOOL dwarf2_parse(struct module* module, unsigned long load_offse
|
|||
extern BOOL dwarf2_virtual_unwind(struct cpu_stack_walk* csw, DWORD_PTR ip,
|
||||
CONTEXT* context, ULONG_PTR* cfa) DECLSPEC_HIDDEN;
|
||||
|
||||
/* rsym.c */
|
||||
extern BOOL rsym_parse(struct module* module, unsigned long load_offset,
|
||||
const void* rsym, int rsymlen) DECLSPEC_HIDDEN;
|
||||
|
||||
|
||||
|
||||
/* stack.c */
|
||||
#ifndef DBGHELP_STATIC_LIB
|
||||
extern BOOL sw_read_mem(struct cpu_stack_walk* csw, DWORD64 addr, void* ptr, DWORD sz) DECLSPEC_HIDDEN;
|
||||
|
|
|
@ -506,6 +506,32 @@ static BOOL pe_load_dwarf(struct module* module)
|
|||
}
|
||||
|
||||
#ifndef DBGHELP_STATIC_LIB
|
||||
/******************************************************************
|
||||
* pe_load_rsym
|
||||
*
|
||||
* look for ReactOS's own rsym format
|
||||
*/
|
||||
static BOOL pe_load_rsym(struct module* module)
|
||||
{
|
||||
struct image_file_map* fmap = &module->format_info[DFI_PE]->u.pe_info->fmap;
|
||||
struct image_section_map sect_rsym;
|
||||
BOOL ret = FALSE;
|
||||
|
||||
if (pe_find_section(fmap, ".rossym", §_rsym))
|
||||
{
|
||||
const char* rsym = image_map_section(§_rsym);
|
||||
if (rsym != IMAGE_NO_MAP)
|
||||
{
|
||||
ret = rsym_parse(module, module->module.BaseOfImage,
|
||||
rsym, image_get_map_size(§_rsym));
|
||||
}
|
||||
image_unmap_section(§_rsym);
|
||||
}
|
||||
TRACE("%s the RSYM debug info\n", ret ? "successfully loaded" : "failed to load");
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/******************************************************************
|
||||
* pe_load_dbg_file
|
||||
*
|
||||
|
@ -704,7 +730,9 @@ BOOL pe_load_debug_info(const struct process* pcs, struct module* module)
|
|||
ret = pe_load_dwarf(module) || ret;
|
||||
#ifndef DBGHELP_STATIC_LIB
|
||||
ret = pe_load_msc_debug_info(pcs, module) || ret;
|
||||
ret = pe_load_rsym(module) || ret;
|
||||
#endif
|
||||
|
||||
ret = ret || pe_load_coff_symbol_table(module); /* FIXME */
|
||||
/* if we still have no debug info (we could only get SymExport at this
|
||||
* point), then do the SymExport except if we have an ELF container,
|
||||
|
|
181
reactos/dll/win32/dbghelp/rsym.c
Normal file
181
reactos/dll/win32/dbghelp/rsym.c
Normal file
|
@ -0,0 +1,181 @@
|
|||
/*
|
||||
* PROJECT: ReactOS dbghelp extension
|
||||
* LICENSE: GPLv2+ - See COPYING in the top level directory
|
||||
* PURPOSE: Parse rsym information for use with dbghelp
|
||||
* PROGRAMMER: Mark Jansen
|
||||
*/
|
||||
|
||||
#include "dbghelp_private.h"
|
||||
#include <reactos/rossym.h>
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(dbghelp_rsym);
|
||||
|
||||
|
||||
typedef struct rsym_file_entry_s
|
||||
{
|
||||
const char* File;
|
||||
unsigned Source;
|
||||
} rsym_file_entry_t;
|
||||
|
||||
typedef struct rsym_func_entry_s
|
||||
{
|
||||
ULONG_PTR Address;
|
||||
struct symt_function* func;
|
||||
struct rsym_func_entry_s* next;
|
||||
} rsym_func_entry_t;
|
||||
|
||||
|
||||
|
||||
/******************************************************************
|
||||
* rsym_finalize_function (copied from stabs_finalize_function)
|
||||
*
|
||||
* Ends function creation: mainly:
|
||||
* - cleans up line number information
|
||||
* - tries to set up a debug-start tag (FIXME: heuristic to be enhanced)
|
||||
*/
|
||||
static void rsym_finalize_function(struct module* module, struct symt_function* func)
|
||||
{
|
||||
IMAGEHLP_LINE64 il;
|
||||
struct location loc;
|
||||
|
||||
if (!func) return;
|
||||
symt_normalize_function(module, func);
|
||||
/* To define the debug-start of the function, we use the second line number.
|
||||
* Not 100% bullet proof, but better than nothing
|
||||
*/
|
||||
if (symt_fill_func_line_info(module, func, func->address, &il) &&
|
||||
symt_get_func_line_next(module, &il))
|
||||
{
|
||||
loc.kind = loc_absolute;
|
||||
loc.offset = il.Address - func->address;
|
||||
symt_add_function_point(module, func, SymTagFuncDebugStart,
|
||||
&loc, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static int is_metadata_sym(const char* name)
|
||||
{
|
||||
ULONG len = name ? strlen(name) : 0;
|
||||
return len > 3 && name[0] == '_' && name[1] != '_' && name[len-1] == '_' && name[len-2] == '_';
|
||||
};
|
||||
|
||||
static int use_raw_address(const char* name)
|
||||
{
|
||||
if (!name)
|
||||
return 0;
|
||||
|
||||
if (!strcmp(name, "__ImageBase"))
|
||||
return 1;
|
||||
|
||||
if (!strcmp(name, "__RUNTIME_PSEUDO_RELOC_LIST__"))
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
BOOL rsym_parse(struct module* module, unsigned long load_offset,
|
||||
const void* rsym_ptr, int rsymlen)
|
||||
{
|
||||
const ROSSYM_HEADER* RosSymHeader;
|
||||
const ROSSYM_ENTRY* First, *Last, *Entry;
|
||||
const CHAR* Strings;
|
||||
|
||||
struct pool pool;
|
||||
struct sparse_array file_table, func_table;
|
||||
rsym_func_entry_t* first_func = NULL;
|
||||
|
||||
|
||||
RosSymHeader = rsym_ptr;
|
||||
|
||||
if (RosSymHeader->SymbolsOffset < sizeof(ROSSYM_HEADER)
|
||||
|| RosSymHeader->StringsOffset < RosSymHeader->SymbolsOffset + RosSymHeader->SymbolsLength
|
||||
|| rsymlen < RosSymHeader->StringsOffset + RosSymHeader->StringsLength
|
||||
|| 0 != (RosSymHeader->SymbolsLength % sizeof(ROSSYM_ENTRY)))
|
||||
{
|
||||
WARN("Invalid ROSSYM_HEADER\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
First = (const ROSSYM_ENTRY *)((const char*)rsym_ptr + RosSymHeader->SymbolsOffset);
|
||||
Last = First + RosSymHeader->SymbolsLength / sizeof(ROSSYM_ENTRY);
|
||||
Strings = (const CHAR*)rsym_ptr + RosSymHeader->StringsOffset;
|
||||
|
||||
pool_init(&pool, 65536);
|
||||
sparse_array_init(&file_table, sizeof(rsym_file_entry_t), 64);
|
||||
sparse_array_init(&func_table, sizeof(rsym_func_entry_t), 128);
|
||||
|
||||
for (Entry = First; Entry != Last; Entry++)
|
||||
{
|
||||
ULONG Address = load_offset + Entry->Address;
|
||||
if (!Entry->FileOffset)
|
||||
{
|
||||
rsym_func_entry_t* func = sparse_array_find(&func_table, Entry->FunctionOffset);
|
||||
|
||||
/* We do not want to define a data point where there is already a function! */
|
||||
if (!func || func->Address != Address)
|
||||
{
|
||||
const char* SymbolName = Strings + Entry->FunctionOffset;
|
||||
if (!is_metadata_sym(SymbolName))
|
||||
{
|
||||
/* TODO: How should we determine the size? */
|
||||
ULONG Size = sizeof(ULONG);
|
||||
if (use_raw_address(SymbolName))
|
||||
Address = Entry->Address;
|
||||
|
||||
symt_new_public(module, NULL, SymbolName, Address, Size);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Maybe use it to fill some metadata? */
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
rsym_file_entry_t* file = sparse_array_find(&file_table, Entry->FileOffset);
|
||||
rsym_func_entry_t* func = sparse_array_find(&func_table, Entry->FunctionOffset);
|
||||
|
||||
if (!file)
|
||||
{
|
||||
file = sparse_array_add(&file_table, Entry->FileOffset, &pool);
|
||||
file->File = Strings + Entry->FileOffset;
|
||||
file->Source = source_new(module, NULL, Strings + Entry->FileOffset);
|
||||
}
|
||||
|
||||
if (!func)
|
||||
{
|
||||
func = sparse_array_add(&func_table, Entry->FunctionOffset, &pool);
|
||||
func->func = symt_new_function(module, NULL, Strings + Entry->FunctionOffset,
|
||||
Address, 0, NULL);
|
||||
func->Address = Address;
|
||||
func->next = first_func;
|
||||
first_func = func;
|
||||
}
|
||||
|
||||
/* TODO: What if we have multiple chunks scattered around? */
|
||||
symt_add_func_line(module, func->func, file->Source, Entry->SourceLine, Address - func->Address);
|
||||
}
|
||||
}
|
||||
|
||||
while (first_func)
|
||||
{
|
||||
/* TODO: Size of function? */
|
||||
rsym_finalize_function(module, first_func->func);
|
||||
first_func = first_func->next;
|
||||
}
|
||||
|
||||
module->module.SymType = SymDia;
|
||||
module->module.CVSig = 'R' | ('S' << 8) | ('Y' << 16) | ('M' << 24);
|
||||
module->module.LineNumbers = TRUE;
|
||||
module->module.GlobalSymbols = TRUE;
|
||||
module->module.TypeInfo = FALSE;
|
||||
module->module.SourceIndexed = TRUE;
|
||||
module->module.Publics = TRUE;
|
||||
|
||||
pool_destroy(&pool);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
Loading…
Reference in a new issue