Page MenuHomeFreeBSD

D23418.id67516.diff
No OneTemporary

D23418.id67516.diff

Index: contrib/elftoolchain/addr2line/addr2line.c
===================================================================
--- contrib/elftoolchain/addr2line/addr2line.c
+++ contrib/elftoolchain/addr2line/addr2line.c
@@ -25,6 +25,7 @@
*/
#include <sys/param.h>
+#include <sys/tree.h>
#include <capsicum_helpers.h>
#include <dwarf.h>
@@ -39,7 +40,6 @@
#include <stdlib.h>
#include <string.h>
-#include "uthash.h"
#include "_elftc.h"
ELFTC_VCSID("$Id: addr2line.c 3499 2016-11-25 16:06:29Z emaste $");
@@ -57,13 +57,14 @@
};
struct CU {
+ RB_ENTRY(CU) entry;
Dwarf_Off off;
Dwarf_Unsigned lopc;
Dwarf_Unsigned hipc;
char **srcfiles;
Dwarf_Signed nsrcfiles;
STAILQ_HEAD(, Func) funclist;
- UT_hash_handle hh;
+ Dwarf_Die die;
};
static struct option longopts[] = {
@@ -80,12 +81,17 @@
{"version", no_argument, NULL, 'V'},
{NULL, 0, NULL, 0}
};
+
static int demangle, func, base, inlines, print_addr, pretty_print;
static char unknown[] = { '?', '?', '\0' };
static Dwarf_Addr section_base;
-static struct CU *culist;
-static Dwarf_Unsigned locache = ~0ULL, hicache;
-static Dwarf_Die last_die = NULL;
+static struct CU *last_cu;
+/* Need a new curlopc that stores last lopc value.
+ * We used to use locache to do this, but locache is not stable anymore
+ * as tree lookup updates cache.
+ */
+static Dwarf_Unsigned curlopc = ~0ULL;
+static RB_HEAD(cutree, CU) head = RB_INITIALIZER(&head);
#define USAGE_MESSAGE "\
Usage: %s [options] hexaddress...\n\
@@ -104,6 +110,15 @@
-H | --help Print a help message.\n\
-V | --version Print a version identifier and exit.\n"
+static int
+lopccmp(struct CU *e1, struct CU *e2)
+{
+ return (e1->lopc < e2->lopc ? -1 : e1->lopc > e2->lopc);
+}
+
+RB_PROTOTYPE(cutree, CU, entry, lopccmp);
+RB_GENERATE(cutree, CU, entry, lopccmp)
+
static void
usage(void)
{
@@ -395,6 +410,7 @@
struct Func *f;
const char *funcname;
char *file, *file0, *pfile;
+
char demangled[1024];
int ec, i, ret;
@@ -404,13 +420,34 @@
file = unknown;
cu = NULL;
die = NULL;
+ ret = DW_DLV_OK;
- if (addr >= locache && addr < hicache && last_die != NULL) {
- die = last_die;
+ if (last_cu != NULL && addr >= last_cu->lopc && addr < last_cu->hipc) {
+ cu = last_cu;
+ die = last_cu->die;
goto status_ok;
}
+ /* Address isn't in cache. Check if it's in cutree. */
+ struct CU find, *res;
+ find.lopc = addr;
+ res = RB_NFIND(cutree, &head, &find);
+ if (res != NULL) {
+ /* go back one res if addr != res->lopc */
+ if (res->lopc != addr) {
+ res = RB_PREV(cutree, &head, res);
+ /* res can be NULL when tree only has useless_node */
+ }
+ /* Found the potential CU, but have to check if addr falls in range */
+ if (res != NULL && addr >= res->lopc && addr < res->hipc) {
+ die = res->die;
+ cu = res;
+ last_cu = cu;
+ goto status_ok;
+ }
+ }
+
while (true) {
/*
* We resume the CU scan from the last place we found a match. Because
@@ -420,7 +457,7 @@
ret = dwarf_next_cu_header(dbg, NULL, NULL, NULL, NULL, NULL,
&de);
if (ret == DW_DLV_NO_ENTRY) {
- if (locache == ~0ULL) {
+ if (curlopc == ~0ULL) {
goto out;
}
ret = dwarf_next_cu_header(dbg, NULL, NULL, NULL, NULL, NULL,
@@ -448,7 +485,7 @@
}
if (dwarf_attrval_unsigned(die, DW_AT_low_pc, &lopc, &de) ==
DW_DLV_OK) {
- if (lopc == locache) {
+ if (lopc == curlopc) {
goto out;
}
if (dwarf_attrval_unsigned(die, DW_AT_high_pc, &hipc,
@@ -465,32 +502,26 @@
hipc = ~0ULL;
}
- /*
- * Record the CU in the hash table for faster lookup
- * later.
- */
if (dwarf_dieoffset(die, &off, &de) != DW_DLV_OK) {
warnx("dwarf_dieoffset failed: %s",
dwarf_errmsg(de));
goto out;
}
- HASH_FIND(hh, culist, &off, sizeof(off), cu);
- if (cu == NULL) {
- if ((cu = calloc(1, sizeof(*cu))) == NULL)
+
+ 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);
- HASH_ADD(hh, culist, off, sizeof(off), cu);
- }
-
- if (addr >= lopc && addr < hipc)
break;
+ }
}
-
next_cu:
- if (die != NULL && die != last_die) {
+ if (die != NULL) {
dwarf_dealloc(dbg, die, DW_DLA_DIE);
die = NULL;
}
@@ -499,13 +530,14 @@
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;
+ /* Add this addr's CU info from brute force to tree */
+ RB_INSERT(cutree, &head, cu);
+
+ /* update curlopc. Not affected by tree or cache lookup. */
+ curlopc = lopc;
+
+ /* update single cache */
+ last_cu = cu;
status_ok:
@@ -750,6 +782,14 @@
else
section_base = 0;
+ /* Add a useless CU node so RB_NFIND can find the last node that has info */
+ struct CU *useless_node;
+ if ((useless_node = calloc(1, sizeof(*useless_node))) == NULL)
+ err(EXIT_FAILURE, "calloc");
+ useless_node->lopc = ~0ULL;
+ useless_node->hipc = 0ULL;
+ RB_INSERT(cutree, &head, useless_node);
+
if (argc > 0)
for (i = 0; i < argc; i++)
translate(dbg, e, argv[i]);
@@ -759,10 +799,6 @@
translate(dbg, e, line);
}
- if (last_die != NULL) {
- dwarf_dealloc(dbg, last_die, DW_DLA_DIE);
- }
-
dwarf_finish(dbg, &de);
(void) elf_end(e);

File Metadata

Mime Type
text/plain
Expires
Mon, Apr 13, 2:58 AM (17 h, 17 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
31390652
Default Alt Text
D23418.id67516.diff (5 KB)

Event Timeline