Page MenuHomeFreeBSD

D23501.diff
No OneTemporary

D23501.diff

Index: head/contrib/elftoolchain/addr2line/addr2line.c
===================================================================
--- head/contrib/elftoolchain/addr2line/addr2line.c
+++ head/contrib/elftoolchain/addr2line/addr2line.c
@@ -65,6 +65,7 @@
Dwarf_Signed nsrcfiles;
STAILQ_HEAD(, Func) funclist;
Dwarf_Die die;
+ Dwarf_Debug dbg;
};
static struct option longopts[] = {
@@ -345,7 +346,8 @@
collect_func(dbg, ret_die, parent, cu);
/* Cleanup */
- dwarf_dealloc(dbg, die, DW_DLA_DIE);
+ if (die != cu->die)
+ dwarf_dealloc(dbg, die, DW_DLA_DIE);
if (abst_die != NULL)
dwarf_dealloc(dbg, abst_die, DW_DLA_DIE);
@@ -411,6 +413,102 @@
return (NULL);
}
+/*
+ * Check whether addr falls into range(s) of current CU, and save current CU
+ * to lookup tree if so.
+ */
+static int
+check_range(Dwarf_Debug dbg, Dwarf_Die die, Dwarf_Unsigned addr,
+ struct CU **cu)
+{
+ Dwarf_Error de;
+ Dwarf_Unsigned addr_base, lopc, hipc;
+ Dwarf_Off ranges_off;
+ Dwarf_Signed ranges_cnt;
+ Dwarf_Ranges *ranges;
+ int i, ret;
+ bool in_range;
+
+ addr_base = 0;
+ ranges = NULL;
+ ranges_cnt = 0;
+ in_range = false;
+
+ ret = dwarf_attrval_unsigned(die, DW_AT_ranges, &ranges_off, &de);
+ if (ret == DW_DLV_NO_ENTRY) {
+ if (dwarf_attrval_unsigned(die, DW_AT_low_pc, &lopc, &de) ==
+ DW_DLV_OK) {
+ if (lopc == curlopc)
+ return (DW_DLV_ERROR);
+ if (dwarf_attrval_unsigned(die, DW_AT_high_pc, &hipc,
+ &de) == DW_DLV_OK) {
+ /*
+ * Check if the address falls into the PC
+ * range of this CU.
+ */
+ if (handle_high_pc(die, lopc, &hipc) !=
+ DW_DLV_OK)
+ return (DW_DLV_ERROR);
+ } else {
+ /* Assume ~0ULL if DW_AT_high_pc not present */
+ hipc = ~0ULL;
+ }
+
+ if (addr >= lopc && addr < hipc) {
+ in_range = true;
+ }
+ }
+ } else if (ret == DW_DLV_OK) {
+ ret = dwarf_get_ranges(dbg, ranges_off, &ranges,
+ &ranges_cnt, NULL, &de);
+ if (ret != DW_DLV_OK)
+ return (ret);
+
+ if (!ranges || ranges_cnt <= 0)
+ return (DW_DLV_ERROR);
+
+ for (i = 0; i < ranges_cnt; i++) {
+ if (ranges[i].dwr_type == DW_RANGES_END)
+ return (DW_DLV_NO_ENTRY);
+
+ if (ranges[i].dwr_type ==
+ DW_RANGES_ADDRESS_SELECTION) {
+ addr_base = ranges[i].dwr_addr2;
+ continue;
+ }
+
+ /* DW_RANGES_ENTRY */
+ lopc = ranges[i].dwr_addr1 + addr_base;
+ hipc = ranges[i].dwr_addr2 + addr_base;
+
+ if (lopc == curlopc)
+ return (DW_DLV_ERROR);
+
+ if (addr >= lopc && addr < hipc){
+ in_range = true;
+ break;
+ }
+ }
+ } else {
+ return (DW_DLV_ERROR);
+ }
+
+ if (in_range) {
+ if ((*cu = calloc(1, sizeof(struct CU))) == NULL)
+ err(EXIT_FAILURE, "calloc");
+ (*cu)->lopc = lopc;
+ (*cu)->hipc = hipc;
+ (*cu)->die = die;
+ (*cu)->dbg = dbg;
+ STAILQ_INIT(&(*cu)->funclist);
+ RB_INSERT(cutree, &cuhead, *cu);
+ curlopc = lopc;
+ return (DW_DLV_OK);
+ } else {
+ return (DW_DLV_NO_ENTRY);
+ }
+}
+
static void
translate(Dwarf_Debug dbg, Elf *e, const char* addrstr)
{
@@ -418,10 +516,9 @@
Dwarf_Line *lbuf;
Dwarf_Error de;
Dwarf_Half tag;
- Dwarf_Unsigned lopc, hipc, addr, lineno, plineno;
+ Dwarf_Unsigned addr, lineno, plineno;
Dwarf_Signed lcount;
Dwarf_Addr lineaddr, plineaddr;
- Dwarf_Off off;
struct CU *cu;
struct Func *f;
const char *funcname;
@@ -439,6 +536,7 @@
cu = culookup(addr);
if (cu != NULL) {
die = cu->die;
+ dbg = cu->dbg;
goto status_ok;
}
@@ -477,44 +575,11 @@
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 == curlopc)
- goto out;
- if (dwarf_attrval_unsigned(die, DW_AT_high_pc, &hipc,
- &de) == DW_DLV_OK) {
- /*
- * Check if the address falls into the PC
- * range of this CU.
- */
- if (handle_high_pc(die, lopc, &hipc) !=
- DW_DLV_OK)
- goto out;
- } else {
- /* Assume ~0ULL if DW_AT_high_pc not present */
- hipc = ~0ULL;
- }
-
- if (dwarf_dieoffset(die, &off, &de) != DW_DLV_OK) {
- warnx("dwarf_dieoffset failed: %s",
- dwarf_errmsg(de));
- goto out;
- }
-
- if (addr >= lopc && addr < hipc) {
- if ((cu = calloc(1, sizeof(*cu))) == NULL)
- err(EXIT_FAILURE, "calloc");
- cu->off = off;
- cu->lopc = lopc;
- cu->hipc = hipc;
- cu->die = die;
- STAILQ_INIT(&cu->funclist);
- RB_INSERT(cutree, &cuhead, cu);
-
- curlopc = lopc;
- break;
- }
- }
+ ret = check_range(dbg, die, addr, &cu);
+ if (ret == DW_DLV_OK)
+ break;
+ if (ret == DW_DLV_ERROR)
+ goto out;
next_cu:
if (die != NULL) {
dwarf_dealloc(dbg, die, DW_DLA_DIE);

File Metadata

Mime Type
text/plain
Expires
Sun, Nov 17, 8:25 PM (21 h, 54 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
14684055
Default Alt Text
D23501.diff (4 KB)

Event Timeline