This is the mail archive of the binutils@sources.redhat.com 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]

RFA: MIPS's _gp symbol and the new orphan-placement code


This patch has been on the back burner since Alan's recent(ish) changes
to the way orphan sections are placed.  This message isn't a complaint
about those changes at all.   However, they did tickle a problem with
the default linker scripts for n32 and n64 on IRIX.

According to the ABI docs, the old .reginfo sections were superceded by
.MIPS.options in n32 and n64, so the associated IRIX linker scripts don't
define a .reginfo section.  Nevertheless, the system /usr/lib32/crt*.o
files do have .reginfo sections, so the linker ends up creating an
output .reginfo and placing it as an orphan.

The new orphan placement code puts this .reginfo section right before
.got.  This should be fine in theory, but unfortunately, the linker
scripts set up _gp using:

  _gp = ALIGN(16) + 0x7ff0;
  .got            : { *(.got.plt) *(.got) }

where the assignment to _gp is provided by OTHER_GOT_SYMBOLS.  bfd's
lazy binding stubs require that _gp - .got be exactly 0x7ff0 and putting
.reginfo before .got will of course break this rule.  As a result, most
objects will quickly segfault.

This definition of _gp has caused problems before (when Thiemo wanted to
decrease the alignment of .got from 16 to the IRIX-standard 4).  In that
instance, we ended up keeping the original alignment for compatibility
with older tools (a good thing IMO), but I think this time we really
will have to change the way _gp is set.

There were lots of different this could be fixed, such as:

  (1) Replacing ALIGN(16) with ADDR(.got).

      --> Unfortunately, this means that every output object will
          get a .got section, which is a bit untidy, although I don't
          know if it would be outright harmful.

  (2) Moving the assignment into .got and using ". + 0x7ff0".

      --> Same problem as (1).

  (3) Defining _gp in the linker instead.

      --> I think it would be difficult to do this and keep backward
          compatibility with existing linker scripts (including the
          kind of scripts used for *-elf targets).

  (4) Just adding .reginfo to the linker script.

      --> Gets us past the current failure point, but it's really just
          hiding the problem.

  (5) Adjusting bfd so that it can cope with offsets other than 0x7ff0.

      --> We don't really want smaller offsets since they'd just lead to
          tighter limits on GOT size.  Going this route would also make
          the bfd code even more complex (I think it would affect the
          stub creation code and multigot partitioning code at the
          very least).

So in the end I went for:

  (6) Defining _gp as follows:

        _gp = (DEFINED (_GLOBAL_OFFSET_TABLE_)
               ? _GLOBAL_OFFSET_TABLE_
               : ALIGN (16)) + 0x7ff0;

      This means that, if the object does need a GOT, _G_O_T_ - gp will
      always be 0x7ff0, just like the bfd linker code requires.  _gp will
      retain its current value otherwise.

Tested with a gcc bootstrap & regression test (all three ABIs)
on mips-sgi-irix6.5.  Also tested against the binutils testsuite
with mips64-elf and mips64-linux-gnu.  OK to install?

Richard


	* emulparams/elf32bmip.sh (OTHER_GOT_SYMBOLS): Make the definition
	of _gp more robust.
	* emulparams/elf32bmipn32-defs.sh (OTHER_GOT_SYMBOLS): Likewise.

Index: ld/emulparams/elf32bmip.sh
===================================================================
RCS file: /cvs/src/src/ld/emulparams/elf32bmip.sh,v
retrieving revision 1.6
diff -u -p -F^\([(a-zA-Z0-9_]\|#define\) -r1.6 elf32bmip.sh
--- ld/emulparams/elf32bmip.sh	21 Apr 2004 20:52:28 -0000	1.6
+++ ld/emulparams/elf32bmip.sh	6 Nov 2004 23:46:36 -0000
@@ -17,7 +17,9 @@ INITIAL_READONLY_SECTIONS="
 "
 OTHER_TEXT_SECTIONS='*(.mips16.fn.*) *(.mips16.call.*)'
 OTHER_GOT_SYMBOLS='
-  _gp = ALIGN(16) + 0x7ff0;
+  _gp = (DEFINED (_GLOBAL_OFFSET_TABLE_)
+	 ? _GLOBAL_OFFSET_TABLE_
+	 : ALIGN (16)) + 0x7ff0;
 '
 OTHER_SDATA_SECTIONS="
   .lit8         ${RELOCATING-0} : { *(.lit8) }
Index: ld/emulparams/elf32bmipn32-defs.sh
===================================================================
RCS file: /cvs/src/src/ld/emulparams/elf32bmipn32-defs.sh,v
retrieving revision 1.6
diff -u -p -F^\([(a-zA-Z0-9_]\|#define\) -r1.6 elf32bmipn32-defs.sh
--- ld/emulparams/elf32bmipn32-defs.sh	14 Feb 2004 11:45:25 -0000	1.6
+++ ld/emulparams/elf32bmipn32-defs.sh	6 Nov 2004 23:46:36 -0000
@@ -37,7 +37,9 @@ ENTRY=__start
 
 # GOT-related settings.  
 OTHER_GOT_SYMBOLS='
-  _gp = ALIGN(16) + 0x7ff0;
+  _gp = (DEFINED (_GLOBAL_OFFSET_TABLE_)
+	 ? _GLOBAL_OFFSET_TABLE_
+	 : ALIGN (16)) + 0x7ff0;
 '
 OTHER_SDATA_SECTIONS="
   .lit8         ${RELOCATING-0} : { *(.lit8) }


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