aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bfd/ChangeLog6
-rw-r--r--bfd/bfd-in2.h1
-rw-r--r--bfd/elf64-bpf.c1
-rw-r--r--bfd/libbfd.h1
-rw-r--r--bfd/reloc.c2
-rw-r--r--gas/ChangeLog15
-rw-r--r--gas/config/tc-bpf.c56
-rw-r--r--gas/doc/c-bpf.texi7
-rw-r--r--gas/testsuite/gas/bpf/jump-be-pseudoc.d2
-rw-r--r--gas/testsuite/gas/bpf/jump-be.d2
-rw-r--r--gas/testsuite/gas/bpf/jump-pseudoc.d2
-rw-r--r--gas/testsuite/gas/bpf/jump-pseudoc.s2
-rw-r--r--gas/testsuite/gas/bpf/jump.d2
-rw-r--r--gas/testsuite/gas/bpf/jump.s4
-rw-r--r--include/ChangeLog5
-rw-r--r--include/opcode/bpf.h3
-rw-r--r--opcodes/ChangeLog4
-rw-r--r--opcodes/bpf-opc.c4
18 files changed, 95 insertions, 24 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index 553dea5..db032df 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,3 +1,9 @@
+2023-07-24 Jose E. Marchesi <jose.marchesi@oracle.com>
+
+ * reloc.c: New reloc BFD_RELOC_BPF_DISPCALL32.
+ * elf64-bpf.c (bpf_reloc_type_lookup): Handle the new reloc.
+ * libbfd.h (bfd_reloc_code_real_names): Regenerate.
+
2023-07-09 Fangrui Song <maskray@google.com>
PR 30592
diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h
index ba7440c..5f49807 100644
--- a/bfd/bfd-in2.h
+++ b/bfd/bfd-in2.h
@@ -7148,6 +7148,7 @@ assembler and not (currently) written to any object files. */
/* Linux eBPF relocations. */
BFD_RELOC_BPF_64,
BFD_RELOC_BPF_DISP32,
+ BFD_RELOC_BPF_DISPCALL32,
BFD_RELOC_BPF_DISP16,
/* Adapteva EPIPHANY - 8 bit signed pc-relative displacement */
diff --git a/bfd/elf64-bpf.c b/bfd/elf64-bpf.c
index 23ede4e..aefad7d 100644
--- a/bfd/elf64-bpf.c
+++ b/bfd/elf64-bpf.c
@@ -88,6 +88,7 @@ bpf_reloc_type_lookup (bfd * abfd ATTRIBUTE_UNUSED,
case BFD_RELOC_BPF_64:
return &bpf_elf_howto_table[ (int) R_BPF_64_64_IDX];
case BFD_RELOC_BPF_DISP32:
+ case BFD_RELOC_BPF_DISPCALL32:
return &bpf_elf_howto_table[ (int) R_BPF_64_32_IDX];
case BFD_RELOC_BPF_DISP16:
return &bpf_elf_howto_table[ (int) R_BPF_GNU_64_16_IDX];
diff --git a/bfd/libbfd.h b/bfd/libbfd.h
index 5dbb087..1fc88a8 100644
--- a/bfd/libbfd.h
+++ b/bfd/libbfd.h
@@ -3346,6 +3346,7 @@ static const char *const bfd_reloc_code_real_names[] = { "@@uninitialized@@",
"BFD_RELOC_TILEGX_IMM8_Y1_TLS_ADD",
"BFD_RELOC_BPF_64",
"BFD_RELOC_BPF_DISP32",
+ "BFD_RELOC_BPF_DISPCALL32",
"BFD_RELOC_BPF_DISP16",
"BFD_RELOC_EPIPHANY_SIMM8",
"BFD_RELOC_EPIPHANY_SIMM24",
diff --git a/bfd/reloc.c b/bfd/reloc.c
index e71a510..07d35e4 100644
--- a/bfd/reloc.c
+++ b/bfd/reloc.c
@@ -7754,6 +7754,8 @@ ENUM
ENUMX
BFD_RELOC_BPF_DISP32
ENUMX
+ BFD_RELOC_BPF_DISPCALL32
+ENUMX
BFD_RELOC_BPF_DISP16
ENUMDOC
Linux eBPF relocations.
diff --git a/gas/ChangeLog b/gas/ChangeLog
index f91c045..b45fd9f 100644
--- a/gas/ChangeLog
+++ b/gas/ChangeLog
@@ -1,3 +1,18 @@
+2023-07-24 Jose E. Marchesi <jose.marchesi@oracle.com>
+
+ * config/tc-bpf.c (struct bpf_insn): New field `id'.
+ (md_assemble): Save the ids of successfully parsed instructions
+ and use the new BFD_RELOC_BPF_DISPCALL32 whenever appropriate.
+ (md_apply_fix): Adapt to the new BFD reloc.
+ * testsuite/gas/bpf/jump.s: Test JAL.
+ * testsuite/gas/bpf/jump.d: Likewise.
+ * testsuite/gas/bpf/jump-pseudoc.d: Likewise.
+ * testsuite/gas/bpf/jump-be.d: Likewise.
+ * testsuite/gas/bpf/jump-be-pseudoc.d: Likewise.
+ * doc/c-bpf.texi (BPF Instructions): Document new instruction
+ jal/gotol.
+ Document new operand type disp32.
+
2023-07-21 Jose E. Marchesi <jose.marchesi@oracle.com>
* testsuite/gas/bpf/mem.s: Add signed load instructions.
diff --git a/gas/config/tc-bpf.c b/gas/config/tc-bpf.c
index 7a54fac..c56b8fe 100644
--- a/gas/config/tc-bpf.c
+++ b/gas/config/tc-bpf.c
@@ -33,6 +33,7 @@
struct bpf_insn
{
+ enum bpf_insn_id id;
int size; /* Instruction size in bytes. */
bpf_insn_word opcode;
uint8_t dst;
@@ -375,30 +376,35 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
minus one. */
*valP = (((long) (*valP)) - 8) / 8;
break;
+ case BFD_RELOC_BPF_DISPCALL32:
case BFD_RELOC_BPF_DISP32:
- /* eBPF supports two kind of CALL instructions: the so called
- pseudo calls ("bpf to bpf") and external calls ("bpf to
- kernel").
-
- Both kind of calls use the same instruction (CALL). However,
- external calls are constructed by passing a constant argument
- to the instruction, whereas pseudo calls result from
- expressions involving symbols. In practice, instructions
- requiring a fixup are interpreted as pseudo-calls. If we are
- executing this code, this is a pseudo call.
-
- The kernel expects for pseudo-calls to be annotated by having
- BPF_PSEUDO_CALL in the SRC field of the instruction. But
- beware the infamous nibble-swapping of eBPF and take
- endianness into account here.
-
- Note that the CALL instruction has only one operand, so
- this code is executed only once per instruction. */
- md_number_to_chars (where + 1, target_big_endian ? 0x01 : 0x10, 1);
-
/* Convert from bytes to number of 64-bit words to the target,
minus one. */
*valP = (((long) (*valP)) - 8) / 8;
+
+ if (fixP->fx_r_type == BFD_RELOC_BPF_DISPCALL32)
+ {
+ /* eBPF supports two kind of CALL instructions: the so
+ called pseudo calls ("bpf to bpf") and external calls
+ ("bpf to kernel").
+
+ Both kind of calls use the same instruction (CALL).
+ However, external calls are constructed by passing a
+ constant argument to the instruction, whereas pseudo
+ calls result from expressions involving symbols. In
+ practice, instructions requiring a fixup are interpreted
+ as pseudo-calls. If we are executing this code, this is
+ a pseudo call.
+
+ The kernel expects for pseudo-calls to be annotated by
+ having BPF_PSEUDO_CALL in the SRC field of the
+ instruction. But beware the infamous nibble-swapping of
+ eBPF and take endianness into account here.
+
+ Note that the CALL instruction has only one operand, so
+ this code is executed only once per instruction. */
+ md_number_to_chars (where + 1, target_big_endian ? 0x01 : 0x10, 1);
+ }
break;
case BFD_RELOC_16_PCREL:
/* Convert from bytes to number of 64-bit words to the target,
@@ -434,6 +440,7 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
md_number_to_chars (where + 2, (uint16_t) *valP, 2);
break;
case BFD_RELOC_BPF_DISP32:
+ case BFD_RELOC_BPF_DISPCALL32:
md_number_to_chars (where + 4, (uint32_t) *valP, 4);
break;
case BFD_RELOC_16_PCREL:
@@ -852,6 +859,7 @@ md_assemble (char *str ATTRIBUTE_UNUSED)
return;
}
+ insn.id = opcode->id;
insn.opcode = opcode->opcode;
#undef PARSE_ERROR
@@ -1044,8 +1052,12 @@ md_assemble (char *str ATTRIBUTE_UNUSED)
{
reloc_howto_type *reloc_howto;
int size;
+ unsigned int bfd_reloc
+ = (insn.id == BPF_INSN_CALL
+ ? BFD_RELOC_BPF_DISPCALL32
+ : BFD_RELOC_BPF_DISP32);
- reloc_howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_BPF_DISP32);
+ reloc_howto = bfd_reloc_type_lookup (stdoutput, bfd_reloc);
if (!reloc_howto)
abort ();
@@ -1053,7 +1065,7 @@ md_assemble (char *str ATTRIBUTE_UNUSED)
fix_new_exp (frag_now, this_frag - frag_now->fr_literal,
size, &insn.disp32, reloc_howto->pc_relative,
- BFD_RELOC_BPF_DISP32);
+ bfd_reloc);
break;
}
default:
diff --git a/gas/doc/c-bpf.texi b/gas/doc/c-bpf.texi
index bebf760..d4fd181 100644
--- a/gas/doc/c-bpf.texi
+++ b/gas/doc/c-bpf.texi
@@ -160,6 +160,9 @@ Signed 16-bit immediate representing an offset in bytes.
@item disp16
Signed 16-bit immediate representing a displacement to a target,
measured in number of 64-bit words @emph{minus one}.
+@item disp32
+Signed 32-bit immediate representing a displacement to a target,
+measured in number of 64-bit words @emph{minus one}.
@item imm32
Signed 32-bit immediate.
@item imm64
@@ -555,6 +558,10 @@ holds true.
@itemx goto disp16
Jump-always.
+@item jal disp32
+@itemx gotol disp32
+Jump-always, long range.
+
@item jeq rd, rs, disp16
@itemx jeq rd, imm32, disp16
@itemx if rd == rs goto disp16
diff --git a/gas/testsuite/gas/bpf/jump-be-pseudoc.d b/gas/testsuite/gas/bpf/jump-be-pseudoc.d
index 3874d58..8277311 100644
--- a/gas/testsuite/gas/bpf/jump-be-pseudoc.d
+++ b/gas/testsuite/gas/bpf/jump-be-pseudoc.d
@@ -30,3 +30,5 @@ Disassembly of section .text:
98: cd 34 00 00 00 00 00 00 if r3s<r4 goto 0
a0: d5 30 00 01 00 00 00 03 if r3s<=3 goto 1
a8: dd 34 00 00 00 00 00 00 if r3s<=r4 goto 0
+ b0: 06 00 00 00 00 00 00 01 gotol 1
+ b8: 06 00 00 00 00 00 00 00 gotol 0
diff --git a/gas/testsuite/gas/bpf/jump-be.d b/gas/testsuite/gas/bpf/jump-be.d
index 7c8a765..fffe1e9 100644
--- a/gas/testsuite/gas/bpf/jump-be.d
+++ b/gas/testsuite/gas/bpf/jump-be.d
@@ -30,3 +30,5 @@ Disassembly of section .text:
98: cd 34 00 00 00 00 00 00 jslt %r3,%r4,0
a0: d5 30 00 01 00 00 00 03 jsle %r3,3,1
a8: dd 34 00 00 00 00 00 00 jsle %r3,%r4,0
+ b0: 06 00 00 00 00 00 00 01 jal 1
+ b8: 06 00 00 00 00 00 00 00 jal 0
diff --git a/gas/testsuite/gas/bpf/jump-pseudoc.d b/gas/testsuite/gas/bpf/jump-pseudoc.d
index 644d2be..9b68108 100644
--- a/gas/testsuite/gas/bpf/jump-pseudoc.d
+++ b/gas/testsuite/gas/bpf/jump-pseudoc.d
@@ -30,3 +30,5 @@ Disassembly of section .text:
98: cd 43 00 00 00 00 00 00 if r3s<r4 goto 0
a0: d5 03 01 00 03 00 00 00 if r3s<=3 goto 1
a8: dd 43 00 00 00 00 00 00 if r3s<=r4 goto 0
+ b0: 06 00 00 00 01 00 00 00 gotol 1
+ b8: 06 00 00 00 00 00 00 00 gotol 0 \ No newline at end of file
diff --git a/gas/testsuite/gas/bpf/jump-pseudoc.s b/gas/testsuite/gas/bpf/jump-pseudoc.s
index 1331bda..9f86080 100644
--- a/gas/testsuite/gas/bpf/jump-pseudoc.s
+++ b/gas/testsuite/gas/bpf/jump-pseudoc.s
@@ -22,4 +22,6 @@
if r3 s< r4 goto 1f
1: if r3 s<= 3 goto 1f
if r3 s<= r4 goto 1f
+1: gotol 1f
+ gotol 1f
1:
diff --git a/gas/testsuite/gas/bpf/jump.d b/gas/testsuite/gas/bpf/jump.d
index 742610a..4da3727 100644
--- a/gas/testsuite/gas/bpf/jump.d
+++ b/gas/testsuite/gas/bpf/jump.d
@@ -30,3 +30,5 @@ Disassembly of section .text:
98: cd 43 00 00 00 00 00 00 jslt %r3,%r4,0
a0: d5 03 01 00 03 00 00 00 jsle %r3,3,1
a8: dd 43 00 00 00 00 00 00 jsle %r3,%r4,0
+ b0: 06 00 00 00 01 00 00 00 jal 1
+ b8: 06 00 00 00 00 00 00 00 jal 0 \ No newline at end of file
diff --git a/gas/testsuite/gas/bpf/jump.s b/gas/testsuite/gas/bpf/jump.s
index aae4295..c3d36bd 100644
--- a/gas/testsuite/gas/bpf/jump.s
+++ b/gas/testsuite/gas/bpf/jump.s
@@ -22,4 +22,6 @@
jslt %r3,%r4,1f
1: jsle %r3,3,1f
jsle %r3,%r4,1f
-1:
+1: jal 1f
+ jal 1f
+1:
diff --git a/include/ChangeLog b/include/ChangeLog
index ccf1661..8cad8e2 100644
--- a/include/ChangeLog
+++ b/include/ChangeLog
@@ -1,3 +1,8 @@
+2023-07-24 Jose E. Marchesi <jose.marchesi@oracle.com>
+
+ * opcode/bpf.h (enum bpf_insn_id): Add entry BPF_INSN_JAL.
+ (enum bpf_insn_id): Remove spurious entry BPF_INSN_CALLI.
+
2023-07-21 Jose E. Marchesi <jose.marchesi@oracle.com>
* opcode/bpf.h (enum bpf_insn_id): Add entries for signed load
diff --git a/include/opcode/bpf.h b/include/opcode/bpf.h
index a491df6..dc1b6e7 100644
--- a/include/opcode/bpf.h
+++ b/include/opcode/bpf.h
@@ -201,7 +201,8 @@ enum bpf_insn_id
BPF_INSN_JEQI, BPF_INSN_JGTI, BPF_INSN_JSGTI,
BPF_INSN_JGEI, BPF_INSN_JSGEI, BPF_INSN_JLTI, BPF_INSN_JSLTI,
BPF_INSN_JSLEI, BPF_INSN_JLEI, BPF_INSN_JSETI, BPF_INSN_JNEI,
- BPF_INSN_CALLI,
+ /* jump-always with 32-bit offset. */
+ BPF_INSN_JAL,
/* 32-bit compare-and-jump instructions (reg OP reg.) */
BPF_INSN_JEQ32R, BPF_INSN_JGT32R, BPF_INSN_JSGT32R,
BPF_INSN_JGE32R, BPF_INSN_JSGE32R, BPF_INSN_JLT32R, BPF_INSN_JSLT32R,
diff --git a/opcodes/ChangeLog b/opcodes/ChangeLog
index f88e9c8..d97eb38 100644
--- a/opcodes/ChangeLog
+++ b/opcodes/ChangeLog
@@ -1,3 +1,7 @@
+2023-07-23 Jose E. Marchesi <jose.marchesi@oracle.com>
+
+ * bpf-opc.c (bpf_opcodes): Add entry for jal.
+
2023-07-21 Jose E. Marchesi <jose.marchesi@oracle.com>
* bpf-opc.c (bpf_opcodes): Add entries for LDXS{B,W,H,DW}
diff --git a/opcodes/bpf-opc.c b/opcodes/bpf-opc.c
index efd3257..4ffd867 100644
--- a/opcodes/bpf-opc.c
+++ b/opcodes/bpf-opc.c
@@ -303,6 +303,10 @@ const struct bpf_opcode bpf_opcodes[] =
{BPF_INSN_JNEI, "jne%W%dr , %i32 , %d16", "if%w%dr != %i32%wgoto%w%d16",
BPF_V1, BPF_CODE, BPF_CLASS_JMP|BPF_CODE_JNE|BPF_SRC_K},
+ /* 32-bit jump-always. */
+ {BPF_INSN_JAL, "jal%W%d32", "gotol%w%d32",
+ BPF_V4, BPF_CODE, BPF_CLASS_JMP32|BPF_CODE_JA|BPF_SRC_K},
+
/* 32-bit compare-and-jump instructions (reg OP reg). */
{BPF_INSN_JEQ32R, "jeq32%W%dr , %sr , %d16", "if%w%dw == %sw%wgoto%w%d16",
BPF_V3, BPF_CODE, BPF_CLASS_JMP32|BPF_CODE_JEQ|BPF_SRC_X},