public inbox for binutils@sourceware.org
 help / color / mirror / Atom feed
* RFC: Patch to fix MIPS -mno-shared with multi-got...
@ 2005-03-03 21:05 David Daney
  2005-03-03 21:48 ` Richard Sandiford
  0 siblings, 1 reply; 18+ messages in thread
From: David Daney @ 2005-03-03 21:05 UTC (permalink / raw)
  To: binutils

[-- Attachment #1: Type: text/plain, Size: 1587 bytes --]

This patch added by Ian Lance Taylor:

http://sourceware.org/ml/binutils/2004-12/msg00094.html

Added a new option for the MIPS assembler -mno-shared which as he stated 
in the message referenced above:


-------------8<-----------------
This patch adds a new option to the MIPS assembler: -mno-shared.
Normally the .cpload pseudo-op generates code which looks like this:

	lui	$gp,%hi(_gp_disp)
	addiu	$gp,$gp,%lo(_gp_disp)
	addu	$gp,$gp,.cpload argument

With -mno-shared, the .cpload pseudo-op will generate code that looks
like this:

	lui	$gp,%hi(_gp)
	addiu	$gp,$gp,%lo(_gp)
------------8<-------------------


When doing a multi-got link the "_gp_disp" virtual symbol refers to one 
of the several GOTs in the output.

The problem is that "_gp" points to the primary GOT but the relocations 
need to be done against which ever GOT is used by the module being linked

The attached patch adds special handling for "_gp" so that it is treated 
in a manner similar to "_gp_disp"

It allows my large (multi-got) application to be compiled with 
-Wa,-mno-shared which is good.

One thing I am not sure about is if there is existing code somewhere 
that that will break with the patch.

Possible problems are code that use relocations other than R_MIPS_HI16, 
R_MIPS_LO16, R_MIPS16_HI16 and R_MIPS16_LO16 against "_gp" as they would 
now be illegal.  Also multi-got code that for some reason needed to 
refer to the "real _gp" instead of the GOT corresponding to the module.

Thoughts?

If it is thought to be a good patch, I could probably create some test 
cases for it.

David Daney


[-- Attachment #2: no-shared-multi-got.diff --]
[-- Type: text/plain, Size: 2669 bytes --]

--- /home/daney/binutils-050218/bfd/elfxx-mips.c	2005-02-15 20:45:23.000000000 -0800
+++ bfd/elfxx-mips.c	2005-03-03 12:19:30.000000000 -0800
@@ -3039,6 +3039,8 @@ mips_elf_calculate_relocation (bfd *abfd
   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 "_gp".  */
+  bfd_boolean gp_p = FALSE;
   Elf_Internal_Shdr *symtab_hdr;
   size_t extsymoff;
   unsigned long r_symndx;
@@ -3135,6 +3137,20 @@ mips_elf_calculate_relocation (bfd *abfd
 
 	  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, "_gp") == 0
+	  && ! NEWABI_P (input_bfd))
+	{
+	  /* Relocations against _gp are permitted only with
+	     R_MIPS_HI16 and R_MIPS_LO16 relocations.  */
+	  if (r_type != R_MIPS_HI16 && r_type != R_MIPS_LO16
+	      && r_type != R_MIPS16_HI16 && r_type != R_MIPS16_LO16)
+	    return bfd_reloc_notsupported;
+
+	  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
@@ -3415,12 +3431,7 @@ mips_elf_calculate_relocation (bfd *abfd
 
     case R_MIPS_HI16:
     case R_MIPS16_HI16:
-      if (!gp_disp_p)
-	{
-	  value = mips_elf_high (addend + symbol);
-	  value &= howto->dst_mask;
-	}
-      else
+      if (gp_disp_p)
 	{
 	  /* For MIPS16 ABI code we generate this sequence
 	        0: li      $v0,%hi(_gp_disp)
@@ -3437,13 +3448,21 @@ mips_elf_calculate_relocation (bfd *abfd
 	    value = mips_elf_high (addend + gp - p);
 	  overflowed_p = mips_elf_overflow_p (value, 16);
 	}
+      else if (gp_p)
+        {
+	  value = mips_elf_high (addend + gp);
+	  overflowed_p = mips_elf_overflow_p (value, 16);
+        }
+      else
+	{
+	  value = mips_elf_high (addend + symbol);
+	  value &= howto->dst_mask;
+	}
       break;
 
     case R_MIPS_LO16:
     case R_MIPS16_LO16:
-      if (!gp_disp_p)
-	value = (symbol + addend) & howto->dst_mask;
-      else
+      if (gp_disp_p)
 	{
 	  /* See the comment for R_MIPS16_HI16 above for the reason
 	     for this conditional.  */
@@ -3468,6 +3487,12 @@ mips_elf_calculate_relocation (bfd *abfd
 	     Therefore, we consider this a bug in the MIPS ABI, and do
 	     not check for overflow here.  */
 	}
+      else if (gp_p)
+        {
+          value = addend + gp;
+        }
+      else
+	value = (symbol + addend) & howto->dst_mask;
       break;
 
     case R_MIPS_LITERAL:

^ permalink raw reply	[flat|nested] 18+ messages in thread

end of thread, other threads:[~2005-03-05  0:03 UTC | newest]

Thread overview: 18+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2005-03-03 21:05 RFC: Patch to fix MIPS -mno-shared with multi-got David Daney
2005-03-03 21:48 ` Richard Sandiford
2005-03-03 22:34   ` David Daney
2005-03-03 22:49     ` Thiemo Seufer
2005-03-03 23:15       ` David Daney
2005-03-03 23:27         ` Thiemo Seufer
2005-03-04  0:41           ` Daniel Jacobowitz
2005-03-03 23:57       ` David Daney
2005-03-04  0:43         ` Daniel Jacobowitz
2005-03-04  9:36         ` Richard Sandiford
2005-03-04 19:43           ` New " David Daney
2005-03-04 19:45             ` Daniel Jacobowitz
2005-03-04 21:53               ` David Daney
2005-03-04 22:12                 ` Thiemo Seufer
2005-03-04 22:21                   ` David Daney
2005-03-04 23:40                     ` Eric Christopher
2005-03-05  0:03                     ` Thiemo Seufer
2005-03-04  4:31     ` RFC: " Ian Lance Taylor

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).