[PATCH] readelf: Warn, don't assert, if loclist or rangelist offset is too big.

Mark Wielaard mjw at redhat.com
Mon Dec 15 18:47:43 UTC 2014


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 at redhat.com>
---
 src/ChangeLog |  6 ++++++
 src/readelf.c | 45 +++++++++++++++++++++++++++++----------------
 2 files changed, 35 insertions(+), 16 deletions(-)

diff --git a/src/ChangeLog b/src/ChangeLog
index 08f9ee4..bb3e84f 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,5 +1,11 @@
 2014-12-15  Mark Wielaard  <mjw at 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 at 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 aa85d73..e9a356d 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:
-- 
1.8.3.1



More information about the elfutils-devel mailing list