[PATCH] bpf: relocation fixes for eBPF ELF backend
Jose E. Marchesi
jose.marchesi@oracle.com
Thu Aug 6 13:16:53 GMT 2020
Hi David.
> 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.
I just installed this in master, on your behalf.
Thanks!
> bfd/ChangeLog
>
> 2020-08-05 David Faust <david.faust@oracle.com>
>
> * 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 <david.faust@oracle.com>
>
> * 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.
> ---
> bfd/elf64-bpf.c | 206 ++++++++++++++-----
> ld/testsuite/ld-bpf/call-2.d | 20 ++
> ld/testsuite/ld-bpf/call-2.s | 3 +
> ld/testsuite/ld-bpf/reloc-data-be.d | 11 +
> ld/testsuite/ld-bpf/reloc-data-le.d | 11 +
> ld/testsuite/ld-bpf/reloc-data.s | 16 ++
> ld/testsuite/ld-bpf/reloc-insn-external-be.d | 16 ++
> ld/testsuite/ld-bpf/reloc-insn-external-le.d | 16 ++
> ld/testsuite/ld-bpf/reloc-insn-external.s | 5 +
> ld/testsuite/ld-bpf/reloc-insn32-be.d | 19 ++
> ld/testsuite/ld-bpf/reloc-insn32-le.d | 19 ++
> ld/testsuite/ld-bpf/reloc-insn32.s | 20 ++
> ld/testsuite/ld-bpf/reloc-insn64-be.d | 12 ++
> ld/testsuite/ld-bpf/reloc-insn64-le.d | 12 ++
> ld/testsuite/ld-bpf/reloc-insn64.s | 9 +
> 15 files changed, 347 insertions(+), 48 deletions(-)
> create mode 100644 ld/testsuite/ld-bpf/call-2.d
> create mode 100644 ld/testsuite/ld-bpf/call-2.s
> create mode 100644 ld/testsuite/ld-bpf/reloc-data-be.d
> create mode 100644 ld/testsuite/ld-bpf/reloc-data-le.d
> create mode 100644 ld/testsuite/ld-bpf/reloc-data.s
> create mode 100644 ld/testsuite/ld-bpf/reloc-insn-external-be.d
> create mode 100644 ld/testsuite/ld-bpf/reloc-insn-external-le.d
> create mode 100644 ld/testsuite/ld-bpf/reloc-insn-external.s
> create mode 100644 ld/testsuite/ld-bpf/reloc-insn32-be.d
> create mode 100644 ld/testsuite/ld-bpf/reloc-insn32-le.d
> create mode 100644 ld/testsuite/ld-bpf/reloc-insn32.s
> create mode 100644 ld/testsuite/ld-bpf/reloc-insn64-be.d
> create mode 100644 ld/testsuite/ld-bpf/reloc-insn64-le.d
> create mode 100644 ld/testsuite/ld-bpf/reloc-insn64.s
>
> diff --git a/bfd/elf64-bpf.c b/bfd/elf64-bpf.c
> index 641caa1f05..c6a726d932 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/testsuite/ld-bpf/call-2.d b/ld/testsuite/ld-bpf/call-2.d
> new file mode 100644
> index 0000000000..3d09095f6b
> --- /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]+ <bar>:
> + *[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 0000000000..e2a5b90647
> --- /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 0000000000..4d793e2b41
> --- /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 0000000000..97cb1b36a2
> --- /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 0000000000..431ef5aef6
> --- /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 0000000000..032d3649d2
> --- /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 0000000000..d3513766ee
> --- /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 0000000000..be12813934
> --- /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 0000000000..27d592d243
> --- /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]+ <main>:
> + *[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]+ <baz>:
> + *[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 0000000000..bdbb45f28c
> --- /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]+ <main>:
> + *[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]+ <baz>:
> + *[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 0000000000..a53a0dc43f
> --- /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 0000000000..ca74e33099
> --- /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 0000000000..63dcce3bd1
> --- /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 0000000000..8cb1d9f896
> --- /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
More information about the Binutils
mailing list