diff options
-rw-r--r-- | bfd/ChangeLog | 6 | ||||
-rw-r--r-- | bfd/bfd-in2.h | 1 | ||||
-rw-r--r-- | bfd/elf64-bpf.c | 1 | ||||
-rw-r--r-- | bfd/libbfd.h | 1 | ||||
-rw-r--r-- | bfd/reloc.c | 2 | ||||
-rw-r--r-- | gas/ChangeLog | 15 | ||||
-rw-r--r-- | gas/config/tc-bpf.c | 56 | ||||
-rw-r--r-- | gas/doc/c-bpf.texi | 7 | ||||
-rw-r--r-- | gas/testsuite/gas/bpf/jump-be-pseudoc.d | 2 | ||||
-rw-r--r-- | gas/testsuite/gas/bpf/jump-be.d | 2 | ||||
-rw-r--r-- | gas/testsuite/gas/bpf/jump-pseudoc.d | 2 | ||||
-rw-r--r-- | gas/testsuite/gas/bpf/jump-pseudoc.s | 2 | ||||
-rw-r--r-- | gas/testsuite/gas/bpf/jump.d | 2 | ||||
-rw-r--r-- | gas/testsuite/gas/bpf/jump.s | 4 | ||||
-rw-r--r-- | include/ChangeLog | 5 | ||||
-rw-r--r-- | include/opcode/bpf.h | 3 | ||||
-rw-r--r-- | opcodes/ChangeLog | 4 | ||||
-rw-r--r-- | opcodes/bpf-opc.c | 4 |
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}, |