From 83f001b6c716bada91d98b46d1463171d58222a7 Mon Sep 17 00:00:00 2001 From: Raphael Junqueira Date: Tue, 17 May 2005 14:32:55 +0000 Subject: [PATCH] Beginning of dbghelp dwarf2 support: - add elf_module entry for dwarf2_parse - stubbed dwarf2_parse in new dwarf.c file --- dlls/dbghelp/Makefile.in | 1 + dlls/dbghelp/dbghelp_private.h | 6 ++ dlls/dbghelp/dwarf.c | 123 +++++++++++++++++++++++++++++++++ dlls/dbghelp/elf_module.c | 42 +++++++++-- 4 files changed, 167 insertions(+), 5 deletions(-) create mode 100644 dlls/dbghelp/dwarf.c diff --git a/dlls/dbghelp/Makefile.in b/dlls/dbghelp/Makefile.in index fc37d627780..14469f1dd44 100644 --- a/dlls/dbghelp/Makefile.in +++ b/dlls/dbghelp/Makefile.in @@ -9,6 +9,7 @@ IMPORTS = psapi kernel32 ntdll C_SRCS = \ coff.c \ dbghelp.c \ + dwarf.c \ elf_module.c \ image.c \ memory.c \ diff --git a/dlls/dbghelp/dbghelp_private.h b/dlls/dbghelp/dbghelp_private.h index 2480fae37be..c114060a872 100644 --- a/dlls/dbghelp/dbghelp_private.h +++ b/dlls/dbghelp/dbghelp_private.h @@ -356,6 +356,12 @@ extern BOOL stabs_parse(struct module* module, unsigned long load_offset const void* stabs, int stablen, const char* strs, int strtablen); +/* dwarf.c */ +extern BOOL dwarf2_parse(struct module* module, unsigned long load_offset, + const unsigned char* debug, unsigned int debug_size, + const unsigned char* abbrev, unsigned int abbrev_size, + const unsigned char* str, unsigned int str_sz); + /* symbol.c */ extern const char* symt_get_name(const struct symt* sym); extern int symt_cmp_addr(const void* p1, const void* p2); diff --git a/dlls/dbghelp/dwarf.c b/dlls/dbghelp/dwarf.c new file mode 100644 index 00000000000..13976b2ffe6 --- /dev/null +++ b/dlls/dbghelp/dwarf.c @@ -0,0 +1,123 @@ +/* + * File dwarf.c - read dwarf2 information from the ELF modules + * + * Copyright (C) 2005, Raphael Junqueira + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "config.h" + +#include +#include +#ifdef HAVE_SYS_STAT_H +# include +#endif +#ifdef HAVE_SYS_MMAN_H +#include +#endif +#include +#include +#include +#ifdef HAVE_UNISTD_H +# include +#endif +#include +#ifndef PATH_MAX +#define PATH_MAX MAX_PATH +#endif +#include +#include + +#include "windef.h" +#include "winbase.h" +#include "winreg.h" +#include "winnls.h" + +#include "dbghelp_private.h" + +#include "wine/debug.h" + +WINE_DEFAULT_DEBUG_CHANNEL(dbghelp_dwarf); + +/** + * + * Main Specs: + * http://www.eagercon.com/dwarf/dwarf3std.htm + * http://www.eagercon.com/dwarf/dwarf-2.0.0.pdf + * + * dwarf2.h: http://www.hakpetzna.com/b/binutils/dwarf2_8h-source.html + * + * example of projects who do dwarf2 parsing: + * http://www.x86-64.org/cgi-bin/cvsweb.cgi/binutils.dead/binutils/readelf.c?rev=1.1.1.2 + * http://elis.ugent.be/diota/log/ltrace_elf.c + */ + +typedef struct dwarf2_parse_context_s { + const unsigned char* data; +} dwarf2_parse_context_t; + +unsigned long dwarf2_leb128_as_unsigned(dwarf2_parse_context_t* ctx) +{ + unsigned long ret = 0; + unsigned char byte; + unsigned shift = 0; + + assert( NULL != ctx ); + + while (1) { + byte = *(ctx->data); + ctx->data++; + ret |= (byte & 0x7f) << shift; + shift += 7; + if (0 == (byte & 0x80)) { break ; } + } + + return ret; +} + +long dwarf2_leb128_as_signed(dwarf2_parse_context_t* ctx) +{ + long ret = 0; + unsigned char byte; + unsigned shift = 0; + const unsigned size = sizeof(int) * 8; + + assert( NULL != ctx ); + + while (1) { + byte = *(ctx->data); + ctx->data++; + ret |= (byte & 0x7f) << shift; + shift += 7; + if (0 == (byte & 0x80)) { break ; } + } + /* as spec: sign bit of byte is 2nd high order bit (80x40) + * -> 0x80 is used as flag. + */ + if ((shift < size) && (byte & 0x40)) { + ret |= - (1 << shift); + } + + return ret; +} + +BOOL dwarf2_parse(struct module* module, unsigned long load_offset, + const unsigned char* debug, unsigned int debug_size, + const unsigned char* abbrev, unsigned int abbrev_size, + const unsigned char* str, unsigned int str_sz) +{ + return FALSE; +} diff --git a/dlls/dbghelp/elf_module.c b/dlls/dbghelp/elf_module.c index a272b0aba1a..ae8ddb1f520 100644 --- a/dlls/dbghelp/elf_module.c +++ b/dlls/dbghelp/elf_module.c @@ -776,7 +776,9 @@ static BOOL elf_load_debug_info_from_map(struct module* module, BOOL ret = FALSE; const char* shstrtab; int i; - int symtab_sect, dynsym_sect, stab_sect, stabstr_sect, debug_sect, debuglink_sect; + int symtab_sect, dynsym_sect, stab_sect, stabstr_sect; + int debug_sect, debug_str_sect, debug_abbrev_sect, debug_line_sect; + int debuglink_sect; struct thunk_area thunks[] = { {"__wine_spec_import_thunks", THUNK_ORDINAL_NOTYPE, 0, 0}, /* inter DLL calls */ @@ -806,8 +808,9 @@ static BOOL elf_load_debug_info_from_map(struct module* module, shstrtab = elf_map_section(fmap, fmap->elfhdr.e_shstrndx); if (shstrtab == NO_MAP) return FALSE; - symtab_sect = dynsym_sect = stab_sect = stabstr_sect = - debug_sect = debuglink_sect = -1; + symtab_sect = dynsym_sect = stab_sect = stabstr_sect = -1; + debug_sect = debug_str_sect = debug_abbrev_sect = debug_line_sect = -1; + debuglink_sect = -1; for (i = 0; i < fmap->elfhdr.e_shnum; i++) { @@ -817,6 +820,12 @@ static BOOL elf_load_debug_info_from_map(struct module* module, stabstr_sect = i; if (strcmp(shstrtab + fmap->sect[i].shdr.sh_name, ".debug_info") == 0) debug_sect = i; + if (strcmp(shstrtab + fmap->sect[i].shdr.sh_name, ".debug_str") == 0) + debug_str_sect = i; + if (strcmp(shstrtab + fmap->sect[i].shdr.sh_name, ".debug_abbrev") == 0) + debug_abbrev_sect = i; + if (strcmp(shstrtab + fmap->sect[i].shdr.sh_name, ".debug_line") == 0) + debug_line_sect = i; if (strcmp(shstrtab + fmap->sect[i].shdr.sh_name, ".gnu_debuglink") == 0) debuglink_sect = i; if ((strcmp(shstrtab + fmap->sect[i].shdr.sh_name, ".symtab") == 0) && @@ -874,8 +883,31 @@ static BOOL elf_load_debug_info_from_map(struct module* module, else if (debug_sect != -1) { /* Dwarf 2 debug information */ - FIXME("Unsupported Dwarf2 information for %s\n", - module->module.ModuleName); + const char* dw2_debug; + const char* dw2_debug_abbrev; + const char* dw2_debug_str; + + FIXME("Alpha-support for Dwarf2 information for %s\n", module->module.ModuleName); + + dw2_debug = elf_map_section(fmap, debug_sect); + dw2_debug_abbrev = elf_map_section(fmap, debug_abbrev_sect); + dw2_debug_str = elf_map_section(fmap, debug_str_sect); + if (dw2_debug != NO_MAP && NO_MAP != dw2_debug_abbrev && dw2_debug_str != NO_MAP) + { + /* OK, now just parse dwarf2 debug infos. */ + ret = dwarf2_parse(module, module->elf_info->elf_addr, + dw2_debug, fmap->sect[debug_sect].shdr.sh_size, + dw2_debug_abbrev, fmap->sect[debug_abbrev_sect].shdr.sh_size, + dw2_debug_str, fmap->sect[debug_str_sect].shdr.sh_size); + } + elf_unmap_section(fmap, debug_sect); + elf_unmap_section(fmap, debug_abbrev_sect); + elf_unmap_section(fmap, debug_str_sect); + if (!ret) + { + WARN("Couldn't correctly read stabs\n"); + return FALSE; + } } else if (debuglink_sect != -1) {