diff options
author | Mark Wielaard <mjw@redhat.com> | 2014-12-15 19:43:02 +0100 |
---|---|---|
committer | Mark Wielaard <mjw@redhat.com> | 2014-12-17 16:47:16 +0100 |
commit | 6a8a9e3d275f6eb053ee009ed8038bdffc8ad44b (patch) | |
tree | e57f74fc83447e7a3ce30bb72764de64965ebeb5 | |
parent | 198e9490dee64cb9eb5a41daa7bda9ff97d52d32 (diff) | |
download | elfutils-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/ChangeLog | 6 | ||||
-rw-r--r-- | src/readelf.c | 45 |
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: |