summaryrefslogtreecommitdiff
path: root/libdwfl/libdwflP.h
diff options
context:
space:
mode:
authorMark Wielaard <mjw@redhat.com>2013-01-16 15:19:32 +0100
committerMark Wielaard <mjw@redhat.com>2013-01-22 16:09:18 +0100
commit5083a70d3b64946fa47ea5766943a15a3ecc6891 (patch)
treef819878e1fade1faf29ac7c9fe0288df529760ec /libdwfl/libdwflP.h
parent6d258ceb8dbf41e255397ed0db7d7635f398134c (diff)
downloadelfutils-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.h41
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.