[PATCH] Recognize new DWARF5 attribute forms.

2018-02-08 Thread Mark Wielaard
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 
---
 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  
+
+   * 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  
 
* 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



[PATCH] Add fallthrough attributes

2018-02-08 Thread Joshua Watt
Adds the __attribute__ ((fallthrough)) annotation to all the places
where switch case fallthrough was occurring. This allows the
-Wimplicit-fallthrough warning to be used even after the source has been
pre-processed.

Signed-off-by: Joshua Watt 
---
 backends/i386_regs.c |  3 +++
 backends/i386_retval.c   |  3 +++
 backends/m68k_retval.c   |  3 +++
 backends/ppc_regs.c  |  3 +++
 backends/x86_64_regs.c   |  3 +++
 configure.ac | 22 ++
 libcpu/i386_disasm.c |  3 +++
 libdw/cfi.c  |  6 ++
 libdw/dwarf_frame_register.c |  3 +++
 libdwfl/dwfl_report_elf.c|  3 +++
 libdwfl/frame_unwind.c   |  3 +++
 libebl/eblobjnote.c  |  3 +++
 libelf/elf32_updatenull.c|  3 +++
 libelf/elf_begin.c   |  6 ++
 libelf/elf_cntl.c|  3 +++
 src/addr2line.c  |  3 +++
 src/elfcompress.c|  3 +++
 src/elflint.c| 12 
 src/objdump.c|  3 +++
 src/readelf.c|  3 +++
 src/strings.c|  3 +++
 tests/backtrace.c|  3 +++
 tests/elfstrmerge.c  |  3 +++
 23 files changed, 103 insertions(+)

diff --git a/backends/i386_regs.c b/backends/i386_regs.c
index fd963a62..1488c1e7 100644
--- a/backends/i386_regs.c
+++ b/backends/i386_regs.c
@@ -92,6 +92,9 @@ i386_register_info (Ebl *ebl __attribute__ ((unused)),
 case 5:
 case 8:
   *type = DW_ATE_address;
+#ifdef HAVE_FALLTHROUGH
+  __attribute__ ((fallthrough));
+#endif
   /* Fallthrough */
 case 0 ... 3:
 case 6 ... 7:
diff --git a/backends/i386_retval.c b/backends/i386_retval.c
index 4aa646fe..56493a74 100644
--- a/backends/i386_retval.c
+++ b/backends/i386_retval.c
@@ -123,6 +123,9 @@ i386_return_value_location (Dwarf_Die *functypedie, const 
Dwarf_Op **locp)
if (size <= 8)
  return nloc_intregpair;
   }
+#ifdef HAVE_FALLTHROUGH
+__attribute__ ((fallthrough));
+#endif
 /* Fallthrough */
 
 case DW_TAG_structure_type:
diff --git a/backends/m68k_retval.c b/backends/m68k_retval.c
index c68ed022..d9ff5cf6 100644
--- a/backends/m68k_retval.c
+++ b/backends/m68k_retval.c
@@ -135,6 +135,9 @@ m68k_return_value_location (Dwarf_Die *functypedie, const 
Dwarf_Op **locp)
if (size <= 8)
  return nloc_intregpair;
   }
+#ifdef HAVE_FALLTHROUGH
+  __attribute__ ((fallthrough));
+#endif
   /* Fallthrough */
 case DW_TAG_structure_type:
 case DW_TAG_class_type:
