* write.c (TC_FORCE_RELOCATION): Provide a default definition.
authorJeff Law <law@redhat.com>
Tue, 30 Nov 1993 21:43:15 +0000 (21:43 +0000)
committerJeff Law <law@redhat.com>
Tue, 30 Nov 1993 21:43:15 +0000 (21:43 +0000)
        (fixup_segment): Allow the target machine to specify that a
        relocation must be generated for a particular fixup.  Remove
        #ifndef TC_HPPA hack.

        * config/tc-hppa.h (TC_FORCE_RELOCATION): Define.

        * config/tc-hppa.c (md_apply_fix_1): Never change fx_addsy to
        be NULL.  Only fixup_segment is supposed to do that.
        (hppa_force_relocation): New function.

gas/ChangeLog
gas/config/tc-hppa.c
gas/write.c

index be9da7498ac9b623050748d6fc5513fff9575b0e..22dd3cb765d28ae4777b201e75883cd40484e747 100644 (file)
@@ -1,3 +1,16 @@
+Tue Nov 30 13:40:30 1993  Jeffrey A. Law  (law@snake.cs.utah.edu)
+
+       * write.c (TC_FORCE_RELOCATION): Provide a default definition.
+       (fixup_segment): Allow the target machine to specify that a 
+       relocation must be generated for a particular fixup.  Remove
+       #ifndef TC_HPPA hack.
+
+       * config/tc-hppa.h (TC_FORCE_RELOCATION): Define.
+
+       * config/tc-hppa.c (md_apply_fix_1): Never change fx_addsy to
+       be NULL.  Only fixup_segment is supposed to do that.
+       (hppa_force_relocation): New function.
+
 Tue Nov 30 11:21:41 1993  Ian Lance Taylor  (ian@tweedledumb.cygnus.com)
 
        * Makefile.in (stabs.o): Added dependencies.
index e588ca89abced5facc978cd96262348a6d2d9e60..6ee3ac2bc929dc3f6c7265f0fd5048778f5e81d8 100644 (file)
@@ -3102,7 +3102,6 @@ md_apply_fix_1 (fixP, val)
 
          dis_assemble_12 (result, &w1, &w);
          result = ((w1 << 2) | w);
-         fixP->fx_addsy = NULL;
          break;
 
 #define stub_needed(CALLER, CALLEE) \
@@ -3129,7 +3128,6 @@ md_apply_fix_1 (fixP, val)
          sign_unext ((new_val - 8) >> 2, 17, &result);
          dis_assemble_17 (result, &w1, &w2, &w);
          result = ((w2 << 2) | (w1 << 16) | w);
-         fixP->fx_addsy = NULL;
          break;
 
 #undef too_far
@@ -6346,6 +6344,39 @@ hppa_fix_adjustable (fixp)
   return 0;
 }
 
+/* Return nonzero if the fixup in FIXP will require a relocation,
+   even it if appears that the fixup could be completely handled
+   within GAS.  */
+
+int
+hppa_force_relocation (fixp)
+     fixS *fixp;
+{
+  struct hppa_fix_struct *hppa_fixp = fixp->tc_fix_data;
+
+#ifdef OBJ_SOM
+  if (fixp->fx_r_type == R_HPPA_ENTRY || fixp->fx_r_type == R_HPPA_EXIT)
+    return 1;
+#endif
+
+#define stub_needed(CALLER, CALLEE) \
+  ((CALLEE) && (CALLER) && ((CALLEE) != (CALLER)))
+
+  /* It is necessary to force PC-relative calls/jumps to have a relocation
+     entry if they're going to need either a argument relocation or long
+     call stub.  FIXME.  Can't we need the same for absolute calls?  */
+  if (fixp->fx_pcrel
+      && (stub_needed (((obj_symbol_type *)
+                       fixp->fx_addsy->bsym)->tc_data.hppa_arg_reloc,
+                      hppa_fixp->fx_arg_reloc)))
+       return 1;
+
+#undef stub_needed
+
+  /* No need (yet) to force another relocations to be emitted.  */
+  return 0;
+}
+
 /* Now for some ELF specific code.  FIXME.  */
 #ifdef OBJ_ELF
 static symext_chainS *symext_rootP;
index f27b5e1b2f91e930dde2b8527adff7360a0e3772..9e0ba8ed46d3a537849392304e3f1d785cea8be1 100644 (file)
 #define NOP_OPCODE 0x00
 #endif
 
+#ifndef TC_FORCE_RELOCATION
+#define TC_FORCE_RELOCATION(FIXP) 0
+#endif
+
 #ifndef WORKING_DOT_WORD
 extern CONST int md_short_jump_size;
 extern CONST int md_long_jump_size;
@@ -638,9 +642,7 @@ write_relocs (abfd, sec, xxx)
       if (fixp->fx_where + fixp->fx_size
          > fixp->fx_frag->fr_fix + fixp->fx_frag->fr_offset)
        abort ();
-      /* Pass bogus address so that when bfd_perform_relocation adds
-        `address' back in, it'll come up with `data', which is where
-        we want it to operate.  */
+
       if (reloc->howto->partial_inplace == false
          && reloc->howto->pcrel_offset == true
          && reloc->howto->pc_relative == true)
@@ -648,6 +650,9 @@ write_relocs (abfd, sec, xxx)
          /* bfd_perform_relocation screws this up */
          reloc->addend += reloc->address;
        }
+      /* Pass bogus address so that when bfd_perform_relocation adds
+        `address' back in, it'll come up with `data', which is where
+        we want it to operate.  */
       s = bfd_perform_relocation (stdoutput, reloc, data - reloc->address,
                                  sec, stdoutput);
       switch (s)
