This is the mail archive of the elfutils-devel@sourceware.org mailing list for the elfutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] libdw: Support DW_OP_addrx/constx and split DWARF addrx/constx support.


DW_OP_addrx/constx and GNU DebugFission DW_OP_GNU_addr/const_index take
as argument an index into the .debug_addr section for the associated CU.
This index gets resolved through dwarf_getlocation_attr. A new fake addr
CU is created per Dwarf for use with this new attribute. For split DWARF
files, the IDX_debug_addr gets replaced with the skeleton section and the
addr base is resolved immediately when constructing the split DWARF CU.
Move __libdw_cu_addr_base to libdwP.h to share with eu-readelf. Also
make it possible to resolve addrx[1234]/GNU_addr_index also as constant
indexes to (also) show when displaying these attributes in eu-readelf.

A new varlocs tests is added to test the resolving for both the DWARF4
and DWARF5 DW_OP variants. And now that addrx forms are resolved in
split DWARF files add the new DIEs with "single ranges" (those DIEs that
have a lowpc/highpc attribute pair) to run-all-dwarf-ranges.sh.

Signed-off-by: Mark Wielaard <mark@klomp.org>
---
 libdw/ChangeLog                   |  19 ++++
 libdw/dwarf_begin_elf.c           |  27 +++++
 libdw/dwarf_end.c                 |  12 ++-
 libdw/dwarf_formaddr.c            |  18 ----
 libdw/dwarf_formudata.c           |  33 ++++++
 libdw/dwarf_getlocation_attr.c    |  31 ++++++
 libdw/libdwP.h                    |  24 ++++-
 libdw/libdw_find_split_unit.c     |  14 +++
 src/ChangeLog                     |   9 ++
 src/readelf.c                     |  64 ++++++++++--
 tests/ChangeLog                   |  14 +++
 tests/Makefile.am                 |   2 +
 tests/addrx_constx-4.dwo.bz2      | Bin 0 -> 809 bytes
 tests/addrx_constx-5.dwo.bz2      | Bin 0 -> 824 bytes
 tests/run-all-dwarf-ranges.sh     |  24 +++++
 tests/run-varlocs.sh              | 208 ++++++++++++++++++++++++++++++++++++++
 tests/testfile-addrx_constx-4.bz2 | Bin 0 -> 2851 bytes
 tests/testfile-addrx_constx-5.bz2 | Bin 0 -> 2847 bytes
 tests/varlocs.c                   |  65 +++++++++---
 19 files changed, 523 insertions(+), 41 deletions(-)
 create mode 100644 tests/addrx_constx-4.dwo.bz2
 create mode 100644 tests/addrx_constx-5.dwo.bz2
 create mode 100755 tests/testfile-addrx_constx-4.bz2
 create mode 100755 tests/testfile-addrx_constx-5.bz2

diff --git a/libdw/ChangeLog b/libdw/ChangeLog
index c575f64..e7fd217 100644
--- a/libdw/ChangeLog
+++ b/libdw/ChangeLog
@@ -1,3 +1,22 @@
+2018-05-21  Mark Wielaard  <mark@klomp.org>
+
+	* dwarf_begin_elf.c (valid_p): Add a fake_addr_cu to the result.
+	* dwarf_end.c (cu_free): Disconnect the fake_addr_cu from the split
+	dwarf if shared with skeleton.
+	(dwarf_end): release fake_addr_cu.
+	* dwarf_formaddr.c (__libdw_cu_addr_base): Move to...
+	* libdwP.h (__libdw_cu_addr_base): ... here.
+	(struct Dwarf): Add fake_addr_cu field.
+	* dwarf_formudata.c (dwarf_formudata): Handle
+	DW_FORM_GNU_addr_index and DW_FORM_addrx[1234].
+	* dwarf_getlocation_attr.c (addr_valp): New static function.
+	(dwarf_getlocation_attr): Create attribute for values of
+	DW_OP_GNU_const_index, DW_OP_constx and DW_OP_GNU_addr_index and
+	DW_OP_addrx.
+	* libdw_find_split_unit.c (__libdw_find_split_unit): Connect
+	IDX_debug_addr sectiondata and fake_addr_cu between split and
+	skeleton.
+
 2018-05-20  Mark Wielaard  <mark@klomp.org>
 
 	* dwarf_cu_info.c: New file.
diff --git a/libdw/dwarf_begin_elf.c b/libdw/dwarf_begin_elf.c
index 0e435c5..5d8e79e 100644
--- a/libdw/dwarf_begin_elf.c
+++ b/libdw/dwarf_begin_elf.c
@@ -246,6 +246,33 @@ valid_p (Dwarf *result)
 	}
     }
 
+  /* For DW_OP_constx/GNU_const_index and DW_OP_addrx/GNU_addr_index
+     the dwarf_location_attr () will need a "fake" address CU to
+     indicate where the attribute data comes from.  This is a just
+     inside the .debug_addr section, if it exists.  */
+  if (result != NULL && result->sectiondata[IDX_debug_addr] != NULL)
+    {
+      result->fake_addr_cu = (Dwarf_CU *) calloc (1, sizeof (Dwarf_CU));
+      if (unlikely (result->fake_addr_cu == NULL))
+	{
+	  Dwarf_Sig8_Hash_free (&result->sig8_hash);
+	  __libdw_seterrno (DWARF_E_NOMEM);
+	  free (result->fake_loc_cu);
+	  free (result);
+	  result = NULL;
+	}
+      else
+	{
+	  result->fake_addr_cu->sec_idx = IDX_debug_addr;
+	  result->fake_addr_cu->dbg = result;
+	  result->fake_addr_cu->startp
+	    = result->sectiondata[IDX_debug_addr]->d_buf;
+	  result->fake_addr_cu->endp
+	    = (result->sectiondata[IDX_debug_addr]->d_buf
+	       + result->sectiondata[IDX_debug_addr]->d_size);
+	}
+    }
+
   if (result != NULL)
     result->debugdir = __libdw_debugdir (result->elf->fildes);
 
diff --git a/libdw/dwarf_end.c b/libdw/dwarf_end.c
index 4702f1b..1954674 100644
--- a/libdw/dwarf_end.c
+++ b/libdw/dwarf_end.c
@@ -59,7 +59,12 @@ cu_free (void *arg)
   /* Free split dwarf one way (from skeleton to split).  */
   if (p->unit_type == DW_UT_skeleton
       && p->split != NULL && p->split != (void *)-1)
