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]

[Bug libdw/23981] dwarf_siblingof() fails with attribute form DW_FORM_ref_addr


https://sourceware.org/bugzilla/show_bug.cgi?id=23981

Mark Wielaard <mark at klomp dot org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|UNCONFIRMED                 |ASSIGNED
   Last reconfirmed|                            |2018-12-25
                 CC|                            |mark at klomp dot org
     Ever confirmed|0                           |1

--- Comment #1 from Mark Wielaard <mark at klomp dot org> ---
(In reply to Andreas Kromke from comment #0)
> The API function dwarf_siblingof() internally calls __libdw_formref() which
> is deprecated and especially does not support DW_FORM_ref_addr, resulting in
> a return code of -1 (format error).
> 
> Instead dwarf_siblingof() should call dwarf_formref_die() or an internal
> variant of that.

Yes, __libdw_formref() only handles relative DIE offsets. In theory a producer
might also use one of the other DIE reference forms, although only
DW_FORM_ref_addr might make sense for DW_AT_sibling (DW_FORM_ref_sig8,
DW_FORM_ref_alt, DW_FORM_ref_sup4, DW_FORM_ref_sup8 and DW_FORM_GNU_ref_alt all
point outside the current CU, so aren't appropriate).

DW_FORM_ref_addr might not be the most efficient way to encode DW_AT_sibling
and is normally used for cross CU DIE references. But we should probably
support it, if it is used as inter CU die reference. Does the following work
for you:

https://code.wildebeest.org/git/user/mjw/elfutils/commit/?h=sibling-ref-addr

diff --git a/libdw/dwarf_siblingof.c b/libdw/dwarf_siblingof.c
index 613d20908..b0d9dd75f 100644
--- a/libdw/dwarf_siblingof.c
+++ b/libdw/dwarf_siblingof.c
@@ -71,8 +71,28 @@ dwarf_siblingof (Dwarf_Die *die, Dwarf_Die *result)
          Dwarf_Off offset;
          sibattr.valp = addr;
          if (unlikely (__libdw_formref (&sibattr, &offset) != 0))
-           /* Something went wrong.  */
-           return -1;
+           {
+             /* __libdw_formref only handles relative forms, there is
+                also DW_FORM_ref_addr which might be used for inter
+                CU DIE references too (all other reference FORMs
+                point outside the current CU by definition).  */
+             if (sibattr.form == DW_FORM_ref_addr)
+               {
+                 uint8_t ref_size;
+                 struct Dwarf_CU *cu = sibattr.cu;
+                 if (cu->version == 2)
+                   ref_size = cu->address_size;
+                 else
+                   ref_size = cu->offset_size;
+
+                 if (__libdw_read_offset (cu->dbg, cu->dbg, IDX_debug_info,
+                                          sibattr.valp, ref_size, &offset,
+                                          IDX_debug_info, 0))
+                   return -1;
+               }
+             else
+               return -1;
+           }

          /* The sibling attribute should point after this DIE in the CU.
             But not after the end of the CU.  */

Also do you have an example file to use as test case?
What DWARF producer generated a DW_AT_sibling with DW_FORM_ref_addr?

-- 
You are receiving this mail because:
You are on the CC list for the bug.

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