Index: contrib/elftoolchain/addr2line/addr2line.c =================================================================== --- contrib/elftoolchain/addr2line/addr2line.c +++ contrib/elftoolchain/addr2line/addr2line.c @@ -84,6 +84,8 @@ static char unknown[] = { '?', '?', '\0' }; static Dwarf_Addr section_base; static struct CU *culist; +static Dwarf_Unsigned locache, hicache; +static Dwarf_Die last_die = NULL; #define USAGE_MESSAGE "\ Usage: %s [options] hexaddress...\n\ @@ -403,8 +405,21 @@ cu = NULL; die = NULL; - while ((ret = dwarf_next_cu_header(dbg, NULL, NULL, NULL, NULL, NULL, - &de)) == DW_DLV_OK) { + + if (addr >= locache && addr < hicache && die != NULL) { + die = last_die; + goto status_ok; + } else if (last_die != NULL) { + goto next_cu; + } + + while (true) { + ret = dwarf_next_cu_header(dbg, NULL, NULL, NULL, NULL, NULL, + &de); + if (ret == DW_DLV_NO_ENTRY) { + ret = dwarf_next_cu_header(dbg, NULL, NULL, NULL, NULL, NULL, + &de); + } die = NULL; while (dwarf_siblingof(dbg, die, &ret_die, &de) == DW_DLV_OK) { if (die != NULL) @@ -420,12 +435,16 @@ if (tag == DW_TAG_compile_unit) break; } + if (ret_die == NULL) { warnx("could not find DW_TAG_compile_unit die"); goto next_cu; } if (dwarf_attrval_unsigned(die, DW_AT_low_pc, &lopc, &de) == DW_DLV_OK) { + if (lopc == locache) { + goto out; + } if (dwarf_attrval_unsigned(die, DW_AT_high_pc, &hipc, &de) == DW_DLV_OK) { /* @@ -465,7 +484,7 @@ } next_cu: - if (die != NULL) { + if (die != NULL && die != last_die) { dwarf_dealloc(dbg, die, DW_DLA_DIE); die = NULL; } @@ -474,6 +493,16 @@ if (ret != DW_DLV_OK || die == NULL) goto out; + locache = lopc; + hicache = hipc; + if (last_die != NULL) { + dwarf_dealloc(dbg, last_die, DW_DLA_DIE); + last_die = NULL; + } + last_die = die; + +status_ok: + switch (dwarf_srclines(die, &lbuf, &lcount, &de)) { case DW_DLV_OK: break; @@ -573,20 +602,8 @@ print_inlines(cu, f->inlined_caller, f->call_file, f->call_line); - if (die != NULL) + if (die != NULL && (die != last_die)) dwarf_dealloc(dbg, die, DW_DLA_DIE); - - /* - * Reset internal CU pointer, so we will start from the first CU - * next round. - */ - while (ret != DW_DLV_NO_ENTRY) { - if (ret == DW_DLV_ERROR) - errx(EXIT_FAILURE, "dwarf_next_cu_header: %s", - dwarf_errmsg(de)); - ret = dwarf_next_cu_header(dbg, NULL, NULL, NULL, NULL, NULL, - &de); - } } static void