-    INTUSE(dwarf_end) (p->split->dbg);
+    {
+      /* The fake_addr_cu might be shared, only release one.  */
+      if (p->dbg->fake_addr_cu == p->split->dbg->fake_addr_cu)
+	p->split->dbg->fake_addr_cu = NULL;
+      INTUSE(dwarf_end) (p->split->dbg);
+    }
 }
 
 
@@ -108,6 +113,11 @@ dwarf_end (Dwarf *dwarf)
 	  cu_free (dwarf->fake_loc_cu);
 	  free (dwarf->fake_loc_cu);
 	}
+      if (dwarf->fake_addr_cu != NULL)
+	{
+	  cu_free (dwarf->fake_addr_cu);
+	  free (dwarf->fake_addr_cu);
+	}
 
       /* Did we find and allocate the alt Dwarf ourselves?  */
       if (dwarf->alt_fd != -1)
diff --git a/libdw/dwarf_formaddr.c b/libdw/dwarf_formaddr.c
index c917dea..3c89a5d 100644
--- a/libdw/dwarf_formaddr.c
+++ b/libdw/dwarf_formaddr.c
@@ -136,21 +136,3 @@ dwarf_formaddr (Dwarf_Attribute *attr, Dwarf_Addr *return_addr)
   return 0;
 }
 INTDEF(dwarf_formaddr)
-
-Dwarf_Off __libdw_cu_addr_base (Dwarf_CU *cu)
-{
-  if (cu->addr_base == (Dwarf_Off) -1)
-    {
-      Dwarf_Die cu_die = CUDIE(cu);
-      Dwarf_Attribute attr;
-      if (dwarf_attr (&cu_die, DW_AT_GNU_addr_base, &attr) != NULL
-	  || dwarf_attr (&cu_die, DW_AT_addr_base, &attr) != NULL)
-	{
-	  Dwarf_Word off;
-	  if (dwarf_formudata (&attr, &off) == 0)
-	    cu->addr_base = off;
-	}
-    }
-
-  return cu->addr_base;
-}
diff --git a/libdw/dwarf_formudata.c b/libdw/dwarf_formudata.c
index 316ad86..d56e7dc 100644
--- a/libdw/dwarf_formudata.c
+++ b/libdw/dwarf_formudata.c
@@ -288,6 +288,39 @@ dwarf_formudata (Dwarf_Attribute *attr, Dwarf_Word *return_uval)
       get_sleb128_unchecked (*return_uval, datap);
       break;
 
+    /* These are indexes into the .debug_addr section, normally resolved
+       with dwarf_formaddr.  Here treat as constants.  */
+    case DW_FORM_GNU_addr_index:
+    case DW_FORM_addrx:
+      if (datap >= endp)
+	goto invalid;
+      get_uleb128 (*return_uval, datap, endp);
+      break;
+
+    case DW_FORM_addrx1:
+      if (datap >= endp - 1)
+	goto invalid;
+      *return_uval = *datap;
+      break;
+
+    case DW_FORM_addrx2:
+      if (datap >= endp - 2)
+	goto invalid;
+      *return_uval = read_2ubyte_unaligned (attr->cu->dbg, datap);
+      break;
+
+    case DW_FORM_addrx3:
+      if (datap >= endp - 3)
+	goto invalid;
+      *return_uval = read_3ubyte_unaligned (attr->cu->dbg, datap);
+      break;
+
+    case DW_FORM_addrx4:
+      if (datap >= endp - 4)
+	goto invalid;
+      *return_uval = read_4ubyte_unaligned (attr->cu->dbg, datap);
+      break;
+
     default:
       __libdw_seterrno (DWARF_E_NO_CONSTANT);
       return -1;
diff --git a/libdw/dwarf_getlocation_attr.c b/libdw/dwarf_getlocation_attr.c
index 162330f..62ef47a 100644
--- a/libdw/dwarf_getlocation_attr.c
+++ b/libdw/dwarf_getlocation_attr.c
@@ -52,6 +52,18 @@ attr_form_cu (Dwarf_Attribute *attr)
     }
 }
 
