aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Schwidefsky <schwidefsky@de.ibm.com>2001-11-05 08:47:46 +0000
committerMartin Schwidefsky <schwidefsky@de.ibm.com>2001-11-05 08:47:46 +0000
commitb8edc45c300fbe12145e84499a2d542baade2223 (patch)
tree6a62c5d454ebb08141c0b766d975eaddb89265e4
parentdef7143b201cce31043a0cf596a325213861e404 (diff)
downloadgdb-b8edc45c300fbe12145e84499a2d542baade2223.zip
gdb-b8edc45c300fbe12145e84499a2d542baade2223.tar.gz
gdb-b8edc45c300fbe12145e84499a2d542baade2223.tar.bz2
Force got and plt relocations.
-rw-r--r--gas/ChangeLog10
-rw-r--r--gas/config/tc-s390.c62
-rw-r--r--gas/config/tc-s390.h8
3 files changed, 67 insertions, 13 deletions
diff --git a/gas/ChangeLog b/gas/ChangeLog
index f79ce03..3e43d3f 100644
--- a/gas/ChangeLog
+++ b/gas/ChangeLog
@@ -1,3 +1,13 @@
+2001-11-05 Martin Schwidefsky <schwidefsky@de.ibm.com>
+
+ * config/tc-s390.c (tc_s390_force_relocation): Force all relocations
+ that need the global offset table.
+ (md_apply_fix3): Add code to undo opertions done in fixup_segment
+ triggered by TC_FORCE_RELOCATION.
+ * config/tc-s390.h (TC_FORCE_RELOCATION): Replace macro code with
+ a call to function tc_s390_force_relocation.
+ (TC_FIX_ADJUSTABLE): Define.
+
2001-11-04 Chris Demetriou <cgd@broadcom.com>
* configure.in (mips-*-netbsd*): Add support for target.
diff --git a/gas/config/tc-s390.c b/gas/config/tc-s390.c
index dc3b16f..1f6f02c 100644
--- a/gas/config/tc-s390.c
+++ b/gas/config/tc-s390.c
@@ -1641,6 +1641,36 @@ tc_s390_fix_adjustable(fixP)
return 1;
}
+/* Return true if we must always emit a reloc for a type and false if
+ there is some hope of resolving it a assembly time. */
+int
+tc_s390_force_relocation (fixp)
+ struct fix *fixp;
+{
+ /* Ensure we emit a relocation for every reference to the global
+ offset table or to the procedure link table. */
+ switch (fixp->fx_r_type)
+ {
+ case BFD_RELOC_390_GOT12:
+ case BFD_RELOC_32_GOT_PCREL:
+ case BFD_RELOC_32_GOTOFF:
+ case BFD_RELOC_390_GOTPC:
+ case BFD_RELOC_390_GOT16:
+ case BFD_RELOC_390_GOTPCDBL:
+ case BFD_RELOC_390_GOT64:
+ case BFD_RELOC_390_GOTENT:
+ case BFD_RELOC_390_PLT32:
+ case BFD_RELOC_390_PLT16DBL:
+ case BFD_RELOC_390_PLT32DBL:
+ case BFD_RELOC_390_PLT64:
+ case BFD_RELOC_VTABLE_INHERIT:
+ case BFD_RELOC_VTABLE_ENTRY:
+ return 1;
+ default:
+ return 0;
+ }
+}
+
/* Apply a fixup to the object code. This is called for all the
fixups we generated by the call to fix_new_exp, above. In the call
above we used a reloc code which was the largest legal reloc code
@@ -1654,7 +1684,7 @@ int
md_apply_fix3 (fixp, valuep, seg)
fixS *fixp;
valueT *valuep;
- segT seg ATTRIBUTE_UNUSED;
+ segT seg;
{
char *where;
valueT value;
@@ -1662,22 +1692,34 @@ md_apply_fix3 (fixp, valuep, seg)
value = *valuep;
where = fixp->fx_frag->fr_literal + fixp->fx_where;
- if (fixp->fx_subsy != NULL)
+ if (fixp->fx_subsy != NULL)
{
+ if ((fixp->fx_addsy != NULL
+ && S_GET_SEGMENT (fixp->fx_addsy) == S_GET_SEGMENT (fixp->fx_subsy)
+ && SEG_NORMAL (S_GET_SEGMENT (fixp->fx_addsy)))
+ || (S_GET_SEGMENT (fixp->fx_subsy) == absolute_section))
+ value += S_GET_VALUE (fixp->fx_subsy);
if (!S_IS_DEFINED (fixp->fx_subsy))
as_bad_where (fixp->fx_file, fixp->fx_line,
_("unresolved fx_subsy symbol that must be resolved"));
value -= S_GET_VALUE(fixp->fx_subsy);
- }
- if (fixp->fx_addsy != NULL)
+ if (S_GET_SEGMENT (fixp->fx_subsy) == seg && ! fixp->fx_pcrel)
+ value += MD_PCREL_FROM_SECTION (fixp, seg);
+ }
+
+ if (fixp->fx_addsy != NULL)
{
- /* `*valuep' may contain the value of the symbol on which the reloc
- will be based; we have to remove it. */
- if (fixp->fx_addsy->sy_used_in_reloc
- && S_GET_SEGMENT (fixp->fx_addsy) != absolute_section
- && S_GET_SEGMENT (fixp->fx_addsy) != undefined_section
- && ! bfd_is_com_section (S_GET_SEGMENT (fixp->fx_addsy)))
+ if ((fixp->fx_subsy != NULL
+ && S_GET_SEGMENT (fixp->fx_addsy) == S_GET_SEGMENT (fixp->fx_subsy)
+ && SEG_NORMAL (S_GET_SEGMENT(fixp->fx_addsy)))
+ || (S_GET_SEGMENT (fixp->fx_addsy) == seg
+ && fixp->fx_pcrel && TC_RELOC_RTSYM_LOC_FIXUP (fixp))
+ || (!fixp->fx_pcrel
+ && S_GET_SEGMENT (fixp->fx_addsy) == absolute_section)
+ || (S_GET_SEGMENT (fixp->fx_addsy) != undefined_section
+ && !bfd_is_com_section (S_GET_SEGMENT (fixp->fx_addsy))
+ && TC_FIX_ADJUSTABLE(fixp)))
value -= S_GET_VALUE (fixp->fx_addsy);
if (fixp->fx_pcrel)
diff --git a/gas/config/tc-s390.h b/gas/config/tc-s390.h
index ad201c3..67d9117 100644
--- a/gas/config/tc-s390.h
+++ b/gas/config/tc-s390.h
@@ -44,13 +44,15 @@ struct fix;
&& S_IS_DEFINED ((FIX)->fx_addsy) \
&& ! S_IS_COMMON ((FIX)->fx_addsy))))
-#define TC_FORCE_RELOCATION(FIXP) \
- ((FIXP)->fx_r_type == BFD_RELOC_VTABLE_INHERIT \
- || (FIXP)->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
+#define TC_FORCE_RELOCATION(FIXP) tc_s390_force_relocation(FIXP)
+extern int tc_s390_force_relocation PARAMS ((struct fix *));
#define tc_fix_adjustable(X) tc_s390_fix_adjustable(X)
extern int tc_s390_fix_adjustable PARAMS ((struct fix *));
+#define TC_FIX_ADJUSTABLE(fixP) \
+ (! symbol_used_in_reloc_p ((fixP)->fx_addsy) && tc_fix_adjustable (fixP))
+
/* The target BFD architecture. */
#define TARGET_ARCH bfd_arch_s390
extern enum bfd_architecture s390_arch PARAMS ((void));