[PATCH] libdwfl: Allow partial relocations also for debug files.

2018-05-27 Thread Mark Wielaard
__libdwfl_relocate is called for get_dwarf and get_elf. We allow not all
relocations to be resolved for Elf files, but required all relocations
(in the debug sections) to be fully resoled in Dwarf files. This used to
mostly work out with .o ET_REL files when the main Elf was gotten before
the Dwarf. But with .dwo files, we (readelf) might open the .o file just
for the (skeleton) Dwarf. In this case it could happen not all relocations
in the debug sections could be resolved (.debug_info and .debug_addr might
contain referenes to undefined symbols). So allow partial relocations
also for debug files.

Signed-off-by: Mark Wielaard 
---
 libdwfl/ChangeLog  | 5 +
 libdwfl/relocate.c | 2 +-
 2 files changed, 6 insertions(+), 1 deletion(-)

diff --git a/libdwfl/ChangeLog b/libdwfl/ChangeLog
index d69fe0c..34aa07d 100644
--- a/libdwfl/ChangeLog
+++ b/libdwfl/ChangeLog
@@ -1,3 +1,8 @@
+2018-05-27  Mark Wielaard  
+
+   * relocate.c (__libdwfl_relocate): Always call relocate_section with
+   partial true.
+
 2018-05-17  Mark Wielaard  
 
* dwfl_module (__libdwfl_module_free): Free elfdir.
diff --git a/libdwfl/relocate.c b/libdwfl/relocate.c
index 1768243..9afcdeb 100644
--- a/libdwfl/relocate.c
+++ b/libdwfl/relocate.c
@@ -751,7 +751,7 @@ __libdwfl_relocate (Dwfl_Module *mod, Elf *debugfile, bool 
debug)
  else
result = relocate_section (mod, debugfile, ehdr, d_shstrndx,
   &reloc_symtab, scn, shdr, tscn,
-  debug, !debug);
+  debug, true /* partial always OK. */);
}
 }
 
-- 
1.8.3.1



[PATCH] readelf: Handle .debug_loclists.

2018-05-27 Thread Mark Wielaard
The new DWARF5 .debug_loclists sections are like .debug_rnglists, but
plus locations. For Split Dwarf GCC generates the .debug_loclists fully
in the split .dwo file. Any references to addresses need to be resolved
through the skeleton .debug_addr section.

Signed-off-by: Mark Wielaard 
---
 libdw/ChangeLog   |  15 ++
 libdw/dwarf.h |  16 ++
 libdw/dwarf_begin_elf.c   |   1 +
 libdw/dwarf_error.c   |   4 +-
 libdw/dwarf_formudata.c   |  23 +-
 libdw/dwarf_getlocation.c |   4 +-
 libdw/libdwP.h|   5 +-
 src/ChangeLog |  19 ++
 src/readelf.c | 562 --
 tests/ChangeLog   |   4 +
 tests/run-readelf-loc.sh  | 560 +
 11 files changed, 1191 insertions(+), 22 deletions(-)

diff --git a/libdw/ChangeLog b/libdw/ChangeLog
index 9991686..0db49bf 100644
--- a/libdw/ChangeLog
+++ b/libdw/ChangeLog
@@ -1,3 +1,18 @@
+2018-04-12  Mark Wielaard  
+
+   * dwarf.h: Add DWARF5 location list entry DW_LLE encodings.
+   * begin_elf.c (dwarf_scnnames): Add IDX_debug_loclists.
+   * dwarf_error.c (errmsgs): Remove DWARF_E_NO_LOCLIST. And replace
+   with DWARF_E_NO_DEBUG_LOC, DWARF_E_NO_DEBUG_LOCLISTS and
+   DWARF_E_NO_LOC_VALUE.
+   * dwarf_formudata.c (dwarf_formudata): Handle DW_AT_loclists_base
+   and DW_FORM_loclistx.
+   * dwarf_getlocation.c (attr_ok): Use DWARF_E_NO_LOC_VALUE.
+   (initial_offset): Use DWARF_E_NO_DEBUG_LOC.
+   * libdwP.h: Add IDX_debug_rnglists. Remove DWARF_E_NO_LOCLIST.
+   Add DWARF_E_NO_DEBUG_LOC, DWARF_E_NO_DEBUG_LOCLISTS and
+   DWARF_E_NO_LOC_VALUE.
+
 2018-05-25  Mark Wielaard  
 
