Author: mjansen
Date: Fri Feb 17 16:18:15 2017
New Revision: 73817
URL:
http://svn.reactos.org/svn/reactos?rev=73817&view=rev
Log:
[DBGHELP] Add experimental rsym support. CORE-12773
Added:
trunk/reactos/dll/win32/dbghelp/rsym.c (with props)
Modified:
trunk/reactos/dll/win32/dbghelp/CMakeLists.txt
trunk/reactos/dll/win32/dbghelp/dbghelp_private.h
trunk/reactos/dll/win32/dbghelp/pe_module.c
Modified: trunk/reactos/dll/win32/dbghelp/CMakeLists.txt
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/dbghelp/CMakeLis…
==============================================================================
--- trunk/reactos/dll/win32/dbghelp/CMakeLists.txt [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/dbghelp/CMakeLists.txt [iso-8859-1] Fri Feb 17 16:18:15 2017
@@ -63,6 +63,7 @@
path.c
pe_module.c
rosstubs.c
+ rsym.c
source.c
stabs.c
stack.c
Modified: trunk/reactos/dll/win32/dbghelp/dbghelp_private.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/dbghelp/dbghelp_…
==============================================================================
--- trunk/reactos/dll/win32/dbghelp/dbghelp_private.h [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/dbghelp/dbghelp_private.h [iso-8859-1] Fri Feb 17 16:18:15
2017
@@ -713,6 +713,12 @@
struct image_file_map* fmap) DECLSPEC_HIDDEN;
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
Modified: trunk/reactos/dll/win32/dbghelp/pe_module.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/dbghelp/pe_modul…
==============================================================================
--- trunk/reactos/dll/win32/dbghelp/pe_module.c [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/dbghelp/pe_module.c [iso-8859-1] Fri Feb 17 16:18:15 2017
@@ -507,6 +507,32 @@
#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
*
* loads a .dbg file
@@ -704,7 +730,9 @@
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,
Added: trunk/reactos/dll/win32/dbghelp/rsym.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/dbghelp/rsym.c?r…
==============================================================================
--- trunk/reactos/dll/win32/dbghelp/rsym.c (added)
+++ trunk/reactos/dll/win32/dbghelp/rsym.c [iso-8859-1] Fri Feb 17 16:18:15 2017
@@ -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;
+}
+
Propchange: trunk/reactos/dll/win32/dbghelp/rsym.c
------------------------------------------------------------------------------
svn:eol-style = native