]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
Add a size to __ehdr_start
authorMatthew Malcomson <matthew.malcomson@arm.com>
Thu, 17 Mar 2022 15:40:52 +0000 (15:40 +0000)
committerMatthew Malcomson <matthew.malcomson@arm.com>
Thu, 17 Mar 2022 15:41:08 +0000 (15:41 +0000)
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.

bfd/elf.c
ld/testsuite/ld-aarch64/aarch64-elf.exp
ld/testsuite/ld-aarch64/c64-ehdr-sized-reloc.d [new file with mode: 0644]
ld/testsuite/ld-aarch64/c64-ehdr-sized-reloc.s [new file with mode: 0644]

index 9a5b472cda2c953cae40d2dfcbce493048ed8168..279f15a3aefaa6e9048ee93a54575a2a06004ae1 100644 (file)
--- 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;
index f0d2048efc37c2df3f4dfea304c7f93f8fe3a169..adb0081720a48c984e246b838d6ccd0922fa1306 100644 (file)
@@ -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 (file)
index 0000000..41c3cff
--- /dev/null
@@ -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 (file)
index 0000000..3b750cf
--- /dev/null
@@ -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]