* libdw_find_split_unit.c (__libdw_find_split_unit): Extract linking
diff --git a/libdw/dwarf.h b/libdw/dwarf.h
index 9c2495e..8985a9d 100644
--- a/libdw/dwarf.h
+++ b/libdw/dwarf.h
@@ -899,6 +899,22 @@ enum
 DW_RLE_start_length = 0x7
   };
 
+
+/* Location list entry encoding.  */
+enum
+  {
+DW_LLE_end_of_list = 0x0,
+DW_LLE_base_addressx = 0x1,
+DW_LLE_startx_endx = 0x2,
+DW_LLE_startx_length = 0x3,
+DW_LLE_offset_pair = 0x4,
+DW_LLE_default_location = 0x5,
+DW_LLE_base_address = 0x6,
+DW_LLE_start_end = 0x7,
+DW_LLE_start_length = 0x8
+  };
+
+
 /* DWARF call frame instruction encodings.  */
 enum
   {
diff --git a/libdw/dwarf_begin_elf.c b/libdw/dwarf_begin_elf.c
index 2e8c5f3..af5096f 100644
--- a/libdw/dwarf_begin_elf.c
+++ b/libdw/dwarf_begin_elf.c
@@ -58,6 +58,7 @@ static const char dwarf_scnnames[IDX_last][19] =
   [IDX_debug_line_str] = ".debug_line_str",
   [IDX_debug_frame] = ".debug_frame",
   [IDX_debug_loc] = ".debug_loc",
+  [IDX_debug_loclists] = ".debug_loclists",
   [IDX_debug_pubnames] = ".debug_pubnames",
   [IDX_debug_str] = ".debug_str",
   [IDX_debug_str_offsets] = ".debug_str_offsets",
diff --git a/libdw/dwarf_error.c b/libdw/dwarf_error.c
index 2e8cd77..46ea16b 100644
--- a/libdw/dwarf_error.c
+++ b/libdw/dwarf_error.c
@@ -85,7 +85,9 @@ static const char *errmsgs[] =
 [DWARF_E_VERSION] = N_("invalid DWARF version"),
 [DWARF_E_INVALID_DIR_IDX] = N_("invalid directory index"),
 [DWARF_E_ADDR_OUTOFRANGE] = N_("address out of range"),
-[DWARF_E_NO_LOCLIST] = N_("no location list value"),
+[DWARF_E_NO_DEBUG_LOC] = N_(".debug_loc section missing"),
+[DWARF_E_NO_DEBUG_LOCLISTS] = N_(".debug_loclists section missing"),
+[DWARF_E_NO_LOC_VALUE] = N_("not a location list value"),
 [DWARF_E_NO_BLOCK] = N_("no block data"),
 [DWARF_E_INVALID_LINE_IDX] = N_("invalid line index"),
 [DWARF_E_INVALID_ARANGE_IDX] = N_("invalid address range index"),
diff --git a/libdw/dwarf_formudata.c b/libdw/dwarf_formudata.c
index 280fef2..26f86f1 100644
--- a/libdw/dwarf_formudata.c
+++ b/libdw/dwarf_formudata.c
@@ -184,11 +184,23 @@ dwarf_formudata (Dwarf_Attribute *attr, Dwarf_Word 
*return_uval)
case DW_AT_use_location:
case DW_AT_vtable_elem_location:
case DW_AT_GNU_locviews:
- /* loclistptr */
- if (__libdw_formptr (attr, IDX_debug_loc,
-  DWARF_E_NO_LOCLIST, NULL,
-  return_uval) == NULL)
-   return -1;
+   case DW_AT_loclists_base:
+ if (attr->cu->version < 5)
+   {
+ /* loclistptr */
+ if (__libdw_formptr (attr, IDX_debug_loc,
+  DWARF_E_NO_DEBUG_LOC, NULL,
+  return_uval) == NULL)
+   return -1;
+   }
+ else
+   {
+ /* loclist, loclistsptr */
+ if (__libdw_formptr (attr, IDX_debug_loclists,
+  DWARF_E_NO_DEBUG_LOCLISTS, NULL,
+  return_uval) == NULL)
+   return -1;
+   }
   

Re: [PATCH] readelf: Add .debug_rnglists support.

2018-05-27 Thread Mark Wielaard
On Wed, May 23, 2018 at 04:29:56PM +0200, Mark Wielaard wrote:
> Parse the .debug_rnglists section for DWARF5 --debug-dump=ranges.
> Add testcase to show both "normal" and "split" DWARF variants are
> handled for DWARF4 and DWARF5.

Pushed to master.