This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB 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]

[RFC/RFA] GDB's .eh_frame unwinder doesn't work when debugging relocatable files loaded at vma != 0.


GDB's .eh_frame unwinder is broken when debugging relocatable
files that are loaded at vma != 0.  I noticed the problem on this
target where shared libraries are really relocatable objects.  I
was marking a function as outermost with the .cfi_undefined trick,
like:

.text
    .global outermost
outermost:
     .cfi_startproc
     .cfi_undefined rip
     <function body>
     .cfi_endproc

but GDB was still trying to unwind past that function, because it was not
finding the FDE with this function's PC in its internal parsed
FDE structures, although the CFI is there on the file, and I could see
it with readelf.  Due to that, the dwarf2 frame sniffer was always rejecting
that function, and GDB was falling back to the prologue analyser, which
happily tried to unwind passed that function, but, miserably failed.

The root of the problem was that the objfile containing that function,
being a relocatable object, ended up with unresolved relocations in it:

:
 11 .eh_frame     00000030  0000000000000000  0000000000000000  0016df50  2**3
                  CONTENTS, ALLOC, LOAD, RELOC, READONLY, DATA
:                                        ^^^^^

... and ...

RELOCATION RECORDS FOR [.eh_frame]:
OFFSET           TYPE              VALUE
0000000000000020 R_X86_64_PC32     .text+0x00000000000c6f00

Since the .eh_frame contents are read from file by:

  dwarf2_build_frame_info
    dwarf2_read_section
       symfile_relocate_debug_section

and .eh_frame is not a really a debug section, this relocation wasn't
being applied, due to the SEC_DEBUGGING check here:

bfd_byte *
symfile_relocate_debug_section (bfd *abfd, asection *sectp, bfd_byte *buf)
{
  /* We're only interested in debugging sections with relocation
     information.  */
  if ((sectp->flags & SEC_RELOC) == 0)
    return NULL;
  if ((sectp->flags & SEC_DEBUGGING) == 0)
    return NULL;
  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  /* We will handle section offsets properly elsewhere, so relocate as if
     all sections begin at 0.  */
  bfd_map_over_sections (abfd, symfile_dummy_outputs, NULL);

  return bfd_simple_get_relocated_section_contents (abfd, sectp, buf, NULL);
}

... that relocation happened to apply to the FDE's initial location value, so,
GDB was parsing an FDE with a broken initial location.  The simplest
fix here is to just remove that SEC_DEBUGGING check.

I've regtested on x86_64-linux, but I didn't expect to see any problems,
since I don't expect to find fully linked libraries with relocs
in .eh_data.  Also, it looks to me that all symfile_relocate_debug_section
callers always pass it a debug section.

Anyone see a problem with this?

-- 
Pedro Alves

2009-03-19  Pedro Alves  <pedro@codesourcery.com>

	* symfile.c (symfile_relocate_debug_section): Remove check for
	SEC_DEBUGGING.

---
 gdb/symfile.c |    9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

Index: src/gdb/symfile.c
===================================================================
--- src.orig/gdb/symfile.c	2009-03-19 13:27:32.000000000 +0000
+++ src/gdb/symfile.c	2009-03-19 14:04:09.000000000 +0000
@@ -3940,17 +3940,18 @@ symfile_dummy_outputs (bfd *abfd, asecti
    one affected platform is PowerPC GNU/Linux, although it depends on
    the version of the linker in use).  Also, ELF object files naturally
    have unresolved relocations for their debug sections.  We need to apply
-   the relocations in order to get the locations of symbols correct.  */
+   the relocations in order to get the locations of symbols correct.
+   Another example that may require relocation processing, is the
+   DWARF-2 .eh_frame section in .o files, although it isn't strictly a
+   debug section.  */
 
 bfd_byte *
 symfile_relocate_debug_section (bfd *abfd, asection *sectp, bfd_byte *buf)
 {
-  /* We're only interested in debugging sections with relocation
+  /* We're only interested in sections with relocation
      information.  */
   if ((sectp->flags & SEC_RELOC) == 0)
     return NULL;
-  if ((sectp->flags & SEC_DEBUGGING) == 0)
-    return NULL;
 
   /* We will handle section offsets properly elsewhere, so relocate as if
      all sections begin at 0.  */


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