aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthew Malcomson <matthew.malcomson@arm.com>2022-03-17 15:40:52 +0000
committerMatthew Malcomson <matthew.malcomson@arm.com>2022-03-17 15:41:08 +0000
commitdd0ed54c1a4e459f6f1a8331499eb63520d31a75 (patch)
treefb6ee8f5a7ceff172f2c4c310da6a8ccbc07fa6b
parent49432a1df068164f265ab9c6bf4d86f5e984762c (diff)
downloadgdb-dd0ed54c1a4e459f6f1a8331499eb63520d31a75.zip
gdb-dd0ed54c1a4e459f6f1a8331499eb63520d31a75.tar.gz
gdb-dd0ed54c1a4e459f6f1a8331499eb63520d31a75.tar.bz2
Add a size to __ehdr_start
This symbol is defined in a binary when there is a segment which contains both the file header and the program header. The symbol points at the file header. The point of this symbol is to allow the program to robustly examine its own output. Glibc uses this symbol. This symbol is currently not marked as a linker or linker script defined symbol, and hence does not get its bounds adjusted. The symbol is given zero size, and consequently any capability initialised as a relocation to this symbol is given zero bounds. In order to allow access to read the headers this symbol points at this patch adds a size to the symbol. We do not believe that the size of this symbol is used for anything other than CHERI bounds, so we believe that this is a safe change to make. Setting the size of the symbol means that c64_fixup_frag uses that size as the bounds to apply to a capability relocation pointing at that symbol. This allows access to the file and program headers loaded into memory. An alternative approach would be to *not* set the size of the symbol, but only change the bounds of the relocation generated. This would be done by checking for the `__ehdr_start' name in c64_fixup_frag and setting the size according to the `sizeof_ehdr' and `elf_program_header_size' values stored on the output BFD object. We chose the approach to set the size on the symbol for code-aesthetic reasons under the belief that having this size on the symbol in the final binary is a slight benefit in readability for a user and causes no downside. I do not believe that Morello lld sets the bounds of a capability to this symbol correctly. That issue has been raised separately.
-rw-r--r--bfd/elf.c1
-rw-r--r--ld/testsuite/ld-aarch64/aarch64-elf.exp1
-rw-r--r--ld/testsuite/ld-aarch64/c64-ehdr-sized-reloc.d18
-rw-r--r--ld/testsuite/ld-aarch64/c64-ehdr-sized-reloc.s11
4 files changed, 31 insertions, 0 deletions
diff --git a/bfd/elf.c b/bfd/elf.c
index 9a5b472..279f15a 100644
--- a/bfd/elf.c
+++ b/bfd/elf.c
@@ -6028,6 +6028,7 @@ assign_file_positions_for_load_sections (bfd *abfd,
hash->root.u.def.section = bfd_abs_section_ptr;
}
+ hash->size = bed->s->sizeof_ehdr + elf_program_header_size (abfd);
hash->root.type = bfd_link_hash_defined;
hash->def_regular = 1;
hash->non_elf = 0;
diff --git a/ld/testsuite/ld-aarch64/aarch64-elf.exp b/ld/testsuite/ld-aarch64/aarch64-elf.exp
index f0d2048..adb0081 100644
--- a/ld/testsuite/ld-aarch64/aarch64-elf.exp
+++ b/ld/testsuite/ld-aarch64/aarch64-elf.exp
@@ -258,6 +258,7 @@ run_dump_test_lp64 "morello-sizeless-local-syms"
run_dump_test_lp64 "morello-sizeless-global-syms"
run_dump_test_lp64 "morello-sizeless-got-syms"
run_dump_test_lp64 "morello-disallow-merged-binaries"
+run_dump_test_lp64 "c64-ehdr-sized-reloc"
run_dump_test_lp64 "morello-capinit"
run_dump_test_lp64 "morello-stubs"
diff --git a/ld/testsuite/ld-aarch64/c64-ehdr-sized-reloc.d b/ld/testsuite/ld-aarch64/c64-ehdr-sized-reloc.d
new file mode 100644
index 0000000..41c3cff
--- /dev/null
+++ b/ld/testsuite/ld-aarch64/c64-ehdr-sized-reloc.d
@@ -0,0 +1,18 @@
+#as: -march=morello+c64
+#ld: -shared
+#objdump: -dR -j .data
+
+.*: file format .*
+
+
+Disassembly of section \.data:
+
+00000000000[[:xdigit:]]* <val>:
+ ...
+ [[:xdigit:]]*: R_MORELLO_RELATIVE \*ABS\*
+# Want to check that the size is non-zero.
+# Check that using a negative line match to a zero size.
+# In fact, when this size is zero objdump doesn't even print a line here, but
+# that just adds extra robustness to our check.
+! .*: 00000000 \.word 0x00000000
+ .*: 01000000 .*
diff --git a/ld/testsuite/ld-aarch64/c64-ehdr-sized-reloc.s b/ld/testsuite/ld-aarch64/c64-ehdr-sized-reloc.s
new file mode 100644
index 0000000..3b750cf
--- /dev/null
+++ b/ld/testsuite/ld-aarch64/c64-ehdr-sized-reloc.s
@@ -0,0 +1,11 @@
+ .data
+ .global val
+val:
+ .chericap __ehdr_start
+ .size val, .-val
+
+ .align 4
+ .text
+ .global _start
+_start:
+ ldr c0, [c0, :got_lo12:val]