ld on irix revisited

Richard Sandiford rsandifo@redhat.com
Sat Jun 21 16:30:00 GMT 2003


I think I've finally got ld working on irix6 with shared libraries.
Patches attached below.

First, here's a summary of the differences I found between glibc and
irix rld.  I'm sure most of this stuff isn't new, but I need to say
it anyway in order to justify the patches.

glibc 2.2.5's behaviour was:

    If the symbol index < DT_MIPS_GOTSYM, add the final symbol value.
    Otherwise add the symbol's final GOT entry.

glibc 2.3.2's behaviour is:

    If the symbol index < DT_MIPS_GOTSYM, add the base address.
    Otherwise add the symbol's final GOT entry.

The irix rld hehaviour seems to be:

    If the symbol index < DT_MIPS_GOT_SYM, subtract the symbol's
    st_value and add its final value.  Otherwise subract the symbol's
    initial GOT entry and add its final GOT entry.

See last weekend's postings for a verbose justification of the irix
behaviour.  But that's all by-the-bye.  Comparing 2.3.2 with rld,
there are three incompatible cases:

A. Relocs against symbol STN_UNDEF
----------------------------------

    - glibc adds the base address
    - irix rld does nothing (st_value = 0, final symbol value = 0)

    (FWIW, glibc seems to be wrong here since the r_info description
    in the gABI says:

	If the index is STN_UNDEF, the undefined symbol index,
	the relocation uses 0 as the "symbol value".

    The 64-bit ABI has similar wording.)

B. Relocs against defined external symbols
------------------------------------------

    - glibc adds the final symbol value
    - irix rld subtracts the initial contents of the GOT (the original
      st_value) and adds the final symbol value

    This one's the killer.  The addend must include the symbol
    value when using irix rld but it must not when using glibc.

C. Relocs against undefined external symbols
--------------------------------------------

    - glibc adds the final symbol value
    - irix rld subtracts the initial contents of the GOT and adds
      the final symbol value

    At the moment, ld initialises the GOT with the value it found in the
    external DSO, so these behaviours aren't compatible.  I think we're
    supposed to initialise the GOT to zero in this case, see:

        http://sources.redhat.com/ml/binutils/2003-06/msg00525.html

    for justification.


The attached patches are intended to fix the irix problems while
keeping compatibility with glibc.  Where the two loaders need
different behaviour (cases (A) and (B) above), I've used SGI_COMPAT
to select between them.

All the patches are needed in order to get correct irix behaviour:
it doesn't really make sense to apply some and not others.  I've split
them up anyway in the hope that they'll be easier to review that way.

Note: the patches are against 2.14.

Patch 1
-------

	* elfxx-mips.c (_bfd_mips_elf_finish_dynamic_symbol): Always
	initialize a GOT entry to the symbol's st_value.

    Fixes the GOT initailisation for (C).  glibc doesn't use the initial
    contents in this case, so the change is compatible with both loaders.
    Again, see:

        http://sources.redhat.com/ml/binutils/2003-06/msg00525.html

    for a justification.

Patch 2
-------

	* bfd/elfxx-mips.c (mips_elf_create_dynamic_relocation): In SGI-
	compatible objects, add the values of defined external symbols
	to the addend.

    Fixes (B) for irix rld.  This is a variation of the patch posted here:

        http://sources.redhat.com/ml/binutils/2003-06/msg00533.html

    but with the change predicated on SGI_COMPAT since it isn't
    compatible with glibc.

Patch 3
-------

	* bfd/elfxx-mips.c (mips_elf_create_dynamic_relocation): Treat
	forced-local symbols like other locals.  Don't create relocations
	against STN_UNDEF in irix objects.

    Disables this patch:

        http://sources.redhat.com/ml/binutils/2003-03/msg00148.html

    for SGI objects since relocations against symbol 0 do not have
    the desired effect ((A) above).

    Also treats forced-local symbols in the same way as other locals.
    At the moment, relocations against forced-local symbols are always
    turned into relocations against symbol 0.  The patch prevents this
    for irix targets but keeps it for glibc.

