diff options
author | Martin Schwidefsky <schwidefsky@de.ibm.com> | 2001-11-05 08:47:46 +0000 |
---|---|---|
committer | Martin Schwidefsky <schwidefsky@de.ibm.com> | 2001-11-05 08:47:46 +0000 |
commit | b8edc45c300fbe12145e84499a2d542baade2223 (patch) | |
tree | 6a62c5d454ebb08141c0b766d975eaddb89265e4 /gas/config/tc-s390.c | |
parent | def7143b201cce31043a0cf596a325213861e404 (diff) | |
download | gdb-b8edc45c300fbe12145e84499a2d542baade2223.zip gdb-b8edc45c300fbe12145e84499a2d542baade2223.tar.gz gdb-b8edc45c300fbe12145e84499a2d542baade2223.tar.bz2 |
Force got and plt relocations.
Diffstat (limited to 'gas/config/tc-s390.c')
-rw-r--r-- | gas/config/tc-s390.c | 62 |
1 files changed, 52 insertions, 10 deletions
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) |