Re: [PATCH] libdw, readelf: Handle .debug_*.dwo section name variants.

2018-05-19 Thread Mark Wielaard
On Tue, May 15, 2018 at 12:33:33PM +0200, Mark Wielaard wrote:
> The .debug_*.dwo section names are handled just like their none .dwo
> variants.  The section contents is the same as sections without the .dwo
> name, but they are only found in split-dwarf files.  This patch allows
> opening and inspecting split-dwarf files.  It doesn't yet connect the
> split-dwarf with their skeleton (or the other way around).  It also
> doesn't yet handle any special split-dwarf attributes or tags.

Pushed to master.


Re: [PATCH] libdw: Add GNU DebugFission attributes, tags, forms and operands.

2018-05-19 Thread Mark Wielaard
On Tue, May 15, 2018 at 01:27:00PM +0200, Mark Wielaard wrote:
> Most are handled just like their DWARF5 counterparts.

Pushed to master.


Re: [PATCH] libdw: Recognize GNU DebugFission split units.

2018-05-19 Thread Mark Wielaard
On Tue, May 15, 2018 at 02:04:31PM +0200, Mark Wielaard wrote:
> The split dwarf dwo unit id and type are not in the CU header itself, but
> can be found in the CU DIE DW_AT_GNU_dwo attributes. Use this to set the
> correct unit_type and id for GNU DebugFission split units. Also show this
> information in eu-readelf when printing units.

Pushed to master.


[PATCH] libdw: Handle GNU DebugFission split ranges.

2018-05-19 Thread Mark Wielaard
GNU DebugFission split dwarf handles DW_FORM_sec_offset specially for
attributes that point to ranges. The .debug_ranges section is not in
the .dwo file, but in the main/skeleton object file. The sec_offset is
not relocated (in the ELF file), but is an offset against the skeleton
DIE DW_AT_GNU_ranges_base attribute. dwarf_formudata is changed so it
still looks like a normal offset ptr into the .debug_ranges section.
dwarf_ranges is adapted to look for the .debug_ranges in the main object
file. dwarf_highpc and dwarf_lowpc now handle the highpc and lowpc
attributes being inherited for the split unit DIE from the skeleton.

A new testcase is added to iterate over all ranges in a split GNU
DebugFission file.

Signed-off-by: Mark Wielaard 
---
 libdw/ChangeLog  |  12 
 libdw/dwarf_formudata.c  |  50 +--
 libdw/dwarf_highpc.c |  18 +++---
 libdw/dwarf_lowpc.c  |  15 ++---
 libdw/dwarf_ranges.c |  22 +--
 libdw/libdwP.h   |  26 
 tests/ChangeLog  |  14 +
 tests/Makefile.am|  11 +++-
 tests/all-dwarf-ranges.c |  90 +++
 tests/run-all-dwarf-ranges.sh|  49 +++
 tests/testfile-ranges-hello.dwo.bz2  | Bin 0 -> 948 bytes
 tests/testfile-ranges-world.dwo.bz2  | Bin 0 -> 1176 bytes
 tests/testfilesplitranges4.debug.bz2 | Bin 0 -> 2154 bytes
 13 files changed, 281 insertions(+), 26 deletions(-)
 create mode 100644 tests/all-dwarf-ranges.c
 create mode 100755 tests/run-all-dwarf-ranges.sh
 create mode 100644 tests/testfile-ranges-hello.dwo.bz2
 create mode 100644 tests/testfile-ranges-world.dwo.bz2
 create mode 100755 tests/testfilesplitranges4.debug.bz2

diff --git a/libdw/ChangeLog b/libdw/ChangeLog
index e067827b..caa2d124 100644
--- a/libdw/ChangeLog
+++ b/libdw/ChangeLog
@@ -1,3 +1,15 @@
+2018-05-18  Mark Wielaard  
+
+   * dwarf_formudata.c (__libdw_formptr): Handle the special case
+   of IDX_debug_ranges for DW_UT_split_compile with version < 5.
+   * dwarf_highpc.c (dwarf_highpc): Use dwarf_lowpc, check for
+   split compile cudie.
+   * dwarf_lowpc.c (dwarf_lowpc): Check for split compile cudie.
+   * dwarf_ranges.c (dwarf_ranges): Switch cu and sectiondata for
+   split compile units.
+   * libdwP.h (struct Dwarf_CU): Add ranges_base field.
+   (__libdw_cu_ranges_base): New static inline function.
+
 2018-05-18  Mark Wielaard  
 
