diff options
-rw-r--r-- | gas/config/tc-bpf.c | 37 | ||||
-rw-r--r-- | gas/testsuite/gas/bpf/jump-relax-ja-be.d | 16 | ||||
-rw-r--r-- | gas/testsuite/gas/bpf/jump-relax-ja.d | 16 | ||||
-rw-r--r-- | gas/testsuite/gas/bpf/jump-relax-ja.s | 13 | ||||
-rw-r--r-- | gas/testsuite/gas/bpf/jump-relax-jump-be.d | 22 | ||||
-rw-r--r-- | gas/testsuite/gas/bpf/jump-relax-jump.d | 22 | ||||
-rw-r--r-- | gas/testsuite/gas/bpf/jump-relax-jump.s | 12 |
7 files changed, 95 insertions, 43 deletions
diff --git a/gas/config/tc-bpf.c b/gas/config/tc-bpf.c index dfa44ea..effb483 100644 --- a/gas/config/tc-bpf.c +++ b/gas/config/tc-bpf.c @@ -434,6 +434,7 @@ relaxed_branch_length (fragS *fragp, asection *sec, int update) && sec == S_GET_SEGMENT (fragp->fr_symbol)) { offsetT val = S_GET_VALUE (fragp->fr_symbol) + fragp->fr_offset; + val -= fragp->fr_address + fragp->fr_fix; /* Convert to 64-bit words, minus one. */ val = (val - 8) / 8; @@ -578,6 +579,7 @@ md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED, && sec == S_GET_SEGMENT (fragp->fr_symbol)) { offsetT val = S_GET_VALUE (fragp->fr_symbol) + fragp->fr_offset; + val -= fragp->fr_address + fragp->fr_fix; /* Convert to 64-bit blocks minus one. */ disp_to_target = (val - 8) / 8; disp_is_known = 1; @@ -626,15 +628,27 @@ md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED, { /* 16-bit disp is known and not in range. Turn the JA into a JAL with a 32-bit displacement. */ - char bytes[8]; + char bytes[8] = {0}; bytes[0] = ((BPF_CLASS_JMP32|BPF_CODE_JA|BPF_SRC_K) >> 56) & 0xff; bytes[1] = (word >> 48) & 0xff; bytes[2] = 0; /* disp16 high */ bytes[3] = 0; /* disp16 lo */ - encode_int32 ((int32_t) disp_to_target, bytes + 4); - write_insn_bytes (buf, bytes); + + /* Install fixup for the JAL. */ + reloc_howto_type *reloc_howto + = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_BPF_DISP32); + if (!reloc_howto) + abort(); + + fixp = fix_new_exp (fragp, buf - (bfd_byte *) fragp->fr_literal, + bfd_get_reloc_size (reloc_howto), + &exp, + reloc_howto->pc_relative, + BFD_RELOC_BPF_DISP32); + fixp->fx_file = fragp->fr_file; + fixp->fx_line = fragp->fr_line; } } else @@ -731,8 +745,23 @@ md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED, bytes[1] = 0; bytes[2] = 0; bytes[3] = 0; - encode_int32 ((int32_t) disp_to_target, bytes + 4); + encode_int32 ((int32_t) 0, bytes + 4); write_insn_bytes (buf, bytes); + + /* Install fixup for the JAL. */ + reloc_howto_type *reloc_howto + = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_BPF_DISP32); + if (!reloc_howto) + abort(); + + fixp = fix_new_exp (fragp, buf - (bfd_byte *) fragp->fr_literal, + bfd_get_reloc_size (reloc_howto), + &exp, + reloc_howto->pc_relative, + BFD_RELOC_BPF_DISP32); + fixp->fx_file = fragp->fr_file; + fixp->fx_line = fragp->fr_line; + buf += 8; } } diff --git a/gas/testsuite/gas/bpf/jump-relax-ja-be.d b/gas/testsuite/gas/bpf/jump-relax-ja-be.d index 5f07847..e5ad30d 100644 --- a/gas/testsuite/gas/bpf/jump-relax-ja-be.d +++ b/gas/testsuite/gas/bpf/jump-relax-ja-be.d @@ -8,10 +8,14 @@ Disassembly of section .text: 0+ <.*>: - 0: 05 00 80 00 00 00 00 00 ja -32768 - 8: 05 00 7f ff 00 00 00 00 ja 32767 - 10: 05 00 ff fd 00 00 00 00 ja -3 - 18: 05 00 00 00 00 00 00 00 ja 0 + 0: 05 00 80 00 00 00 00 00 ja -32768 + 8: 05 00 7f ff 00 00 00 00 ja 32767 + 10: 05 00 ff fd 00 00 00 00 ja -3 + 18: 05 00 00 00 00 00 00 00 ja 0 18: R_BPF_GNU_64_16 undefined - 20: 06 00 00 00 00 00 80 01 jal 32769 - 28: 06 00 00 00 00 00 80 01 jal 32769 + 20: 06 00 00 00 00 00 80 00 jal 32768 + 28: 05 00 7f ff 00 00 00 00 ja 32767 + ... + +0+40028 <tail>: + 40028: 06 00 00 00 ff ff 7f fa jal -32774 diff --git a/gas/testsuite/gas/bpf/jump-relax-ja.d b/gas/testsuite/gas/bpf/jump-relax-ja.d index ed3aa6b..1ac33f5 100644 --- a/gas/testsuite/gas/bpf/jump-relax-ja.d +++ b/gas/testsuite/gas/bpf/jump-relax-ja.d @@ -8,10 +8,14 @@ Disassembly of section .text: 0+ <.*>: - 0: 05 00 00 80 00 00 00 00 ja -32768 - 8: 05 00 ff 7f 00 00 00 00 ja 32767 - 10: 05 00 fd ff 00 00 00 00 ja -3 - 18: 05 00 00 00 00 00 00 00 ja 0 + 0: 05 00 00 80 00 00 00 00 ja -32768 + 8: 05 00 ff 7f 00 00 00 00 ja 32767 + 10: 05 00 fd ff 00 00 00 00 ja -3 + 18: 05 00 00 00 00 00 00 00 ja 0 18: R_BPF_GNU_64_16 undefined - 20: 06 00 00 00 01 80 00 00 jal 32769 - 28: 06 00 00 00 01 80 00 00 jal 32769 + 20: 06 00 00 00 00 80 00 00 jal 32768 + 28: 05 00 ff 7f 00 00 00 00 ja 32767 + ... + +0+40028 <tail>: + 40028: 06 00 00 00 fa 7f ff ff jal -32774 diff --git a/gas/testsuite/gas/bpf/jump-relax-ja.s b/gas/testsuite/gas/bpf/jump-relax-ja.s index f164176..61f2e61 100644 --- a/gas/testsuite/gas/bpf/jump-relax-ja.s +++ b/gas/testsuite/gas/bpf/jump-relax-ja.s @@ -4,13 +4,18 @@ 1: ja -32768 ja 32767 /* The following instruction refers to a defined symbol that - is on reach, so it should not be relaxed. */ + is in reach, so it should not be relaxed. */ ja 1b /* The following instruction has an undefined symbol as a target. It is not to be relaxed. */ ja undefined + 10 - /* The following instructions refer to a defined symbol that - is not on reach. They shall be relaxed to a JAL. */ + /* The following instruction refers to a defined symbol that + is not in reach, so it shall be relaxed to JAL. */ ja tail - tail = .text + 262160 + /* Now the symbol is in reach, and the following instruction + shall not be relaxed. */ ja tail + .space 262136 + tail = . + /* The jump back is too large and shall be relaxed. */ + ja 1b diff --git a/gas/testsuite/gas/bpf/jump-relax-jump-be.d b/gas/testsuite/gas/bpf/jump-relax-jump-be.d index 0cacdb3..5cf3bce 100644 --- a/gas/testsuite/gas/bpf/jump-relax-jump-be.d +++ b/gas/testsuite/gas/bpf/jump-relax-jump-be.d @@ -8,12 +8,16 @@ Disassembly of section .text: 0+ <.*>: - 0: 1d 12 80 00 00 00 00 00 jeq %r1,%r2,-32768 - 8: ad 12 7f ff 00 00 00 00 jlt %r1,%r2,32767 - 10: bd 12 ff fd 00 00 00 00 jle %r1,%r2,-3 - 18: 1d 12 00 01 00 00 00 00 jeq %r1,%r2,1 - 20: 05 00 00 01 00 00 00 00 ja 1 - 28: 06 00 00 00 00 00 80 01 jal 32769 - 30: 2d 12 00 01 00 00 00 00 jgt %r1,%r2,1 - 38: 05 00 00 01 00 00 00 00 ja 1 - 40: 06 00 00 00 00 00 80 01 jal 32769 + 0: 1d 12 80 00 00 00 00 00 jeq %r1,%r2,-32768 + 8: ad 12 7f ff 00 00 00 00 jlt %r1,%r2,32767 + 10: bd 12 ff fd 00 00 00 00 jle %r1,%r2,-3 + 18: 1d 12 00 01 00 00 00 00 jeq %r1,%r2,1 + 20: 05 00 00 01 00 00 00 00 ja 1 + 28: 06 00 00 00 00 00 80 00 jal 32768 + 30: 2d 12 7f ff 00 00 00 00 jgt %r1,%r2,32767 + ... + +0+40030 <tail>: + 40030: 55 10 00 01 00 00 00 00 jne %r1,0,1 + 40038: 05 00 00 01 00 00 00 00 ja 1 + 40040: 06 00 00 00 ff ff 7f f7 jal -32777 diff --git a/gas/testsuite/gas/bpf/jump-relax-jump.d b/gas/testsuite/gas/bpf/jump-relax-jump.d index dd31ba5..4300bf3 100644 --- a/gas/testsuite/gas/bpf/jump-relax-jump.d +++ b/gas/testsuite/gas/bpf/jump-relax-jump.d @@ -8,12 +8,16 @@ Disassembly of section .text: 0+ <.*>: - 0: 1d 21 00 80 00 00 00 00 jeq %r1,%r2,-32768 - 8: ad 21 ff 7f 00 00 00 00 jlt %r1,%r2,32767 - 10: bd 21 fd ff 00 00 00 00 jle %r1,%r2,-3 - 18: 1d 21 01 00 00 00 00 00 jeq %r1,%r2,1 - 20: 05 00 01 00 00 00 00 00 ja 1 - 28: 06 00 00 00 01 80 00 00 jal 32769 - 30: 2d 21 01 00 00 00 00 00 jgt %r1,%r2,1 - 38: 05 00 01 00 00 00 00 00 ja 1 - 40: 06 00 00 00 01 80 00 00 jal 32769 + 0: 1d 21 00 80 00 00 00 00 jeq %r1,%r2,-32768 + 8: ad 21 ff 7f 00 00 00 00 jlt %r1,%r2,32767 + 10: bd 21 fd ff 00 00 00 00 jle %r1,%r2,-3 + 18: 1d 21 01 00 00 00 00 00 jeq %r1,%r2,1 + 20: 05 00 01 00 00 00 00 00 ja 1 + 28: 06 00 00 00 00 80 00 00 jal 32768 + 30: 2d 21 ff 7f 00 00 00 00 jgt %r1,%r2,32767 + ... + +0+40030 <tail>: + 40030: 55 01 01 00 00 00 00 00 jne %r1,0,1 + 40038: 05 00 01 00 00 00 00 00 ja 1 + 40040: 06 00 00 00 f7 7f ff ff jal -32777 diff --git a/gas/testsuite/gas/bpf/jump-relax-jump.s b/gas/testsuite/gas/bpf/jump-relax-jump.s index 5ea6110..6b23c56 100644 --- a/gas/testsuite/gas/bpf/jump-relax-jump.s +++ b/gas/testsuite/gas/bpf/jump-relax-jump.s @@ -2,11 +2,13 @@ fix in the jump 16-bit signed displacement operand. */ 1: jeq %r1, %r2, -32768 jlt %r1, %r2, 32767 - /* The following instruction refers to a defined symbol that - is on reach, so it should not be relaxed. */ + /* The following instructions refer to defined symbols that + are in reach, so they should not be relaxed. */ jle %r1, %r2, 1b - /* The following instructions refer to a defined symbol that - is not on reach. They shall be relaxed. */ jeq %r1, %r2, tail - tail = .text + 262160 jgt %r1, %r2, tail + /* The following instructions refers to defined symbols that + are not in reach, so they shall be relaxied. */ + .space 262136 + tail = . + jne %r1, 0, 1b |