Page MenuHomeFreeBSD

D18843.id54088.diff
No OneTemporary

D18843.id54088.diff

Index: contrib/elftoolchain/readelf/readelf.c
===================================================================
--- contrib/elftoolchain/readelf/readelf.c
+++ contrib/elftoolchain/readelf/readelf.c
@@ -225,6 +225,15 @@
const char *desc;
};
+struct loc_at {
+ Dwarf_Attribute la_at;
+ Dwarf_Unsigned la_off;
+ Dwarf_Unsigned la_lowpc;
+ Dwarf_Half la_cu_psize;
+ Dwarf_Half la_cu_osize;
+ Dwarf_Half la_cu_ver;
+};
+
static void add_dumpop(struct readelf *re, size_t si, const char *sn, int op,
int t);
static const char *aeabi_adv_simd_arch(uint64_t simd);
@@ -341,6 +350,7 @@
static const char *get_symbol_name(struct readelf *re, int symtab, int i);
static uint64_t get_symbol_value(struct readelf *re, int symtab, int i);
static void load_sections(struct readelf *re);
+static int loc_at_comparator(const void *la1, const void *la2);
static const char *mips_abi_fp(uint64_t fp);
static const char *note_type(const char *note_name, unsigned int et,
unsigned int nt);
@@ -359,7 +369,8 @@
static void readelf_usage(int status);
static void readelf_version(void);
static void search_loclist_at(struct readelf *re, Dwarf_Die die,
- Dwarf_Unsigned lowpc);
+ Dwarf_Unsigned lowpc, struct loc_at **la_list,
+ unsigned int *la_list_len, unsigned int *la_list_cap);
static void search_ver(struct readelf *re);
static const char *section_type(unsigned int mach, unsigned int stype);
static void set_cu_context(struct readelf *re, Dwarf_Half psize,
@@ -6034,20 +6045,20 @@
}
}
-struct loc_at {
- Dwarf_Attribute la_at;
- Dwarf_Unsigned la_off;
- Dwarf_Unsigned la_lowpc;
- Dwarf_Half la_cu_psize;
- Dwarf_Half la_cu_osize;
- Dwarf_Half la_cu_ver;
- TAILQ_ENTRY(loc_at) la_next;
-};
+static int
+loc_at_comparator(const void *la1, const void *la2)
+{
+ const struct loc_at *left, *right;
+ left = (const struct loc_at *)la1;
+ right = (const struct loc_at *)la2;
-static TAILQ_HEAD(, loc_at) lalist = TAILQ_HEAD_INITIALIZER(lalist);
+ return ((left->la_off > right->la_off) - (left->la_off < right->la_off));
+}
static void
-search_loclist_at(struct readelf *re, Dwarf_Die die, Dwarf_Unsigned lowpc)
+search_loclist_at(struct readelf *re, Dwarf_Die die, Dwarf_Unsigned lowpc,
+ struct loc_at **la_list, unsigned int *la_list_len,
+ unsigned int *la_list_cap)
{
Dwarf_Attribute *attr_list;
Dwarf_Die ret_die;
@@ -6057,7 +6068,6 @@
Dwarf_Half attr, form;
Dwarf_Bool is_info;
Dwarf_Error de;
- struct loc_at *la, *nla;
int i, ret;
is_info = dwarf_get_die_infotypes_flag(die);
@@ -6105,33 +6115,22 @@
} else
continue;
- TAILQ_FOREACH(la, &lalist, la_next) {
- if (off == la->la_off)
- break;
- if (off < la->la_off) {
- if ((nla = malloc(sizeof(*nla))) == NULL)
- err(EXIT_FAILURE, "malloc failed");
- nla->la_at = attr_list[i];
- nla->la_off = off;
- nla->la_lowpc = lowpc;
- nla->la_cu_psize = re->cu_psize;
- nla->la_cu_osize = re->cu_osize;
- nla->la_cu_ver = re->cu_ver;
- TAILQ_INSERT_BEFORE(la, nla, la_next);
- break;
+ if (*la_list_cap == *la_list_len) {
+ *la_list = realloc(*la_list,
+ *la_list_cap * 2 * sizeof(**la_list));
+ if (la_list == NULL) {
+ errx(EXIT_FAILURE, "realloc failed");
+ return;
}
+ *la_list_cap *= 2;
}
- if (la == NULL) {
- if ((nla = malloc(sizeof(*nla))) == NULL)
- err(EXIT_FAILURE, "malloc failed");
- nla->la_at = attr_list[i];
- nla->la_off = off;
- nla->la_lowpc = lowpc;
- nla->la_cu_psize = re->cu_psize;
- nla->la_cu_osize = re->cu_osize;
- nla->la_cu_ver = re->cu_ver;
- TAILQ_INSERT_TAIL(&lalist, nla, la_next);
- }
+ (*la_list)[*la_list_len].la_at = attr_list[i];
+ (*la_list)[*la_list_len].la_off = off;
+ (*la_list)[*la_list_len].la_lowpc = lowpc;
+ (*la_list)[*la_list_len].la_cu_psize = re->cu_psize;
+ (*la_list)[*la_list_len].la_cu_osize = re->cu_osize;
+ (*la_list)[*la_list_len].la_cu_ver = re->cu_ver;
+ (*la_list_len)++;
}
cont_search:
@@ -6140,14 +6139,16 @@
if (ret == DW_DLV_ERROR)
warnx("dwarf_child: %s", dwarf_errmsg(de));
else if (ret == DW_DLV_OK)
- search_loclist_at(re, ret_die, lowpc);
+ search_loclist_at(re, ret_die, lowpc, la_list,
+ la_list_len, la_list_cap);
/* Search sibling. */
ret = dwarf_siblingof_b(re->dbg, die, &ret_die, is_info, &de);
if (ret == DW_DLV_ERROR)
warnx("dwarf_siblingof: %s", dwarf_errmsg(de));
else if (ret == DW_DLV_OK)
- search_loclist_at(re, ret_die, lowpc);
+ search_loclist_at(re, ret_die, lowpc, la_list,
+ la_list_len, la_list_cap);
}
static void
@@ -6430,9 +6431,15 @@
Dwarf_Signed lcnt;
Dwarf_Half tag, version, pointer_size, off_size;
Dwarf_Error de;
- struct loc_at *la;
+ struct loc_at *la_list, *left, *right, *la;
+ unsigned int la_list_len, la_list_cap, duplicates, k;
int i, j, ret, has_content;
+ la_list_len = 0;
+ la_list_cap = 200;
+ la_list = calloc(la_list_cap, sizeof(struct loc_at));
+ if ((la_list = calloc(la_list_cap, sizeof(struct loc_at))) == NULL)
+ errx(EXIT_FAILURE, "realloc failed");
/* Search .debug_info section. */
while ((ret = dwarf_next_cu_header_b(re->dbg, NULL, &version, NULL,
&pointer_size, &off_size, NULL, NULL, &de)) == DW_DLV_OK) {
@@ -6453,7 +6460,8 @@
}
/* Search attributes for reference to .debug_loc section. */
- search_loclist_at(re, die, lowpc);
+ search_loclist_at(re, die, lowpc, &la_list,
+ &la_list_len, &la_list_cap);
}
if (ret == DW_DLV_ERROR)
warnx("dwarf_next_cu_header: %s", dwarf_errmsg(de));
@@ -6485,17 +6493,36 @@
* Search attributes for reference to .debug_loc
* section.
*/
- search_loclist_at(re, die, lowpc);
+ search_loclist_at(re, die, lowpc, &la_list,
+ &la_list_len, &la_list_cap);
}
if (ret == DW_DLV_ERROR)
warnx("dwarf_next_cu_header: %s", dwarf_errmsg(de));
} while (dwarf_next_types_section(re->dbg, &de) == DW_DLV_OK);
- if (TAILQ_EMPTY(&lalist))
+ if (la_list_len == 0) {
+ free(la_list);
return;
+ }
+
+ /* Sort la_list using loc_at_comparator. */
+ qsort(la_list, la_list_len, sizeof(struct loc_at), loc_at_comparator);
+
+ /* Get rid of the duplicates in la_list. */
+ duplicates = 0;
+ for(k = 1; k < la_list_len; ++k) {
+ left = &la_list[k - 1 - duplicates];
+ right = &la_list[k];
+
+ if(left->la_off == right->la_off)
+ duplicates += 1;
+ else
+ la_list[k - duplicates] = *right;
+ }
has_content = 0;
- TAILQ_FOREACH(la, &lalist, la_next) {
+ for(k = 0; k < la_list_len; ++k) {
+ la = &la_list[k];
if ((ret = dwarf_loclist_n(la->la_at, &llbuf, &lcnt, &de)) !=
DW_DLV_OK) {
if (ret != DW_DLV_NO_ENTRY)
@@ -6545,6 +6572,8 @@
if (!has_content)
printf("\nSection '.debug_loc' has no debugging data.\n");
+
+ free(la_list);
}
/*
@@ -6892,7 +6921,6 @@
static void
dump_dwarf(struct readelf *re)
{
- struct loc_at *la, *_la;
Dwarf_Error de;
int error;
@@ -6930,11 +6958,6 @@
if (re->dop & DW_O)
dump_dwarf_loclist(re);
- TAILQ_FOREACH_SAFE(la, &lalist, la_next, _la) {
- TAILQ_REMOVE(&lalist, la, la_next);
- free(la);
- }
-
dwarf_finish(re->dbg, &de);
}

File Metadata

Mime Type
text/plain
Expires
Sat, Apr 18, 12:18 PM (1 h, 26 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
31678389
Default Alt Text
D18843.id54088.diff (6 KB)

Event Timeline