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

Re: [patch,PE-COFF,head+2.22] Don't generate bogus base relocs in .eh_frame of DLLs.


>  The latest release of the libstdc++ DLL for Cygwin breaks exception handling
>if it is rebased away from its default address.  Debugging this shows that one
>of the Dwarf-2 FDEs in the .eh_frame section gets mangled, which causes the
>libgcc unwind code to get confused and fail to find the FDE for a given return
>address from the stack frame, resulting in an early exit through terminate().
>
>  It turns out that the FDE in question refers to an inline function, which
>exists in one of the input object files linked to build the final DLL in a
>COMDAT section.  When the COMDAT resolution picks a copy of the section from a
>different object file, the .eh_frame FDE data contains a reloc that now points
>to a discarded section.  This happens a lot because there's only one .eh_frame
>section per object file that covers all the text sections, any one of which
>might get discarded.
>
>  The generic linker handles it just fine; it gets a value of zero against the
>*ABS* section, resulting in a zero in the relocated section contents, and the
>libgcc unwind code interprets a zero start address in an FDE to mean that the
>FDE is discarded.  However the PE linker still goes and generates a base reloc
>corresponding to the effectively-disregarded BFD reloc.  (PE DLLs are
>pre-linked to assume they will be loaded at a chosen base address; if they end
>up loaded elsewhere at runtime, the OS loader applies a set of PE-specific
>relocations known as "base relocations".)  Thus when the DLL is rebased, the
>start address field in the FDE gets written with the offset by which the DLL
>is being rebased, and libgcc interprets this as an FDE for a PC range
>somewhere in low or high memory (according to the direction in which the DLL
>is rebased) and gets its internal list of memory regions in a twist.
>
>  The attached patch is conservative; it checks just for BFD against symbols
>from discarded input sections, and if the reloc itself is in an EH section it
>doesn't generate a corresponding base reloc.  It doesn't cause any failures in
>the ld testsuite, but then I don't think we have anything to verify base reloc
>generation in there anyway, so I'm also running a GCC bootstrap and test cycle
>using the patched binutils.  (I already checked that the libstdc++ DLL that it
>builds omits the specific base relocs that were causing the problem and
>handles exceptions just fine even after rebasing).  It'll probably be another
>48 hours before the results from that are in, so this is advance warning for
>Tristan; I'd like to get this into the 2.22 release so that it can be in the
>next Cygwin binutils package.  Ok, Tristan?
>
>ld/ChangeLog:
>
>2011-09-25  Dave Korn  <dave.korn.cygwin@...
>
>	* pe-dll.c (generate_reloc): Don't emit base reloc if underlying
>	BFD reloc is from an EH section and refers to a discarded input
>	COMDAT section.
>
>    cheers,
>      DaveK
>
>
>
>Index: ld/pe-dll.c
>===================================================================
>RCS file: /cvs/src/src/ld/pe-dll.c,v
>retrieving revision 1.138
>diff -p -u -r1.138 pe-dll.c
>--- ld/pe-dll.c	16 Sep 2011 01:15:19 -0000	1.138
>+++ ld/pe-dll.c	25 Sep 2011 12:59:34 -0000
>@@ -1395,6 +1395,16 @@ generate_reloc (bfd *abfd, struct bfd_li
> 		      else if (!blhe || blhe->type != bfd_link_hash_defined)
> 			continue;
> 		    }
>+		  /* Nor for Dwarf FDE references to discarded sections.  */
>+		  else if (bfd_is_abs_section (sym->section->output_section))
>+		    {
>+		      /* These are the same section names that
>+			 _bfd_elf_default_action_discarded chooses to discard
>+			 relocs against.  */
>+		      if (!strcmp (s->name, ".eh_frame")
>+			  || !strcmp (s->name, ".gcc_except_table"))
>+			continue;
>+		    }
>
> 		  reloc_data[total_relocs].vma = sec_vma + relocs[i]->address;
>

This patch still isn't in. Is it not needed any more?

--
O.S.


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