aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gas/config/tc-bpf.c37
-rw-r--r--gas/testsuite/gas/bpf/jump-relax-ja-be.d16
-rw-r--r--gas/testsuite/gas/bpf/jump-relax-ja.d16
-rw-r--r--gas/testsuite/gas/bpf/jump-relax-ja.s13
-rw-r--r--gas/testsuite/gas/bpf/jump-relax-jump-be.d22
-rw-r--r--gas/testsuite/gas/bpf/jump-relax-jump.d22
-rw-r--r--gas/testsuite/gas/bpf/jump-relax-jump.s12
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