From: David Faust Date: Thu, 6 Aug 2020 13:14:54 +0000 (+0200) Subject: bpf: relocation fixes for eBPF ELF backend X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=3ee9565c95f49b6f9e80641f6fda51adffc3af1e;p=binutils-gdb.git bpf: relocation fixes for eBPF ELF backend The eBPF ELF backend was not properly recording relocation addends during installation, nor reading and applying them when performing the final relocation. This lead to various issues with incorrect relocations. These issues are fixed with a new howto special function to install the relocations, and updates to bpf_elf_relocate_section to read and use the addends as recorded in the input_bfd. bfd/ChangeLog 2020-08-05 David Faust * elf64-bpf.c (bpf_elf_generic_reloc): New function. (bpf_elf_howto_table): Use it here. (bpf_elf_relocate_section): Use addends recorded in input_bfd for instruction and data relocations. ld/ChangeLog 2020-08-05 David Faust * testsuite/ld-bpf/call-2.s: New file. * testsuite/ld-bpf/call-2.d: Likewise. * testsuite/ld-bpf/reloc-data-be.d: Likewise. * testsuite/ld-bpf/reloc-data-le.d: Likewise. * testsuite/ld-bpf/reloc-data.s: Likewise. * testsuite/ld-bpf/reloc-insn-external-be.d: Likewise. * testsuite/ld-bpf/reloc-insn-external-le.d: Likewise. * testsuite/ld-bpf/reloc-insn-external.s: Likewise. * testsuite/ld-bpf/reloc-insn32-be.d: Likewise. * testsuite/ld-bpf/reloc-insn32-le.d: Likewise. * testsuite/ld-bpf/reloc-insn32.s: Likewise. * testsuite/ld-bpf/reloc-insn64-be.d: Likewise. * testsuite/ld-bpf/reloc-insn64-le.d: Likewise. * testsuite/ld-bpf/reloc-insn64.s: Likewise. --- diff --git a/bfd/ChangeLog b/bfd/ChangeLog index aae554b560d..1c96c22008c 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,10 @@ +2020-08-05 David Faust + + * elf64-bpf.c (bpf_elf_generic_reloc): New function. + (bpf_elf_howto_table): Use it here. + (bpf_elf_relocate_section): Use addends recorded in input_bfd for + instruction and data relocations. + 2020-08-03 Alan Modra * vms-lib.c (vms_traverse_index): Sanity check size remaining diff --git a/bfd/elf64-bpf.c b/bfd/elf64-bpf.c index 641caa1f058..c6a726d9324 100644 --- a/bfd/elf64-bpf.c +++ b/bfd/elf64-bpf.c @@ -31,6 +31,9 @@ #define BASEADDR(SEC) ((SEC)->output_section->vma + (SEC)->output_offset) +static bfd_reloc_status_type bpf_elf_generic_reloc + (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **); + /* Relocation tables. */ static reloc_howto_type bpf_elf_howto_table [] = { @@ -42,7 +45,7 @@ static reloc_howto_type bpf_elf_howto_table [] = FALSE, /* pc_relative */ 0, /* bitpos */ complain_overflow_dont, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ + bpf_elf_generic_reloc, /* special_function */ "R_BPF_NONE", /* name */ FALSE, /* partial_inplace */ 0, /* src_mask */ @@ -55,27 +58,27 @@ static reloc_howto_type bpf_elf_howto_table [] = 4, /* size (0 = byte, 1 = short, 2 = long) */ 64, /* bitsize */ FALSE, /* pc_relative */ - 0, /* bitpos */ + 32, /* bitpos */ complain_overflow_signed, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ + bpf_elf_generic_reloc, /* special_function */ "R_BPF_INSN_64", /* name */ - FALSE, /* partial_inplace */ - 0, /* src_mask */ + TRUE, /* partial_inplace */ + MINUS_ONE, /* src_mask */ MINUS_ONE, /* dst_mask */ TRUE), /* pcrel_offset */ - /* 32-immediate in many instructions. Note: handled manually. */ + /* 32-immediate in many instructions. */ HOWTO (R_BPF_INSN_32, /* type */ 0, /* rightshift */ 2, /* size (0 = byte, 1 = short, 2 = long) */ 32, /* bitsize */ FALSE, /* pc_relative */ - 0, /* bitpos */ + 32, /* bitpos */ complain_overflow_signed, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ + bpf_elf_generic_reloc, /* special_function */ "R_BPF_INSN_32", /* name */ - FALSE, /* partial_inplace */ - 0, /* src_mask */ + TRUE, /* partial_inplace */ + 0xffffffff, /* src_mask */ 0xffffffff, /* dst_mask */ TRUE), /* pcrel_offset */ @@ -85,12 +88,12 @@ static reloc_howto_type bpf_elf_howto_table [] = 1, /* size (0 = byte, 1 = short, 2 = long) */ 16, /* bitsize */ FALSE, /* pc_relative */ - 0, /* bitpos */ + 16, /* bitpos */ complain_overflow_signed, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ + bpf_elf_generic_reloc, /* special_function */ "R_BPF_INSN_16", /* name */ - FALSE, /* partial_inplace */ - 0, /* src_mask */ + TRUE, /* partial_inplace */ + 0x0000ffff, /* src_mask */ 0x0000ffff, /* dst_mask */ TRUE), /* pcrel_offset */ @@ -100,11 +103,11 @@ static reloc_howto_type bpf_elf_howto_table [] = 1, /* size (0 = byte, 1 = short, 2 = long) */ 16, /* bitsize */ TRUE, /* pc_relative */ - 32, /* bitpos */ + 16, /* bitpos */ complain_overflow_signed, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ + bpf_elf_generic_reloc, /* special_function */ "R_BPF_INSN_DISP16", /* name */ - FALSE, /* partial_inplace */ + TRUE, /* partial_inplace */ 0xffff, /* src_mask */ 0xffff, /* dst_mask */ TRUE), /* pcrel_offset */ @@ -116,10 +119,10 @@ static reloc_howto_type bpf_elf_howto_table [] = TRUE, /* pc_relative */ 0, /* bitpos */ complain_overflow_signed, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ + bpf_elf_generic_reloc, /* special_function */ "R_BPF_8_PCREL", /* name */ - FALSE, /* partial_inplace */ - 0, /* src_mask */ + TRUE, /* partial_inplace */ + 0xff, /* src_mask */ 0xff, /* dst_mask */ TRUE), /* pcrel_offset */ @@ -130,10 +133,10 @@ static reloc_howto_type bpf_elf_howto_table [] = TRUE, /* pc_relative */ 0, /* bitpos */ complain_overflow_signed, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ + bpf_elf_generic_reloc, /* special_function */ "R_BPF_16_PCREL", /* name */ FALSE, /* partial_inplace */ - 0, /* src_mask */ + 0xffff, /* src_mask */ 0xffff, /* dst_mask */ TRUE), /* pcrel_offset */ @@ -144,10 +147,10 @@ static reloc_howto_type bpf_elf_howto_table [] = TRUE, /* pc_relative */ 0, /* bitpos */ complain_overflow_signed, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ + bpf_elf_generic_reloc, /* special_function */ "R_BPF_32_PCREL", /* name */ FALSE, /* partial_inplace */ - 0, /* src_mask */ + 0xffffffff, /* src_mask */ 0xffffffff, /* dst_mask */ TRUE), /* pcrel_offset */ @@ -158,10 +161,10 @@ static reloc_howto_type bpf_elf_howto_table [] = FALSE, /* pc_relative */ 0, /* bitpos */ complain_overflow_unsigned, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ + bpf_elf_generic_reloc, /* special_function */ "R_BPF_DATA_8", /* name */ - FALSE, /* partial_inplace */ - 0, /* src_mask */ + TRUE, /* partial_inplace */ + 0xff, /* src_mask */ 0xff, /* dst_mask */ FALSE), /* pcrel_offset */ @@ -172,10 +175,10 @@ static reloc_howto_type bpf_elf_howto_table [] = FALSE, /* pc_relative */ 0, /* bitpos */ complain_overflow_unsigned, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ + bpf_elf_generic_reloc, /* special_function */ "R_BPF_DATA_16", /* name */ FALSE, /* partial_inplace */ - 0, /* src_mask */ + 0xffff, /* src_mask */ 0xffff, /* dst_mask */ FALSE), /* pcrel_offset */ @@ -185,11 +188,11 @@ static reloc_howto_type bpf_elf_howto_table [] = 2, /* size (0 = byte, 1 = short, 2 = long) */ 32, /* bitsize */ TRUE, /* pc_relative */ - 0, /* bitpos */ + 32, /* bitpos */ complain_overflow_signed, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ + bpf_elf_generic_reloc, /* special_function */ "R_BPF_INSN_DISP32", /* name */ - FALSE, /* partial_inplace */ + TRUE, /* partial_inplace */ 0xffffffff, /* src_mask */ 0xffffffff, /* dst_mask */ TRUE), /* pcrel_offset */ @@ -202,10 +205,10 @@ static reloc_howto_type bpf_elf_howto_table [] = FALSE, /* pc_relative */ 0, /* bitpos */ complain_overflow_bitfield, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ + bpf_elf_generic_reloc, /* special_function */ "R_BPF_DATA_32", /* name */ FALSE, /* partial_inplace */ - 0, /* src_mask */ + 0xffffffff, /* src_mask */ 0xffffffff, /* dst_mask */ TRUE), /* pcrel_offset */ @@ -217,7 +220,7 @@ static reloc_howto_type bpf_elf_howto_table [] = FALSE, /* pc_relative */ 0, /* bitpos */ complain_overflow_bitfield, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ + bpf_elf_generic_reloc, /* special_function */ "R_BPF_DATA_64", /* name */ FALSE, /* partial_inplace */ 0, /* src_mask */ @@ -231,10 +234,10 @@ static reloc_howto_type bpf_elf_howto_table [] = TRUE, /* pc_relative */ 0, /* bitpos */ complain_overflow_signed, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ + bpf_elf_generic_reloc, /* special_function */ "R_BPF_64_PCREL", /* name */ FALSE, /* partial_inplace */ - 0, /* src_mask */ + MINUS_ONE, /* src_mask */ MINUS_ONE, /* dst_mask */ TRUE), /* pcrel_offset */ }; @@ -391,6 +394,8 @@ bpf_elf_relocate_section (bfd *output_bfd ATTRIBUTE_UNUSED, bfd_reloc_status_type r; const char * name = NULL; int r_type ATTRIBUTE_UNUSED; + bfd_signed_vma addend; + bfd_byte * where; r_type = ELF64_R_TYPE (rel->r_info); r_symndx = ELF64_R_SYM (rel->r_info); @@ -398,6 +403,7 @@ bpf_elf_relocate_section (bfd *output_bfd ATTRIBUTE_UNUSED, h = NULL; sym = NULL; sec = NULL; + where = contents + rel->r_offset; if (r_symndx < symtab_hdr->sh_info) { @@ -435,8 +441,6 @@ bpf_elf_relocate_section (bfd *output_bfd ATTRIBUTE_UNUSED, case R_BPF_INSN_DISP16: case R_BPF_INSN_DISP32: { - bfd_signed_vma addend; - /* Make the relocation PC-relative, and change its unit to 64-bit words. */ relocation -= sec_addr (input_section) + rel->r_offset; @@ -460,11 +464,35 @@ bpf_elf_relocate_section (bfd *output_bfd ATTRIBUTE_UNUSED, r = bfd_reloc_ok; break; } + case R_BPF_DATA_8: + case R_BPF_DATA_16: + case R_BPF_DATA_32: + case R_BPF_DATA_64: + { + addend = bfd_get (howto->bitsize, input_bfd, where); + relocation += addend; + bfd_put (howto->bitsize, input_bfd, relocation, where); + + r = bfd_reloc_ok; + break; + } + case R_BPF_INSN_16: + { + + addend = bfd_get_16 (input_bfd, where + 2); + relocation += addend; + bfd_put_16 (input_bfd, relocation, where + 2); + + r = bfd_reloc_ok; + break; + } case R_BPF_INSN_32: { /* Write relocated value */ - bfd_put (howto->bitsize, input_bfd, relocation, - contents + rel->r_offset + 4); + + addend = bfd_get_32 (input_bfd, where + 4); + relocation += addend; + bfd_put_32 (input_bfd, relocation, where + 4); r = bfd_reloc_ok; break; @@ -478,19 +506,30 @@ bpf_elf_relocate_section (bfd *output_bfd ATTRIBUTE_UNUSED, The upper 32 bits of the immediate are stored at the end of the instruction. */ - bfd_put (32, input_bfd, (relocation & 0xFFFFFFFF), - contents + rel->r_offset + 4); - bfd_put (32, input_bfd, (relocation >> 32), - contents + rel->r_offset + 12); + + + /* Get the addend. The upper and lower 32 bits are split. + 'where' is the beginning of the 16-byte instruction. */ + addend = bfd_get_32 (input_bfd, where + 4); + addend |= (bfd_get_32 (input_bfd, where + 12) << 32); + + relocation += addend; + + bfd_put_32 (input_bfd, (relocation & 0xFFFFFFFF), where + 4); + bfd_put_32 (input_bfd, (relocation >> 32), where + 12); r = bfd_reloc_ok; break; } default: - r = _bfd_final_link_relocate (howto, input_bfd, input_section, - contents, rel->r_offset, relocation, - rel->r_addend); + r = bfd_reloc_notsupported; } + if (r == bfd_reloc_ok) + r = bfd_check_overflow (howto->complain_on_overflow, + howto->bitsize, + howto->rightshift, + 64, relocation); + if (r != bfd_reloc_ok) { const char * msg = NULL; @@ -548,6 +587,77 @@ elf64_bpf_merge_private_bfd_data (bfd *ibfd, struct bfd_link_info *info) return TRUE; } +/* A generic howto special function for installing BPF relocations. + This function will be called by the assembler (via bfd_install_relocation). + At link time, bpf_elf_relocate_section will resolve the final relocations. + + BPF instructions are always big endian, and this approach avoids problems in + bfd_install_relocation. */ + +static bfd_reloc_status_type +bpf_elf_generic_reloc (bfd * abfd, arelent *reloc_entry, asymbol *symbol, + void *data, asection *input_section, + bfd *output_bfd, + char **error_message ATTRIBUTE_UNUSED) +{ + + bfd_signed_vma relocation; + bfd_reloc_status_type status; + bfd_byte *where; + + /* Sanity check that the address is in range. */ + if (reloc_entry->address > bfd_get_section_limit (abfd, input_section)) + return bfd_reloc_outofrange; + + /* Get the symbol value. */ + if (bfd_is_com_section (symbol->section)) + relocation = 0; + else + relocation = symbol->value; + + if (symbol->flags & BSF_SECTION_SYM) + /* Relocation against a section symbol: add in the section base address. */ + relocation += BASEADDR (symbol->section); + + relocation += reloc_entry->addend; + + where = (bfd_byte *) data + reloc_entry->address; + + status = bfd_check_overflow (reloc_entry->howto->complain_on_overflow, + reloc_entry->howto->bitsize, + reloc_entry->howto->rightshift, 64, relocation); + + if (status != bfd_reloc_ok) + return status; + + /* Now finally install the relocation. */ + if (reloc_entry->howto->type == R_BPF_INSN_64) + { + /* lddw is a 128-bit (!) instruction that allows loading a 64-bit + immediate into a register. the immediate is split in half, with the + lower 32 bits in the same position as the imm32 field of other + instructions, and the upper 32 bits placed at the very end of the + instruction. that is, there are 32 unused bits between them. */ + + bfd_put_32 (output_bfd, (relocation & 0xFFFFFFFF), where + 4); + bfd_put_32 (output_bfd, (relocation >> 32), where + 12); + } + else + { + /* For other kinds of relocations, the relocated value simply goes + BITPOS bits from the start of the entry. This is always a multiple + of 8, i.e. whole bytes. */ + bfd_put (reloc_entry->howto->bitsize, output_bfd, relocation, + where + reloc_entry->howto->bitpos / 8); + } + + reloc_entry->addend = relocation; + reloc_entry->address += input_section->output_offset; + + return bfd_reloc_ok; +} + + /* The macros below configure the architecture. */ #define TARGET_LITTLE_SYM bpf_elf64_le_vec diff --git a/ld/ChangeLog b/ld/ChangeLog index b4134184714..d46e9769c08 100644 --- a/ld/ChangeLog +++ b/ld/ChangeLog @@ -1,3 +1,20 @@ +2020-08-05 David Faust + + * testsuite/ld-bpf/call-2.s: New file. + * testsuite/ld-bpf/call-2.d: Likewise. + * testsuite/ld-bpf/reloc-data-be.d: Likewise. + * testsuite/ld-bpf/reloc-data-le.d: Likewise. + * testsuite/ld-bpf/reloc-data.s: Likewise. + * testsuite/ld-bpf/reloc-insn-external-be.d: Likewise. + * testsuite/ld-bpf/reloc-insn-external-le.d: Likewise. + * testsuite/ld-bpf/reloc-insn-external.s: Likewise. + * testsuite/ld-bpf/reloc-insn32-be.d: Likewise. + * testsuite/ld-bpf/reloc-insn32-le.d: Likewise. + * testsuite/ld-bpf/reloc-insn32.s: Likewise. + * testsuite/ld-bpf/reloc-insn64-be.d: Likewise. + * testsuite/ld-bpf/reloc-insn64-le.d: Likewise. + * testsuite/ld-bpf/reloc-insn64.s: Likewise. + 2020-08-06 Jozef Lawrynowicz * emultempl/msp430.em (change_output_section): Update the tail diff --git a/ld/testsuite/ld-bpf/call-2.d b/ld/testsuite/ld-bpf/call-2.d new file mode 100644 index 00000000000..3d09095f6be --- /dev/null +++ b/ld/testsuite/ld-bpf/call-2.d @@ -0,0 +1,20 @@ +#as: --EL +#source: call-2.s +#source: bar.s +#objdump: -dr +#ld: -EL +#name: CALL with disp32 reloc and addend + +.*: +file format .*bpf.* + +Disassembly of section .text: + +[0-9a-f]+ <.*>: + *[0-9a-f]+: b7 01 00 00 01 00 00 00 mov %r1,1 + *[0-9a-f]+: 85 10 00 00 02 00 00 00 call 2 + *[0-9a-f]+: 95 00 00 00 00 00 00 00 exit + +[0-9a-f]+ : + *[0-9a-f]+: bf 21 00 00 00 00 00 00 mov %r1,%r2 + *[0-9a-f]+: bf 13 00 00 00 00 00 00 mov %r3,%r1 + *[0-9a-f]+: 95 00 00 00 00 00 00 00 exit diff --git a/ld/testsuite/ld-bpf/call-2.s b/ld/testsuite/ld-bpf/call-2.s new file mode 100644 index 00000000000..e2a5b90647d --- /dev/null +++ b/ld/testsuite/ld-bpf/call-2.s @@ -0,0 +1,3 @@ + mov %r1, 1 + call bar + 0x1 + exit diff --git a/ld/testsuite/ld-bpf/reloc-data-be.d b/ld/testsuite/ld-bpf/reloc-data-be.d new file mode 100644 index 00000000000..4d793e2b41a --- /dev/null +++ b/ld/testsuite/ld-bpf/reloc-data-be.d @@ -0,0 +1,11 @@ +#as: --EB +#source: reloc-data.s +#objdump: -s +#ld: -Tdata=0x20 -EB +#name: data relocs BE + +.*: file format .*-bpfbe + +Contents of section \.data: + 0020 666f6f00 62617200 00000000 00000020 .* + 0030 00000028 003034 .* diff --git a/ld/testsuite/ld-bpf/reloc-data-le.d b/ld/testsuite/ld-bpf/reloc-data-le.d new file mode 100644 index 00000000000..97cb1b36a2a --- /dev/null +++ b/ld/testsuite/ld-bpf/reloc-data-le.d @@ -0,0 +1,11 @@ +#as: --EL +#source: reloc-data.s +#objdump: -s +#ld: -Tdata=0x20 -EL +#name: data relocs LE + +.*: file format .*-bpfle + +Contents of section \.data: + 0020 666f6f00 62617200 20000000 00000000 .* + 0030 28000000 300034 .* diff --git a/ld/testsuite/ld-bpf/reloc-data.s b/ld/testsuite/ld-bpf/reloc-data.s new file mode 100644 index 00000000000..431ef5aef61 --- /dev/null +++ b/ld/testsuite/ld-bpf/reloc-data.s @@ -0,0 +1,16 @@ + .data +foo: + .string "foo" + + .global bar +bar: + .string "bar" + +d64: + .quad foo +d32: + .word d64 +d16: + .half d32 +d8: + .byte d16 diff --git a/ld/testsuite/ld-bpf/reloc-insn-external-be.d b/ld/testsuite/ld-bpf/reloc-insn-external-be.d new file mode 100644 index 00000000000..032d3649d2a --- /dev/null +++ b/ld/testsuite/ld-bpf/reloc-insn-external-be.d @@ -0,0 +1,16 @@ +#as: --EB +#source: reloc-data.s +#source: reloc-insn-external.s +#objdump: -dr +#ld: -Tdata=0x20 -EB +#name: reloc insn external BE + +.*: +file format .*bpfbe + +Disassembly of section .text: + +[0-9a-f]+ <.*>: + *[0-9a-f]+: 18 10 00 00 00 00 00 28[ ]*lddw %r1,0x28 + *[0-9a-f]+: 00 00 00 00 00 00 00 00[ ]* + *[0-9a-f]+: b7 20 00 00 00 00 00 26[ ]*mov %r2,0x26 + *[0-9a-f]+: 61 34 00 24 00 00 00 00[ ]*ldxw %r3,\[%r4\+0x24\] diff --git a/ld/testsuite/ld-bpf/reloc-insn-external-le.d b/ld/testsuite/ld-bpf/reloc-insn-external-le.d new file mode 100644 index 00000000000..d3513766ee8 --- /dev/null +++ b/ld/testsuite/ld-bpf/reloc-insn-external-le.d @@ -0,0 +1,16 @@ +#as: --EL +#source: reloc-data.s +#source: reloc-insn-external.s +#objdump: -dr +#ld: -Tdata=0x20 -EL +#name: reloc insn external LE + +.*: +file format .*bpfle + +Disassembly of section .text: + +[0-9a-f]+ <.*>: + *[0-9a-f]+: 18 01 00 00 28 00 00 00[ ]*lddw %r1,0x28 + *[0-9a-f]+: 00 00 00 00 00 00 00 00[ ]* + *[0-9a-f]+: b7 02 00 00 26 00 00 00[ ]*mov %r2,0x26 + *[0-9a-f]+: 61 43 24 00 00 00 00 00[ ]*ldxw %r3,\[%r4\+0x24\] diff --git a/ld/testsuite/ld-bpf/reloc-insn-external.s b/ld/testsuite/ld-bpf/reloc-insn-external.s new file mode 100644 index 00000000000..be12813934a --- /dev/null +++ b/ld/testsuite/ld-bpf/reloc-insn-external.s @@ -0,0 +1,5 @@ + + lddw %r1, bar + 4 + mov %r2, bar + 2 + + ldxw %r3, [%r4 + bar] diff --git a/ld/testsuite/ld-bpf/reloc-insn32-be.d b/ld/testsuite/ld-bpf/reloc-insn32-be.d new file mode 100644 index 00000000000..27d592d2439 --- /dev/null +++ b/ld/testsuite/ld-bpf/reloc-insn32-be.d @@ -0,0 +1,19 @@ +#as: --EB +#source: reloc-insn32.s +#objdump: -d +#ld: -Tdata=0xdabeef -EB +#name: reloc INSN32 BE + +.*: +file format .*bpfbe + +Disassembly of section .text: + +[0-9a-f]+
: + *[0-9a-f]+: b7 10 00 00 00 da be f3[ ]*mov %r1,0xdabef3 + *[0-9a-f]+: 16 10 00 02 00 da be f3[ ]*jeq32 %r1,0xdabef3,2 + *[0-9a-f]+: 38 00 00 00 00 da be ff[ ]*ldabsdw 0xdabeff + *[0-9a-f]+: 95 00 00 00 00 00 00 00[ ]*exit + +[0-9a-f]+ : + *[0-9a-f]+: 07 10 00 00 00 da be ef[ ]*add %r1,0xdabeef + *[0-9a-f]+: 62 20 00 08 00 da be f7[ ]*stw \[%r2\+8\],0xdabef7 diff --git a/ld/testsuite/ld-bpf/reloc-insn32-le.d b/ld/testsuite/ld-bpf/reloc-insn32-le.d new file mode 100644 index 00000000000..bdbb45f28c6 --- /dev/null +++ b/ld/testsuite/ld-bpf/reloc-insn32-le.d @@ -0,0 +1,19 @@ +#as: --EL +#source: reloc-insn32.s +#objdump: -d +#ld: -Tdata=0xdabeef -EL +#name: reloc INSN32 LE + +.*: +file format .*bpfle + +Disassembly of section .text: + +[0-9a-f]+
: + *[0-9a-f]+: b7 01 00 00 f3 be da 00[ ]*mov %r1,0xdabef3 + *[0-9a-f]+: 16 01 02 00 f3 be da 00[ ]*jeq32 %r1,0xdabef3,2 + *[0-9a-f]+: 38 00 00 00 ff be da 00[ ]*ldabsdw 0xdabeff + *[0-9a-f]+: 95 00 00 00 00 00 00 00[ ]*exit + +[0-9a-f]+ : + *[0-9a-f]+: 07 01 00 00 ef be da 00[ ]*add %r1,0xdabeef + *[0-9a-f]+: 62 02 08 00 f7 be da 00[ ]*stw \[%r2\+8\],0xdabef7 diff --git a/ld/testsuite/ld-bpf/reloc-insn32.s b/ld/testsuite/ld-bpf/reloc-insn32.s new file mode 100644 index 00000000000..a53a0dc43f8 --- /dev/null +++ b/ld/testsuite/ld-bpf/reloc-insn32.s @@ -0,0 +1,20 @@ + .data +foo: + .string "foo" +bar: + .string "bar" +d64: + .dword bar +d32: + .word d64 + + .text +main: + mov %r1, bar + jeq32 %r1, bar, baz + ldabsdw d32 + exit + +baz: + add %r1, foo + stw [%r2 + 8], d64 diff --git a/ld/testsuite/ld-bpf/reloc-insn64-be.d b/ld/testsuite/ld-bpf/reloc-insn64-be.d new file mode 100644 index 00000000000..ca74e33099c --- /dev/null +++ b/ld/testsuite/ld-bpf/reloc-insn64-be.d @@ -0,0 +1,12 @@ +#as: --EB +#source: reloc-insn64.s +#objdump: -s +#ld: -Tdata=0xdeadbeef1234 -EB +#name: reloc INSN64 big-endian + +.*: file format .*-bpfbe + +#... +Contents of section \.text: +[ ][0-9a-f]+ 18100000 beef1238 00000000 0000dead .* +#pass diff --git a/ld/testsuite/ld-bpf/reloc-insn64-le.d b/ld/testsuite/ld-bpf/reloc-insn64-le.d new file mode 100644 index 00000000000..63dcce3bd17 --- /dev/null +++ b/ld/testsuite/ld-bpf/reloc-insn64-le.d @@ -0,0 +1,12 @@ +#as: --EL +#source: reloc-insn64.s +#objdump: -s +#ld: -Tdata=0xdeadbeef1234 -EL +#name: reloc INSN64 little-endian + +.*: file format .*-bpfle + +#... +Contents of section \.text: +[ ][0-9a-f]+ 18010000 3812efbe 00000000 adde0000 .* +#pass diff --git a/ld/testsuite/ld-bpf/reloc-insn64.s b/ld/testsuite/ld-bpf/reloc-insn64.s new file mode 100644 index 00000000000..8cb1d9f896d --- /dev/null +++ b/ld/testsuite/ld-bpf/reloc-insn64.s @@ -0,0 +1,9 @@ + .data +x: + .string "foo" +y: + .string "bar" + + .text +main: + lddw %r1, y