ld/ARM: Fix IFUNC and TLS descriptors in the same shared object
[deliverable/binutils-gdb.git] / gas / config / tc-vax.c
index 7a9ef0b15b8468d6f1683f203ecff924ee30210b..bccf596b55b10d4d0184b158dfd89f775fbfe44c 100644 (file)
@@ -278,15 +278,21 @@ md_apply_fix (fixS *fixP, valueT *valueP, segT seg ATTRIBUTE_UNUSED)
 {
   valueT value = * valueP;
 
-  if (((fixP->fx_addsy == NULL && fixP->fx_subsy == NULL)
-       && fixP->fx_r_type != BFD_RELOC_32_PLT_PCREL
-       && fixP->fx_r_type != BFD_RELOC_32_GOT_PCREL)
-      || fixP->fx_r_type == NO_RELOC)
-    number_to_chars_littleendian (fixP->fx_where + fixP->fx_frag->fr_literal,
-                                 value, fixP->fx_size);
+  if (fixP->fx_subsy != (symbolS *) NULL)
+    as_bad_where (fixP->fx_file, fixP->fx_line, _("expression too complex"));
 
-  if (fixP->fx_addsy == NULL && fixP->fx_pcrel == 0)
+  if (fixP->fx_addsy == NULL)
     fixP->fx_done = 1;
+
+  if (fixP->fx_done)
+    number_to_chars_littleendian (fixP->fx_where + fixP->fx_frag->fr_literal,
+                                 value, fixP->fx_size);
+  else
+    /* Initialise the part of an instruction frag covered by the
+       relocation.  (Many occurrences of frag_more followed by fix_new
+       lack any init of the frag.)  Since VAX uses RELA relocs the
+       value we write into this field doesn't really matter.  */
+    memset (fixP->fx_where + fixP->fx_frag->fr_literal, 0, fixP->fx_size);
 }
 
 /* Convert a number from VAX byte order (little endian)
@@ -2336,7 +2342,7 @@ tc_gen_reloc (asection *section ATTRIBUTE_UNUSED, fixS *fixp)
   if (fixp->fx_tcbit)
     abort ();
 
-  if (fixp->fx_r_type != BFD_RELOC_NONE)
+  if (fixp->fx_r_type != NO_RELOC)
     {
       code = fixp->fx_r_type;
 
@@ -3264,12 +3270,11 @@ md_begin (void)
     }
 }
 
-static char *vax_cons_special_reloc;
-
-void
+bfd_reloc_code_real_type
 vax_cons (expressionS *exp, int size)
 {
   char *save;
+  char *vax_cons_special_reloc;
 
   SKIP_WHITESPACE ();
   vax_cons_special_reloc = NULL;
@@ -3373,35 +3378,29 @@ vax_cons (expressionS *exp, int size)
     }
   if (vax_cons_special_reloc == NULL)
     expression (exp);
+  else
+    switch (size)
+      {
+      case 1: return BFD_RELOC_8_PCREL;
+      case 2: return BFD_RELOC_16_PCREL;
+      case 4: return BFD_RELOC_32_PCREL;
+      }
+  return NO_RELOC;
 }
 
 /* This is called by emit_expr via TC_CONS_FIX_NEW when creating a
    reloc for a cons.  */
 
 void
-vax_cons_fix_new (fragS *frag, int where, unsigned int nbytes, expressionS *exp)
+vax_cons_fix_new (fragS *frag, int where, unsigned int nbytes, expressionS *exp,
+                 bfd_reloc_code_real_type r)
 {
-  bfd_reloc_code_real_type r;
-
-  r = (nbytes == 1 ? BFD_RELOC_8 :
-       (nbytes == 2 ? BFD_RELOC_16 : BFD_RELOC_32));
-
-  if (vax_cons_special_reloc)
-    {
-      if (*vax_cons_special_reloc == 'p')
-       {
-         switch (nbytes)
-           {
-           case 1: r = BFD_RELOC_8_PCREL; break;
-           case 2: r = BFD_RELOC_16_PCREL; break;
-           case 4: r = BFD_RELOC_32_PCREL; break;
-           default: abort ();
-           }
-       }
-    }
+  if (r == NO_RELOC)
+    r = (nbytes == 1 ? BFD_RELOC_8
+        : nbytes == 2 ? BFD_RELOC_16
+        : BFD_RELOC_32);
 
   fix_new_exp (frag, where, (int) nbytes, exp, 0, r);
-  vax_cons_special_reloc = NULL;
 }
 
 char *
This page took 0.024321 seconds and 4 git commands to generate.