@@ -1288,10 +1293,6 @@ write_object_file ()
 #endif /* VMS */
 #else /* BFD_ASSEMBLER */
 
-#ifdef obj_check_file_symbols
-  obj_check_file_symbols ();
-#endif
-
   bfd_map_over_sections (stdoutput, adjust_reloc_syms, (char *)0);
 
   /* Set up symbol table, and write it out.  */
@@ -1329,60 +1330,58 @@ write_object_file ()
                  symp->bsym->flags,
                  segment_name (symp->bsym->section));
 #endif
-         if (! symp->sy_used_in_reloc)
-           {
+
 #ifdef obj_frob_symbol
-             {
-               int punt = 0;
-               obj_frob_symbol (symp, punt);
-               if (punt)
-                 goto punt_it;
-             }
+         {
+           int punt = 0;
+           obj_frob_symbol (symp, punt);
+           if (punt)
+             goto punt_it;
+         }
 #endif
 #ifdef tc_frob_symbol
-             {
-               int punt = 0;
-               tc_frob_symbol (symp, punt);
-               if (punt)
-                 goto punt_it;
-             }
+         {
+           int punt = 0;
+           tc_frob_symbol (symp, punt);
+           if (punt)
+             goto punt_it;
+         }
 #endif
-           }
 
          /* If we don't want to keep this symbol, splice it out of the
             chain now.  */
-         if (! symp->sy_used_in_reloc
-             && S_IS_LOCAL (symp))
+         if (S_IS_LOCAL (symp))
            {
-             symbolS *prev, *next;
-#if defined (obj_frob_symbol) || defined (tc_frob_symbol)
            punt_it:
-#endif
-             prev = symbol_previous (symp);
-             next = symbol_next (symp);
+             if (! symp->sy_used_in_reloc)
+               {
+                 symbolS *prev, *next;
+                 prev = symbol_previous (symp);
+                 next = symbol_next (symp);
 #ifdef DEBUG_SYMS
-             verify_symbol_chain_2 (symp);
+                 verify_symbol_chain_2 (symp);
 #endif
-             if (prev)
-               {
-                 symbol_next (prev) = next;
-                 symp = prev;
-               }
-             else if (symp == symbol_rootP)
-               symbol_rootP = next;
-             else
-               abort ();
-             if (next)
-               symbol_previous (next) = prev;
-             else
-               symbol_lastP = prev;
+                 if (prev)
+                   {
+                     symbol_next (prev) = next;
+                     symp = prev;
+                   }
+                 else if (symp == symbol_rootP)
+                   symbol_rootP = next;
+                 else
+                   abort ();
+                 if (next)
+                   symbol_previous (next) = prev;
+                 else
+                   symbol_lastP = prev;
 #ifdef DEBUG_SYMS
-             if (prev)
-               verify_symbol_chain_2 (prev);
-             else if (next)
-               verify_symbol_chain_2 (next);
+                 if (prev)
+                   verify_symbol_chain_2 (prev);
+                 else if (next)
+                   verify_symbol_chain_2 (next);
 #endif
-             continue;
+                 continue;
+               }
            }
 
          /* Make sure we really got a value for the symbol.  */
@@ -1896,7 +1895,12 @@ fixup_segment (fixP, this_segment_type)
                  S_GET_VALUE (sub_symbolP);
 
                add_symbolP = NULL;
-               fixP->fx_addsy = NULL;
+
+               /* Let the target machine make the final determination
+                  as to whether or not a relocation will be needed to
+                  handle this fixup.  */
+               if (!TC_FORCE_RELOCATION (fixP))
+                 fixP->fx_addsy = NULL;
              }
            else
              {
@@ -1960,9 +1964,12 @@ fixup_segment (fixP, this_segment_type)
                add_number += S_GET_VALUE (add_symbolP);
                add_number -= md_pcrel_from (fixP);
                pcrel = 0;      /* Lie. Don't want further pcrel processing. */
-#ifndef TC_HPPA
-               fixP->fx_addsy = NULL;  /* No relocations please. */
-#endif
+
+               /* Let the target machine make the final determination
+                  as to whether or not a relocation will be needed to
+                  handle this fixup.  */
+               if (!TC_FORCE_RELOCATION (fixP))
+                 fixP->fx_addsy = NULL;
              }
            else
              {
@@ -1973,7 +1980,12 @@ fixup_segment (fixP, this_segment_type)
                    reloc_callj (fixP);
 #endif /* TC_I960 */
                    add_number += S_GET_VALUE (add_symbolP);
-                   fixP->fx_addsy = NULL;
+
+                   /* Let the target machine make the final determination
+                      as to whether or not a relocation will be needed to
+                      handle this fixup.  */
+                   if (!TC_FORCE_RELOCATION (fixP))
+                     fixP->fx_addsy = NULL;
                    add_symbolP = NULL;
                  }
                else if (add_symbol_segment == undefined_section
@@ -1991,7 +2003,12 @@ fixup_segment (fixP, this_segment_type)
                         * relocation.
                         */
                        as_bad ("can't use COBR format with external label");
-                       fixP->fx_addsy = NULL;  /* No relocations please. */
+
+                       /* Let the target machine make the final determination
+                          as to whether or not a relocation will be needed to
+                          handle this fixup.  */
+                       if (!TC_FORCE_RELOCATION (fixP))
+                         fixP->fx_addsy = NULL;
                        continue;
                      }         /* COBR */
 #endif /* TC_I960 */