Mark Wielaard b1a53d
Upstream commits since 0.172:
Mark Wielaard b1a53d
Mark Wielaard b1a53d
  b4dced3 readelf: While printing .debug_loc make sure that next_off doesn't overflow.
Mark Wielaard b1a53d
  bb11e36 libdw: Make __libdw_dieabbrev more robust on failure.
Mark Wielaard b1a53d
  3647b5b readelf: Make sure print_form_data always consumes DW_FORM_strx[1234] data.
Mark Wielaard b1a53d
  eaaf908 readelf: Check there are at least 4 bytes available for DWARF_FORM_block4.
Mark Wielaard b1a53d
  0d93f49 libdw, readelf: Don't handle DW_FORM_data16 as expression block/location.
Mark Wielaard b1a53d
  9495c26 libdw: aggregate_size check NULL result from get_type.
Mark Wielaard b1a53d
  e636112 libdw: dwarf_peel_type break long chains/cycles.
Mark Wielaard b1a53d
  5956b8a libdw: Break dwarf_aggregate_size recursion because of type cycles.
Mark Wielaard b1a53d
  ca0d831 libelf: Don't return unaligned data returned from elf_getdata[_rawchunk].
Mark Wielaard b1a53d
Mark Wielaard b1a53d
diff --git a/libdw/dwarf_aggregate_size.c b/libdw/dwarf_aggregate_size.c
Mark Wielaard b1a53d
index 6e50185..75105e4 100644
Mark Wielaard b1a53d
--- a/libdw/dwarf_aggregate_size.c
Mark Wielaard b1a53d
+++ b/libdw/dwarf_aggregate_size.c
Mark Wielaard b1a53d
@@ -46,13 +46,17 @@ get_type (Dwarf_Die *die, Dwarf_Attribute *attr_mem, Dwarf_Die *type_mem)
Mark Wielaard b1a53d
   return type;
Mark Wielaard b1a53d
 }
Mark Wielaard b1a53d
 
Mark Wielaard b1a53d
+static int aggregate_size (Dwarf_Die *die, Dwarf_Word *size,
Mark Wielaard b1a53d
+			   Dwarf_Die *type_mem, int depth);
Mark Wielaard b1a53d
+
Mark Wielaard b1a53d
 static int
