public inbox for elfutils@sourceware.org
 help / color / mirror / Atom feed
* [Bug libdw/23981] New: dwarf_siblingof() fails with attribute form DW_FORM_ref_addr
@ 2018-12-13 17:06 Andreas.Kromke at dreamchip dot de
  2018-12-25 14:10 ` [Bug libdw/23981] " mark at klomp dot org
                   ` (3 more replies)
  0 siblings, 4 replies; 5+ messages in thread
From: Andreas.Kromke at dreamchip dot de @ 2018-12-13 17:06 UTC (permalink / raw)
  To: elfutils-devel

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

            Bug ID: 23981
           Summary: dwarf_siblingof() fails with attribute form
                    DW_FORM_ref_addr
           Product: elfutils
           Version: unspecified
            Status: UNCONFIRMED
          Severity: normal
          Priority: P2
         Component: libdw
          Assignee: unassigned at sourceware dot org
          Reporter: Andreas.Kromke at dreamchip dot de
                CC: elfutils-devel at sourceware dot org
  Target Milestone: ---

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.

A temporary workaround might be:

int my_dwarf_siblingof(Dwarf_Die *die, Dwarf_Die *result) {
    int ret = dwarf_siblingof(die, result);
    if (ret >= 0) return ret;
    Dwarf_Attribute attr_result;
    Dwarf_Attribute *attr = dwarf_attr(die, DW_AT_sibling, &attr_result);
    if (attr == NULL) return -1;
    Dwarf_Die *formref_die = dwarf_formref_die(attr, result);
    if (formref_die == NULL) return -1;
    return 0;
}

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

^ permalink raw reply	[flat|nested] 5+ messages in thread

* [Bug libdw/23981] dwarf_siblingof() fails with attribute form DW_FORM_ref_addr
  2018-12-13 17:06 [Bug libdw/23981] New: dwarf_siblingof() fails with attribute form DW_FORM_ref_addr Andreas.Kromke at dreamchip dot de
@ 2018-12-25 14:10 ` mark at klomp dot org
  2019-01-02 17:06 ` Andreas.Kromke at dreamchip dot de
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 5+ messages in thread
From: mark at klomp dot org @ 2018-12-25 14:10 UTC (permalink / raw)
  To: elfutils-devel

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.

^ permalink raw reply	[flat|nested] 5+ messages in thread

* [Bug libdw/23981] dwarf_siblingof() fails with attribute form DW_FORM_ref_addr
  2018-12-13 17:06 [Bug libdw/23981] New: dwarf_siblingof() fails with attribute form DW_FORM_ref_addr Andreas.Kromke at dreamchip dot de
  2018-12-25 14:10 ` [Bug libdw/23981] " mark at klomp dot org
@ 2019-01-02 17:06 ` Andreas.Kromke at dreamchip dot de
  2019-01-03 17:25 ` Andreas.Kromke at dreamchip dot de
  2019-01-13 16:37 ` mark at klomp dot org
  3 siblings, 0 replies; 5+ messages in thread
From: Andreas.Kromke at dreamchip dot de @ 2019-01-02 17:06 UTC (permalink / raw)
  To: elfutils-devel

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

--- Comment #2 from Andreas Kromke <Andreas.Kromke at dreamchip dot de> ---
Unfortunately I cannot provide the example file (due to legal restrictions),
but I can tell that the producer is the following:

"GHS C 5.2.4 [dual]"

GHS probably means "Green Hills".

The machine is PowerPC.

Hopefully I can test your solution soon (if time allows).

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

^ permalink raw reply	[flat|nested] 5+ messages in thread

* [Bug libdw/23981] dwarf_siblingof() fails with attribute form DW_FORM_ref_addr
  2018-12-13 17:06 [Bug libdw/23981] New: dwarf_siblingof() fails with attribute form DW_FORM_ref_addr Andreas.Kromke at dreamchip dot de
  2018-12-25 14:10 ` [Bug libdw/23981] " mark at klomp dot org
  2019-01-02 17:06 ` Andreas.Kromke at dreamchip dot de
@ 2019-01-03 17:25 ` Andreas.Kromke at dreamchip dot de
  2019-01-13 16:37 ` mark at klomp dot org
  3 siblings, 0 replies; 5+ messages in thread
From: Andreas.Kromke at dreamchip dot de @ 2019-01-03 17:25 UTC (permalink / raw)
  To: elfutils-devel

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

--- Comment #3 from Andreas Kromke <Andreas.Kromke at dreamchip dot de> ---
I changed the source file accordingly, rebuilt the library and rerun the tests.
The result is, unfortunately, the same, i.e. there is no improvement.

Analysis showed that in failure case these lines are executed:

            if (sibattr.form == DW_FORM_ref_addr)
and
                uint8_t ref_size;
and
                  ref_size = cu->address_size;
and
              __libdw_seterrno (DWARF_E_INVALID_DWARF);
              return -1;

So obviously the new code piece was run, but the failure was still detected
later, in the old code.

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

^ permalink raw reply	[flat|nested] 5+ messages in thread

* [Bug libdw/23981] dwarf_siblingof() fails with attribute form DW_FORM_ref_addr
  2018-12-13 17:06 [Bug libdw/23981] New: dwarf_siblingof() fails with attribute form DW_FORM_ref_addr Andreas.Kromke at dreamchip dot de
                   ` (2 preceding siblings ...)
  2019-01-03 17:25 ` Andreas.Kromke at dreamchip dot de
@ 2019-01-13 16:37 ` mark at klomp dot org
  3 siblings, 0 replies; 5+ messages in thread
From: mark at klomp dot org @ 2019-01-13 16:37 UTC (permalink / raw)
  To: elfutils-devel

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

--- Comment #4 from Mark Wielaard <mark at klomp dot org> ---
(In reply to Andreas Kromke from comment #3)
> I changed the source file accordingly, rebuilt the library and rerun the
> tests. The result is, unfortunately, the same, i.e. there is no improvement.
> 
> Analysis showed that in failure case these lines are executed:
> 
>             if (sibattr.form == DW_FORM_ref_addr)
> and
>                 uint8_t ref_size;
> and
>                   ref_size = cu->address_size;
> and
> 	      __libdw_seterrno (DWARF_E_INVALID_DWARF);
> 	      return -1;
> 
> So obviously the new code piece was run, but the failure was still detected
> later, in the old code.

This is really hard to debug with just this information and without the exact
DWARF that is being decoded. Could you please post an example DWARF description
and/or a backtrace when the error occurs/__libdw_seterrno is called?

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

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2019-01-13 16:37 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-12-13 17:06 [Bug libdw/23981] New: dwarf_siblingof() fails with attribute form DW_FORM_ref_addr Andreas.Kromke at dreamchip dot de
2018-12-25 14:10 ` [Bug libdw/23981] " mark at klomp dot org
2019-01-02 17:06 ` Andreas.Kromke at dreamchip dot de
2019-01-03 17:25 ` Andreas.Kromke at dreamchip dot de
2019-01-13 16:37 ` mark at klomp dot org

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).