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]

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

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