aboutsummaryrefslogtreecommitdiff
path: root/gas/config/tc-s390.c
diff options
context:
space:
mode:
authorMartin Schwidefsky <schwidefsky@de.ibm.com>2003-01-20 11:48:32 +0000
committerMartin Schwidefsky <schwidefsky@de.ibm.com>2003-01-20 11:48:32 +0000
commit2a19f73f879a10f230fbae6bccbdc114119584ff (patch)
tree0cf41931f60f991d0c4a1c56798ee49a4afd4e26 /gas/config/tc-s390.c
parent5236c819d286710b9daa83f5d38573b84e442f67 (diff)
downloadgdb-2a19f73f879a10f230fbae6bccbdc114119584ff.zip
gdb-2a19f73f879a10f230fbae6bccbdc114119584ff.tar.gz
gdb-2a19f73f879a10f230fbae6bccbdc114119584ff.tar.bz2
* config/tc-s390.c (elf_suffix_type): Add suffix enums for gotoff,
gotplt and pltoff relocations. (s390_elf_suffix): Add suffix strings for gotoff, gotplt and pltoff. (s390_elf_cons): Map new lenght/elf suffix combinations for gotoff, gotplt and pltoff to bfd relocations. (md_gather_operands): Map new instruction operand/elf suffix combinations to bfd relocations. (tc_s390_fix_adjustable): Add new gotoff, gotplt and pltoff relocations to the list of unadjustable relocations. (tc_s390_force_relocation): Always emit relocations for gotoff, gotplt and pltoff relocations. (md_apply_fix3): Add the new relocations.
Diffstat (limited to 'gas/config/tc-s390.c')
-rw-r--r--gas/config/tc-s390.c82
1 files changed, 80 insertions, 2 deletions
diff --git a/gas/config/tc-s390.c b/gas/config/tc-s390.c
index b7de6fa..d65c406 100644
--- a/gas/config/tc-s390.c
+++ b/gas/config/tc-s390.c
@@ -606,7 +606,10 @@ typedef enum
ELF_SUFFIX_NONE = 0,
ELF_SUFFIX_GOT,
ELF_SUFFIX_PLT,
- ELF_SUFFIX_GOTENT
+ ELF_SUFFIX_GOTENT,
+ ELF_SUFFIX_GOTOFF,
+ ELF_SUFFIX_GOTPLT,
+ ELF_SUFFIX_PLTOFF
}
elf_suffix_type;
@@ -635,6 +638,9 @@ s390_elf_suffix (str_p, exp_p)
{ "got12", 5, ELF_SUFFIX_GOT },
{ "plt", 3, ELF_SUFFIX_PLT },
{ "gotent", 6, ELF_SUFFIX_GOTENT },
+ { "gotoff", 6, ELF_SUFFIX_GOTOFF },
+ { "gotplt", 6, ELF_SUFFIX_GOTPLT },
+ { "pltoff", 6, ELF_SUFFIX_PLTOFF },
{ NULL, 0, ELF_SUFFIX_NONE }
};
@@ -956,10 +962,26 @@ s390_elf_cons (nbytes)
reloc = BFD_RELOC_32_GOT_PCREL;
else if (nbytes == 8 && suffix == ELF_SUFFIX_GOT)
reloc = BFD_RELOC_390_GOT64;
+ else if (nbytes == 2 && suffix == ELF_SUFFIX_GOTOFF)
+ reloc = BFD_RELOC_16_GOTOFF;
+ else if (nbytes == 4 && suffix == ELF_SUFFIX_GOTOFF)
+ reloc = BFD_RELOC_32_GOTOFF;
+ else if (nbytes == 8 && suffix == ELF_SUFFIX_GOTOFF)
+ reloc = BFD_RELOC_390_GOTOFF64;
+ else if (nbytes == 2 && suffix == ELF_SUFFIX_PLTOFF)
+ reloc = BFD_RELOC_390_PLTOFF16;
+ else if (nbytes == 4 && suffix == ELF_SUFFIX_PLTOFF)
+ reloc = BFD_RELOC_390_PLTOFF32;
+ else if (nbytes == 8 && suffix == ELF_SUFFIX_PLTOFF)
+ reloc = BFD_RELOC_390_PLTOFF64;
else if (nbytes == 4 && suffix == ELF_SUFFIX_PLT)
reloc = BFD_RELOC_390_PLT32;
else if (nbytes == 8 && suffix == ELF_SUFFIX_PLT)
reloc = BFD_RELOC_390_PLT64;
+ else if (nbytes == 4 && suffix == ELF_SUFFIX_GOTPLT)
+ reloc = BFD_RELOC_390_GOTPLT32;
+ else if (nbytes == 8 && suffix == ELF_SUFFIX_GOTPLT)
+ reloc = BFD_RELOC_390_GOTPLT64;
else
reloc = BFD_RELOC_UNUSED;
@@ -1121,6 +1143,30 @@ md_gather_operands (str, insn, opcode)
&& (operand->bits == 32))
reloc = BFD_RELOC_390_GOTENT;
}
+ else if (suffix == ELF_SUFFIX_GOTOFF)
+ {
+ if ((operand->flags & S390_OPERAND_SIGNED)
+ && (operand->bits == 16))
+ reloc = BFD_RELOC_16_GOTOFF;
+ }
+ else if (suffix == ELF_SUFFIX_PLTOFF)
+ {
+ if ((operand->flags & S390_OPERAND_SIGNED)
+ && (operand->bits == 16))
+ reloc = BFD_RELOC_390_PLTOFF16;
+ }
+ else if (suffix == ELF_SUFFIX_GOTPLT)
+ {
+ if ((operand->flags & S390_OPERAND_DISP)
+ && (operand->bits == 12))
+ reloc = BFD_RELOC_390_GOTPLT12;
+ else if ((operand->flags & S390_OPERAND_SIGNED)
+ && (operand->bits == 16))
+ reloc = BFD_RELOC_390_GOTPLT16;
+ else if ((operand->flags & S390_OPERAND_PCREL)
+ && (operand->bits == 32))
+ reloc = BFD_RELOC_390_GOTPLTENT;
+ }
if (suffix != ELF_SUFFIX_NONE && reloc == BFD_RELOC_UNUSED)
as_bad (_("invalid operand suffix"));
@@ -1633,7 +1679,12 @@ tc_s390_fix_adjustable (fixP)
if ((S_GET_SEGMENT (fixP->fx_addsy)->flags & SEC_MERGE) != 0)
return 0;
/* adjust_reloc_syms doesn't know about the GOT. */
- if ( fixP->fx_r_type == BFD_RELOC_32_GOTOFF
+ if ( fixP->fx_r_type == BFD_RELOC_16_GOTOFF
+ || fixP->fx_r_type == BFD_RELOC_32_GOTOFF
+ || fixP->fx_r_type == BFD_RELOC_390_GOTOFF64
+ || fixP->fx_r_type == BFD_RELOC_390_PLTOFF16
+ || fixP->fx_r_type == BFD_RELOC_390_PLTOFF32
+ || fixP->fx_r_type == BFD_RELOC_390_PLTOFF64
|| fixP->fx_r_type == BFD_RELOC_390_PLT16DBL
|| fixP->fx_r_type == BFD_RELOC_390_PLT32
|| fixP->fx_r_type == BFD_RELOC_390_PLT32DBL
@@ -1643,6 +1694,11 @@ tc_s390_fix_adjustable (fixP)
|| fixP->fx_r_type == BFD_RELOC_32_GOT_PCREL
|| fixP->fx_r_type == BFD_RELOC_390_GOT64
|| fixP->fx_r_type == BFD_RELOC_390_GOTENT
+ || fixP->fx_r_type == BFD_RELOC_390_GOTPLT12
+ || fixP->fx_r_type == BFD_RELOC_390_GOTPLT16
+ || fixP->fx_r_type == BFD_RELOC_390_GOTPLT32
+ || fixP->fx_r_type == BFD_RELOC_390_GOTPLT64
+ || fixP->fx_r_type == BFD_RELOC_390_GOTPLTENT
|| fixP->fx_r_type == BFD_RELOC_VTABLE_INHERIT
|| fixP->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
return 0;
@@ -1662,6 +1718,10 @@ tc_s390_force_relocation (fixp)
case BFD_RELOC_390_GOT12:
case BFD_RELOC_32_GOT_PCREL:
case BFD_RELOC_32_GOTOFF:
+ case BFD_RELOC_390_GOTOFF64:
+ case BFD_RELOC_390_PLTOFF16:
+ case BFD_RELOC_390_PLTOFF32:
+ case BFD_RELOC_390_PLTOFF64:
case BFD_RELOC_390_GOTPC:
case BFD_RELOC_390_GOT16:
case BFD_RELOC_390_GOTPCDBL:
@@ -1671,6 +1731,11 @@ tc_s390_force_relocation (fixp)
case BFD_RELOC_390_PLT16DBL:
case BFD_RELOC_390_PLT32DBL:
case BFD_RELOC_390_PLT64:
+ case BFD_RELOC_390_GOTPLT12:
+ case BFD_RELOC_390_GOTPLT16:
+ case BFD_RELOC_390_GOTPLT32:
+ case BFD_RELOC_390_GOTPLT64:
+ case BFD_RELOC_390_GOTPLTENT:
case BFD_RELOC_VTABLE_INHERIT:
case BFD_RELOC_VTABLE_ENTRY:
return 1;
@@ -1802,6 +1867,7 @@ md_apply_fix3 (fixP, valP, seg)
break;
case BFD_RELOC_390_12:
case BFD_RELOC_390_GOT12:
+ case BFD_RELOC_390_GOTPLT12:
if (fixP->fx_done)
{
unsigned short mop;
@@ -1828,6 +1894,8 @@ md_apply_fix3 (fixP, valP, seg)
md_number_to_chars (where, value, 2);
break;
case BFD_RELOC_390_GOT16:
+ case BFD_RELOC_390_PLTOFF16:
+ case BFD_RELOC_390_GOTPLT16:
if (fixP->fx_done)
md_number_to_chars (where, value, 2);
break;
@@ -1853,7 +1921,9 @@ md_apply_fix3 (fixP, valP, seg)
md_number_to_chars (where, value, 4);
break;
case BFD_RELOC_32_GOT_PCREL:
+ case BFD_RELOC_390_PLTOFF32:
case BFD_RELOC_390_PLT32:
+ case BFD_RELOC_390_GOTPLT32:
if (fixP->fx_done)
md_number_to_chars (where, value, 4);
break;
@@ -1861,6 +1931,7 @@ md_apply_fix3 (fixP, valP, seg)
case BFD_RELOC_390_PLT32DBL:
case BFD_RELOC_390_GOTPCDBL:
case BFD_RELOC_390_GOTENT:
+ case BFD_RELOC_390_GOTPLTENT:
value += 2;
if (fixP->fx_done)
md_number_to_chars (where, (offsetT) value >> 1, 4);
@@ -1871,8 +1942,15 @@ md_apply_fix3 (fixP, valP, seg)
md_number_to_chars (where, value, sizeof (int));
break;
+ case BFD_RELOC_390_GOTOFF64:
+ if (fixP->fx_done)
+ md_number_to_chars (where, value, 8);
+ break;
+
case BFD_RELOC_390_GOT64:
+ case BFD_RELOC_390_PLTOFF64:
case BFD_RELOC_390_PLT64:
+ case BFD_RELOC_390_GOTPLT64:
if (fixP->fx_done)
md_number_to_chars (where, value, 8);
break;