* libdw_findcu.c (__libdw_intern_next_unit): Init files to NULL.
diff --git a/libdw/dwarf_formudata.c b/libdw/dwarf_formudata.c
index 19d34f8e..316ad865 100644
--- a/libdw/dwarf_formudata.c
+++ b/libdw/dwarf_formudata.c
@@ -43,6 +43,17 @@ __libdw_formptr (Dwarf_Attribute *attr, int sec_index,
 return NULL;
 
   const Elf_Data *d = attr->cu->dbg->sectiondata[sec_index];
+  Dwarf_CU *skel = NULL; /* See below, needed for GNU DebugFission.  */
+  if (unlikely (d == NULL
+   && sec_index == IDX_debug_ranges
+   && attr->cu->version < 5
+   && attr->cu->unit_type == DW_UT_split_compile))
+{
+  skel = __libdw_find_split_unit (attr->cu);
+  if (skel != NULL)
+   d = skel->dbg->sectiondata[IDX_debug_ranges];
+}
+
   if (unlikely (d == NULL))
 {
   __libdw_seterrno (err_nodata);
@@ -52,10 +63,41 @@ __libdw_formptr (Dwarf_Attribute *attr, int sec_index,
   Dwarf_Word offset;
   if (attr->form == DW_FORM_sec_offset)
 {
-  if (__libdw_read_offset (attr->cu->dbg, attr->cu->dbg,
-  cu_sec_idx (attr->cu), attr->valp,
-  attr->cu->offset_size, &offset, sec_index, 0))
-   return NULL;
+  /* GNU DebugFission is slightly odd.  It uses DW_FORM_sec_offset
+in split units, but they are really (unrelocated) offsets
+from the skeleton DW_AT_GNU_ranges_base (which is only used
+for the split unit, not the skeleton ranges itself, see also
+DW_AT_rnglists_base, which is used in DWARF5 for both, but
+points to the offsets index).  So it isn't really a formptr,
+but an offset + base calculation.  */
+  if (unlikely (skel != NULL))
+   {
+ Elf_Data *data = attr->cu->dbg->sectiondata[cu_sec_idx (attr->cu)];
+ const unsigned char *datap = attr->valp;
+ size_t size = attr->cu->offset_size;
+ if (unlikely (data == NULL
+   || datap < (const unsigned char *) data->d_buf
+   || data->d_size < size
+   || ((size_t) (datap
+ - (const unsigned char *) data->d_buf)
+   > data->d_size - size)))
+   goto invalid;
+
+ if (size == 4)
+   offset = read_4ubyte_unaligned (attr->cu->dbg, datap);
+ else
+   offset = read_8ubyte_unaligned (attr->cu->dbg, datap);
+
+ offset += __l

Re: [PATCH] libdw: dwarf_get_units find split units from .dwo.

2018-05-19 Thread Mark Wielaard
On Wed, May 16, 2018 at 09:15:01PM +0200, Mark Wielaard wrote:
> For a skeleton DIE dwarf_get_units should provide the split DIE as subdie.
> This implements that by trying to find the (named) .dwo file and finding
> the matching CU in it. The .dwo file is search relative to the current
> DWARF or using the comp_dir of the skeleton DIE.
> 
> Also fixes a small issue with str_offsets_base_off which is tested in the
> new testcase (by getting the name of the split CU DIE).

Pushed to master.


[COMMITTED] Mark __libdw_find_split_unit mark as internal_function.

2018-05-19 Thread Mark Wielaard
As pointed out by the i386-debian buildbot.

The prototype and definition should match. On i386 this is important
because it changes the calling convention.

Signed-off-by: Mark Wielaard 
---
 libdw/ChangeLog | 4 
 libdw/libdwP.h  | 3 ++-
 2 files changed, 6 insertions(+), 1 deletion(-)

diff --git a/libdw/ChangeLog b/libdw/ChangeLog
index a87a7092..fffe0cc9 100644
--- a/libdw/ChangeLog
+++ b/libdw/ChangeLog
@@ -1,3 +1,7 @@
+2018-05-19  Mark Wielaard  
+
+   * libdwP.h (__libdw_find_split_unit): Mark as internal_function.
+
 2018-05-15  Mark Wielaard  
 
* Makefile.am (libdw_a_SOURCES): Add libdw_find_split_unit.c.
diff --git a/libdw/libdwP.h b/libdw/libdwP.h
index 60572276..db14b689 100644
--- a/libdw/libdwP.h
+++ b/libdw/libdwP.h
@@ -596,7 +596,8 @@ extern struct Dwarf_CU *__libdw_findcu_addr (Dwarf *dbg, 
void *addr)
  __nonnull_attribute__ (1) internal_function;
 
 /* Find the split (or skeleton) unit.  */
-extern struct Dwarf_CU *__libdw_find_split_unit (Dwarf_CU *cu);
+extern struct Dwarf_CU *__libdw_find_split_unit (Dwarf_CU *cu)
+ internal_function;
 
 /* Get abbreviation with given code.  */
 extern Dwarf_Abbrev *__libdw_findabbrev (struct Dwarf_CU *cu,
-- 
2.17.0