Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPeder Andersen2012-03-09 00:08:38 +0000
committerEugene Tarassov2012-03-12 17:53:00 +0000
commitbca72ff48dbcbc597d5d00cf72c9ce6c391a49dc (patch)
tree0148f399275369f90fdf07b381a3d1ed8d5a048d
parent283d960758ffb3b542a99f6ab6d175c3039fab99 (diff)
downloadorg.eclipse.tcf.agent-bca72ff48dbcbc597d5d00cf72c9ce6c391a49dc.tar.gz
org.eclipse.tcf.agent-bca72ff48dbcbc597d5d00cf72c9ce6c391a49dc.tar.xz
org.eclipse.tcf.agent-bca72ff48dbcbc597d5d00cf72c9ce6c391a49dc.zip
ELF parser: use dynamic symbol table as a fallback
Shared libraries will often have their regular symbol tables stripped, while retaining their dynamic symbol table for the purposes of runtime linking. If no symbol table is found, this change allows TCF clients to use the object's dynamic symbol table for lookup. Note that in the case where an object has both static and dynamic symbol tables, the dynamic entries aren't added to the object's symbol list because they would simply duplicate existing static entries.
-rw-r--r--agent/tcf/services/tcf_elf.c28
1 files changed, 26 insertions, 2 deletions
diff --git a/agent/tcf/services/tcf_elf.c b/agent/tcf/services/tcf_elf.c
index 4b129914..fbf5915d 100644
--- a/agent/tcf/services/tcf_elf.c
+++ b/agent/tcf/services/tcf_elf.c
@@ -380,6 +380,9 @@ static ELF_File * create_elf_cache(const char * file_name) {
if (error == 0) {
Elf32_Ehdr hdr;
+ int symtab_found;
+ ELF_Section * dynsym_section;
+
memset(&hdr, 0, sizeof(hdr));
if (read(file->fd, (char *)&hdr, sizeof(hdr)) < 0) error = errno;
if (error == 0 && strncmp((char *)hdr.e_ident, ELFMAG, SELFMAG) != 0) {
@@ -397,6 +400,9 @@ static ELF_File * create_elf_cache(const char * file_name) {
}
file->byte_swap = file->big_endian != big_endian_host();
}
+
+ symtab_found = 0;
+ dynsym_section = NULL;
if (error != 0) {
/* Nothing */
}
@@ -466,7 +472,14 @@ static ELF_File * create_elf_cache(const char * file_name) {
sec->link = shdr.sh_link;
sec->info = shdr.sh_info;
sec->entsize = shdr.sh_entsize;
- if (sec->type == SHT_SYMTAB) sec->sym_count = (unsigned)(sec->size / sizeof(Elf32_Sym));
+ if (sec->type == SHT_SYMTAB) {
+ sec->sym_count = (unsigned int)(sec->size / sizeof(Elf32_Sym));
+ symtab_found = 1;
+ } else if (sec->type == SHT_DYNSYM) {
+ assert(dynsym_section == NULL);
+ sec->sym_count = (unsigned int)(sec->size / sizeof(Elf32_Sym));
+ dynsym_section = sec;
+ }
cnt++;
}
}
@@ -580,7 +593,15 @@ static ELF_File * create_elf_cache(const char * file_name) {
sec->link = shdr.sh_link;
sec->info = shdr.sh_info;
sec->entsize = (U4_T)shdr.sh_entsize;
- if (sec->type == SHT_SYMTAB) sec->sym_count = (unsigned)(sec->size / sizeof(Elf64_Sym));
+ if (sec->type == SHT_SYMTAB) {
+ sec->sym_count = (unsigned)(sec->size / sizeof(Elf64_Sym));
+ symtab_found = 1;
+ } else if (sec->type == SHT_DYNSYM) {
+ assert(dynsym_section == NULL);
+ sec->sym_count = (unsigned int)(sec->size / sizeof(Elf64_Sym));
+ dynsym_section = sec;
+ }
+
cnt++;
}
}
@@ -642,6 +663,9 @@ static ELF_File * create_elf_cache(const char * file_name) {
}
}
}
+
+ if ((dynsym_section != NULL) && (symtab_found == 1))
+ dynsym_section->sym_count = 0;
}
file->debug_info_file = is_debug_info_file(file);
if (error == 0 && !file->debug_info_file) {

Back to the top