For DWARF version 4 or higher a block form really encodes a block,
not an expression location. Also constant offsets can be expressed
as DW_FORM_implicit_const in DWARF version 5.

Signed-off-by: Mark Wielaard <m...@klomp.org>
---
 libdw/ChangeLog           |  6 ++++++
 libdw/dwarf_getlocation.c | 17 +++++++++++++++++
 src/ChangeLog             |  5 +++++
 src/readelf.c             |  4 +++-
 4 files changed, 31 insertions(+), 1 deletion(-)

diff --git a/libdw/ChangeLog b/libdw/ChangeLog
index b8038f00..f01bee39 100644
--- a/libdw/ChangeLog
+++ b/libdw/ChangeLog
@@ -1,3 +1,9 @@
+2021-02-12  Mark Wielaard  <m...@klomp.org>
+
+       * dwarf_getlocation.c (attr_ok): For DWARF version 4 or higher
+       block forms are not expression locations.
+       (is_constant_offset): DW_FORM_implicit_const is also a constant.
+
 2020-12-20  Dmitry V. Levin  <l...@altlinux.org>
 
        * .gitignore: New file.
diff --git a/libdw/dwarf_getlocation.c b/libdw/dwarf_getlocation.c
index 4e582db2..5db3cf97 100644
--- a/libdw/dwarf_getlocation.c
+++ b/libdw/dwarf_getlocation.c
@@ -48,6 +48,22 @@ attr_ok (Dwarf_Attribute *attr)
   if (dwarf_whatform (attr) == DW_FORM_exprloc)
     return true;
 
+  if (attr->cu->version >= 4)
+    {
+      /* Must be an exprloc (or constant), just not any block form.  */
+      switch (dwarf_whatform (attr))
+       {
+       case DW_FORM_block:
+       case DW_FORM_block1:
+       case DW_FORM_block2:
+       case DW_FORM_block4:
+         __libdw_seterrno (DWARF_E_NO_LOC_VALUE);
+         return false;
+       default:
+         break;
+       }
+    }
+
   /* Otherwise must be one of the attributes listed below.  Older
      DWARF versions might have encoded the exprloc as block, and we
      cannot easily distinguish attributes in the loclist class because
@@ -186,6 +202,7 @@ is_constant_offset (Dwarf_Attribute *attr,
     case DW_FORM_data8:
     case DW_FORM_sdata:
     case DW_FORM_udata:
+    case DW_FORM_implicit_const:
       break;
     }
 
diff --git a/src/ChangeLog b/src/ChangeLog
index e65620fd..61cd98f4 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,8 @@
+2021-02-12  Mark Wielaard  <m...@klomp.org>
+
+       * readelf.c (attr_callback): Don't handle blocks as expression
+       blocks for DWARF version 4 or higher.
+
 2021-02-03 Timm Bäder <tbae...@redhat.com>
 
        * ar.c (do_oper_extract): Extract should_truncate_fname function
diff --git a/src/readelf.c b/src/readelf.c
index 11692bb5..9d2a25a4 100644
--- a/src/readelf.c
+++ b/src/readelf.c
@@ -7599,7 +7599,9 @@ attr_callback (Dwarf_Attribute *attrp, void *arg)
        case DW_AT_GNU_call_site_data_value:
        case DW_AT_GNU_call_site_target:
        case DW_AT_GNU_call_site_target_clobbered:
-         if (form != DW_FORM_data16)
+         if (form == DW_FORM_exprloc
+             || (form != DW_FORM_data16
+                 && attrp->cu->version < 4)) /* blocks were expressions.  */
            {
              putchar ('\n');
              print_ops (cbargs->dwflmod, cbargs->dbg,
-- 
2.18.4

Reply via email to