From: David Faust Date: Thu, 28 May 2020 18:53:29 +0000 (+0200) Subject: bfd: fix handling of R_BPF_INSN_{32,64} relocations. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=12adf8053ba0b241d3973b46109842a1cbfa60de;p=binutils-gdb.git bfd: fix handling of R_BPF_INSN_{32,64} relocations. 2020-05-28 David Faust * elf64-bpf.c (bpf_elf_relocate_section): Fix handling of R_BPF_INSN_{32,64} relocations. --- diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 482bf81e689..05452c5d467 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,8 @@ +2020-05-28 David Faust + + * elf64-bpf.c (bpf_elf_relocate_section): Fix handling of + R_BPF_INSN_{32,64} relocations. + 2020-05-28 Stephen Casner * pdp11.c: Implement BRD_RELOC_32 to relocate the low 16 bits of diff --git a/bfd/elf64-bpf.c b/bfd/elf64-bpf.c index bf488af81f6..641caa1f058 100644 --- a/bfd/elf64-bpf.c +++ b/bfd/elf64-bpf.c @@ -64,7 +64,7 @@ static reloc_howto_type bpf_elf_howto_table [] = MINUS_ONE, /* dst_mask */ TRUE), /* pcrel_offset */ - /* 32-immediate in LDDW instruction. */ + /* 32-immediate in many instructions. Note: handled manually. */ HOWTO (R_BPF_INSN_32, /* type */ 0, /* rightshift */ 2, /* size (0 = byte, 1 = short, 2 = long) */ @@ -460,6 +460,31 @@ bpf_elf_relocate_section (bfd *output_bfd ATTRIBUTE_UNUSED, 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); + + r = bfd_reloc_ok; + break; + } + case R_BPF_INSN_64: + { + /* + LDDW instructions are 128 bits long, with a 64-bit immediate. + The lower 32 bits of the immediate are in the same position + as the imm32 field of other instructions. + 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); + r = bfd_reloc_ok; + break; + } default: r = _bfd_final_link_relocate (howto, input_bfd, input_section, contents, rel->r_offset, relocation,