Convert absolute personalities into PC-relative ones

Richard Sandiford rdsandiford@googlemail.com
Sun Sep 13 19:53:00 GMT 2009


As discussed with Mark recently, this patch allows the linker to turn
absolute-but-locally-binding personality pointers into PC-relative ones,
under the usual "info->shared && we support this" condition.  MIPS needs
this to work for indirect pointers too, and that shows up a problem in
the current elf-eh-frame.c code: it treats the top nibble as an enum
of the base address, whereas DW_EH_PE_indirect is really a separate
flag.  So, for example, when adjusting PC-relative offsets to account
for things like removed CIEs and FDEs, we use:

   (encoding & 0xf0) == DW_EH_PE_pcrel

even though (AIUI) the adjustment ought to be applied to
DW_EH_PE_pcrel | DW_EH_PE_indirect as well.

The patch goes through elf-eh-frame.c and replaces 0xf0 with 0x70.
This wasn't just mechanical though!  I did try to justify that each
one was correct.  And I think each one is.  However:

	      switch (ent->fde_encoding & 0xf0)
		{
		case DW_EH_PE_indirect:
		case DW_EH_PE_textrel:
		  BFD_ASSERT (hdr_info == NULL);
		  break;
		case DW_EH_PE_datarel:
		  {
		    asection *got = bfd_get_section_by_name (abfd, ".got");

		    BFD_ASSERT (got != NULL);
		    address += got->vma;
		  }
		  break;
		case DW_EH_PE_pcrel:
		  value += (bfd_vma) ent->offset - ent->new_offset;
		  address += (sec->output_section->vma
			      + sec->output_offset
			      + ent->offset + 8);
		  break;
		}

is an interesting case.  It seems to be asserting that we only have
an .eh_frame_hdr (and thus only use "address") in cases where we can
correctly calculate the address of the target code.  That sounds like
a good idea in principle, but as mentioned above, we ought to exclude
all DW_EH_PE_indirect encodings, not just:

  DW_EH_PE_indirect | DW_EH_PE_absptr

Admittedly that's probably only of academic interest, since no-one is
likely to use indirect pointers for the FDE ranges (are they? ;-)).

More importantly, we don't seem to actually enforce the asserted
condition anywhere, so I'm wondering whether we ought to have
something like the second (completely untested) patch as well.

I tested the first patch in combination with the third (gcc) patch
on mips64octeon-linux-gnu.  There were no regressions from unpatched
GCC and binutils.  After the patches, libstdc++.so still has a read-only
.eh_frame, but it is free from text relocations.

Any objections to the first patch?  Any thoughts on the second?
If the first patch is OK, is it too invasive for the branch?
I'd ideally like to get this into 2.20, so that the feature is
in a released binutils when GCC 4.5 comes out.

If the first patch goes in, I'll apply the GCC one too, and then
do a follow-up to check for the correct linker version.  I'll make
-fno-dwarf2-cfi-asm the default when this linker version check fails.
I'll also make -fno-dwarf2-cfi-asm the unconditional default for MIPS
GCC 4.4, as long as Mark or another GCC release manager agress.

Richard


-------------- next part --------------
A non-text attachment was scrubbed...
Name: ld-rel-personality.patch
Type: text/x-diff
Size: 21400 bytes
Desc: not available
URL: <https://sourceware.org/pipermail/binutils/attachments/20090913/f653926c/attachment.bin>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: followon.patch
Type: text/x-diff
Size: 1691 bytes
Desc: not available
URL: <https://sourceware.org/pipermail/binutils/attachments/20090913/f653926c/attachment-0001.bin>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: gcc.patch
Type: text/x-diff
Size: 1457 bytes
Desc: not available
URL: <https://sourceware.org/pipermail/binutils/attachments/20090913/f653926c/attachment-0002.bin>


More information about the Binutils mailing list