+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.
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);
+ }
+}
+
\f
/* Functions concerning relocs. */
#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. */
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;
{
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);
}
{
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);
}
{
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);
}
{
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);
}
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)
{
{ "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 },
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
.*: 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
- 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.
.*: 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
ja 32767
- jeq %r1,%r2,32768 ; Overflows
+ jeq %r1,%r2,65536 ; Overflows
jlt %r3,%r4,-32768
jge %r5,10,-32769 ; Overflows
.*: 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
call -2147483648
call -2147483649 ; This overflows.
- call 2147483647
- call 2147483648 ; This overflows.
+ call 4294967295
+ call 4294967296 ; This overflows.
.*: 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
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.
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
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
;; 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
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
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
;; 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
.*: 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
- 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