diff options
author | Mark Wielaard <mjw@redhat.com> | 2013-01-16 15:19:32 +0100 |
---|---|---|
committer | Mark Wielaard <mjw@redhat.com> | 2013-01-22 16:09:18 +0100 |
commit | 5083a70d3b64946fa47ea5766943a15a3ecc6891 (patch) | |
tree | f819878e1fade1faf29ac7c9fe0288df529760ec /libdwfl/libdwflP.h | |
parent | 6d258ceb8dbf41e255397ed0db7d7635f398134c (diff) | |
download | elfutils-5083a70d3b64946fa47ea5766943a15a3ecc6891.tar.gz |
libdwfl: Add minisymtab support.
Add an auxiliary symbol table dwfl_file aux_sym to Dwfl_Module if all we
have is the dynsym table. The main file might contain a .gnu_debugdata
section. The .gnu_debugdata section is a compressed embedded ELF file
that contains the text (code) section symbols from the symtab table
that are not in the main file dynsym table. dwfl_module_getsymtab (),
dwfl_module_addrsym () and dwfl_module_getsym () will use the auxiliary
symbol table when available (and no full symtab is available from the
debug file).
* libdwflP.h (struct Dwfl_Module): Add aux_sym, aux_symdata,
aux_syments, aux_symstrdata, aux_symxndxdata and aux_first_global.
(dwfl_adjusted_aux_sym_addr): New function.
(dwfl_deadjust_aux_sym_addr): Likewise.
(dwfl_adjusted_st_value): Take and check symfile argument.
(dwfl_deadjust_st_value): Likewise.
* dwfl_module_getdwarf.c (find_prelink_address_sync): Take and
use dwfl_file as argument to set address_sync.
(find_debuginfo): Call find_prelink_address_sync with debug file.
(find_aux_sym): New function.
(find_symtab): Use find_aux_sym if all we have is the dynsym table
and fill in aux DwflModule fields.
(dwfl_module_getsymtab): Return syments plus aux_syments.
(load_symtab): Always set first_global.
* dwfl_module_addrsym.c (dwfl_module_addrsym): Check symfile
when using same_section. Calculate first_global based on both
mod->first_global and mod->aux_first_global.
* dwfl_module.c (__libdwfl_module_free): Free aux_sym.
* dwfl_module_getsym.c (dwfl_module_getsym): Use auxsym table
to retrieve symbol and name if necessary, making sure all locals
from any table come before any globals.
* dwfl_module_info.c (dwfl_module_info): Call dwfl_adjusted_st_value
with symfile.
* relocate.c (resolve_symbol): Likewise.
https://fedoraproject.org/wiki/Features/MiniDebugInfo
Signed-off-by: Mark Wielaard <mjw@redhat.com>
Diffstat (limited to 'libdwfl/libdwflP.h')
-rw-r--r-- | libdwfl/libdwflP.h | 41 |
1 files changed, 34 insertions, 7 deletions
diff --git a/libdwfl/libdwflP.h b/libdwfl/libdwflP.h index 806ebcd9..5aaa7785 100644 --- a/libdwfl/libdwflP.h +++ b/libdwfl/libdwflP.h @@ -142,7 +142,7 @@ struct Dwfl_Module char *name; /* Iterator name for this module. */ GElf_Addr low_addr, high_addr; - struct dwfl_file main, debug; + struct dwfl_file main, debug, aux_sym; GElf_Addr main_bias; Ebl *ebl; GElf_Half e_type; /* GElf_Ehdr.e_type cache. */ @@ -152,10 +152,15 @@ struct Dwfl_Module struct dwfl_file *symfile; /* Either main or debug. */ Elf_Data *symdata; /* Data in the ELF symbol table section. */ + Elf_Data *aux_symdata; /* Data in the auxiliary ELF symbol table. */ size_t syments; /* sh_size / sh_entsize of that section. */ + size_t aux_syments; /* sh_size / sh_entsize of aux_sym section. */ int first_global; /* Index of first global symbol of table. */ + int aux_first_global; /* Index of first global of aux_sym table. */ Elf_Data *symstrdata; /* Data for its string table. */ + Elf_Data *aux_symstrdata; /* Data for aux_sym string table. */ Elf_Data *symxndxdata; /* Data in the extended section index table. */ + Elf_Data *aux_symxndxdata; /* Data in the extended auxiliary table. */ Dwarf *dw; /* libdw handle for its debugging info. */ @@ -255,20 +260,42 @@ dwfl_deadjust_dwarf_addr (Dwfl_Module *mod, Dwarf_Addr addr) + mod->debug.address_sync); } +static inline Dwarf_Addr +dwfl_adjusted_aux_sym_addr (Dwfl_Module *mod, Dwarf_Addr addr) +{ + return dwfl_adjusted_address (mod, (addr + - mod->aux_sym.address_sync + + mod->main.address_sync)); +} + +static inline Dwarf_Addr +dwfl_deadjust_aux_sym_addr (Dwfl_Module *mod, Dwarf_Addr addr) +{ + return (dwfl_deadjust_address (mod, addr) + - mod->main.address_sync + + mod->aux_sym.address_sync); +} + static inline GElf_Addr -dwfl_adjusted_st_value (Dwfl_Module *mod, GElf_Addr addr) +dwfl_adjusted_st_value (Dwfl_Module *mod, struct dwfl_file *symfile, + GElf_Addr addr) { - if (mod->symfile == &mod->main) + if (symfile == &mod->main) return dwfl_adjusted_address (mod, addr); - return dwfl_adjusted_dwarf_addr (mod, addr); + if (symfile == &mod->debug) + return dwfl_adjusted_dwarf_addr (mod, addr); + return dwfl_adjusted_aux_sym_addr (mod, addr); } static inline GElf_Addr -dwfl_deadjust_st_value (Dwfl_Module *mod, GElf_Addr addr) +dwfl_deadjust_st_value (Dwfl_Module *mod, struct dwfl_file *symfile, + GElf_Addr addr) { - if (mod->symfile == &mod->main) + if (symfile == &mod->main) return dwfl_deadjust_address (mod, addr); - return dwfl_deadjust_dwarf_addr (mod, addr); + if (symfile == &mod->debug) + return dwfl_deadjust_dwarf_addr (mod, addr); + return dwfl_deadjust_aux_sym_addr (mod, addr); } /* This describes a contiguous address range that lies in a single CU. |