diff --git a/backends/ppc_regs.c b/backends/ppc_regs.c
index c2d50118..0e0fed20 100644
--- a/backends/ppc_regs.c
+++ b/backends/ppc_regs.c
@@ -140,6 +140,9 @@ ppc_register_info (Ebl *ebl __attribute__ ((unused)),
 case 100:
   if (*bits == 32)
return stpcpy (name, "mq") + 1 - name;
+#ifdef HAVE_FALLTHROUGH
+  __attribute__ ((fallthrough));
+#endif
   /* Fallthrough */
 case 102 ... 107:
   name[0] = 's';
diff --git a/backends/x86_64_regs.c b/backends/x86_64_regs.c
index 84304407..a867b0d3 100644
--- a/backends/x86_64_regs.c
+++ b/backends/x86_64_regs.c
@@ -87,6 +87,9 @@ x86_64_register_info (Ebl *ebl __attribute__ ((unused)),
 
 case 6 ... 7:
   *type = DW_ATE_address;
+#ifdef HAVE_FALLTHROUGH
+  __attribute__ ((fallthrough));
+#endif
   /* Fallthrough */
 case 0 ... 5:
   name[0] = 'r';
diff --git a/configure.ac b/configure.ac
index 4ab8816a..3e91b367 100644
--- a/configure.ac
+++ b/configure.ac
@@ -143,6 +143,28 @@ if test "$ac_cv_visibility" = "yes"; then
  [Defined if __attribute__((visibility())) is supported])
 fi
 
+AC_CACHE_CHECK([whether gcc supports __attribute__((fallthrough))],
+   ac_cv_fallthrough, [dnl
+save_CFLAGS="$CFLAGS"
+CFLAGS="$save_CFLAGS -Werror"
+AC_COMPILE_IFELSE([AC_LANG_SOURCE([dnl
+void
+foo (int a)
+{
+  switch(a)
+{
+case 1:
+__attribute__((fallthrough));
+default:
+break;
+}
+}])], ac_cv_fallthrough=yes, ac_cv_fallthrough=no)
+CFLAGS="$save_CFLAGS"])
+if test "$ac_cv_fallthrough" = "yes"; then
+   AC_DEFINE([HAVE_FALLTHROUGH], [1],
+ [Defined if __attribute__((fallthrough)) is supported])
+fi
+
 AC_CACHE_CHECK([whether gcc supports __attribute__((gcc_struct))],
ac_cv_gcc_struct, [dnl
 save_CFLAGS="$CFLAGS"
diff --git a/libcpu/i386_disasm.c b/libcpu/i386_disasm.c
index 831afbe2..740a637a 100644
--- a/libcpu/i386_disasm.c
+++ b/libcpu/i386_disasm.c
@@ -819,6 +819,9 @@ i386_disasm (Ebl *ebl __attribute__((unused)),
  ++param_start;
  break;
}
+#ifdef HAVE_FALLTHROUGH
+ __attribute__ ((fallthrough));
+#endif
  /* Fallthrough */
default:
  assert (! "INVALID not handled");
diff --git a/libdw/cfi.c b/libdw/cfi.c
index daa845f3..b8f51266 100644
--- a/libdw/cfi.c
+++ b/libdw/cfi.c
@@ -

[PATCH v2] Add fallthrough attributes

2018-02-08 Thread Joshua Watt
Adds the __attribute__ ((fallthrough)) annotation to all the places
where switch case fallthrough was occurring. This allows the
-Wimplicit-fallthrough warning to be used even after the source has been
pre-processed.

If the fallthrough attribute is supported, the -Wimplicit-fallthrough
warning is strengthened so that it *only* allows the attribute; comments
alone are insufficient.

Signed-off-by: Joshua Watt 
---
 backends/aarch64_retval.c|  3 +++
 backends/alpha_retval.c  |  6 ++
 backends/arm_regs.c  |  3 +++
 backends/arm_retval.c|  3 +++
 backends/i386_regs.c |  3 +++
 backends/i386_retval.c   |  6 ++
 backends/ia64_retval.c   |  3 +++
 backends/linux-core-note.c   |  3 +++
 backends/m68k_retval.c   |  6 ++
 backends/ppc64_retval.c  |  9 +
 backends/ppc_regs.c  |  3 +++
 backends/ppc_retval.c|  6 ++
 backends/s390_retval.c   |  6 ++
 backends/sh_retval.c |  3 +++
 backends/sparc_retval.c  |  3 +++
 backends/tilegx_retval.c |  6 ++
 backends/x86_64_regs.c   |  3 +++
 backends/x86_64_retval.c |  3 +++
 config/eu.am |  4 
 configure.ac | 24 
 libcpu/i386_disasm.c |  3 +++
 libdw/cfi.c  |  6 ++
 libdw/dwarf_frame_register.c |  3 +++
 libdwfl/dwfl_report_elf.c|  3 +++
 libdwfl/frame_unwind.c   |  3 +++
 libebl/eblobjnote.c  |  3 +++
 libelf/elf32_updatenull.c|  3 +++
 libelf/elf_begin.c   |  6 ++
 libelf/elf_cntl.c|  3 +++
 src/addr2line.c  |  3 +++
 src/elfcompress.c|  3 +++
 src/elflint.c| 12 
 src/objdump.c|  3 +++
 src/readelf.c| 12 
 src/strings.c|  3 +++
 tests/backtrace.c|  3 +++
 tests/elfstrmerge.c  |  3 +++
 37 files changed, 181 insertions(+)

diff --git a/backends/aarch64_retval.c b/backends/aarch64_retval.c
index 68de307e..4b4d7c54 100644
--- a/backends/aarch64_retval.c
+++ b/backends/aarch64_retval.c
@@ -292,6 +292,9 @@ aarch64_return_value_location (Dwarf_Die *functypedie, 
const Dwarf_Op **locp)
  assert (count > 0);
  if (count <= 4)
return pass_hfa (locp, base_size, count);
+#ifdef HAVE_FALLTHROUGH
+ __attribute__ ((fallthrough));
+#endif
  /* Fall through.  */
 
case 1:
diff --git a/backends/alpha_retval.c b/backends/alpha_retval.c
index 53dbfa45..f19c5e4a 100644
--- a/backends/alpha_retval.c
+++ b/backends/alpha_retval.c
@@ -85,6 +85,9 @@ alpha_return_value_location (Dwarf_Die *functypedie, const 
Dwarf_Op **locp)
  typedie = dwarf_formref_die (attr, &die_mem);
  tag = DWARF_TAG_OR_RETURN (typedie);
}
+#ifdef HAVE_FALLTHROUGH
+  __attribute__ ((fallthrough));
+#endif
   /* Fall through.  */
 
 case DW_TAG_base_type:
@@ -131,6 +134,9 @@ alpha_return_value_location (Dwarf_Die *functypedie, const 
Dwarf_Op **locp)
  }
   }
 
