From feb4bea70a297eb6316d1b0685bbbb8095b7fb29 Mon Sep 17 00:00:00 2001 From: Andreas Krebbel Date: Fri, 4 Nov 2016 19:48:35 +0100 Subject: [PATCH] S/390: Fix 16 bit pc relative relocs. Since the bpp instruction has been added the 16 bit wide pc relative relocs might occur at offset 2 as well at offset 4 in an instruction. With this patch the different adjustment is passed from md_gather_operand to md_apply_fix via fx_pcrel_adjust field in the fix data structure. No regressions on s390x. gas/ChangeLog: 2016-11-04 Andreas Krebbel * config/tc-s390.c (md_gather_operands): Set fx_pcrel_adjust. (md_apply_fix): Use/Set fx_pcrel_adjust. * testsuite/gas/s390/zarch-zEC12.d: Add bpp reloc test pattern. * testsuite/gas/s390/zarch-zEC12.s: Add bpp reloc test. --- gas/config/tc-s390.c | 24 ++++++++++++++++++++---- gas/testsuite/gas/s390/zarch-zEC12.d | 13 ++++++++++--- gas/testsuite/gas/s390/zarch-zEC12.s | 3 +++ 3 files changed, 33 insertions(+), 7 deletions(-) diff --git a/gas/config/tc-s390.c b/gas/config/tc-s390.c index bc318ee54c5..d8a4f92aa8c 100644 --- a/gas/config/tc-s390.c +++ b/gas/config/tc-s390.c @@ -1652,6 +1652,9 @@ md_gather_operands (char *str, || fixups[i].reloc == BFD_RELOC_390_GOT20 || fixups[i].reloc == BFD_RELOC_390_GOT16) fixP->fx_no_overflow = 1; + + if (operand->flags & S390_OPERAND_PCREL) + fixP->fx_pcrel_adjust = operand->shift / 8; } else fix_new_exp (frag_now, f - frag_now->fr_literal, 4, &fixups[i].exp, @@ -2306,6 +2309,7 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED) fixP->fx_size = 2; fixP->fx_where += 1; fixP->fx_offset += 1; + fixP->fx_pcrel_adjust = 1; fixP->fx_r_type = BFD_RELOC_390_PC12DBL; } else if (operand->bits == 16 && operand->shift == 16) @@ -2316,16 +2320,27 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED) { fixP->fx_r_type = BFD_RELOC_390_PC16DBL; fixP->fx_offset += 2; + fixP->fx_pcrel_adjust = 2; } else fixP->fx_r_type = BFD_RELOC_16; } + else if (operand->bits == 16 && operand->shift == 32 + && (operand->flags & S390_OPERAND_PCREL)) + { + fixP->fx_size = 2; + fixP->fx_where += 4; + fixP->fx_offset += 4; + fixP->fx_pcrel_adjust = 4; + fixP->fx_r_type = BFD_RELOC_390_PC16DBL; + } else if (operand->bits == 24 && operand->shift == 24 && (operand->flags & S390_OPERAND_PCREL)) { fixP->fx_size = 3; fixP->fx_where += 3; fixP->fx_offset += 3; + fixP->fx_pcrel_adjust = 3; fixP->fx_r_type = BFD_RELOC_390_PC24DBL; } else if (operand->bits == 32 && operand->shift == 16 @@ -2334,6 +2349,7 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED) fixP->fx_size = 4; fixP->fx_where += 2; fixP->fx_offset += 2; + fixP->fx_pcrel_adjust = 2; fixP->fx_r_type = BFD_RELOC_390_PC32DBL; } else @@ -2369,7 +2385,7 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED) case BFD_RELOC_390_PC12DBL: case BFD_RELOC_390_PLT12DBL: if (fixP->fx_pcrel) - value++; + value += fixP->fx_pcrel_adjust; if (fixP->fx_done) { @@ -2420,14 +2436,14 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED) break; case BFD_RELOC_390_PC16DBL: case BFD_RELOC_390_PLT16DBL: - value += 2; + value += fixP->fx_pcrel_adjust; if (fixP->fx_done) md_number_to_chars (where, (offsetT) value >> 1, 2); break; case BFD_RELOC_390_PC24DBL: case BFD_RELOC_390_PLT24DBL: - value += 3; + value += fixP->fx_pcrel_adjust; if (fixP->fx_done) { unsigned int mop; @@ -2465,7 +2481,7 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED) case BFD_RELOC_390_GOTPCDBL: case BFD_RELOC_390_GOTENT: case BFD_RELOC_390_GOTPLTENT: - value += 2; + value += fixP->fx_pcrel_adjust; if (fixP->fx_done) md_number_to_chars (where, (offsetT) value >> 1, 4); break; diff --git a/gas/testsuite/gas/s390/zarch-zEC12.d b/gas/testsuite/gas/s390/zarch-zEC12.d index 2989ddab8c4..a4be510d3a2 100644 --- a/gas/testsuite/gas/s390/zarch-zEC12.d +++ b/gas/testsuite/gas/s390/zarch-zEC12.d @@ -54,9 +54,16 @@ Disassembly of section .text: .*: b2 e8 c0 56 [ ]*ppa %r5,%r6,12 .*: b9 8f 60 59 [ ]*crdte %r5,%r6,%r9 .*: b9 8f 61 59 [ ]*crdte %r5,%r6,%r9,1 -.*: c5 a0 06 00 00 06 [ ]*bprp 10,11e ,11e +.*: c5 a0 0c 00 00 0c [ ]*bprp 10,12a ,12a .*: c5 a0 00 00 00 00 [ ]*bprp 10,118 ,118 [ ]*119: R_390_PLT12DBL bar\+0x1 [ ]*11b: R_390_PLT24DBL bar\+0x3 -.* : -.*: 07 07 [ ]*nopr %r7 +.*: c7 a0 00 00 00 00 [ ]*bpp 10,11e ,0 +[ ]*122: R_390_PLT16DBL bar\+0x4 +.*: c7 a0 00 00 00 00 [ ]*bpp 10,124 ,0 +[ ]*128: R_390_PC16DBL baz\+0x4 + + +000000000000012a : + +.*: 07 07 [ ]*nopr %r7 diff --git a/gas/testsuite/gas/s390/zarch-zEC12.s b/gas/testsuite/gas/s390/zarch-zEC12.s index 98f0fdedeb1..4754b2089c5 100644 --- a/gas/testsuite/gas/s390/zarch-zEC12.s +++ b/gas/testsuite/gas/s390/zarch-zEC12.s @@ -55,4 +55,7 @@ foo: bprp 10,bar,bar bprp 10,bar@PLT,bar@PLT + + bpp 10,bar@PLT,0 + bpp 10,baz,0 bar: -- 2.30.2