+static unsigned char *
+addr_valp (Dwarf_CU *cu, Dwarf_Word index)
+{
+  Elf_Data *debug_addr = cu->dbg->sectiondata[IDX_debug_addr];
+  Dwarf_Word offset = __libdw_cu_addr_base (cu) + (index * cu->address_size);
+  if (debug_addr == NULL)
+    /* This is really an error, will trigger with dwarf_formaddr.  */
+    return (unsigned char *) offset;
+
+  return (unsigned char *) debug_addr->d_buf + offset;
+}
+
 int
 dwarf_getlocation_attr (Dwarf_Attribute *attr, const Dwarf_Op *op, Dwarf_Attribute *result)
 {
@@ -83,6 +95,25 @@ dwarf_getlocation_attr (Dwarf_Attribute *attr, const Dwarf_Op *op, Dwarf_Attribu
 	result->cu = attr_form_cu (attr);
 	break;
 
+      case DW_OP_GNU_const_index:
+      case DW_OP_constx:
+	result->code = DW_AT_const_value;
+	if (attr->cu->address_size == 4)
+	  result->form = DW_FORM_data4;
+	else
+	  result->form = DW_FORM_data8;
+	result->valp = addr_valp (attr->cu, op->number);
+	result->cu = attr->cu->dbg->fake_addr_cu;
+	break;
+
+      case DW_OP_GNU_addr_index:
+      case DW_OP_addrx:
+	result->code = DW_AT_low_pc;
+	result->form = DW_FORM_addr;
+	result->valp = addr_valp (attr->cu, op->number);
+	result->cu = attr->cu->dbg->fake_addr_cu;
+	break;
+
       case DW_OP_call2:
       case DW_OP_call4:
       case DW_OP_call_ref:
diff --git a/libdw/libdwP.h b/libdw/libdwP.h
index 2b5b5ea..82ee5d0 100644
--- a/libdw/libdwP.h
+++ b/libdw/libdwP.h
@@ -204,6 +204,9 @@ struct Dwarf
      came from a location list entry in dwarf_getlocation_attr.  */
   struct Dwarf_CU *fake_loc_cu;
 
+  /* Similar for addrx/constx, which will come from .debug_addr section.  */
+  struct Dwarf_CU *fake_addr_cu;
+
   /* Internal memory handling.  This is basically a simplified
      reimplementation of obstacks.  Unfortunately the standard obstack
      implementation is not usable in libraries.  */
@@ -947,7 +950,26 @@ const char *__libdw_getcompdir (Dwarf_Die *cudie);
 Dwarf_Addr __libdw_cu_base_address (Dwarf_CU *cu);
 
 /* Get the address base for the CU, fetches it when not yet set.  */
-Dwarf_Off __libdw_cu_addr_base (Dwarf_CU *cu);
+static inline Dwarf_Off
+__libdw_cu_addr_base (Dwarf_CU *cu)
+{
+  if (cu->addr_base == (Dwarf_Off) -1)
+    {
+      Dwarf_Die cu_die = CUDIE(cu);
+      Dwarf_Attribute attr;
+      Dwarf_Off offset = 0;
+      if (dwarf_attr (&cu_die, DW_AT_GNU_addr_base, &attr) != NULL
+	  || dwarf_attr (&cu_die, DW_AT_addr_base, &attr) != NULL)
+	{
+	  Dwarf_Word off;
+	  if (dwarf_formudata (&attr, &off) == 0)
+	    offset = off;
+	}
+      cu->addr_base = offset;
+    }
+
+  return cu->addr_base;
+}
 
 /* Gets the .debug_str_offsets base offset to use.  static inline to
    be shared between libdw and eu-readelf.  */
diff --git a/libdw/libdw_find_split_unit.c b/libdw/libdw_find_split_unit.c
index bd48b9e..78c9a2a 100644
--- a/libdw/libdw_find_split_unit.c
+++ b/libdw/libdw_find_split_unit.c
@@ -88,6 +88,20 @@ __libdw_find_split_unit (Dwarf_CU *cu)
 			      cu->split = split;
 			      split->split = cu;
 
+			      /* Get .debug_addr and addr_base greedy.
+			         We also need it for the fake addr cu.
+				 There is only one per split debug.  */
+			      Dwarf *dbg = cu->dbg;
+			      Dwarf *sdbg = split->dbg;
+			      if (sdbg->sectiondata[IDX_debug_addr] == NULL
+				  && dbg->sectiondata[IDX_debug_addr] != NULL)
+				{
+				  sdbg->sectiondata[IDX_debug_addr]
+				    = dbg->sectiondata[IDX_debug_addr];
+				  split->addr_base = __libdw_cu_addr_base (cu);
+				  sdbg->fake_addr_cu = dbg->fake_addr_cu;
+			        }
+
 			      /* We have everything we need from this
 				 ELF file.  And we are going to close
 				 the fd to not run out of file
diff --git a/src/ChangeLog b/src/ChangeLog
index e187277..1a9f4a3 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,12 @@
+2018-01-21  Mark Wielaard  <mark@klomp.org>
+
+	* readelf.c (get_indexed_addr): New function.
+	(print_ops): Handle DW_OP_addrx, DW_OP_GNU_addr_index,
+	DW_OP_constx, DW_OP_GNU_const_index separately and resolve
+	address.
+	(attr_callback): Print index and address for
+	DW_FORM_GNU_addr_index and DW_FORM_addrx[1234].
+
 2018-01-19  Mark Wielaard  <mark@klomp.org>
 
 	* readelf.c (options): Add info+.
diff --git a/src/readelf.c b/src/readelf.c
index 466d941..1858802 100644
--- a/src/readelf.c
+++ b/src/readelf.c
@@ -4180,6 +4180,29 @@ print_bytes (size_t n, const unsigned char *bytes)
     }
 }
 
+static int
+get_indexed_addr (Dwarf_CU *cu, Dwarf_Word idx, Dwarf_Addr *addr)
+{
+  Elf_Data *debug_addr = cu->dbg->sectiondata[IDX_debug_addr];
+  if (debug_addr == NULL)
+    return -1;
+
+  Dwarf_Off base = __libdw_cu_addr_base (cu);
+  Dwarf_Word off = idx * cu->address_size;
+  if (base > debug_addr->d_size
+      || off > debug_addr->d_size - base
+      || cu->address_size > debug_addr->d_size - base - off)
+    return -1;
+
+  const unsigned char *addrp = debug_addr->d_buf + base + off;
+  if (cu->address_size == 4)
+    *addr = read_4ubyte_unaligned (cu->dbg, addrp);
+  else
+    *addr = read_8ubyte_unaligned (cu->dbg, addrp);
+
+  return 0;
+}
+
 static void
 print_ops (Dwfl_Module *dwflmod, Dwarf *dbg, int indent, int indentrest,
 	   unsigned int vers, unsigned int addrsize, unsigned int offset_size,
@@ -4348,19 +4371,36 @@ print_ops (Dwfl_Module *dwflmod, Dwarf *dbg, int indent, int indentrest,
 	case DW_OP_piece:
 	case DW_OP_regx:
 	case DW_OP_plus_uconst:
-	case DW_OP_constu:
+	case DW_OP_constu:;
+	  const unsigned char *start = data;
+	  uint64_t uleb;
+	  NEED (1);
+	  get_uleb128 (uleb, data, data + len);
+	  printf ("%*s[%2" PRIuMAX "] %s %" PRIu64 "\n",
+		  indent, "", (uintmax_t) offset, op_name, uleb);
+	  CONSUME (data - start);
+	  offset += 1 + (data - start);
+	  break;
+
 	case DW_OP_addrx:
 	case DW_OP_GNU_addr_index:
 	case DW_OP_constx:
 	case DW_OP_GNU_const_index:;
-	  const unsigned char *start = data;
-	  uint64_t uleb;
+	  start = data;
 	  NEED (1);
 	  get_uleb128 (uleb, data, data + len);
-	  printf ("%*s[%2" PRIuMAX "] %s %" PRIu64 "\n",
+	  printf ("%*s[%2" PRIuMAX "] %s [%" PRIu64 "] ",
 		  indent, "", (uintmax_t) offset, op_name, uleb);
 	  CONSUME (data - start);
 	  offset += 1 + (data - start);
+	  if (get_indexed_addr (cu, uleb, &addr) != 0)
+	    printf ("???\n");
+	  else
+	    {
+	      a = format_dwarf_addr (dwflmod, 0, addr, addr);
+	      printf ("%s\n", a);
+	      free (a);
+	    }
 	  break;
 
 	case DW_OP_bit_piece:
@@ -6148,9 +6188,19 @@ attr_callback (Dwarf_Attribute *attrp, void *arg)
 	    }
 	  char *a = format_dwarf_addr (cbargs->dwflmod, cbargs->addrsize,
 				       addr, addr);
-	  printf ("           %*s%-20s (%s) %s\n",
-		  (int) (level * 2), "", dwarf_attr_name (attr),
-		  dwarf_form_name (form), a);
+	  if (form != DW_FORM_addr )
+	    {
+	      Dwarf_Word index;
+	      if (dwarf_formudata (attrp, &index) != 0)
+		goto attrval_out;
+	      printf ("           %*s%-20s (%s) [%" PRIx64 "] %s\n",
+		      (int) (level * 2), "", dwarf_attr_name (attr),
+		      dwarf_form_name (form), index, a);
+	    }
+	  else
+	    printf ("           %*s%-20s (%s) %s\n",
+		    (int) (level * 2), "", dwarf_attr_name (attr),
+		    dwarf_form_name (form), a);
 	  free (a);
 	}
       break;
diff --git a/tests/ChangeLog b/tests/ChangeLog
index 3dc1db7..e6f9959 100644
--- a/tests/ChangeLog
+++ b/tests/ChangeLog
@@ -1,3 +1,17 @@
+2018-05-21  Mark Wielaard  <mark@klomp.org>
+
+	* addrx_constx-4.dwo.bz2: New testfile.
+	* addrx_constx-5.dwo.bz2: Likewise.
+	* testfile-addrx_constx-4.bz2: Likewise.
+	* testfile-addrx_constx-5.bz2: Likewise
+	* Makefile.am (EXTRA_DIST): Add addrx_constx-5.dwo.bz2
+	testfile-addrx_constx-4\ .bz2 testfile-addrx_constx-5.bz2.
+	* run-varlocs.sh: Add addrx_constx tests for DWARF4 and DWARF5.
+	* varlocx.c (print_expr): Handle DW_OP_GNU_addr_index,
+	DW_OP_addrx, DW_OP_GNU_const_index and DW_OP_constx.
+	(main): Handle split DWARF.
+	* run-all-dwarf-ranges.sh: Add new ranges for addrx low/highpc.
+
 2018-05-20  Mark Wielaard  <mark@klomp.org>
 
 	* unit-info.c: New test.
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 9beae14..4b13be2 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -305,6 +305,8 @@ EXTRA_DIST = run-arextract.sh run-arsymtest.sh run-ar.sh \
 	     testfile_entry_value.c testfile_entry_value.bz2 \
 	     testfile_implicit_value.c testfile_implicit_value.bz2 \
 	     testfile_aarch64_core.bz2 testfile_i686_core.bz2 \
+	     addrx_constx-4.dwo.bz2 addrx_constx-5.dwo.bz2 \
+	     testfile-addrx_constx-4.bz2 testfile-addrx_constx-5.bz2 \
 	     run-funcretval.sh funcretval_test.c funcretval_test_aarch64.bz2 \
 	     run-backtrace-data.sh run-backtrace-dwarf.sh cleanup-13.c \
 	     run-backtrace-native.sh run-backtrace-native-biarch.sh \
diff --git a/tests/addrx_constx-4.dwo.bz2 b/tests/addrx_constx-4.dwo.bz2
new file mode 100644
index 0000000000000000000000000000000000000000..f0bae1cd56a3448993c40664f22ab1d7ebfb9a9a
GIT binary patch
literal 809
zcmV+^1J?XPT4*^jL0KkKS+X85FaQCsfB*mQ`0m$l|NHx|?-&37|K|T>aNLsnHd6Fr
zVUC1Gd*eU?91Bg(;Zss#8a)xFgGPf*4^RU^pfn8tXlNP+o}r)vMuv?VG6PING}<PE
z)YH_{Oq)=OOqwRt(`htf14bYX28>KbgG~U@pglt%4F;Mt0MG!_Kn#XKlR(e`6+DTk
zY2`LZ%?%?XAZRiT4F-S!0B8nAfB*o{00000000=06pz%z^-m;dHmB;3C;-u+pfu0`
zdV|tv&<0OJ02&%J000dSNB{uP2v|9SKqd6NtdaeGp$kZ1<B`vP`qMFq;66;rZBi37
z$u|?UdhO0;Wpa>#6KAjjy$IB35@xHsKPAAzfv7|n5fQAS0Fc^x#|(ljh$#&aM6wA3
z5(aVrW{?0{*0w8liWWFWg1V&Wkb3qP0oAH!=hqV8mOVW3V6Z=U%`5NIzstOKi$NO`
zs6z6C8z~?#mWaim*d`=HS7&9=edG{CB}D)-F)?wXTBeC(GXpx}DNUz+gROuK{Hm+H
z;~^g+0YQsSha?H|n6MOs?Y75XVhhEH^R@|?&q5QgjF=sYM(zzJ?vOzi%pd}$EDzA`
zfw2Q_$swdeh9cdo!sE{v?qC*`V`b(>Xrb}cyX0g_CL}E+VNZn@=)xX<1zl)HHUKL{
z(Wx?N!qEr~-ByUE7R0(Z+tJLD?)ALG=A1wxgUuQl<@I(lMhTs@C+V@XD<+wjM<ScW
zC;|(hf$EVNOMqyAx&T~&3V5st#_L5nQUv>0L<CS1rMQY+7?cD_f#<k(a=d6ztAkAy
z`4M6Y-6?RzydX5`4-&F`Eeb(n%7Q(Xra3}Bl12w48Za8<KzT*ao*HZwaViJpA_D+K
z1PE0iLRJgS14vu~PXG(aQkVeJMh5~T4EHOr@PZBrO@Q-+P*Hm%oh=>!;+#>t2nAmS
zOT6B5ePZQxX+Nd8u!g#0>Uh#pU8?PPNq+ANepBuBL$b%iv!8HB;_|r6KH4Dc0-;5F
nQzMLr2}B4`TAY(dQd~9NOp7f;+vfF=-{S5_rwS4lL&gRG7{6Ga

literal 0
HcmV?d00001

diff --git a/tests/addrx_constx-5.dwo.bz2 b/tests/addrx_constx-5.dwo.bz2
new file mode 100644
index 0000000000000000000000000000000000000000..a5f4b1a6766b726587ea13584ece648527c0fea9
GIT binary patch
literal 824
zcmV-81IPSAT4*^jL0KkKS=}ah;s628fB*mfz5VxV|NHyD?)Sg{|Nh%MV<thgM6j;@
z_f+-+TW~-EJA&PJcHpRnga)3YCX9g4Jw}0`0iXte&}aY#jWoyr4Kxf)K+s}n0Mih8
z2B6g@jG$?uqfI?WsiQy*4Kx~L(?9@d0B8n=fEoiJ&;S4cXaE2JA{5h8)XbyF2Gjrm
z00Te(0009(27m^DXaE7A27mwn9-x%eN<(PW_KBilHj(7@L7)v810&J^00Yz>pa1{>
z001-whJXM70fb^=0LB0@`LIOPl$Kz@LWSZC(wNg&8+e>TQh5}B$V3*dd6du5v#8Z7
zbTNIJ<_M^|!B{3{ZZ(x2ECW*}D-#Tm*ksdC0aTeF9h$6u4Fi_d134E00mw*ca~w2C
z3sk^Ns!WOUU@v=@5!2BH&avU?km^XWEYA{#2ou>ezZZA<d_}RArS(Ss|F@KlK}Jzq
zJ0VcuI4QESLBt7#d2@9W2Xz&5<-O^p4jjT<%S*R`U1cflL8v+!1B~JHFR}b6R}6>@
z>WBb$th&X+7&e!Z#U%>Fve?UzHw|fk*z|fmPRg~|noWCPrp-Ey4Uq-_-u}Yj2C+aW
z_@<&wh`cZZ90?+gG6?uUVR*#K;RV;4fodK~EG`vH(qkdZMP}Iii`zKI56pB05|rVo
zNI@G)C{H>D#PJz?e6@*;_%e!4nA9}U!r>knh6gL<<yA0mAIEGN2M!}=$?)AN$7h<B
zagZ=bw?y`{j83|Nc?3ap)T-dG!ZC7oE!)QohMkQmn()R^r%OyAV5kP1KyW80tQn)X
zQ6M#!KGGb>G7uqvG^i^YfcAp{&<L#LP8uJI3l|vQ$dEsWBTk3}NJHQ}r<kLm;lz^2
zCD?#zVEm|hAjmr3b#YT#h~getwA%6VB8n0h*s`g=6CkT41TZ<Ivqz2ytWau(5CjTV
z6ei{n!Ux>UcGAd0J^&Ocla@Lstv;xa9zcoDia|i^mJPmVn3qQJ`Dxd#-9IXpUGL-q
zBL^q1sEv=}NE!C}$g^<npPOaVn*wdhapWq{NUBT*ussDOS#TYx{}*yaI8cz?CV1jK
CENl}1

literal 0
HcmV?d00001

diff --git a/tests/run-all-dwarf-ranges.sh b/tests/run-all-dwarf-ranges.sh
index 0bd641b..b1b7fce 100755
--- a/tests/run-all-dwarf-ranges.sh
+++ b/tests/run-all-dwarf-ranges.sh
@@ -33,9 +33,30 @@ die: hello.c (11)
  4004e0..4004ff
  4003e0..4003f7
 
+die: no_say (2e)
+ 4004f0..4004ff
+
+die: main (2e)
+ 4003e0..4003f7
+
+die: subject (1d)
+ 4003e3..4003ef
+
+die: subject (2e)
+ 4004e0..4004f0
+
 die: world.c (11)
  400500..400567
 
+die: no_main (2e)
+ 400550..400567
+
+die: no_subject (1d)
+ 400553..40055f
+
+die: say (2e)
+ 400500..400540
+
 die: happy (1d)
  8009e0..8009ff
  8008e0..8008f7
@@ -44,6 +65,9 @@ die: sad (1d)
  400530..400534
  400535..40053f
 
+die: no_subject (2e)
+ 400540..400550
+
 EOF
 
 exit 0
diff --git a/tests/run-varlocs.sh b/tests/run-varlocs.sh
index 9c4b313..2781fef 100755
--- a/tests/run-varlocs.sh
+++ b/tests/run-varlocs.sh
@@ -125,4 +125,212 @@ module 'testfile_implicit_pointer'
 EOF
 
 
+# DW_OP_addrx and DW_OP_constx testcases.
+#
+# int i, j, k;
+# __thread int l, m, n;
+#
+# int main ()
+# {
+#   int r1 = i + j + k;
+#   int r2 = l + m + n;
+#   int res = r1 + r2;
+#
+#   return res;
+# }
+#
+# gcc -O2 -gdwarf-5 -gsplit-dwarf -o addrx_constx-5.o -c addrx_constx.c
+# gcc -O2 -gdwarf-5 -gsplit-dwarf -o testfile-addrx_constx-5 addrx_constx-5.o
+# gcc -O2 -gdwarf-4 -gsplit-dwarf -o addrx_constx-4.o -c addrx_constx.c
+# gcc -O2 -gdwarf-4 -gsplit-dwarf -o testfile-addrx_constx-4 addrx_constx-4.o
+
+testfiles testfile-addrx_constx-5 addrx_constx-5.dwo
+testrun_compare ${abs_top_builddir}/tests/varlocs --exprlocs -e testfile-addrx_constx-5 <<\EOF
+module 'testfile-addrx_constx-5'
+[14] CU 'addrx_constx.c'
+  producer (strx)
+  language (data1)
+  name (strx)
+  comp_dir (strx)
+  [19] variable "i"
+    name (string)
+    decl_file (implicit_const)
+    decl_line (data1)
+    decl_column (data1)
+    type (ref4)
+    external (flag_present)
+    location (exprloc) {addr: 0x404038}
+  [25] base_type "int"
+    byte_size (data1)
+    encoding (data1)
+    name (string)
+  [2c] variable "j"
+    name (string)
+    decl_file (implicit_const)
+    decl_line (data1)
+    decl_column (data1)
+    type (ref4)
+    external (flag_present)
+    location (exprloc) {addr: 0x404034}
+  [38] variable "k"
+    name (string)
+    decl_file (implicit_const)
+    decl_line (data1)
+    decl_column (data1)
+    type (ref4)
+    external (flag_present)
+    location (exprloc) {addr: 0x40403c}
+  [44] variable "l"
+    name (string)
+    decl_file (implicit_const)
+    decl_line (data1)
+    decl_column (data1)
+    type (ref4)
+    external (flag_present)
+    location (exprloc) {const: 0x403e10, form_tls_address}
+  [51] variable "m"
+    name (string)
+    decl_file (implicit_const)
+    decl_line (data1)
+    decl_column (data1)
+    type (ref4)
+    external (flag_present)
+    location (exprloc) {const: 0x403e0c, form_tls_address}
+  [5e] variable "n"
+    name (string)
+    decl_file (implicit_const)
+    decl_line (data1)
+    decl_column (data1)
+    type (ref4)
+    external (flag_present)
+    location (exprloc) {const: 0x403e08, form_tls_address}
+  [6b] subprogram "main"
+    external (flag_present)
+    name (strx)
+    decl_file (data1)
+    decl_line (data1)
+    decl_column (data1)
+    type (ref4)
+    low_pc (addrx)
+    high_pc (data8)
+    frame_base (exprloc) {call_frame_cfa {bregx(7,8)}}
+    call_all_calls (flag_present)
+    [7f] variable "r1"
+      name (string)
+      decl_file (implicit_const)
+      decl_line (data1)
+      decl_column (implicit_const)
+      type (ref4)
+      location (exprloc) {addr: 0x404038, deref_size(4), addr: 0x404034, deref_size(4), plus, addr: 0x40403c, deref_size(4), plus, stack_value}
+    [98] variable "r2"
+      name (string)
+      decl_file (implicit_const)
+      decl_line (data1)
+      decl_column (implicit_const)
+      type (ref4)
+      location (exprloc) {form_tls_address, const: 0x403e10, deref_size(4), form_tls_address, const: 0x403e0c, deref_size(4), plus, form_tls_address, const: 0x403e08, deref_size(4), plus, stack_value}
+    [b4] variable "res"
+      name (string)
+      decl_file (implicit_const)
+      decl_line (data1)
+      decl_column (implicit_const)
+      type (ref4)
+      location (exprloc) {addr: 0x404038, deref_size(4), form_tls_address, const: 0x403e08, deref_size(4), plus, form_tls_address, const: 0x403e0c, deref_size(4), plus, form_tls_address, const: 0x403e10, deref_size(4), plus, addr: 0x404034, deref_size(4), plus, addr: 0x40403c, deref_size(4), plus, stack_value}
+EOF
+
+testfiles testfile-addrx_constx-4 addrx_constx-4.dwo
+testrun_compare ${abs_top_builddir}/tests/varlocs --exprlocs -e testfile-addrx_constx-4 <<\EOF
+module 'testfile-addrx_constx-4'
+[b] CU 'addrx_constx.c'
+  producer (GNU_str_index)
+  language (data1)
+  name (GNU_str_index)
+  comp_dir (GNU_str_index)
+  GNU_dwo_id (data8)
+  [18] variable "i"
+    name (string)
+    decl_file (data1)
+    decl_line (data1)
+    decl_column (data1)
+    type (ref4)
+    external (flag_present)
+    location (exprloc) {addr: 0x404038}
+  [25] base_type "int"
+    byte_size (data1)
+    encoding (data1)
+    name (string)
+  [2c] variable "j"
+    name (string)
+    decl_file (data1)
+    decl_line (data1)
+    decl_column (data1)
+    type (ref4)
+    external (flag_present)
+    location (exprloc) {addr: 0x404034}
+  [39] variable "k"
+    name (string)
+    decl_file (data1)
+    decl_line (data1)
+    decl_column (data1)
+    type (ref4)
+    external (flag_present)
+    location (exprloc) {addr: 0x40403c}
+  [46] variable "l"
+    name (string)
+    decl_file (data1)
+    decl_line (data1)
+    decl_column (data1)
+    type (ref4)
+    external (flag_present)
+    location (exprloc) {const: 0x403e10, GNU_push_tls_address}
+  [54] variable "m"
+    name (string)
+    decl_file (data1)
+    decl_line (data1)
+    decl_column (data1)
+    type (ref4)
+    external (flag_present)
+    location (exprloc) {const: 0x403e0c, GNU_push_tls_address}
+  [62] variable "n"
+    name (string)
+    decl_file (data1)
+    decl_line (data1)
+    decl_column (data1)
+    type (ref4)
+    external (flag_present)
+    location (exprloc) {const: 0x403e08, GNU_push_tls_address}
+  [70] subprogram "main"
+    external (flag_present)
+    name (GNU_str_index)
+    decl_file (data1)
+    decl_line (data1)
+    decl_column (data1)
+    type (ref4)
+    low_pc (GNU_addr_index)
+    high_pc (data8)
+    frame_base (exprloc) {call_frame_cfa {bregx(7,8)}}
+    GNU_all_call_sites (flag_present)
+    [84] variable "r1"
+      name (string)
+      decl_file (data1)
+      decl_line (data1)
+      decl_column (data1)
+      type (ref4)
+      location (exprloc) {addr: 0x404038, deref_size(4), addr: 0x404034, deref_size(4), plus, addr: 0x40403c, deref_size(4), plus, stack_value}
+    [9f] variable "r2"
+      name (string)
+      decl_file (data1)
+      decl_line (data1)
+      decl_column (data1)
+      type (ref4)
+      location (exprloc) {GNU_push_tls_address, const: 0x403e10, deref_size(4), GNU_push_tls_address, const: 0x403e0c, deref_size(4), plus, GNU_push_tls_address, const: 0x403e08, deref_size(4), plus, stack_value}
+    [bd] variable "res"
+      name (string)
+      decl_file (data1)
+      decl_line (data1)
+      decl_column (data1)
+      type (ref4)
+      location (exprloc) {addr: 0x404038, deref_size(4), GNU_push_tls_address, const: 0x403e08, deref_size(4), plus, GNU_push_tls_address, const: 0x403e0c, deref_size(4), plus, GNU_push_tls_address, const: 0x403e10, deref_size(4), plus, addr: 0x404034, deref_size(4), plus, addr: 0x40403c, deref_size(4), plus, stack_value}
+EOF
+
 exit 0
diff --git a/tests/testfile-addrx_constx-4.bz2 b/tests/testfile-addrx_constx-4.bz2
new file mode 100755
index 0000000000000000000000000000000000000000..cf10fbb1082a5a188c5ac11af0c8404de461b9e0
GIT binary patch
literal 2851
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
B1&aUx

literal 0
HcmV?d00001

diff --git a/tests/testfile-addrx_constx-5.bz2 b/tests/testfile-addrx_constx-5.bz2
new file mode 100755
index 0000000000000000000000000000000000000000..eb2a1f17817ab13a32ea7256cf2a60c69cf9b53b
GIT binary patch
literal 2847
zcma)#WmwaT0*C+9fH`E;94RG&j2?9q+!&4;N~hF_vk^xc1P(F@iP2rsB||#I00v4b
zBLpO5G!h~l0TtAH?&tgEzMp>2`#itr)v+UJDxqzq%x%x$>i}@U<H7I$WrfKkcKO!+
z^yZz}2M5b^_9802l&?CO87m0Gi2|Y%5(ahUVJ^yU`C2@l1Y$L9dLo_%B9#(=DN!WS
z4HTD;Jl4XJvB}6O2^7Gg41kOUAgQJm=rRUSH7RRg%3vF5&;mTJE^wpyp#FOz2q0;|
z6gs^E1-Q`wfC(D~03dOIrVI!WkZu6r1}cCQfKdNRtOO%G8DK)u2n2w}go{S~ySc@=
zm<2qM1tqmp1n`Z_V+>|`xO#y6*kDJ?n7{H!uQsfZy{>GBgHv)IT}nfOqL4^Ht*qtW
z2B&HH{~JLGfKW`vAaWD{iJC%ZqJ{tf7#eWKaFqfC0S*p803fCj0DvIWaJ@sL$vX9z
zP0JCYbw9aCDpxF~S>&*!q<CdKXe=hy!_5=^CVL%<aL~X~CaQ|V`ri_$b2o$uryAZ?
zKWWc|;!l)vIqoHhe3QR`9_Y~XyGW`X|3H(jWKB~nybf{o3u25`3ZP;(@acQ$gXQFh
z?xy8genHHSkcT}ocP{O5yc6>{dIq1hV+_scE>vo~@qTWM^=W=Zte%|5>q4kujI@X2
z{b)1~uk(5)DW4zAy>5G3Fl2l8rm4X-9Lh?Ooi3uiaN#n!Gaxx~Fh5dm#^dq0d;R1b
zA+~~9S%B7OYusO8fL$gF$A#(aD$J_Ksg4_@jZ9%|n-=bm9RCb)DIl)i`7?i_ChUDt
z#~i??7Wdu$>rmdO<ArmI)^Wsw=3jSFJIng2`+<QXHb^g6Wgi#Ml&J2nxNc7cL_n&k
zz;`|H=s#;!#1Cnrpq5B(ZnuFGjBh!e8yC;T&EnGL__D%ckfqn8*IX$-AWPqXlQ{ZL
zpcRWw`9PdH`z}Dao7N@AW`_W_ZoZkcksD7lZ;5T~U-<Ik{Gj-y>wX+Uleh2NQ|K62
z$YxTeB_3UPtJ4rN9TvLNQa&GMbCjv}X)$|Dn&4GSKwoBhRpdNRWO7zxytq**;X4V<
zB(j6B47w*65>hJDr&_Gz5W=gt)YeT(YU^flR)$#&v2aMnJ14gqo(RoyD9F$HDUw7i
zD|34UphkQ)jDo1B^`;HQoK(qve<XMBMpK-ctdd2ZJ$K5z(samO8<LooJ{!SESW47q
zn1>OvXD&9>yJ7@w(v#CP=b*-m#vf0i&qTDdi{B~MJ{(mRBMXZB4wqU{v|zO!-qeFl
zY)0xQfv--V5L7|EryU*HvO4m`0?n2(uI{+<Q5AiUVK=ZxFBP)S6uR@Nbz<H)@KyHu
z*B`kC0rlz?pUBPVvYP6yn9J-tDvs)!XZ%UZlbedc1$uHLGeSi#_XM^I|52)sRupyr
z+bY7&B?rfj3-P9F5)Us*QnuPCjwhvOQj&t!*ufCJ)2tIe<VV4W9k0A1^ypu<cIfH|
zR$oN2k!A0inF|N0d-eQRPR~uFVy9xp4`H^?iL%M550`uD16Na4mmg%dlXyfwKbNm%
zFb5YvpzMlH<LxB*X(FHdTUM@0A8cxRA4wM35_I!4Rz-dGQDAV240Fds^c8o+n-uIk
zHw;|{KWt9t61>!jcY6M)B>46!b+*m@c^$Ns3k%^ML1qk{_6~757hTCwZ7`}bsP=Y+
z_Y*F29fS;_pf#>e?GC}$s_H;$BTFv2+Zep6w^dcS6{p%FMvdHLB^DD2U(;SrrFCuJ
zTYgaB*sP+x>Mr-s)^5F7+B+FV{sTP~%ex^t$-KtW82nVN?)L?>f@&^uvzIP;eJywO
zM3Tp=gmF)fbq24JhsU>Ww&g5U<}#Efx@33q2Z%&SMq92#%p#5o4_uT^1b4db?f>vz
zlzn!8ya6=&R%;?-h?gE<;Tqm4I9C|0+f_eC7lU;<5^o?X$BH0b-!mWq+71XE>GIjf
zqAuT5KOr9JIP*G%I~|tVrF(f0h7wB%T$U3N{?Z#NUK&ipw2E8T_0hX64=q1)hRott
zLm6VeLUnNl8?DEQS-0#5>mnu;dQx_Hr{|oX^gsM0Ol^>m7}~l9vu}GF)PPfAkI@tw
z8`D-k>;6r&esTT9j8igx5WXZdMk(xK;avT8LsJ!_yp5iFrk<p3d+SN)d1#4&%8h&A
zj{+mdiJRuD{H|cEcJMBbZ+)V-DXAO|KjLPrHL+sgg^tisJ{RGo@oJSQF-iY8MqV__
zP8#Da%;=nYzTiT=$w~8z@EdNpyM+t&8y3Fe@VY-3`LS69vO_v)_ebQ`uL_~&G0Tr8
zzwK|gc)#t-i>_@*UwUoBbaBLUvx5DLzP{;{+5|<9t)Eww|H@P!E^JH=7I2}KoWa&w
zIUzbhak$)Z%kOEbufws3&cMP*+Lg=M0-kK{<fiy{5Nd{)F7Hw!`YD}b!&N0^Vbb)Q
z5zn=iNtr8SLw0TL?q(he1^B$bh+cN?Gr8PY_Ny#7(8b1!F)PA_1B)`gD-JkWwx*0r
zmNrU`ukOyDJ9a3YhfhZ>R$d^rZzm)fE`7!aS$e@|<uXJ*pgnaYyGH91@*a0|v^n(k
zhV`sbgJ+32`z&4c^PjaWaI$WhO{SkIScZen=`SB${8%{ibt5FKgA!9o&C|$XI7bw^
zh!ZthFq#DJ77FY^tl9ieo<F7qkuY&=wvVy;`Rc)8<Li-PUZ+=y5&Me>P49J>--&B|
z23cWcWnI?t-H>9Xft>7lOHNKSp=55!v<DKbsTX^vv+U~l%OMkN?XI9K++8*_oNw{>
zw3B3D07m_ZY)e8-9t9UT|0Be9|2+e}F-Uhg)P7)Z7Ls;w$I)d=-hJ_`1R0G?TAhAY
z9sm~3ntk!EtRQISkXTjnL#biYj7g)8ew)I-Lq^BHe|>^)vG{bKq(dEPe<=oypK;wg
zbTanj<nC<QqsSMt8Rsixg2@dFLfrr&D&TRSDn?Rtl4E!vC=?r|i*nkrmOP5)n?6z;
z{7m)fmwO6L)xP}dYduUafMiuxR6WIAlTh4#ri;@4Fu?5Q{HD2i-q-8)$hQ^ftQK=G
zg&MwsyKqA7;t|Wgos?&%&sZ(hO}Kc8mv4BCc{ReY6ZX;=F9?oJ=NXkst8y())<eu~
zTCKD3d7H7z>gjANC4!&Vyp^jAF4l$h8|ky%^<tZzRN;-6I%io{0&n-S20CNJ>0~ER
zZ4)yHmLmt$^Z9ono2Nl_TZ}(YhM`R)AG<7YFDm8^pM>N!I5zU<eVs4(bmsvRX+T=@
zprG4GhD7;1X~^~78T!NQ>oWBy2%oSj3PCWzd_|?j3mYX9N0f4;o8U|gL(Vq!kyIO{
z6hs>|G;zsV<P=t%NHVn;f?{}PuIO4;T_~lc?XvYIG$)=WW56eWn6G@CbzBR)7j`@f
z1Ps{L)I!#&w^0b+HwiT>PS$oi$T8Z$TPs23MpJ^zPs<Lesqh-~gD9x-N{z|xscOqr
z&{n{i4DZ)mumZh3K={yFxTGq#zu#qjo1#%yrSEFS6X@S#Q4rdh8b(&sO0pYt_TRS}
zyEKO?UBhQpiD`tl<*5j_2|ZaT{!{i@pv=*nrvCwFOytL^9rr6m4%WL#t@ZM2K1ZI%
za%UZ3hHVTlKdd=9_P@3?jqLQoXjDzGp(Xqbs`H0`JwI#s*{^6nqd%q@!&-%xRvr11
k?4)EPy|#!mOl(c39UQHEx%qMTchWQQB5D1<$^HQFA3D@HQvd(}

literal 0
HcmV?d00001

diff --git a/tests/varlocs.c b/tests/varlocs.c
index b2ceda2..859068d 100644
--- a/tests/varlocs.c
+++ b/tests/varlocs.c
@@ -652,6 +652,42 @@ print_expr (Dwarf_Attribute *attr, Dwarf_Op *expr, Dwarf_Addr addr)
       }
       break;
 
+    case DW_OP_GNU_addr_index:
+    case DW_OP_addrx:
+      /* Address from the .debug_addr section (indexed based on CU).  */
+      {
+	Dwarf_Attribute addr_attr;
+	if (dwarf_getlocation_attr (attr, expr, &addr_attr) != 0)
+	  error (EXIT_FAILURE, 0, "dwarf_getlocation_attr for addr: %s",
+		 dwarf_errmsg (-1));
+
+	Dwarf_Addr address;
+	if (dwarf_formaddr (&addr_attr, &address) != 0)
+	  error (EXIT_FAILURE, 0, "dwarf_formaddr address failed: %s",
+		 dwarf_errmsg (-1));
+
+	printf ("addr: 0x%" PRIx64, address);
+      }
+      break;
+
+    case DW_OP_GNU_const_index:
+    case DW_OP_constx:
+      /* Constant from the .debug_addr section (indexed based on CU).  */
+      {
+	Dwarf_Attribute addr_attr;
+	if (dwarf_getlocation_attr (attr, expr, &addr_attr) != 0)
+	  error (EXIT_FAILURE, 0, "dwarf_getlocation_attr for addr: %s",
+		 dwarf_errmsg (-1));
+
+	Dwarf_Word constant;
+	if (dwarf_formudata (&addr_attr, &constant) != 0)
+	  error (EXIT_FAILURE, 0, "dwarf_formudata constant failed: %s",
+		 dwarf_errmsg (-1));
+
+	printf ("const: 0x%" PRIx64, constant);
+      }
+      break;
+
     default:
       error (EXIT_FAILURE, 0, "unhandled opcode: DW_OP_%s (0x%x)",
 	     opname, atom);
@@ -1019,9 +1055,18 @@ main (int argc, char *argv[])
       /* Only walk actual compile units (not partial units) that
 	 contain code if we are only interested in the function variable
 	 locations.  */
+      Dwarf_Die cudie;
+      Dwarf_Die subdie;
+      uint8_t unit_type;
+      if (dwarf_cu_info (cu->cu, NULL, &unit_type, &cudie, &subdie,
+		         NULL, NULL, NULL) != 0)
+	error (EXIT_FAILURE, 0, "dwarf_cu_info: %s", dwarf_errmsg (-1));
+      if (unit_type == DW_UT_skeleton)
+	cudie = subdie;
+
       Dwarf_Addr cubase;
-      if (dwarf_tag (cu) == DW_TAG_compile_unit
-	  && (exprlocs || dwarf_lowpc (cu, &cubase) == 0))
+      if (dwarf_tag (&cudie) == DW_TAG_compile_unit
+	  && (exprlocs || dwarf_lowpc (&cudie, &cubase) == 0))
 	{
 	  found_cu = true;
 
@@ -1043,7 +1088,7 @@ main (int argc, char *argv[])
 			      ? modname
 			      :  basename (mainfile));
 	  printf ("module '%s'\n", name);
-	  print_die (cu, "CU", 0);
+	  print_die (&cudie, "CU", 0);
 
 	  Dwarf_Addr elfbias;
 	  Elf *elf = dwfl_module_getelf (mod, &elfbias);
@@ -1060,18 +1105,10 @@ main (int argc, char *argv[])
 	  GElf_Ehdr ehdr_mem, *ehdr = gelf_getehdr (elf, &ehdr_mem);
 	  is_ET_REL = ehdr->e_type == ET_REL;
 
-	  // Get the actual CU DIE and walk all all DIEs (or just the
-	  // functions) inside it.
-	  Dwarf_Die cudie;
-	  uint8_t offsize;
-	  uint8_t addrsize;
-	  if (dwarf_diecu (cu, &cudie, &addrsize, &offsize) == NULL)
-	    error (EXIT_FAILURE, 0, "dwarf_diecu %s", dwarf_errmsg (-1));
-
 	  if (exprlocs)
 	    {
 	      Dwarf_Addr entrypc;
-	      if (dwarf_entrypc (cu, &entrypc) != 0)
+	      if (dwarf_entrypc (&cudie, &entrypc) != 0)
 		entrypc = 0;
 
 	      /* XXX - Passing true for has_frame_base is not really true.
@@ -1079,9 +1116,9 @@ main (int argc, char *argv[])
 		 attributes. Technically we should check that the DIE
 		 (types) are referenced from variables that are defined in
 		 a context (function) that has a frame base.  */
-	      handle_die (cu, 0, true /* Should be false */, entrypc);
+	      handle_die (&cudie, 0, true /* Should be false */, entrypc);
 	    }
-	  else if (dwarf_getfuncs (cu, handle_function, NULL, 0) != 0)
+	  else if (dwarf_getfuncs (&cudie, handle_function, NULL, 0) != 0)
 	    error (EXIT_FAILURE, 0, "dwarf_getfuncs %s",
 		   dwarf_errmsg (-1));
 	}
-- 
1.8.3.1


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]