Mark Wielaard b1a53d
 array_size (Dwarf_Die *die, Dwarf_Word *size,
Mark Wielaard b1a53d
-	    Dwarf_Attribute *attr_mem, Dwarf_Die *type_mem)
Mark Wielaard b1a53d
+	    Dwarf_Attribute *attr_mem, int depth)
Mark Wielaard b1a53d
 {
Mark Wielaard b1a53d
   Dwarf_Word eltsize;
Mark Wielaard b1a53d
-  if (INTUSE(dwarf_aggregate_size) (get_type (die, attr_mem, type_mem),
Mark Wielaard b1a53d
-				    &eltsize) != 0)
Mark Wielaard b1a53d
+  Dwarf_Die type_mem, aggregate_type_mem;
Mark Wielaard b1a53d
+  if (aggregate_size (get_type (die, attr_mem, &type_mem), &eltsize,
Mark Wielaard b1a53d
+		      &aggregate_type_mem, depth) != 0)
Mark Wielaard b1a53d
       return -1;
Mark Wielaard b1a53d
 
Mark Wielaard b1a53d
   /* An array can have DW_TAG_subrange_type or DW_TAG_enumeration_type
Mark Wielaard b1a53d
@@ -167,21 +171,30 @@ array_size (Dwarf_Die *die, Dwarf_Word *size,
Mark Wielaard b1a53d
 }
Mark Wielaard b1a53d
 
Mark Wielaard b1a53d
 static int
Mark Wielaard b1a53d
-aggregate_size (Dwarf_Die *die, Dwarf_Word *size, Dwarf_Die *type_mem)
Mark Wielaard b1a53d
+aggregate_size (Dwarf_Die *die, Dwarf_Word *size,
Mark Wielaard b1a53d
+		Dwarf_Die *type_mem, int depth)
Mark Wielaard b1a53d
 {
Mark Wielaard b1a53d
   Dwarf_Attribute attr_mem;
Mark Wielaard b1a53d
 
Mark Wielaard b1a53d
+/* Arrays of arrays of subrange types of arrays... Don't recurse too deep.  */
Mark Wielaard b1a53d
+#define MAX_DEPTH 256
Mark Wielaard b1a53d
+  if (die == NULL || depth++ >= MAX_DEPTH)
Mark Wielaard b1a53d
+    return -1;
Mark Wielaard b1a53d
+
Mark Wielaard b1a53d
   if (INTUSE(dwarf_attr_integrate) (die, DW_AT_byte_size, &attr_mem) != NULL)
Mark Wielaard b1a53d
     return INTUSE(dwarf_formudata) (&attr_mem, size);
Mark Wielaard b1a53d
 
Mark Wielaard b1a53d
   switch (INTUSE(dwarf_tag) (die))
Mark Wielaard b1a53d
     {
Mark Wielaard b1a53d
     case DW_TAG_subrange_type:
Mark Wielaard b1a53d
-      return aggregate_size (get_type (die, &attr_mem, type_mem),
Mark Wielaard b1a53d
-			     size, type_mem); /* Tail call.  */
Mark Wielaard b1a53d
+      {
Mark Wielaard b1a53d
+	Dwarf_Die aggregate_type_mem;
Mark Wielaard b1a53d
+	return aggregate_size (get_type (die, &attr_mem, type_mem),
Mark Wielaard b1a53d
+			       size, &aggregate_type_mem, depth);
Mark Wielaard b1a53d
+      }
Mark Wielaard b1a53d
 
Mark Wielaard b1a53d
     case DW_TAG_array_type:
Mark Wielaard b1a53d
-      return array_size (die, size, &attr_mem, type_mem);
Mark Wielaard b1a53d
+      return array_size (die, size, &attr_mem, depth);
Mark Wielaard b1a53d
 
Mark Wielaard b1a53d
     /* Assume references and pointers have pointer size if not given an
Mark Wielaard b1a53d
        explicit DW_AT_byte_size.  */
Mark Wielaard b1a53d
@@ -204,7 +217,7 @@ dwarf_aggregate_size (Dwarf_Die *die, Dwarf_Word *size)
Mark Wielaard b1a53d
   if (INTUSE (dwarf_peel_type) (die, &die_mem) != 0)
Mark Wielaard b1a53d
     return -1;
Mark Wielaard b1a53d
 
Mark Wielaard b1a53d
-  return aggregate_size (&die_mem, size, &type_mem);
Mark Wielaard b1a53d
+  return aggregate_size (&die_mem, size, &type_mem, 0);
Mark Wielaard b1a53d
 }
Mark Wielaard b1a53d
 INTDEF (dwarf_aggregate_size)
Mark Wielaard b1a53d
 OLD_VERSION (dwarf_aggregate_size, ELFUTILS_0.144)
Mark Wielaard b1a53d
diff --git a/libdw/dwarf_getlocation.c b/libdw/dwarf_getlocation.c
Mark Wielaard b1a53d
index 7f294fe..fc59a2a 100644
Mark Wielaard b1a53d
--- a/libdw/dwarf_getlocation.c
Mark Wielaard b1a53d
+++ b/libdw/dwarf_getlocation.c
Mark Wielaard b1a53d
@@ -174,6 +174,8 @@ check_constant_offset (Dwarf_Attribute *attr,
Mark Wielaard b1a53d
     default:
Mark Wielaard b1a53d
       return 1;
Mark Wielaard b1a53d
 
Mark Wielaard b1a53d
+      /* Note, we don't regard DW_FORM_data16 as a constant form,
Mark Wielaard b1a53d
+	 even though technically it is according to the standard.  */
Mark Wielaard b1a53d
     case DW_FORM_data1:
Mark Wielaard b1a53d
     case DW_FORM_data2:
Mark Wielaard b1a53d
     case DW_FORM_data4:
Mark Wielaard b1a53d
@@ -665,7 +667,13 @@ dwarf_getlocation (Dwarf_Attribute *attr, Dwarf_Op **llbuf, size_t *listlen)
Mark Wielaard b1a53d
   if (result != 1)
Mark Wielaard b1a53d
     return result;
Mark Wielaard b1a53d
 
Mark Wielaard b1a53d
-  /* If it has a block form, it's a single location expression.  */
Mark Wielaard b1a53d
+  /* If it has a block form, it's a single location expression.
Mark Wielaard b1a53d
+     Except for DW_FORM_data16, which is a 128bit constant.  */
Mark Wielaard b1a53d
+  if (attr->form == DW_FORM_data16)
Mark Wielaard b1a53d
+    {
Mark Wielaard b1a53d
+      __libdw_seterrno (DWARF_E_NO_BLOCK);
Mark Wielaard b1a53d
+      return -1;
Mark Wielaard b1a53d
+    }
Mark Wielaard b1a53d
   Dwarf_Block block;
Mark Wielaard b1a53d
   if (INTUSE(dwarf_formblock) (attr, &block) != 0)
Mark Wielaard b1a53d
     return -1;
Mark Wielaard b1a53d
@@ -863,9 +871,11 @@ dwarf_getlocation_addr (Dwarf_Attribute *attr, Dwarf_Addr address,
Mark Wielaard b1a53d
   if (llbufs == NULL)
Mark Wielaard b1a53d
     maxlocs = SIZE_MAX;
Mark Wielaard b1a53d
 
Mark Wielaard b1a53d
-  /* If it has a block form, it's a single location expression.  */
Mark Wielaard b1a53d
+  /* If it has a block form, it's a single location expression.
Mark Wielaard b1a53d
+     Except for DW_FORM_data16, which is a 128bit constant.  */
Mark Wielaard b1a53d
   Dwarf_Block block;
Mark Wielaard b1a53d
-  if (INTUSE(dwarf_formblock) (attr, &block) == 0)
Mark Wielaard b1a53d
+  if (attr->form != DW_FORM_data16
Mark Wielaard b1a53d
+      && INTUSE(dwarf_formblock) (attr, &block) == 0)
Mark Wielaard b1a53d
     {
Mark Wielaard b1a53d
       if (maxlocs == 0)
Mark Wielaard b1a53d
 	return 0;
Mark Wielaard b1a53d
@@ -876,11 +886,14 @@ dwarf_getlocation_addr (Dwarf_Attribute *attr, Dwarf_Addr address,
Mark Wielaard b1a53d
       return listlens[0] == 0 ? 0 : 1;
Mark Wielaard b1a53d
     }
Mark Wielaard b1a53d
 
Mark Wielaard b1a53d
-  int error = INTUSE(dwarf_errno) ();
Mark Wielaard b1a53d
-  if (unlikely (error != DWARF_E_NO_BLOCK))
Mark Wielaard b1a53d
+  if (attr->form != DW_FORM_data16)
Mark Wielaard b1a53d
     {
Mark Wielaard b1a53d
-      __libdw_seterrno (error);
Mark Wielaard b1a53d
-      return -1;
Mark Wielaard b1a53d
+      int error = INTUSE(dwarf_errno) ();
Mark Wielaard b1a53d
+      if (unlikely (error != DWARF_E_NO_BLOCK))
Mark Wielaard b1a53d
+	{
Mark Wielaard b1a53d
+	  __libdw_seterrno (error);
Mark Wielaard b1a53d
+	  return -1;
Mark Wielaard b1a53d
+	}
Mark Wielaard b1a53d
     }
Mark Wielaard b1a53d
 
Mark Wielaard b1a53d
   int result = check_constant_offset (attr, &llbufs[0], &listlens[0]);
Mark Wielaard b1a53d
@@ -938,9 +951,11 @@ dwarf_getlocations (Dwarf_Attribute *attr, ptrdiff_t offset, Dwarf_Addr *basep,
Mark Wielaard b1a53d
 
Mark Wielaard b1a53d
   if (offset == 0)
Mark Wielaard b1a53d
     {
Mark Wielaard b1a53d
-      /* If it has a block form, it's a single location expression.  */
Mark Wielaard b1a53d
+      /* If it has a block form, it's a single location expression.
Mark Wielaard b1a53d
+	 Except for DW_FORM_data16, which is a 128bit constant.  */
Mark Wielaard b1a53d
       Dwarf_Block block;
Mark Wielaard b1a53d
-      if (INTUSE(dwarf_formblock) (attr, &block) == 0)
Mark Wielaard b1a53d
+      if (attr->form != DW_FORM_data16
Mark Wielaard b1a53d
+	  && INTUSE(dwarf_formblock) (attr, &block) == 0)
Mark Wielaard b1a53d
 	{
Mark Wielaard b1a53d
 	  if (getlocation (attr->cu, &block, expr, exprlen,
Mark Wielaard b1a53d
 			   cu_sec_idx (attr->cu)) != 0)
Mark Wielaard b1a53d
@@ -952,11 +967,14 @@ dwarf_getlocations (Dwarf_Attribute *attr, ptrdiff_t offset, Dwarf_Addr *basep,
Mark Wielaard b1a53d
 	  return 1;
Mark Wielaard b1a53d
 	}
Mark Wielaard b1a53d
 
Mark Wielaard b1a53d
-      int error = INTUSE(dwarf_errno) ();
Mark Wielaard b1a53d
-      if (unlikely (error != DWARF_E_NO_BLOCK))
Mark Wielaard b1a53d
+      if (attr->form != DW_FORM_data16)
Mark Wielaard b1a53d
 	{
Mark Wielaard b1a53d
-	  __libdw_seterrno (error);
Mark Wielaard b1a53d
-	  return -1;
Mark Wielaard b1a53d
+	  int error = INTUSE(dwarf_errno) ();
Mark Wielaard b1a53d
+	  if (unlikely (error != DWARF_E_NO_BLOCK))
Mark Wielaard b1a53d
+	    {
Mark Wielaard b1a53d
+	      __libdw_seterrno (error);
Mark Wielaard b1a53d
+	      return -1;
Mark Wielaard b1a53d
+	    }
Mark Wielaard b1a53d
 	}
Mark Wielaard b1a53d
 
Mark Wielaard b1a53d
       int result = check_constant_offset (attr, expr, exprlen);
Mark Wielaard b1a53d
diff --git a/libdw/dwarf_peel_type.c b/libdw/dwarf_peel_type.c
Mark Wielaard b1a53d
index 6bbfd42..59fc6f1 100644
Mark Wielaard b1a53d
--- a/libdw/dwarf_peel_type.c
Mark Wielaard b1a53d
+++ b/libdw/dwarf_peel_type.c
Mark Wielaard b1a53d
@@ -46,14 +46,19 @@ dwarf_peel_type (Dwarf_Die *die, Dwarf_Die *result)
Mark Wielaard b1a53d
 
Mark Wielaard b1a53d
   *result = *die;
Mark Wielaard b1a53d
   tag = INTUSE (dwarf_tag) (result);
Mark Wielaard b1a53d
-  while (tag == DW_TAG_typedef
Mark Wielaard b1a53d
-	 || tag == DW_TAG_const_type
Mark Wielaard b1a53d
-	 || tag == DW_TAG_volatile_type
Mark Wielaard b1a53d
-	 || tag == DW_TAG_restrict_type
Mark Wielaard b1a53d
-	 || tag == DW_TAG_atomic_type
Mark Wielaard b1a53d
-	 || tag == DW_TAG_immutable_type
Mark Wielaard b1a53d
-	 || tag == DW_TAG_packed_type
Mark Wielaard b1a53d
-	 || tag == DW_TAG_shared_type)
Mark Wielaard b1a53d
+
Mark Wielaard b1a53d
+/* Stack 8 of all these modifiers, after that it gets silly.  */
Mark Wielaard b1a53d
+#define MAX_DEPTH (8 * 8)
Mark Wielaard b1a53d
+  int max_depth = MAX_DEPTH;
Mark Wielaard b1a53d
+  while ((tag == DW_TAG_typedef
Mark Wielaard b1a53d
+	  || tag == DW_TAG_const_type
Mark Wielaard b1a53d
+	  || tag == DW_TAG_volatile_type
Mark Wielaard b1a53d
+	  || tag == DW_TAG_restrict_type
Mark Wielaard b1a53d
+	  || tag == DW_TAG_atomic_type
Mark Wielaard b1a53d
+	  || tag == DW_TAG_immutable_type
Mark Wielaard b1a53d
+	  || tag == DW_TAG_packed_type
Mark Wielaard b1a53d
+	  || tag == DW_TAG_shared_type)
Mark Wielaard b1a53d
+	&& max_depth-- > 0)
Mark Wielaard b1a53d
     {
Mark Wielaard b1a53d
       Dwarf_Attribute attr_mem;
Mark Wielaard b1a53d
       Dwarf_Attribute *attr = INTUSE (dwarf_attr_integrate) (result, DW_AT_type,
Mark Wielaard b1a53d
@@ -67,7 +72,7 @@ dwarf_peel_type (Dwarf_Die *die, Dwarf_Die *result)
Mark Wielaard b1a53d
       tag = INTUSE (dwarf_tag) (result);
Mark Wielaard b1a53d
     }
Mark Wielaard b1a53d
 
Mark Wielaard b1a53d
-  if (tag == DW_TAG_invalid)
Mark Wielaard b1a53d
+  if (tag == DW_TAG_invalid || max_depth <= 0)
Mark Wielaard b1a53d
     return -1;
Mark Wielaard b1a53d
 
Mark Wielaard b1a53d
   return 0;
Mark Wielaard b1a53d
diff --git a/libdw/libdwP.h b/libdw/libdwP.h
Mark Wielaard b1a53d
index 3d8e145..eebb7d1 100644
Mark Wielaard b1a53d
--- a/libdw/libdwP.h
Mark Wielaard b1a53d
+++ b/libdw/libdwP.h
Mark Wielaard b1a53d
@@ -653,8 +653,9 @@ __libdw_dieabbrev (Dwarf_Die *die, const unsigned char **readp)
Mark Wielaard b1a53d
       /* Get the abbreviation code.  */
Mark Wielaard b1a53d
       unsigned int code;
Mark Wielaard b1a53d
       const unsigned char *addr = die->addr;
Mark Wielaard b1a53d
-      if (die->cu == NULL || addr >= (const unsigned char *) die->cu->endp)
Mark Wielaard b1a53d
-	return DWARF_END_ABBREV;
Mark Wielaard b1a53d
+      if (unlikely (die->cu == NULL
Mark Wielaard b1a53d
+		    || addr >= (const unsigned char *) die->cu->endp))
Mark Wielaard b1a53d
+	return die->abbrev = DWARF_END_ABBREV;
Mark Wielaard b1a53d
       get_uleb128 (code, addr, die->cu->endp);
Mark Wielaard b1a53d
       if (readp != NULL)
Mark Wielaard b1a53d
 	*readp = addr;
Mark Wielaard b1a53d
diff --git a/libdw/memory-access.h b/libdw/memory-access.h
Mark Wielaard b1a53d
index 22918cb..a39ad6d 100644
Mark Wielaard b1a53d
--- a/libdw/memory-access.h
Mark Wielaard b1a53d
+++ b/libdw/memory-access.h
Mark Wielaard b1a53d
@@ -362,6 +362,11 @@ read_3ubyte_unaligned (Dwarf *dbg, const unsigned char *p)
Mark Wielaard b1a53d
 }
Mark Wielaard b1a53d
 
Mark Wielaard b1a53d
 
Mark Wielaard b1a53d
+#define read_3ubyte_unaligned_inc(Dbg, Addr) \
Mark Wielaard b1a53d
+  ({ uint32_t t_ = read_2ubyte_unaligned (Dbg, Addr);			      \
Mark Wielaard b1a53d
+     Addr = (__typeof (Addr)) (((uintptr_t) (Addr)) + 3);		      \
Mark Wielaard b1a53d
+     t_; })
Mark Wielaard b1a53d
+
Mark Wielaard b1a53d
 #define read_addr_unaligned_inc(Nbytes, Dbg, Addr)			\
Mark Wielaard b1a53d
   (assert ((Nbytes) == 4 || (Nbytes) == 8),				\
Mark Wielaard b1a53d
     ((Nbytes) == 4 ? read_4ubyte_unaligned_inc (Dbg, Addr)		\
Mark Wielaard b1a53d
diff --git a/libelf/elf_getdata.c b/libelf/elf_getdata.c
Mark Wielaard b1a53d
index 97c503b..278dfa8 100644
Mark Wielaard b1a53d
--- a/libelf/elf_getdata.c
Mark Wielaard b1a53d
+++ b/libelf/elf_getdata.c
Mark Wielaard b1a53d
@@ -76,7 +76,6 @@ static const Elf_Type shtype_map[EV_NUM - 1][TYPEIDX (SHT_HISUNW) + 1] =
Mark Wielaard b1a53d
     }
Mark Wielaard b1a53d
   };
Mark Wielaard b1a53d
 
Mark Wielaard b1a53d
-#if !ALLOW_UNALIGNED
Mark Wielaard b1a53d
 /* Associate libelf types with their internal alignment requirements.  */
Mark Wielaard b1a53d
 const uint_fast8_t __libelf_type_aligns[EV_NUM - 1][ELFCLASSNUM - 1][ELF_T_NUM] =
Mark Wielaard b1a53d
   {
Mark Wielaard b1a53d
@@ -115,7 +114,6 @@ const uint_fast8_t __libelf_type_aligns[EV_NUM - 1][ELFCLASSNUM - 1][ELF_T_NUM]
Mark Wielaard b1a53d
     }
Mark Wielaard b1a53d
 # undef TYPE_ALIGNS
Mark Wielaard b1a53d
   };
Mark Wielaard b1a53d
-#endif
Mark Wielaard b1a53d
 
Mark Wielaard b1a53d
 
Mark Wielaard b1a53d
 Elf_Type
Mark Wielaard b1a53d
@@ -173,8 +171,7 @@ convert_data (Elf_Scn *scn, int version __attribute__ ((unused)), int eclass,
Mark Wielaard b1a53d
       /* Make sure the source is correctly aligned for the conversion
Mark Wielaard b1a53d
 	 function to directly access the data elements.  */
Mark Wielaard b1a53d
       char *rawdata_source;
Mark Wielaard b1a53d
-      if (ALLOW_UNALIGNED ||
Mark Wielaard b1a53d
-	  ((((size_t) (char *) scn->rawdata_base)) & (align - 1)) == 0)
Mark Wielaard b1a53d
+      if (((((size_t) (char *) scn->rawdata_base)) & (align - 1)) == 0)
Mark Wielaard b1a53d
 	rawdata_source = scn->rawdata_base;
Mark Wielaard b1a53d
       else
Mark Wielaard b1a53d
 	{
Mark Wielaard b1a53d
diff --git a/libelf/elf_getdata_rawchunk.c b/libelf/elf_getdata_rawchunk.c
Mark Wielaard b1a53d
index 31b2fe7..d0c0b75 100644
Mark Wielaard b1a53d
--- a/libelf/elf_getdata_rawchunk.c
Mark Wielaard b1a53d
+++ b/libelf/elf_getdata_rawchunk.c
Mark Wielaard b1a53d
@@ -80,8 +80,7 @@ elf_getdata_rawchunk (Elf *elf, off_t offset, size_t size, Elf_Type type)
Mark Wielaard b1a53d
     {
Mark Wielaard b1a53d
     /* If the file is mmap'ed we can use it directly, if aligned for type.  */
Mark Wielaard b1a53d
       char *rawdata = elf->map_address + elf->start_offset + offset;
Mark Wielaard b1a53d
-      if (ALLOW_UNALIGNED ||
Mark Wielaard b1a53d
-	  ((uintptr_t) rawdata & (align - 1)) == 0)
Mark Wielaard b1a53d
+      if (((uintptr_t) rawdata & (align - 1)) == 0)
Mark Wielaard b1a53d
 	rawchunk = rawdata;
Mark Wielaard b1a53d
       else
Mark Wielaard b1a53d
 	{
Mark Wielaard b1a53d
diff --git a/libelf/libelfP.h b/libelf/libelfP.h
Mark Wielaard b1a53d
index ca805ac..ed216c8 100644
Mark Wielaard b1a53d
--- a/libelf/libelfP.h
Mark Wielaard b1a53d
+++ b/libelf/libelfP.h
Mark Wielaard b1a53d
@@ -443,15 +443,11 @@ extern int __libelf_version_initialized attribute_hidden;
Mark Wielaard b1a53d
 # define LIBELF_EV_IDX	(__libelf_version - 1)
Mark Wielaard b1a53d
 #endif
Mark Wielaard b1a53d
 
Mark Wielaard b1a53d
-#if !ALLOW_UNALIGNED
Mark Wielaard b1a53d
 /* Array with alignment requirements of the internal types indexed by ELF
Mark Wielaard b1a53d
    version, binary class, and type. */
Mark Wielaard b1a53d
 extern const uint_fast8_t __libelf_type_aligns[EV_NUM - 1][ELFCLASSNUM - 1][ELF_T_NUM] attribute_hidden;
Mark Wielaard b1a53d
 # define __libelf_type_align(class, type)	\
Mark Wielaard b1a53d
     (__libelf_type_aligns[LIBELF_EV_IDX][class - 1][type] ?: 1)
Mark Wielaard b1a53d
-#else
Mark Wielaard b1a53d
-# define __libelf_type_align(class, type)	1
Mark Wielaard b1a53d
-#endif
Mark Wielaard b1a53d
 
Mark Wielaard b1a53d
 /* Given an Elf handle and a section type returns the Elf_Data d_type.
Mark Wielaard b1a53d
    Should not be called when SHF_COMPRESSED is set, the d_type should
Mark Wielaard b1a53d
diff --git a/src/readelf.c b/src/readelf.c
Mark Wielaard b1a53d
index f185897..313f940 100644
Mark Wielaard b1a53d
--- a/src/readelf.c
Mark Wielaard b1a53d
+++ b/src/readelf.c
Mark Wielaard b1a53d
@@ -7403,11 +7403,16 @@ attr_callback (Dwarf_Attribute *attrp, void *arg)
Mark Wielaard b1a53d
 	case DW_AT_GNU_call_site_data_value:
Mark Wielaard b1a53d
 	case DW_AT_GNU_call_site_target:
Mark Wielaard b1a53d
 	case DW_AT_GNU_call_site_target_clobbered:
Mark Wielaard b1a53d
-	  putchar ('\n');
Mark Wielaard b1a53d
-	  print_ops (cbargs->dwflmod, cbargs->dbg,
Mark Wielaard b1a53d
-		     12 + level * 2, 12 + level * 2,
Mark Wielaard b1a53d
-		     cbargs->version, cbargs->addrsize, cbargs->offset_size,
Mark Wielaard b1a53d
-		     attrp->cu, block.length, block.data);
Mark Wielaard b1a53d
+	  if (form != DW_FORM_data16)
Mark Wielaard b1a53d
+	    {
Mark Wielaard b1a53d
+	      putchar ('\n');
Mark Wielaard b1a53d
+	      print_ops (cbargs->dwflmod, cbargs->dbg,
Mark Wielaard b1a53d
+			 12 + level * 2, 12 + level * 2,
Mark Wielaard b1a53d
+			 cbargs->version, cbargs->addrsize, cbargs->offset_size,
Mark Wielaard b1a53d
+			 attrp->cu, block.length, block.data);
Mark Wielaard b1a53d
+	    }
Mark Wielaard b1a53d
+	  else
Mark Wielaard b1a53d
+	    print_block (block.length, block.data);
Mark Wielaard b1a53d
 	  break;
Mark Wielaard b1a53d
 	}
Mark Wielaard b1a53d
       break;
Mark Wielaard b1a53d
@@ -7907,7 +7912,7 @@ print_form_data (Dwarf *dbg, int form, const unsigned char *readp,
Mark Wielaard b1a53d
       break;
Mark Wielaard b1a53d
 
Mark Wielaard b1a53d
     case DW_FORM_block4:
Mark Wielaard b1a53d
-      if (readendp - readp < 2)
Mark Wielaard b1a53d
+      if (readendp - readp < 4)
Mark Wielaard b1a53d
 	goto invalid_data;
Mark Wielaard b1a53d
       val = read_4ubyte_unaligned_inc (dbg, readp);
Mark Wielaard b1a53d
       if ((size_t) (readendp - readp) < val)
Mark Wielaard b1a53d
@@ -7994,9 +7999,9 @@ print_form_data (Dwarf *dbg, int form, const unsigned char *readp,
Mark Wielaard b1a53d
 	    {
Mark Wielaard b1a53d
 	      Dwarf_Off idx;
Mark Wielaard b1a53d
 	      if (offset_len == 8)
Mark Wielaard b1a53d
-		idx = read_8ubyte_unaligned_inc (dbg, strreadp);
Mark Wielaard b1a53d
+		idx = read_8ubyte_unaligned (dbg, strreadp);
Mark Wielaard b1a53d
 	      else
Mark Wielaard b1a53d
-		idx = read_4ubyte_unaligned_inc (dbg, strreadp);
Mark Wielaard b1a53d
+		idx = read_4ubyte_unaligned (dbg, strreadp);
Mark Wielaard b1a53d
 
Mark Wielaard b1a53d
 	      data = dbg->sectiondata[IDX_debug_str];
Mark Wielaard b1a53d
 	      if (data == NULL || idx >= data->d_size
Mark Wielaard b1a53d
@@ -8013,25 +8018,25 @@ print_form_data (Dwarf *dbg, int form, const unsigned char *readp,
Mark Wielaard b1a53d
     case DW_FORM_strx1:
Mark Wielaard b1a53d
       if (readendp - readp < 1)
Mark Wielaard b1a53d
 	goto invalid_data;
Mark Wielaard b1a53d
-      val = *readp;
Mark Wielaard b1a53d
+      val = *readp++;
Mark Wielaard b1a53d
       goto strx_val;
Mark Wielaard b1a53d
 
Mark Wielaard b1a53d
     case DW_FORM_strx2:
Mark Wielaard b1a53d
       if (readendp - readp < 2)
Mark Wielaard b1a53d
 	goto invalid_data;
Mark Wielaard b1a53d
-      val = read_2ubyte_unaligned (dbg, readp);
Mark Wielaard b1a53d
+      val = read_2ubyte_unaligned_inc (dbg, readp);
Mark Wielaard b1a53d
       goto strx_val;
Mark Wielaard b1a53d
 
Mark Wielaard b1a53d
     case DW_FORM_strx3:
Mark Wielaard b1a53d
       if (readendp - readp < 3)
Mark Wielaard b1a53d
 	goto invalid_data;
Mark Wielaard b1a53d
-      val = read_3ubyte_unaligned (dbg, readp);
Mark Wielaard b1a53d
+      val = read_3ubyte_unaligned_inc (dbg, readp);
Mark Wielaard b1a53d
       goto strx_val;
Mark Wielaard b1a53d
 
Mark Wielaard b1a53d
     case DW_FORM_strx4:
Mark Wielaard b1a53d
       if (readendp - readp < 4)
Mark Wielaard b1a53d
 	goto invalid_data;
Mark Wielaard b1a53d
-      val = read_4ubyte_unaligned (dbg, readp);
Mark Wielaard b1a53d
+      val = read_4ubyte_unaligned_inc (dbg, readp);
Mark Wielaard b1a53d
       goto strx_val;
Mark Wielaard b1a53d
 
Mark Wielaard b1a53d
     default:
Mark Wielaard b1a53d
@@ -9230,7 +9235,9 @@ print_debug_loc_section (Dwfl_Module *dwflmod,
Mark Wielaard b1a53d
 						    listptr_idx);
Mark Wielaard b1a53d
 	  const unsigned char *locp = readp;
Mark Wielaard b1a53d
 	  const unsigned char *locendp;
Mark Wielaard b1a53d
-	  if (next_off == 0)
Mark Wielaard b1a53d
+	  if (next_off == 0
Mark Wielaard b1a53d
+	      || next_off > (size_t) (endp
Mark Wielaard b1a53d
+				      - (const unsigned char *) data->d_buf))
Mark Wielaard b1a53d
 	    locendp = endp;
Mark Wielaard b1a53d
 	  else
Mark Wielaard b1a53d
 	    locendp = (const unsigned char *) data->d_buf + next_off;