static void debug_translateAddress(const char *symbol, bfd_vma address) { const char *file, *func; unsigned int line; asection *section; for (section = abfd->sections; section != NULL; section = section->next) { if ((bfd_get_section_flags(abfd, section) & SEC_ALLOC) == 0) continue; bfd_vma vma = bfd_get_section_vma(abfd, section); bfd_size_type size = bfd_get_section_size(section); if (address < vma || address >= vma + size) continue; if (!bfd_find_nearest_line(abfd, section, syms, address - vma, &file, &func, &line)) continue; do { if (func == NULL || func[0] == '\0') func = "??"; if (file == NULL || file[0] == '\0') file = "??"; DEBUG("%s %s(...):%u %s", symbol, func, line, file); } while (bfd_find_inliner_info(abfd, &file, &func, &line)); return; } DEBUG("%s %s(...):%u %s", symbol, "??", 0, "??"); }
static int addr2line(const char *dso_name, u64 addr, char **file, unsigned int *line, struct dso *dso, bool unwind_inlines, struct inline_node *node, struct symbol *sym) { int ret = 0; struct a2l_data *a2l = dso->a2l; if (!a2l) { dso->a2l = addr2line_init(dso_name); a2l = dso->a2l; } if (a2l == NULL) { pr_warning("addr2line_init failed for %s\n", dso_name); return 0; } a2l->addr = addr; a2l->found = false; bfd_map_over_sections(a2l->abfd, find_address_in_section, a2l); if (!a2l->found) return 0; if (unwind_inlines) { int cnt = 0; if (node && inline_list__append_dso_a2l(dso, node, sym)) return 0; while (bfd_find_inliner_info(a2l->abfd, &a2l->filename, &a2l->funcname, &a2l->line) && cnt++ < MAX_INLINE_NEST) { if (a2l->filename && !strlen(a2l->filename)) a2l->filename = NULL; if (node != NULL) { if (inline_list__append_dso_a2l(dso, node, sym)) return 0; // found at least one inline frame ret = 1; } } } if (file) { *file = a2l->filename ? strdup(a2l->filename) : NULL; ret = *file ? 1 : 0; } if (line) *line = a2l->line; return ret; }
static void process_section(bfd *bfdobj, asection *section, void *obj) { struct bfd_data *data = obj; const char *file, *func; unsigned int line; bfd_vma offset; bfd_vma vma; bfd_size_type size; bfd_boolean line_found = 0; char *fn; int inlined = 0; offset = data->pc - (data->dynamic ? (bfd_vma)(uintptr_t) data->dli.dli_fbase : 0); if (!(bfd_get_section_flags(bfdobj, section) & SEC_ALLOC)) { return; } vma = bfd_get_section_vma(bfdobj, section); size = bfd_get_section_size(section); if (offset < vma || offset >= vma + size) { /* Not in this section */ return; } line_found = bfd_find_nearest_line(bfdobj, section, data->syms, offset - vma, &file, &func, &line); if (!line_found) { return; } /* * If we find a line, we will want to continue calling bfd_find_inliner_info * to capture any inlined functions that don't have their own stack frames. */ do { data->found++; /* file can possibly be null even with a success result from bfd_find_nearest_line */ file = file ? file : ""; fn = strrchr(file, '/'); #define FMT_INLINED "[%s] %s %s:%u %s()" #define FMT_NOT_INLINED "[%p] %s %s:%u %s()" snprintf(data->msg, MSG_BUFF_LEN, inlined ? FMT_INLINED : FMT_NOT_INLINED, inlined ? "inlined" : (char *)(uintptr_t) data->pc, data->libname, fn ? fn + 1 : file, line, S_OR(func, "???")); if (AST_VECTOR_APPEND(data->return_strings, strdup(data->msg))) { return; } inlined++; /* Let's see if there are any inlined functions */ } while (bfd_find_inliner_info(bfdobj, &file, &func, &line)); }
static void find_address_in_section(bfd *abfd, asection *section, void *data) { addr2line_data *adata = reinterpret_cast<addr2line_data*>(data); bfd_vma vma; bfd_size_type size; if (adata->found) { return; } if ((bfd_get_section_flags(abfd, section) & SEC_ALLOC) == 0) { return; } vma = bfd_get_section_vma(abfd, section); if (adata->pc < vma) { return; } size = bfd_get_section_size(section); if (adata->pc >= vma + size) { return; } // libdwarf allocates its own unaligned memory so it doesn't play well with // valgrind #ifndef VALGRIND adata->found = bfd_find_nearest_line(abfd, section, adata->syms, adata->pc - vma, &adata->filename, &adata->functionname, &adata->line); #endif if (adata->found) { const char *file = adata->filename; unsigned int line = adata->line; bfd_boolean found = TRUE; while (found) { found = bfd_find_inliner_info(abfd, &file, &adata->functionname, &line); } } }
static void wpa_trace_bfd_addr(void *pc) { bfd *abfd = cached_abfd; struct bfd_data data; const char *name; char *aname = NULL; const char *filename; if (abfd == NULL) return; data.pc = (bfd_vma) pc; data.found = FALSE; bfd_map_over_sections(abfd, find_addr_sect, &data); if (!data.found) return; do { if (data.function) aname = bfd_demangle(abfd, data.function, DMGL_ANSI | DMGL_PARAMS); name = aname ? aname : data.function; filename = data.filename; if (filename) { char *end = os_strrchr(filename, '/'); int i = 0; while (*filename && *filename == prg_fname[i] && filename <= end) { filename++; i++; } } wpa_printf(MSG_INFO, " %s() %s:%u", name, filename, data.line); free(aname); data.found = bfd_find_inliner_info(abfd, &data.filename, &data.function, &data.line); } while (data.found); }
static void find_address_in_section(bfd *abfd, asection *section, void *data) { addr2line_data *adata = reinterpret_cast<addr2line_data*>(data); bfd_vma vma; bfd_size_type size; if (adata->found) { return; } if ((bfd_get_section_flags(abfd, section) & SEC_ALLOC) == 0) { return; } vma = bfd_get_section_vma(abfd, section); if (adata->pc < vma) { return; } size = bfd_get_section_size(section); if (adata->pc >= vma + size) { return; } adata->found = bfd_find_nearest_line(abfd, section, adata->syms, adata->pc - vma, &adata->filename, &adata->functionname, &adata->line); if (adata->found) { const char *file = adata->filename; unsigned int line = adata->line; bfd_boolean found = TRUE; while (found) { found = bfd_find_inliner_info(abfd, &file, &adata->functionname, &line); } } }