Patch 4
-------

	* elfxx-mips.c (mips_elf_link_hash_entry): Remove min_dyn_reloc_index.
	(mips_elf_link_hash_newfunc): Don't set it.
	(mips_elf_create_dynamic_relocation): Likewise.
	(_bfd_mips_elf_copy_indirect_symbol): Likewise.
	(bfd_mips_elf_swap_msym_in): Reenable.
	(mips_elf_adjust_msym_indices): New function.
	(_bfd_mips_elf_finish_dynamic_symbol): Just use a 0 symbol index.
	(_bfd_mips_elf_finish_dynamic_sections): After sorting .rel.dyn,
	go through .msym and set up the ms_info fields appropriately.

    This is the same as the patch posted here:
    
        http://sources.redhat.com/ml/binutils/2003-06/msg00533.html

    except that the new version should use more canonical types.
    See the message for a full explanation.

Patch 5
-------

	* elfxx-mips.c (_bfd_mips_elf_finish_dynamic_symbol): Don't try to
	create .msym entries for forced-local symbols.

    At the moment we try this and corrupt the end of the previous section.

Patch 6
-------

	* elfxx-mips.c (mips_elf_create_dynamic_relocation): Fix handling
	of relocations whose offset is -2.

    Fix the handling of .eh_frame if things like language-specific
    data are made relative.  The .eh_frame code then expects to
    have fully-relocated lsda fields, but we never add in the
    symbol value.

Patch 7
-------

	* elfxx-mips.c (mips_elf_irix6_finish_dynamic_symbol): Make the
	symbols protected.

    This is something I noticed while looking at other stuff.
    It copies the behaviour of the native linker and it seems
    fairly obvious, but I'm not aware of anything specific
    that breaks without it.

Are these patches likely to be accepted?  If so, I'll come up
with something for the testsuite.

The patches were tested on a mipsel-linux-gnu cross compiler and by
bootstrapping and regression testing mips-sgi-irix6.5 --with-gnu-as
--with-gnu-ld.  I needed some gcc patches for the irix config: I'll
post them to gcc-patches if the bfd side is accepted.

Richard

-------------- next part --------------
A non-text attachment was scrubbed...
Name: irix-patch-1.diff
Type: text/x-patch
Size: 1155 bytes
Desc: not available
URL: <https://sourceware.org/pipermail/binutils/attachments/20030621/b124d3db/attachment.bin>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: irix-patch-2.diff
Type: text/x-patch
Size: 1469 bytes
Desc: not available
URL: <https://sourceware.org/pipermail/binutils/attachments/20030621/b124d3db/attachment-0001.bin>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: irix-patch-3.diff
Type: text/x-patch
Size: 1819 bytes
Desc: not available
URL: <https://sourceware.org/pipermail/binutils/attachments/20030621/b124d3db/attachment-0002.bin>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: irix-patch-4.diff
Type: text/x-patch
Size: 6693 bytes
Desc: not available
URL: <https://sourceware.org/pipermail/binutils/attachments/20030621/b124d3db/attachment-0003.bin>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: irix-patch-5.diff
Type: text/x-patch
Size: 345 bytes
Desc: not available
URL: <https://sourceware.org/pipermail/binutils/attachments/20030621/b124d3db/attachment-0004.bin>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: irix-patch-6.diff
Type: text/x-patch
Size: 1068 bytes
Desc: not available
URL: <https://sourceware.org/pipermail/binutils/attachments/20030621/b124d3db/attachment-0005.bin>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: irix-patch-7.diff
Type: text/x-patch
Size: 455 bytes
Desc: not available
URL: <https://sourceware.org/pipermail/binutils/attachments/20030621/b124d3db/attachment-0006.bin>


More information about the Binutils mailing list