aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bfd/bpf-reloc.def6
-rw-r--r--bfd/elf64-bpf.c34
-rw-r--r--gas/testsuite/gas/bpf/bpf.exp3
-rw-r--r--gas/testsuite/gas/bpf/elf-relo-1.d35
-rw-r--r--gas/testsuite/gas/bpf/elf-relo-1.s25
5 files changed, 89 insertions, 14 deletions
diff --git a/bfd/bpf-reloc.def b/bfd/bpf-reloc.def
index 42ba1a1..65228d4 100644
--- a/bfd/bpf-reloc.def
+++ b/bfd/bpf-reloc.def
@@ -38,7 +38,7 @@
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 */
@@ -53,7 +53,7 @@
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 */
@@ -103,7 +103,7 @@
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 */
diff --git a/bfd/elf64-bpf.c b/bfd/elf64-bpf.c
index 0bffe2c..c922a3e 100644
--- a/bfd/elf64-bpf.c
+++ b/bfd/elf64-bpf.c
@@ -385,8 +385,7 @@ elf64_bpf_merge_private_bfd_data (bfd *ibfd, struct bfd_link_info *info)
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)
{
@@ -394,6 +393,22 @@ bpf_elf_generic_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
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;
@@ -407,18 +422,15 @@ bpf_elf_generic_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
|| 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,
@@ -449,8 +461,8 @@ bpf_elf_generic_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
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;
}
diff --git a/gas/testsuite/gas/bpf/bpf.exp b/gas/testsuite/gas/bpf/bpf.exp
index 44b050e..dae8bd9 100644
--- a/gas/testsuite/gas/bpf/bpf.exp
+++ b/gas/testsuite/gas/bpf/bpf.exp
@@ -83,4 +83,7 @@ if {[istarget bpf*-*-*]} {
# Test that parser does not create undefined symbols
run_dump_test asm-extra-sym-1
+
+ # Test relocation installation
+ run_dump_test elf-relo-1
}
diff --git a/gas/testsuite/gas/bpf/elf-relo-1.d b/gas/testsuite/gas/bpf/elf-relo-1.d
new file mode 100644
index 0000000..4a1c794
--- /dev/null
+++ b/gas/testsuite/gas/bpf/elf-relo-1.d
@@ -0,0 +1,35 @@
+#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
diff --git a/gas/testsuite/gas/bpf/elf-relo-1.s b/gas/testsuite/gas/bpf/elf-relo-1.s
new file mode 100644
index 0000000..23424e0
--- /dev/null
+++ b/gas/testsuite/gas/bpf/elf-relo-1.s
@@ -0,0 +1,25 @@
+ .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