From d3853d7c10c1879f674311a493d4643012697870 Mon Sep 17 00:00:00 2001 From: naruse Date: Thu, 11 Oct 2018 23:55:47 +0000 Subject: Support FreeBSD git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@65013 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- addr2line.c | 104 +++++++++++++++++++++++++++++++----------------------------- 1 file changed, 54 insertions(+), 50 deletions(-) (limited to 'addr2line.c') diff --git a/addr2line.c b/addr2line.c index 15a8a76468..53304021a2 100644 --- a/addr2line.c +++ b/addr2line.c @@ -1230,7 +1230,6 @@ di_skip_records(DebugInfoReader *reader) { } typedef struct { - char *debug_ranges; uint64_t low_pc; uint64_t high_pc; uint64_t ranges; @@ -1257,14 +1256,14 @@ ranges_set_ranges(ranges_t *ptr, uint64_t ranges) { ptr->ranges_set = true; } -static bool +static uintptr_t ranges_include(DebugInfoReader *reader, ranges_t *ptr, uint64_t addr) { if (ptr->high_pc_set) { if (ptr->ranges_set || !ptr->low_pc_set) { exit(1); } if (ptr->low_pc <= addr && addr <= ptr->low_pc + ptr->high_pc) { - return true; + return ptr->low_pc; } } else if (ptr->ranges_set) { @@ -1274,13 +1273,13 @@ ranges_include(DebugInfoReader *reader, ranges_t *ptr, uint64_t addr) { uint64_t to = read_uint64(&p); if (!from && !to) break; if (from <= addr && addr <= to) { - return true; + return from; } } } else if (ptr->low_pc_set) { if (ptr->low_pc == addr) { - return true; + return ptr->low_pc; } } return false; @@ -1288,7 +1287,7 @@ ranges_include(DebugInfoReader *reader, ranges_t *ptr, uint64_t addr) { #if 0 static void -ranges_inspect(ranges_t *ptr) { +ranges_inspect(DebugInfoReader *reader, ranges_t *ptr) { if (ptr->high_pc_set) { if (ptr->ranges_set || !ptr->low_pc_set) { fprintf(stderr,"low_pc_set:%d high_pc_set:%d ranges_set:%d\n",ptr->low_pc_set,ptr->high_pc_set,ptr->ranges_set); @@ -1298,13 +1297,15 @@ ranges_inspect(ranges_t *ptr) { } else if (ptr->ranges_set) { char *p; - fprintf(stderr,"low_pc:%lx ranges:%lx\n",ptr->low_pc,ptr->ranges); - p = ptr->debug_ranges + ptr->ranges; + fprintf(stderr,"low_pc:%lx ranges:%lx ",ptr->low_pc,ptr->ranges); + p = reader->obj->debug_ranges.ptr + ptr->ranges; for (;;) { uint64_t from = read_uint64(&p); uint64_t to = read_uint64(&p); if (!from && !to) break; + fprintf(stderr,"%lx-%lx ",ptr->low_pc+from,ptr->low_pc+to); } + fprintf(stderr,"\n"); } else if (ptr->low_pc_set) { fprintf(stderr,"low_pc:%lx\n",ptr->low_pc); @@ -1395,12 +1396,14 @@ debug_info_read(DebugInfoReader *reader, int num_traces, void **traces, break; } } + /* ranges_inspect(reader, &ranges); */ /* fprintf(stderr,"%d:%tx: %x ",__LINE__,diepos,die.tag); */ for (int i=offset; i < num_traces; i++) { uintptr_t addr = (uintptr_t)traces[i]; uintptr_t offset = addr - reader->obj->base_addr; - if (ranges_include(reader, &ranges, offset)) { - //fprintf(stderr, "%d:%tx: %lx->%lx %x %s: %s/%s %d %s\n",__LINE__,die.pos, addr,offset, die.tag,line.sname,line.dirname,line.filename,line.line,reader->obj->path); + uintptr_t saddr; + if (saddr = ranges_include(reader, &ranges, offset)) { + fprintf(stderr, "%d:%tx: %d %lx->%lx %x %s: %s/%s %d %s %s %s\n",__LINE__,die.pos, i,addr,offset, die.tag,line.sname,line.dirname,line.filename,line.line,reader->obj->path,line.sname,lines[i].sname); if (lines[i].sname) { line_info_t *lp = malloc(sizeof(line_info_t)); memcpy(lp, &lines[i], sizeof(line_info_t)); @@ -1413,7 +1416,7 @@ debug_info_read(DebugInfoReader *reader, int num_traces, void **traces, lines[i].path = reader->obj->path; lines[i].base_addr = line.base_addr; lines[i].sname = line.sname; - lines[i].saddr = reader->obj->base_addr + ranges.low_pc; + lines[i].saddr = reader->obj->base_addr + saddr; } } } while (reader->level > 0); @@ -1622,17 +1625,6 @@ fill_lines(int num_traces, void **traces, int check_debuglink, } } - if (!obj->debug_line.shdr) { - /* This file doesn't have .debug_line section, - let's check .gnu_debuglink section instead. */ - if (gnu_debuglink_shdr && check_debuglink) { - follow_debuglink(file + gnu_debuglink_shdr->sh_offset, - num_traces, traces, - objp, lines, offset); - } - goto finish; - } - if (obj->debug_info.ptr && obj->debug_abbrev.ptr) { DebugInfoReader reader; debug_info_reader_init(&reader, obj); @@ -1643,6 +1635,46 @@ fill_lines(int num_traces, void **traces, int check_debuglink, debug_info_read(&reader, num_traces, traces, lines, offset); } } + else { + /* This file doesn't have dwarf, use symtab or dynsym */ + if (!symtab_shdr) { + /* This file doesn't have symtab, use dynsym instead */ + 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); + int symtab_count = (int)(symtab_shdr->sh_size / sizeof(ElfW(Sym))); + for (j = 0; j < symtab_count; j++) { + ElfW(Sym) *sym = &symtab[j]; + uintptr_t saddr = (uintptr_t)sym->st_value + obj->base_addr; + if (ELF_ST_TYPE(sym->st_info) != STT_FUNC || sym->st_size <= 0) continue; + for (i = offset; i < num_traces; i++) { + uintptr_t d = (uintptr_t)traces[i] - saddr; + if (lines[i].line > 0 || d <= 0 || d > (uintptr_t)sym->st_size) + continue; + /* fill symbol name and addr from .symtab */ + if (!lines[i].sname) lines[i].sname = strtab + sym->st_name; + lines[i].saddr = saddr; + lines[i].path = obj->path; + lines[i].base_addr = obj->base_addr; + } + } + } + } + + if (!obj->debug_line.shdr) { + /* This file doesn't have .debug_line section, + let's check .gnu_debuglink section instead. */ + if (gnu_debuglink_shdr && check_debuglink) { + follow_debuglink(file + gnu_debuglink_shdr->sh_offset, + num_traces, traces, + objp, lines, offset); + } + goto finish; + } if (parse_debug_line(num_traces, traces, obj->debug_line.ptr, @@ -1650,34 +1682,6 @@ fill_lines(int num_traces, void **traces, int check_debuglink, obj, lines, offset) == -1) goto fail; - /* This file doesn't have symtab, use dynsym instead */ - if (!symtab_shdr) { - symtab_shdr = dynsym_shdr; - strtab_shdr = dynstr_shdr; - } - - /* This file doesn't have dwarf, use symtab */ - if (symtab_shdr && strtab_shdr) { - char *strtab = file + strtab_shdr->sh_offset; - ElfW(Sym) *symtab = (ElfW(Sym) *)(file + symtab_shdr->sh_offset); - int symtab_count = (int)(symtab_shdr->sh_size / sizeof(ElfW(Sym))); - for (j = 0; j < symtab_count; j++) { - ElfW(Sym) *sym = &symtab[j]; - uintptr_t saddr = (uintptr_t)sym->st_value + obj->base_addr; - if (ELF_ST_TYPE(sym->st_info) != STT_FUNC || sym->st_size <= 0) continue; - for (i = offset; i < num_traces; i++) { - uintptr_t d = (uintptr_t)traces[i] - saddr; - if (lines[i].line > 0 || d <= 0 || d > (uintptr_t)sym->st_size) - continue; - /* fill symbol name and addr from .symtab */ - if (!lines[i].sname) lines[i].sname = strtab + sym->st_name; - lines[i].saddr = saddr; - lines[i].path = obj->path; - lines[i].base_addr = obj->base_addr; - } - } - } - finish: return dladdr_fbase; fail: -- cgit v1.2.3