Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F102763329
D23501.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
4 KB
Referenced Files
None
Subscribers
None
D23501.diff
View Options
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
Details
Attached
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)
Attached To
Mode
D23501: Added ranges to Addr2line
Attached
Detach File
Event Timeline
Log In to Comment