summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Wielaard <mjw@redhat.com>2014-12-15 19:43:02 +0100
committerMark Wielaard <mjw@redhat.com>2014-12-17 16:47:16 +0100
commit6a8a9e3d275f6eb053ee009ed8038bdffc8ad44b (patch)
treee57f74fc83447e7a3ce30bb72764de64965ebeb5
parent198e9490dee64cb9eb5a41daa7bda9ff97d52d32 (diff)
downloadelfutils-6a8a9e3d275f6eb053ee009ed8038bdffc8ad44b.tar.gz
readelf: Warn, don't assert, if loclist or rangelist offset is too big.
We use a couple of bits to keep track of the addr size, dwarf size and warning given for a loclist or rangelist offset. Normally offset won't be that big and will fit in 61-bits easily. But if not, don't assert, but just warn we don't handle such large offsets. Signed-off-by: Mark Wielaard <mjw@redhat.com>
-rw-r--r--src/ChangeLog6
-rw-r--r--src/readelf.c45
2 files changed, 35 insertions, 16 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index 1f91de60..f401c353 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,5 +1,11 @@
2014-12-15 Mark Wielaard <mjw@redhat.com>
+ * readelf.c (notice_listptr): Return false if offset doesn't fit
+ in 61-bits.
+ (attr_callback): Warn if loclist or rangelist offset doesn't fit.
+
+2014-12-15 Mark Wielaard <mjw@redhat.com>
+
* readelf.c (print_ops): Don't assert when addr_size or ref_size
is not 4 or 8, just report invalid data.
diff --git a/src/readelf.c b/src/readelf.c
index aa85d73a..e9a356d1 100644
--- a/src/readelf.c
+++ b/src/readelf.c
@@ -4426,7 +4426,8 @@ reset_listptr (struct listptr_table *table)
table->n = table->alloc = 0;
}
-static void
+/* Returns false if offset doesn't fit. See struct listptr. */
+static bool
notice_listptr (enum section_e section, struct listptr_table *table,
uint_fast8_t address_size, uint_fast8_t offset_size,
struct Dwarf_CU *cu, Dwarf_Off offset)
@@ -4452,8 +4453,14 @@ notice_listptr (enum section_e section, struct listptr_table *table,
.offset = offset,
.cu = cu
};
- assert (p->offset == offset);
+
+ if (p->offset != offset)
+ {
+ table->n--;
+ return false;
+ }
}
+ return true;
}
static void
@@ -5849,23 +5856,29 @@ attr_callback (Dwarf_Attribute *attrp, void *arg)
case DW_AT_GNU_call_site_data_value:
case DW_AT_GNU_call_site_target:
case DW_AT_GNU_call_site_target_clobbered:
- notice_listptr (section_loc, &known_loclistptr,
- cbargs->addrsize, cbargs->offset_size,
- cbargs->cu, num);
- if (!cbargs->silent)
- printf (" %*s%-20s (%s) location list [%6" PRIxMAX "]\n",
- (int) (level * 2), "", dwarf_attr_name (attr),
- dwarf_form_name (form), (uintmax_t) num);
+ {
+ bool nlpt = notice_listptr (section_loc, &known_loclistptr,
+ cbargs->addrsize, cbargs->offset_size,
+ cbargs->cu, num);
+ if (!cbargs->silent)
+ printf (" %*s%-20s (%s) location list [%6" PRIxMAX "]%s\n",
+ (int) (level * 2), "", dwarf_attr_name (attr),
+ dwarf_form_name (form), (uintmax_t) num,
+ nlpt ? "" : " <WARNING offset too big>");
+ }
return DWARF_CB_OK;
case DW_AT_ranges:
- notice_listptr (section_ranges, &known_rangelistptr,
- cbargs->addrsize, cbargs->offset_size,
- cbargs->cu, num);
- if (!cbargs->silent)
- printf (" %*s%-20s (%s) range list [%6" PRIxMAX "]\n",
- (int) (level * 2), "", dwarf_attr_name (attr),
- dwarf_form_name (form), (uintmax_t) num);
+ {
+ bool nlpt = notice_listptr (section_ranges, &known_rangelistptr,
+ cbargs->addrsize, cbargs->offset_size,
+ cbargs->cu, num);
+ if (!cbargs->silent)
+ printf (" %*s%-20s (%s) range list [%6" PRIxMAX "]%s\n",
+ (int) (level * 2), "", dwarf_attr_name (attr),
+ dwarf_form_name (form), (uintmax_t) num,
+ nlpt ? "" : " <WARNING offset too big>");
+ }
return DWARF_CB_OK;
case DW_AT_language: