summaryrefslogtreecommitdiff
path: root/addr2line.c
diff options
context:
space:
mode:
authornaruse <naruse@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2014-03-31 22:39:07 (GMT)
committernaruse <naruse@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2014-03-31 22:39:07 (GMT)
commitf265ce708d975d32db295fc85c7e92d89c7f6d20 (patch)
tree4b23a1e51636dba9c648083638d6af75403ffea4 /addr2line.c
parente1952036a44449b6557d820b08a4f299e8f5c631 (diff)
* addr2line.c (fill_lines): use dynsym, which is used for dynamic
linking and always exists, if there's no symtab. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@45491 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'addr2line.c')
-rw-r--r--addr2line.c16
1 files changed, 14 insertions, 2 deletions
diff --git a/addr2line.c b/addr2line.c
index 71cec4c..1094b60 100644
--- a/addr2line.c
+++ b/addr2line.c
@@ -464,8 +464,8 @@ fill_lines(int num_traces, void **traces, int check_debuglink,
int fd;
off_t filesize;
char *file;
- ElfW(Shdr) *symtab_shdr = NULL;
- ElfW(Shdr) *strtab_shdr = NULL;
+ ElfW(Shdr) *symtab_shdr = NULL, *strtab_shdr = NULL;
+ ElfW(Shdr) *dynsym_shdr = NULL, *dynstr_shdr = NULL;
fd = open(binary_filename, O_RDONLY);
if (fd < 0) {
@@ -532,11 +532,18 @@ fill_lines(int num_traces, void **traces, int check_debuglink,
if (!strcmp(section_name, ".strtab")) {
strtab_shdr = shdr + i;
}
+ else if (!strcmp(section_name, ".dynstr")) {
+ dynstr_shdr = shdr + i;
+ }
break;
case SHT_SYMTAB:
/* if (!strcmp(section_name, ".symtab")) */
symtab_shdr = shdr + i;
break;
+ case SHT_DYNSYM:
+ /* if (!strcmp(section_name, ".dynsym")) */
+ dynsym_shdr = shdr + i;
+ break;
case SHT_PROGBITS:
if (!strcmp(section_name, ".debug_line")) {
debug_line_shdr = shdr + i;
@@ -548,6 +555,11 @@ fill_lines(int num_traces, void **traces, int check_debuglink,
}
}
+ if (!symtab_shdr) {
+ symtab_shdr = dynsym_shdr;
+ strtab_shdr = dynstr_shdr;
+ }
+
if (symtab_shdr && strtab_shdr) {
char *strtab = file + strtab_shdr->sh_offset;
ElfW(Sym) *symtab = (ElfW(Sym) *)(file + symtab_shdr->sh_offset);