bpf: gas: consolidate handling of immediate overflows
This commit changes the BPF GAS port in order to handle immediate overflows the same way than the clang BPF assembler: - For an immediate field of N bits, any written number (positive or negative) whose two's complement encoding fit in N its is accepted. This means that -2 is the same than 0xffffffe. It is up to the instructions to decide how to interpret the encoded value. - Immediate fields in jump instructions are no longer relaxed. Relaxing to jump instructions with wider range is only performed when expressions are involved. - The manual is updated to document this, and testsuite adapted accordingly. Tested in x86_64-linux-gnu host, bpf-unknown-none target. gas/ChangeLog: 2023-08-17 Jose E. Marchesi <jose.marchesi@oracle.com> * config/tc-bpf.c (check_immediate_overflow): New function. (encode_insn): Use check_immediate_overflow. (md_assemble): Do not relax instructions with constant disp16 fields. * doc/c-bpf.texi (BPF Instructions): Add note about how numerical literal values are interpreted for instruction immediate operands. * testsuite/gas/bpf/disp16-overflow.s: Adapt accordingly. * testsuite/gas/bpf/jump-relax-jump.s: Likewise. * testsuite/gas/bpf/jump-relax-jump.d: Likewise. * testsuite/gas/bpf/jump-relax-jump-be.d: Likewise. * testsuite/gas/bpf/jump-relax-ja.s: Likewise. * testsuite/gas/bpf/jump-relax-ja.d: Likewise. * testsuite/gas/bpf/jump-relax-ja-be.d: Likewise. * testsuite/gas/bpf/disp16-overflow-relax.l: Likewise. * testsuite/gas/bpf/imm32-overflow.s: Likewise. * testsuite/gas/bpf/disp32-overflow.s: Likewise. * testsuite/gas/bpf/disp16-overflow.l: Likewise. * testsuite/gas/bpf/disp32-overflow.l: Likewise. * testsuite/gas/bpf/imm32-overflow.l: Likewise. * testsuite/gas/bpf/offset16-overflow.l: Likewise.
This commit is contained in:
parent
646657284f
commit
5be1b78727
@ -1,3 +1,26 @@
|
||||
2023-08-17 Jose E. Marchesi <jose.marchesi@oracle.com>
|
||||
|
||||
* config/tc-bpf.c (check_immediate_overflow): New function.
|
||||
(encode_insn): Use check_immediate_overflow.
|
||||
(md_assemble): Do not relax instructions with
|
||||
constant disp16 fields.
|
||||
* doc/c-bpf.texi (BPF Instructions): Add note about how numerical
|
||||
literal values are interpreted for instruction immediate operands.
|
||||
* testsuite/gas/bpf/disp16-overflow.s: Adapt accordingly.
|
||||
* testsuite/gas/bpf/jump-relax-jump.s: Likewise.
|
||||
* testsuite/gas/bpf/jump-relax-jump.d: Likewise.
|
||||
* testsuite/gas/bpf/jump-relax-jump-be.d: Likewise.
|
||||
* testsuite/gas/bpf/jump-relax-ja.s: Likewise.
|
||||
* testsuite/gas/bpf/jump-relax-ja.d: Likewise.
|
||||
* testsuite/gas/bpf/jump-relax-ja-be.d: Likewise.
|
||||
* testsuite/gas/bpf/disp16-overflow-relax.l: Likewise.
|
||||
* testsuite/gas/bpf/imm32-overflow.s: Likewise.
|
||||
* testsuite/gas/bpf/disp32-overflow.s: Likewise.
|
||||
* testsuite/gas/bpf/disp16-overflow.l: Likewise.
|
||||
* testsuite/gas/bpf/disp32-overflow.l: Likewise.
|
||||
* testsuite/gas/bpf/imm32-overflow.l: Likewise.
|
||||
* testsuite/gas/bpf/offset16-overflow.l: Likewise.
|
||||
|
||||
2023-07-30 Jose E. Marchesi <jose.marchesi@oracle.com>
|
||||
|
||||
* config/tc-bpf.h (elf_tc_final_processing): Define.
|
||||
|
@ -286,6 +286,26 @@ signed_overflow (offsetT value, unsigned bits)
|
||||
return (value < -lim || value >= lim);
|
||||
}
|
||||
|
||||
/* Return non-zero if the two's complement encoding of VALUE would
|
||||
overflow an immediate field of width BITS bits. */
|
||||
|
||||
static bool
|
||||
immediate_overflow (int64_t value, unsigned bits)
|
||||
{
|
||||
if (value < 0)
|
||||
return signed_overflow (value, bits);
|
||||
else
|
||||
{
|
||||
valueT lim;
|
||||
|
||||
if (bits >= sizeof (valueT) * 8)
|
||||
return false;
|
||||
|
||||
lim = (valueT) 1 << bits;
|
||||
return ((valueT) value >= lim);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Functions concerning relocs. */
|
||||
|
||||
@ -379,7 +399,7 @@ tc_gen_reloc (asection *sec ATTRIBUTE_UNUSED, fixS *fixP)
|
||||
#define RELAX_BRANCH_UNCOND(i) (((i) & 1) != 0)
|
||||
|
||||
|
||||
/* Compute the length of a branch seuqence, and adjust the stored
|
||||
/* Compute the length of a branch sequence, and adjust the stored
|
||||
length accordingly. If FRAG is NULL, the worst-case length is
|
||||
returned. */
|
||||
|
||||
@ -854,7 +874,8 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
|
||||
immediates are encoded as zeroes. */
|
||||
|
||||
static void
|
||||
encode_insn (struct bpf_insn *insn, char *bytes, int relaxed)
|
||||
encode_insn (struct bpf_insn *insn, char *bytes,
|
||||
int relaxed ATTRIBUTE_UNUSED)
|
||||
{
|
||||
uint8_t src, dst;
|
||||
|
||||
@ -911,8 +932,8 @@ encode_insn (struct bpf_insn *insn, char *bytes, int relaxed)
|
||||
{
|
||||
int64_t imm = insn->imm32.X_add_number;
|
||||
|
||||
if (signed_overflow (imm, 32))
|
||||
as_bad (_("signed immediate out of range, shall fit in 32 bits"));
|
||||
if (immediate_overflow (imm, 32))
|
||||
as_bad (_("immediate out of range, shall fit in 32 bits"));
|
||||
else
|
||||
encode_int32 (insn->imm32.X_add_number, bytes + 4);
|
||||
}
|
||||
@ -921,8 +942,8 @@ encode_insn (struct bpf_insn *insn, char *bytes, int relaxed)
|
||||
{
|
||||
int64_t disp = insn->disp32.X_add_number;
|
||||
|
||||
if (signed_overflow (disp, 32))
|
||||
as_bad (_("signed pc-relative offset out of range, shall fit in 32 bits"));
|
||||
if (immediate_overflow (disp, 32))
|
||||
as_bad (_("pc-relative offset out of range, shall fit in 32 bits"));
|
||||
else
|
||||
encode_int32 (insn->disp32.X_add_number, bytes + 4);
|
||||
}
|
||||
@ -931,8 +952,8 @@ encode_insn (struct bpf_insn *insn, char *bytes, int relaxed)
|
||||
{
|
||||
int64_t offset = insn->offset16.X_add_number;
|
||||
|
||||
if (signed_overflow (offset, 16))
|
||||
as_bad (_("signed pc-relative offset out of range, shall fit in 16 bits"));
|
||||
if (immediate_overflow (offset, 16))
|
||||
as_bad (_("pc-relative offset out of range, shall fit in 16 bits"));
|
||||
else
|
||||
encode_int16 (insn->offset16.X_add_number, bytes + 2);
|
||||
}
|
||||
@ -941,8 +962,8 @@ encode_insn (struct bpf_insn *insn, char *bytes, int relaxed)
|
||||
{
|
||||
int64_t disp = insn->disp16.X_add_number;
|
||||
|
||||
if (!relaxed && signed_overflow (disp, 16))
|
||||
as_bad (_("signed pc-relative offset out of range, shall fit in 16 bits"));
|
||||
if (immediate_overflow (disp, 16))
|
||||
as_bad (_("pc-relative offset out of range, shall fit in 16 bits"));
|
||||
else
|
||||
encode_int16 (insn->disp16.X_add_number, bytes + 2);
|
||||
}
|
||||
@ -1517,7 +1538,7 @@ md_assemble (char *str ATTRIBUTE_UNUSED)
|
||||
break;
|
||||
}
|
||||
insn.has_disp16 = 1;
|
||||
insn.is_relaxable = 1;
|
||||
insn.is_relaxable = (insn.disp16.X_op != O_constant);
|
||||
p += 4;
|
||||
}
|
||||
else if (strncmp (p, "%d32", 4) == 0)
|
||||
|
@ -844,7 +844,7 @@ struct pop_entry pop_table[] =
|
||||
{
|
||||
{ "hix", BFD_RELOC_SPARC_HIX22, F_POP_V9 },
|
||||
{ "lox", BFD_RELOC_SPARC_LOX10, F_POP_V9 },
|
||||
{ "hi", BFD_RELOC_HI22, F_POP_PCREL },
|
||||
{ "hi"5, BFD_RELOC_HI22, F_POP_PCREL },
|
||||
{ "lo", BFD_RELOC_LO10, F_POP_PCREL },
|
||||
{ "pc22", BFD_RELOC_SPARC_PC22, F_POP_PCREL },
|
||||
{ "pc10", BFD_RELOC_SPARC_PC10, F_POP_PCREL },
|
||||
|
@ -172,6 +172,14 @@ Signed 32-bit immediate.
|
||||
Signed 64-bit immediate.
|
||||
@end table
|
||||
|
||||
@noindent
|
||||
Note that the assembler allows to express the value for an immediate
|
||||
using any numerical literal whose two's complement encoding fits in
|
||||
the immediate field. For example, @code{-2}, @code{0xfffffffe} and
|
||||
@code{4294967294} all denote the same encoded 32-bit immediate, whose
|
||||
value may be then interpreted by different instructions as either as a
|
||||
negative or a positive number.
|
||||
|
||||
@subsection Arithmetic instructions
|
||||
|
||||
The destination register in these instructions act like an
|
||||
|
@ -1,3 +1,5 @@
|
||||
.*: Assembler messages:
|
||||
.*:2: Error: signed instruction operand out of range, shall fit in 32 bits
|
||||
.*:4: Error: signed instruction operand out of range, shall fit in 32 bits
|
||||
.*:1: Error: pc-relative offset out of range, shall fit in 16 bits
|
||||
.*:2: Error: pc-relative offset out of range, shall fit in 16 bits
|
||||
.*:3: Error: pc-relative offset out of range, shall fit in 16 bits
|
||||
.*:4: Error: pc-relative offset out of range, shall fit in 16 bits
|
||||
|
@ -1,4 +1,4 @@
|
||||
jeq %r1,%r2,2147483647
|
||||
jeq %r1,%r2,2147483647 ; Overflows.
|
||||
jlt %r3,%r4,2147483648 ; Overflows.
|
||||
jge %r5,10,-2147483648
|
||||
jge %r5,10,-2147483648 ; Overflows.
|
||||
ja -2147483649 ; Overflows.
|
||||
|
@ -1,3 +1,3 @@
|
||||
.*: Assembler messages:
|
||||
.*:2: Error: signed pc-relative offset out of range, shall fit in 16 bits
|
||||
.*:4: Error: signed pc-relative offset out of range, shall fit in 16 bits
|
||||
.*:2: Error: pc-relative offset out of range, shall fit in 16 bits
|
||||
.*:4: Error: pc-relative offset out of range, shall fit in 16 bits
|
||||
|
@ -1,4 +1,4 @@
|
||||
ja 32767
|
||||
jeq %r1,%r2,32768 ; Overflows
|
||||
jeq %r1,%r2,65536 ; Overflows
|
||||
jlt %r3,%r4,-32768
|
||||
jge %r5,10,-32769 ; Overflows
|
||||
|
@ -1,3 +1,3 @@
|
||||
.*: Assembler messages:
|
||||
.*:2: Error: signed pc-relative offset out of range, shall fit in 32 bits
|
||||
.*:4: Error: signed pc-relative offset out of range, shall fit in 32 bits
|
||||
.*:2: Error: pc-relative offset out of range, shall fit in 32 bits
|
||||
.*:4: Error: pc-relative offset out of range, shall fit in 32 bits
|
||||
|
@ -1,4 +1,4 @@
|
||||
call -2147483648
|
||||
call -2147483649 ; This overflows.
|
||||
call 2147483647
|
||||
call 2147483648 ; This overflows.
|
||||
call 4294967295
|
||||
call 4294967296 ; This overflows.
|
||||
|
@ -1,3 +1,3 @@
|
||||
.*: Assembler messages:
|
||||
.*:2: Error: signed immediate out of range, shall fit in 32 bits
|
||||
.*:4: Error: signed immediate out of range, shall fit in 32 bits
|
||||
.*:2: Error: immediate out of range, shall fit in 32 bits
|
||||
.*:4: Error: immediate out of range, shall fit in 32 bits
|
||||
|
@ -1,4 +1,4 @@
|
||||
add %r1, 2147483647
|
||||
or %r2, 2147483648 ; This overflows.
|
||||
xor %r3, -2147483648
|
||||
sub %r4, -2147483649 ; This overflows.
|
||||
or %r2, 4294967296 ; This overflows.
|
||||
xor %r3, 4294967295
|
||||
sub %r4, 4294967296 ; This overflows.
|
||||
|
@ -13,7 +13,5 @@ Disassembly of section .text:
|
||||
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 ff ff 7f ff jal -32769
|
||||
28: 06 00 00 00 00 00 80 00 jal 32768
|
||||
30: 06 00 00 00 00 00 80 01 jal 32769
|
||||
38: 06 00 00 00 00 00 80 01 jal 32769
|
||||
20: 06 00 00 00 00 00 80 01 jal 32769
|
||||
28: 06 00 00 00 00 00 80 01 jal 32769
|
||||
|
@ -13,7 +13,5 @@ Disassembly of section .text:
|
||||
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 ff 7f ff ff jal -32769
|
||||
28: 06 00 00 00 00 80 00 00 jal 32768
|
||||
30: 06 00 00 00 01 80 00 00 jal 32769
|
||||
38: 06 00 00 00 01 80 00 00 jal 32769
|
||||
20: 06 00 00 00 01 80 00 00 jal 32769
|
||||
28: 06 00 00 00 01 80 00 00 jal 32769
|
||||
|
@ -9,10 +9,6 @@
|
||||
;; The following instruction has an undefined symbol as a
|
||||
;; target. It is not to be relaxed.
|
||||
ja undefined + 10
|
||||
;; The following instructions are relaxed to JAL instructions
|
||||
;; so they can fit their displacements.
|
||||
ja -32769
|
||||
ja 32768
|
||||
;; The following instructions refer to a defined symbol that
|
||||
;; is not on reach. They shall be relaxed to a JAL.
|
||||
ja tail
|
||||
|
@ -11,15 +11,9 @@ Disassembly of section .text:
|
||||
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: 3d 12 00 01 00 00 00 00 jge %r1,%r2,1
|
||||
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 ff ff 7f ff jal -32769
|
||||
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 00 jal 32768
|
||||
48: 1d 12 00 01 00 00 00 00 jeq %r1,%r2,1
|
||||
50: 05 00 00 01 00 00 00 00 ja 1
|
||||
58: 06 00 00 00 00 00 80 01 jal 32769
|
||||
60: 2d 12 00 01 00 00 00 00 jgt %r1,%r2,1
|
||||
68: 05 00 00 01 00 00 00 00 ja 1
|
||||
70: 06 00 00 00 00 00 80 01 jal 32769
|
||||
40: 06 00 00 00 00 00 80 01 jal 32769
|
||||
|
@ -11,15 +11,9 @@ Disassembly of section .text:
|
||||
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: 3d 21 01 00 00 00 00 00 jge %r1,%r2,1
|
||||
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 ff 7f ff ff jal -32769
|
||||
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 00 80 00 00 jal 32768
|
||||
48: 1d 21 01 00 00 00 00 00 jeq %r1,%r2,1
|
||||
50: 05 00 01 00 00 00 00 00 ja 1
|
||||
58: 06 00 00 00 01 80 00 00 jal 32769
|
||||
60: 2d 21 01 00 00 00 00 00 jgt %r1,%r2,1
|
||||
68: 05 00 01 00 00 00 00 00 ja 1
|
||||
70: 06 00 00 00 01 80 00 00 jal 32769
|
||||
40: 06 00 00 00 01 80 00 00 jal 32769
|
||||
|
@ -5,11 +5,6 @@
|
||||
;; The following instruction refers to a defined symbol that
|
||||
;; is on reach, so it should not be relaxed.
|
||||
jle %r1, %r2, 1b
|
||||
;; The following instructions are relaxed to sequences
|
||||
;; involving unconditional jumps, so they can fi their
|
||||
;; displacements.
|
||||
jge %r1, %r2, -32769
|
||||
jgt %r1, %r2, 32768
|
||||
;; The following instructions refer to a defined symbol that
|
||||
;; is not on reach. They shall be relaxed.
|
||||
jeq %r1, %r2, tail
|
||||
|
@ -1,3 +1,3 @@
|
||||
.*: Assembler messages:
|
||||
.*:2: Error: signed pc-relative offset out of range, shall fit in 16 bits
|
||||
.*:4: Error: signed pc-relative offset out of range, shall fit in 16 bits
|
||||
.*:2: Error: pc-relative offset out of range, shall fit in 16 bits
|
||||
.*:4: Error: pc-relative offset out of range, shall fit in 16 bits
|
||||
|
@ -1,4 +1,4 @@
|
||||
ldxh %r2, [%r1 + 32767]
|
||||
ldxw %r2, [%r1 + 32768] ; This overflows
|
||||
ldxh %r2, [%r1 + 65535]
|
||||
ldxw %r2, [%r1 + 65536] ; This overflows
|
||||
stxw [%r2 - 32768], %r1
|
||||
stxdw [%r2 - 32769], %r1 ; This overflows
|
||||
|
Loading…
x
Reference in New Issue
Block a user