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]

[PATCH] x86: fix gas' relocation type selection


Relocation type selection up to now was dependent on the current code
size
model, but it instead should exclusively depend on the output file
format
(for example, even when in 64-bit code but in a 32-bit object, i386
relocations should be used rather than x86-64 ones [or perhaps a
mixture of
both]).

Built and tested on x86_64-unknown-linux-gnu.

Jan

gas/
2005-07-18  Jan Beulich  <jbeulich@novell.com>

	* config/tc-i386.c (use_rela_relocations): Change type to
unsigned.
	(output_disp): Use use_rela_relocations for relocation type
	determination.
	(output_imm): Likewise.
	(i386_validate_fix): Likewise.
	(tc_gen_reloc): Likewise.
	(lex_got): Likewise. Remove static mode_name. Change array size
	of gotrel's rel field, and adjust its initializer. Adjust
diagnostic.
	(x86_cons): Use use_rela_relocations for deciding whether quad
fields
	can have relocations.

---
/home/jbeulich/src/binutils/mainline/2005-07-18/gas/config/tc-i386.c	2005-07-18
08:26:50.000000000 +0200
+++ 2005-07-18/gas/config/tc-i386.c	2005-07-18 13:46:49.045072752
+0200
@@ -284,7 +284,7 @@ enum flag_code {
 #define NUM_FLAG_CODE ((int) CODE_64BIT + 1)
 
 static enum flag_code flag_code;
-static int use_rela_relocations = 0;
+static unsigned int use_rela_relocations = 0;
 
 /* The names used to print error messages.  */
 static const char *flag_code_names[] =
@@ -3591,7 +3591,7 @@ output_disp (insn_start_frag, insn_start
 		      add += p - frag_now->fr_literal;
 		    }
 
-		  if (flag_code != CODE_64BIT)
+		  if (!use_rela_relocations)
 		    reloc_type = BFD_RELOC_386_GOTPC;
 		  else
 		    reloc_type = BFD_RELOC_X86_64_GOTPC32;
@@ -3728,7 +3728,7 @@ output_imm (insn_start_frag, insn_start_
 		      add += p - frag_now->fr_literal;
 		    }
 
-		  if (flag_code != CODE_64BIT)
+		  if (!use_rela_relocations)
 		    reloc_type = BFD_RELOC_386_GOTPC;
 		  else
 		    reloc_type = BFD_RELOC_X86_64_GOTPC32;
@@ -3756,25 +3756,24 @@ lex_got (enum bfd_reloc_code_real *reloc
      int *adjust,
      unsigned int *types)
 {
-  static const char * const mode_name[NUM_FLAG_CODE] = { "32", "16",
"64" };
   static const struct {
     const char *str;
-    const enum bfd_reloc_code_real rel[NUM_FLAG_CODE];
+    const enum bfd_reloc_code_real rel[2];
     const unsigned int types64;
   } gotrel[] = {
-    { "PLT",      { BFD_RELOC_386_PLT32,      0,
BFD_RELOC_X86_64_PLT32    }, Imm32|Imm32S|Disp32 },
-    { "GOTOFF",   { BFD_RELOC_386_GOTOFF,     0,
BFD_RELOC_X86_64_GOTOFF64 }, Imm64|Disp64 },
-    { "GOTPCREL", { 0,                        0,
BFD_RELOC_X86_64_GOTPCREL }, Imm32|Imm32S|Disp32 },
-    { "TLSGD",    { BFD_RELOC_386_TLS_GD,     0,
BFD_RELOC_X86_64_TLSGD    }, Imm32|Imm32S|Disp32 },
-    { "TLSLDM",   { BFD_RELOC_386_TLS_LDM,    0, 0                    
    }, 0 },
-    { "TLSLD",    { 0,                        0,
BFD_RELOC_X86_64_TLSLD    }, Imm32|Imm32S|Disp32 },
-    { "GOTTPOFF", { BFD_RELOC_386_TLS_IE_32,  0,
BFD_RELOC_X86_64_GOTTPOFF }, Imm32|Imm32S|Disp32 },
-    { "TPOFF",    { BFD_RELOC_386_TLS_LE_32,  0,
BFD_RELOC_X86_64_TPOFF32  }, Imm32|Imm32S|Imm64|Disp32|Disp64 },
-    { "NTPOFF",   { BFD_RELOC_386_TLS_LE,     0, 0                    
    }, 0 },
-    { "DTPOFF",   { BFD_RELOC_386_TLS_LDO_32, 0,
BFD_RELOC_X86_64_DTPOFF32 }, Imm32|Imm32S|Imm64|Disp32|Disp64 },
-    { "GOTNTPOFF",{ BFD_RELOC_386_TLS_GOTIE,  0, 0                    
    }, 0 },
-    { "INDNTPOFF",{ BFD_RELOC_386_TLS_IE,     0, 0                    
    }, 0 },
-    { "GOT",      { BFD_RELOC_386_GOT32,      0,
BFD_RELOC_X86_64_GOT32    }, Imm32|Imm32S|Disp32 }
+    { "PLT",      { BFD_RELOC_386_PLT32,      BFD_RELOC_X86_64_PLT32  
 }, Imm32|Imm32S|Disp32 },
+    { "GOTOFF",   { BFD_RELOC_386_GOTOFF,    
BFD_RELOC_X86_64_GOTOFF64 }, Imm64|Disp64 },
+    { "GOTPCREL", { 0,                       
BFD_RELOC_X86_64_GOTPCREL }, Imm32|Imm32S|Disp32 },
+    { "TLSGD",    { BFD_RELOC_386_TLS_GD,     BFD_RELOC_X86_64_TLSGD  
 }, Imm32|Imm32S|Disp32 },
+    { "TLSLDM",   { BFD_RELOC_386_TLS_LDM,    0                       
 }, 0 },
+    { "TLSLD",    { 0,                        BFD_RELOC_X86_64_TLSLD  
 }, Imm32|Imm32S|Disp32 },
+    { "GOTTPOFF", { BFD_RELOC_386_TLS_IE_32, 
BFD_RELOC_X86_64_GOTTPOFF }, Imm32|Imm32S|Disp32 },
+    { "TPOFF",    { BFD_RELOC_386_TLS_LE_32,  BFD_RELOC_X86_64_TPOFF32
 }, Imm32|Imm32S|Imm64|Disp32|Disp64 },
+    { "NTPOFF",   { BFD_RELOC_386_TLS_LE,     0                       
 }, 0 },
+    { "DTPOFF",   { BFD_RELOC_386_TLS_LDO_32,
BFD_RELOC_X86_64_DTPOFF32 }, Imm32|Imm32S|Imm64|Disp32|Disp64 },
+    { "GOTNTPOFF",{ BFD_RELOC_386_TLS_GOTIE,  0                       
 }, 0 },
+    { "INDNTPOFF",{ BFD_RELOC_386_TLS_IE,     0                       
 }, 0 },
+    { "GOT",      { BFD_RELOC_386_GOT32,      BFD_RELOC_X86_64_GOT32  
 }, Imm32|Imm32S|Disp32 }
   };
   char *cp;
   unsigned int j;
@@ -3790,12 +3789,12 @@ lex_got (enum bfd_reloc_code_real *reloc
       len = strlen (gotrel[j].str);
       if (strncasecmp (cp + 1, gotrel[j].str, len) == 0)
 	{
-	  if (gotrel[j].rel[(unsigned int) flag_code] != 0)
+	  if (gotrel[j].rel[use_rela_relocations] != 0)
 	    {
 	      int first, second;
 	      char *tmpbuf, *past_reloc;
 
-	      *reloc = gotrel[j].rel[(unsigned int) flag_code];
+	      *reloc = gotrel[j].rel[use_rela_relocations];
 	      if (adjust)
 		*adjust = len;
 
@@ -3834,8 +3833,8 @@ lex_got (enum bfd_reloc_code_real *reloc
 	      return tmpbuf;
 	    }
 
-	  as_bad (_("@%s reloc is not supported in %s bit mode"),
-		  gotrel[j].str, mode_name[(unsigned int) flag_code]);
+	  as_bad (_("@%s reloc is not supported with %d-bit output
format"),
+		  gotrel[j].str, 1 << (5 + use_rela_relocations));
 	  return NULL;
 	}
     }
@@ -3865,7 +3864,7 @@ x86_cons (exp, size)
      expressionS *exp;
      int size;
 {
-  if (size == 4 || (flag_code == CODE_64BIT && size == 8))
+  if (size == 4 || (use_rela_relocations && size == 8))
     {
       /* Handle @GOTOFF and the like in an expression.  */
       char *save;
@@ -5451,13 +5450,13 @@ i386_validate_fix (fixp)
     {
       if (fixp->fx_r_type == BFD_RELOC_32_PCREL)
 	{
-	  if (flag_code != CODE_64BIT)
+	  if (!use_rela_relocations)
 	    abort ();
 	  fixp->fx_r_type = BFD_RELOC_X86_64_GOTPCREL;
 	}
       else
 	{
-	  if (flag_code != CODE_64BIT)
+	  if (!use_rela_relocations)
 	    fixp->fx_r_type = BFD_RELOC_386_GOTOFF;
 	  else
 	    fixp->fx_r_type = BFD_RELOC_X86_64_GOTOFF64;
@@ -5559,7 +5558,7 @@ tc_gen_reloc (section, fixp)
       && GOT_symbol
       && fixp->fx_addsy == GOT_symbol)
     {
-      if (flag_code != CODE_64BIT)
+      if (!use_rela_relocations)
 	code = BFD_RELOC_386_GOTPC;
       else
 	code = BFD_RELOC_X86_64_GOTPC32;

Attachment: binutils-mainline-x86-reloc-type.patch
Description: Text document


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