summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPeder Andersen2012-03-08 19:08:38 (EST)
committer Eugene Tarassov2012-03-12 13:53:00 (EDT)
commitbca72ff48dbcbc597d5d00cf72c9ce6c391a49dc (patch)
tree0148f399275369f90fdf07b381a3d1ed8d5a048d
parent283d960758ffb3b542a99f6ab6d175c3039fab99 (diff)
downloadorg.eclipse.tcf.agent-bca72ff48dbcbc597d5d00cf72c9ce6c391a49dc.zip
org.eclipse.tcf.agent-bca72ff48dbcbc597d5d00cf72c9ce6c391a49dc.tar.gz
org.eclipse.tcf.agent-bca72ff48dbcbc597d5d00cf72c9ce6c391a49dc.tar.bz2
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 4b12991..fbf5915 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) {