This is the mail archive of the
binutils@sources.redhat.com
mailing list for the binutils project.
Re: RFC: Patch to fix MIPS -mno-shared with multi-got...
Thiemo Seufer wrote:
David Daney wrote:
[snip]
WRT possible breakge to things expecting the real "_gp": I agree that
might be a problem. One possibility would be to define a new symbol,
something like __gnu_local_gp, and make -mno-shared use that instead
of plain _gp. -mno-shared is a new option, so there's no backwards
compatiblity problem.
OK, I kind of like this idea. But I am not an ABI authority. I am
assuming the the meaning of "_gp_disp" is defined somewhere in the ABI
specs. I know _gp is specified. Does anybody have objections to adding
the new magic __gnu_local_gp symbol?
I have the general (and still vague) idea to have multigot-capable object
files, with _gp _gp.1 .. _gp.n and _gp_disp _gp_disp.1 .. _gp_disp.n
depending on the GOT in use, and with the single got case staying binary
compatible. I think this would cover your case as well, but it's of
course much more work.
Yes, it makes my head hurt just to think about it.
In lieu of doing that I present the attached patch.
The main question being: Use _gp or __gnu_local_gp ?
The pros of using _gp are that Thiemo's plan to magically rename _gp
would be binary compatible.
The pros of using __gnu_local_gp are that existing code using _gp
outside of .cpload would continue to work.
I am inclined to use _gp as it does not create a gnu specific ABI
extension, but I am apprehensive about what will happen when I try to
build glibc.
David Daney.
Only in /home/daney/binutils_reference/binutils-050218/bfd/doc: bfd.info-1
Only in /home/daney/binutils_reference/binutils-050218/bfd/doc: bfd.info-2
diff -rcp --exclude='*.info' /home/daney/binutils_reference/binutils-050218/bfd/elfxx-mips.c binutils-050218/bfd/elfxx-mips.c
*** /home/daney/binutils_reference/binutils-050218/bfd/elfxx-mips.c 2005-02-15 20:45:23.000000000 -0800
--- binutils-050218/bfd/elfxx-mips.c 2005-03-03 14:41:04.000000000 -0800
*************** mips_elf_calculate_relocation (bfd *abfd
*** 3039,3044 ****
--- 3039,3046 ----
bfd_boolean local_p, was_local_p;
/* TRUE if the symbol referred to by this relocation is "_gp_disp". */
bfd_boolean gp_disp_p = FALSE;
+ /* TRUE if the symbol referred to by this relocation is "__gnu_local_gp". */
+ bfd_boolean gnu_local_gp_p = FALSE;
Elf_Internal_Shdr *symtab_hdr;
size_t extsymoff;
unsigned long r_symndx;
*************** mips_elf_calculate_relocation (bfd *abfd
*** 3135,3140 ****
--- 3137,3148 ----
gp_disp_p = TRUE;
}
+ /* See if this is the special _gp symbol. Note that such a
+ symbol must always be a global symbol. */
+ else if (strcmp (*namep, "__gnu_local_gp") == 0)
+ gnu_local_gp_p = TRUE;
+
+
/* If this symbol is defined, calculate its address. Note that
_gp_disp is a magic symbol, always implicitly defined by the
linker, so it's inappropriate to check to see whether or not
*************** mips_elf_calculate_relocation (bfd *abfd
*** 3336,3341 ****
--- 3344,3352 ----
break;
}
+ if (gnu_local_gp_p)
+ symbol = gp;
+
/* Figure out what kind of relocation is being performed. */
switch (r_type)
{
Only in binutils-050218/bfd: elfxx-mips.c~
diff -rcp --exclude='*.info' /home/daney/binutils_reference/binutils-050218/gas/config/tc-mips.c binutils-050218/gas/config/tc-mips.c
*** /home/daney/binutils_reference/binutils-050218/gas/config/tc-mips.c 2005-02-17 05:46:04.000000000 -0800
--- binutils-050218/gas/config/tc-mips.c 2005-03-03 15:33:20.000000000 -0800
*************** macro_build_lui (expressionS *ep, int re
*** 3395,3407 ****
else
{
assert (ep->X_op == O_symbol);
! /* _gp_disp is a special case, used from s_cpload. _gp is used
if mips_no_shared. */
assert (mips_pic == NO_PIC
|| (! HAVE_NEWABI
&& strcmp (S_GET_NAME (ep->X_add_symbol), "_gp_disp") == 0)
|| (! mips_in_shared
! && strcmp (S_GET_NAME (ep->X_add_symbol), "_gp") == 0));
*r = BFD_RELOC_HI16_S;
}
--- 3395,3407 ----
else
{
assert (ep->X_op == O_symbol);
! /* _gp_disp is a special case, used from s_cpload. __gnu_local_gp is used
if mips_no_shared. */
assert (mips_pic == NO_PIC
|| (! HAVE_NEWABI
&& strcmp (S_GET_NAME (ep->X_add_symbol), "_gp_disp") == 0)
|| (! mips_in_shared
! && strcmp (S_GET_NAME (ep->X_add_symbol), "__gnu_local_gp") == 0));
*r = BFD_RELOC_HI16_S;
}
*************** s_abicalls (int ignore ATTRIBUTE_UNUSED)
*** 11797,11808 ****
The .cpload argument is normally $25 == $t9.
The -mno-shared option changes this to:
! lui $gp,%hi(_gp)
! addiu $gp,$gp,%lo(_gp)
and the argument is ignored. This saves an instruction, but the
resulting code is not position independent; it uses an absolute
! address for _gp. Thus code assembled with -mno-shared can go into
! an ordinary executable, but not into a shared library. */
static void
s_cpload (int ignore ATTRIBUTE_UNUSED)
--- 11797,11808 ----
The .cpload argument is normally $25 == $t9.
The -mno-shared option changes this to:
! lui $gp,%hi(__gnu_local_gp)
! addiu $gp,$gp,%lo(__gnu_local_gp)
and the argument is ignored. This saves an instruction, but the
resulting code is not position independent; it uses an absolute
! address for __gnu_local_gp. Thus code assembled with -mno-shared
! can go into an ordinary executable, but not into a shared library. */
static void
s_cpload (int ignore ATTRIBUTE_UNUSED)
*************** s_cpload (int ignore ATTRIBUTE_UNUSED)
*** 11830,11836 ****
in_shared = mips_in_shared || HAVE_64BIT_ADDRESSES;
ex.X_op = O_symbol;
! ex.X_add_symbol = symbol_find_or_make (in_shared ? "_gp_disp" : "_gp");
ex.X_op_symbol = NULL;
ex.X_add_number = 0;
--- 11830,11836 ----
in_shared = mips_in_shared || HAVE_64BIT_ADDRESSES;
ex.X_op = O_symbol;
! ex.X_add_symbol = symbol_find_or_make (in_shared ? "_gp_disp" : "__gnu_local_gp");
ex.X_op_symbol = NULL;
ex.X_add_number = 0;
*************** MIPS options:\n\
*** 14078,14083 ****
--- 14078,14085 ----
-non_shared do not generate position independent code\n\
-xgot assume a 32 bit GOT\n\
-mpdr, -mno-pdr enable/disable creation of .pdr sections\n\
+ -mshared, -mno-shared disable/enable .cpload optimization for\n\
+ non-shared code\n\
-mabi=ABI create ABI conformant object file for:\n"));
first = 1;
Only in binutils-050218/gas/config: tc-mips.c.orig