Hi,

jankratochvil/l_addr

eu-stack: "Callback returned failure" for seemingly OK shared libraries
https://bugzilla.redhat.com/show_bug.cgi?id=1112610#c2

attaching the fix.  I find it obviously right.
It also has no testsuite regressions.

The problem was that user dumping the core file had DSOs prelinked but
downloaded DSOs from RPMs are not prelinked.  l_addr is then zero but it
cannot be determined from the DSO file.

Unfortunately I do not provide a testcase.  It fixes the Bug above as tested
on its core file but I cannot disclose the core file (or its parts).
And despite I did try I haven't reproduced it by a hand-made testcase.

The problem is the modules placing code got overcomplicated and IMO it could
be simplified one day.  There is the former placement which works somehow and
there is the placement by patches of mine which force it here and there to the
right positions.  Trying to exploit failure of the add-on code of mine always
ended up on the former code placing it right on its own.


Thanks,
Jan
--- Begin Message ---
Signed-off-by: Jan Kratochvil <jan.kratoch...@redhat.com>
---
 libdwfl/ChangeLog  |  6 ++++++
 libdwfl/link_map.c | 10 +++++++---
 2 files changed, 13 insertions(+), 3 deletions(-)

diff --git a/libdwfl/ChangeLog b/libdwfl/ChangeLog
index 4a1b9d5..ab47c40 100644
--- a/libdwfl/ChangeLog
+++ b/libdwfl/ChangeLog
@@ -1,3 +1,9 @@
+2014-07-24  Jan Kratochvil  <jan.kratoch...@redhat.com>
+
+       Fix report_r_debug for prelinked libraries.
+       * link_map.c (report_r_debug): Comment out variable l_addr.
+       Use instead new variable base recalculated from l_ld.
+
 2014-06-24  Kurt Roeckx  <k...@roeckx.be>
 
        * linux-pid-attach.c: Make it build on non linux hosts.
diff --git a/libdwfl/link_map.c b/libdwfl/link_map.c
index 2913d9f..9ee1dc0 100644
--- a/libdwfl/link_map.c
+++ b/libdwfl/link_map.c
@@ -321,7 +321,8 @@ report_r_debug (uint_fast8_t elfclass, uint_fast8_t elfdata,
       if (read_addrs (next, 4))
        return release_buffer (-1);
 
-      GElf_Addr l_addr = addrs[0];
+      // unused:
+      // GElf_Addr l_addr = addrs[0];
       GElf_Addr l_name = addrs[1];
       GElf_Addr l_ld = addrs[2];
       next = addrs[3];
@@ -432,11 +433,14 @@ report_r_debug (uint_fast8_t elfclass, uint_fast8_t 
elfdata,
 
                  if (valid)
                    {
+                     // It is like l_addr but it handles differently prelinked
+                     // files at core dumping vs. core loading time
+                     GElf_Addr base = l_ld - elf_dynamic_vaddr;
                      if (r_debug_info_module == NULL)
                        {
                          // XXX hook for sysroot
                          mod = __libdwfl_report_elf (dwfl, basename (name),
-                                                     name, fd, elf, l_addr,
+                                                     name, fd, elf, base,
                                                      true, true);
                          if (mod != NULL)
                            {
@@ -444,7 +448,7 @@ report_r_debug (uint_fast8_t elfclass, uint_fast8_t elfdata,
                              fd = -1;
                            }
                        }
-                     else if (__libdwfl_elf_address_range (elf, l_addr, true,
+                     else if (__libdwfl_elf_address_range (elf, base, true,
                                                            true, NULL, NULL,
                                                    &r_debug_info_module->start,
                                                    &r_debug_info_module->end,
-- 
1.9.3

--- End Message ---

Reply via email to