+#ifdef HAVE_FALLTHROUGH
+  __attribute__ ((fallthrough));
+#endif
   /* Else fall through.  */
 
 case DW_TAG_structure_type:
diff --git a/backends/arm_regs.c b/backends/arm_regs.c
index 21c5ad3a..1c1ee8fd 100644
--- a/backends/arm_regs.c
+++ b/backends/arm_regs.c
@@ -77,6 +77,9 @@ arm_register_info (Ebl *ebl __attribute__ ((unused)),
 
 case 16 + 0 ... 16 + 7:
   regno += 96 - 16;
+#ifdef HAVE_FALLTHROUGH
+  __attribute__ ((fallthrough));
+#endif
   /* Fall through.  */
 case 96 + 0 ... 96 + 7:
   *setname = "FPA";
diff --git a/backends/arm_retval.c b/backends/arm_retval.c
index 7aced742..7fe6e6a9 100644
--- a/backends/arm_retval.c
+++ b/backends/arm_retval.c
@@ -82,6 +82,9 @@ arm_return_value_location (Dwarf_Die *functypedie, const 
Dwarf_Op **locp)
  typedie = dwarf_formref_die (attr, &die_mem);
  tag = DWARF_TAG_OR_RETURN (typedie);
}
+#ifdef HAVE_FALLTHROUGH
+  __attribute__ ((fallthrough));
+#endif
   /* Fall through.  */
 
 case DW_TAG_base_type:
diff --git a/backends/i386_regs.c b/backends/i386_regs.c
index fd963a62..1488c1e7 100644
--- a/backends/i386_regs.c
+++ b/backends/i386_regs.c
@@ -92,6 +92,9 @@ i386_register_info (Ebl *ebl __attribute__ ((unused)),
 case 5:
 case 8:
   *type = DW_ATE_address;
+#ifdef HAVE_FALLTHROUGH
+  __attribute__ ((fallthrough));
+#endif
   /* Fallthrough */
 case 0 ... 3:
 case 6 ... 7:
diff --git a/backends/i386_retval.c b/backends/i386_retval.c
index 4aa646fe..e36e6c4a 100644
--- a/backends/i386_retval.c
+++ b/backends/i386_retval.c
@@ -85,6 +85,9 @@ i386_return_value_location (Dwarf_Die *functypedie, const 
Dwarf_Op **locp)
  typedie = dwarf_formref_die (attr, &die_mem);
  tag = DWARF_TAG_OR_RETURN (typedie);
}
+#ifdef HAVE_FALLTHROUGH
+  __attribute__ ((fallthrough));
+#endif
   /* Fall through.  */
 
 case DW_TAG