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;
+ }