complain_overflow_bitfield, /* complain_on_overflow */
bpf_elf_generic_reloc, /* special_function */
"R_BPF_64_ABS32", /* name */
- false, /* partial_inplace */
+ true, /* partial_inplace */
0xffffffff, /* src_mask */
0xffffffff, /* dst_mask */
true) /* pcrel_offset */
complain_overflow_bitfield, /* complain_on_overflow */
bpf_elf_generic_reloc, /* special_function */
"R_BPF_64_ABS64", /* name */
- false, /* partial_inplace */
+ true, /* partial_inplace */
0, /* src_mask */
MINUS_ONE, /* dst_mask */
true) /* pcrel_offset */
complain_overflow_bitfield, /* complain_on_overflow */
bpf_elf_generic_reloc, /* special_function */
"R_BPF_64_NODYLD32", /* name */
- false, /* partial_inplace */
+ true, /* partial_inplace */
0xffffffff, /* src_mask */
0xffffffff, /* dst_mask */
true) /* pcrel_offset */
static bfd_reloc_status_type
bpf_elf_generic_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
- void *data, asection *input_section,
- bfd *output_bfd ATTRIBUTE_UNUSED,
+ void *data, asection *input_section, bfd *output_bfd,
char **error_message ATTRIBUTE_UNUSED)
{
bfd_reloc_status_type status;
bfd_byte *where;
+ /* From bfd_elf_generic_reloc. */
+ if (output_bfd != NULL
+ && (symbol->flags & BSF_SECTION_SYM) == 0
+ && (! reloc_entry->howto->partial_inplace
+ || reloc_entry->addend == 0))
+ {
+ reloc_entry->address += input_section->output_offset;
+ return bfd_reloc_ok;
+ }
+
+ if (output_bfd == NULL
+ && !reloc_entry->howto->pc_relative
+ && (symbol->section->flags & SEC_DEBUGGING) != 0
+ && (input_section->flags & SEC_DEBUGGING) != 0)
+ reloc_entry->addend -= symbol->section->output_section->vma;
+
/* Sanity check that the address is in range. */
bfd_size_type end = bfd_get_section_limit_octets (abfd, input_section);
bfd_size_type reloc_size;
|| end - reloc_entry->address < reloc_size)
return bfd_reloc_outofrange;
- /* Get the symbol value. */
- if (bfd_is_com_section (symbol->section))
- relocation = 0;
- else
- relocation = symbol->value;
+ /* Behave similarly to bfd_install_relocation with install_addend set.
+ That is, just install the addend and do not include the value of
+ the symbol. */
+ relocation = reloc_entry->addend;
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,
where + reloc_entry->howto->bitpos / 8);
}
- reloc_entry->addend = relocation;
- reloc_entry->address += input_section->output_offset;
+ if (output_bfd != NULL)
+ reloc_entry->address += input_section->output_offset;
return bfd_reloc_ok;
}
# Test that parser does not create undefined symbols
run_dump_test asm-extra-sym-1
+
+ # Test relocation installation
+ run_dump_test elf-relo-1
}
--- /dev/null
+#as: -EL -mdialect=normal
+#objdump: -tdr
+#source elf-relo-1.s
+#name: eBPF ELF relocations 1
+
+.*: +file format elf64-bpfle
+
+SYMBOL TABLE:
+0000000000000000 l d .text 0000000000000000 .text
+0000000000000000 l d .data 0000000000000000 .data
+0000000000000000 l d .bss 0000000000000000 .bss
+0000000000000006 l .data 0000000000000000 bar
+0000000000000000 l F .text 0000000000000000 baz
+0000000000000030 l F .text 0000000000000000 qux
+0000000000000004 g .data 0000000000000000 foo
+0000000000000000 \*UND\* 0000000000000000 somefunc
+
+
+
+Disassembly of section .text:
+
+0+ <baz>:
+ 0: 18 01 00 00 00 00 00 00 lddw %r1,0
+ 8: 00 00 00 00 00 00 00 00
+ 0: R_BPF_64_64 foo
+ 10: b7 02 00 00 06 00 00 00 mov %r2,6
+ 14: R_BPF_64_ABS32 .data
+ 18: 18 03 00 00 30 00 00 00 lddw %r3,48
+ 20: 00 00 00 00 00 00 00 00
+ 18: R_BPF_64_64 .text
+ 28: 85 10 00 00 ff ff ff ff call -1
+ 28: R_BPF_64_32 somefunc
+
+0+30 <qux>:
+ 30: 95 00 00 00 00 00 00 00 exit
--- /dev/null
+ .global foo
+ .data
+ .byte 1
+ .byte 2
+ .byte 3
+ .byte 4
+foo:
+ .byte 5
+ .byte 6
+bar:
+ .byte 7
+ .byte 8
+
+ .text
+ .align 3
+ .type baz, @function
+baz:
+ lddw %r1, foo
+ mov %r2, bar
+ lddw %r3, qux
+ call somefunc
+
+ .type qux, @function
+qux:
+ exit