[PATCH] Recognize new DWARF5 attribute forms.

Mark Wielaard mark@klomp.org
Thu Feb 8 16:07:00 GMT 2018


This just makes sure we know how the new forms are encoded.
It doesn't yet handle them in the dwarf_form* functions.
But it does make it possible to skip them when reading DWARF5.

DW_FORM_implicit_const has zero size (the value is in the abbrev,
not in the info). DW_FORM_addrx[1234], DW_FORM_strx[1234],
DW_FORM_ref_sup[48] and DW_FORM_data16 have constant size.
DW_FORM_strp_sup and DW_FORM_line_strp are offset size.
DW_FORM_addrx, DW_FORM_strx, DW_FORM_loclistx and DW_FORM_rnglistx
encode a uleb128.

Signed-off-by: Mark Wielaard <mark@klomp.org>
---
 libdw/ChangeLog    | 10 ++++++++++
 libdw/dwarf.h      | 18 ++++++++++++++++++
 libdw/libdwP.h     | 22 ++++++++++++++++++----
 libdw/libdw_form.c |  6 ++++++
 4 files changed, 52 insertions(+), 4 deletions(-)

diff --git a/libdw/ChangeLog b/libdw/ChangeLog
index 8e3bbef..65e4ddc 100644
--- a/libdw/ChangeLog
+++ b/libdw/ChangeLog
@@ -1,3 +1,13 @@
+2018-02-08  Mark Wielaard  <mark@klomp.org>
+
+	* dwarf.h: Add DWARF5 DW_FORMs.
+	* libdwP.h (__libdw_form_val_compute_len): Handle fix length
+	DW_FORM_implicit_const, DW_FORM_addrx[1234], DW_FORM_strx[1234],
+	DW_FORM_ref_sup[48] and DW_FORM_data16.
+	* libdw_form.c (__libdw_form_val_compute_len): DW_FORM_strp_sup
+	and DW_FORM_line_strp are offset_size. DW_FORM_addrx, DW_FORM_strx,
+	DW_FORM_loclistx and DW_FORM_rnglistx are uleb128.
+
 2018-01-30  Mark Wielaard  <mark@klomp.org>
 
 	* Makefile.am (libdw_a_SOURCES): Add dwarf_get_units.c.
diff --git a/libdw/dwarf.h b/libdw/dwarf.h
index bf81694..4f36206 100644
--- a/libdw/dwarf.h
+++ b/libdw/dwarf.h
@@ -382,7 +382,25 @@ enum
     DW_FORM_sec_offset = 0x17,
     DW_FORM_exprloc = 0x18,
     DW_FORM_flag_present = 0x19,
+    DW_FORM_strx = 0x1a,
+    DW_FORM_addrx = 0x1b,
+    DW_FORM_ref_sup4 = 0x1c,
+    DW_FORM_strp_sup = 0x1d,
+    DW_FORM_data16 = 0x1e,
+    DW_FORM_line_strp = 0x1f,
     DW_FORM_ref_sig8 = 0x20,
+    DW_FORM_implicit_const = 0x21,
+    DW_FORM_loclistx = 0x22,
+    DW_FORM_rnglistx = 0x23,
+    DW_FORM_ref_sup8 = 0x24,
+    DW_FORM_strx1 = 0x25,
+    DW_FORM_strx2 = 0x26,
+    DW_FORM_strx3 = 0x27,
+    DW_FORM_strx4 = 0x28,
+    DW_FORM_addrx1 = 0x29,
+    DW_FORM_addrx2 = 0x2a,
+    DW_FORM_addrx3 = 0x2b,
+    DW_FORM_addrx4 = 0x2c,
 
     DW_FORM_GNU_ref_alt = 0x1f20, /* offset in alternate .debuginfo.  */
     DW_FORM_GNU_strp_alt = 0x1f21 /* offset in alternate .debug_str. */
diff --git a/libdw/libdwP.h b/libdw/libdwP.h
index 10d1a86..b31497d 100644
--- a/libdw/libdwP.h
+++ b/libdw/libdwP.h
@@ -576,7 +576,7 @@ extern size_t __libdw_form_val_compute_len (struct Dwarf_CU *cu,
 					    const unsigned char *valp)
      __nonnull_attribute__ (1, 3) internal_function;
 
-/* Find the length of a form attribute.  */
+/* Find the length of a form attribute in DIE/info data.  */
 static inline size_t
 __nonnull_attribute__ (1, 3)
 __libdw_form_val_len (struct Dwarf_CU *cu, unsigned int form,
@@ -587,10 +587,24 @@ __libdw_form_val_len (struct Dwarf_CU *cu, unsigned int form,
   static const uint8_t form_lengths[] =
     {
       [DW_FORM_flag_present] = 0x80,
-      [DW_FORM_data1] = 1, [DW_FORM_ref1] = 1, [DW_FORM_flag] = 1,
+      [DW_FORM_implicit_const] = 0x80, /* Value is in abbrev, not in info.  */
+
+      [DW_FORM_flag] = 1,
+      [DW_FORM_data1] = 1, [DW_FORM_ref1] = 1,
+      [DW_FORM_addrx1] = 1, [DW_FORM_strx1] = 1,
+
       [DW_FORM_data2] = 2, [DW_FORM_ref2] = 2,
-      [DW_FORM_data4] = 4, [DW_FORM_ref4] = 4,
-      [DW_FORM_data8] = 8, [DW_FORM_ref8] = 8, [DW_FORM_ref_sig8] = 8,
+      [DW_FORM_addrx2] = 2, [DW_FORM_strx2] = 2,
+
+      [DW_FORM_addrx3] = 3, [DW_FORM_strx3] = 3,
+
+      [DW_FORM_data4] = 4, [DW_FORM_ref4] = 4, [DW_FORM_ref_sup4] = 4,
+      [DW_FORM_addrx4] = 4, [DW_FORM_strx4] = 4,
+
+      [DW_FORM_ref_sig8] = 8,
+      [DW_FORM_data8] = 8, [DW_FORM_ref8] = 8, [DW_FORM_ref_sup8] = 8,
+
+      [DW_FORM_data16] = 16,
     };
 
   /* Return immediately for forms with fixed lengths.  */
diff --git a/libdw/libdw_form.c b/libdw/libdw_form.c
index 72e2390..ebe6002 100644
--- a/libdw/libdw_form.c
+++ b/libdw/libdw_form.c
@@ -60,6 +60,8 @@ __libdw_form_val_compute_len (struct Dwarf_CU *cu, unsigned int form,
       break;
 
     case DW_FORM_strp:
+    case DW_FORM_strp_sup:
+    case DW_FORM_line_strp:
     case DW_FORM_sec_offset:
     case DW_FORM_GNU_ref_alt:
     case DW_FORM_GNU_strp_alt:
@@ -103,6 +105,10 @@ __libdw_form_val_compute_len (struct Dwarf_CU *cu, unsigned int form,
     case DW_FORM_sdata:
     case DW_FORM_udata:
     case DW_FORM_ref_udata:
+    case DW_FORM_addrx:
+    case DW_FORM_loclistx:
+    case DW_FORM_rnglistx:
+    case DW_FORM_strx:
       get_uleb128 (u128, valp, endp);
       result = valp - startp;
       break;
-- 
1.8.3.1



More information about the Elfutils-devel mailing list