]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
Treat `start_stop` symbols as having section size
authorMatthew Malcomson <matthew.malcomson@arm.com>
Mon, 7 Mar 2022 18:10:54 +0000 (18:10 +0000)
committerJohn Baldwin <jhb@FreeBSD.org>
Thu, 1 Sep 2022 22:59:25 +0000 (15:59 -0700)
There is special handling to ensure that symbols which look like they
are supposed to point at the start of a section are given a size to span
that entire section.

GNU ld has special `start_stop` symbols which are automatically provided
by the linker for sections where the output section and input section
share a name and that name is representable as a C identifier.
(see commit cbd0eecf2)

These special symbols represent the start and end address of the output
section.  These special symbols are used in much the same way in source
code as section-start symbols provided by the linker script.  Glibc uses
these for the __libc_atexit section containing pointers for functions to
run at exit.

This change accounts for these `start_stop` symbols by giving them the
size of the "remaining" range of the output section in the same way as
linker script defined symbols.  This means that the `start` symbols get
section-spanning bounds and the `stop` symbols get bounds of zero.

N.b. We will have to also account for these symbols in the
`resize_sections` function, but that's not done yet.

bfd/elfnn-aarch64.c
ld/testsuite/ld-aarch64/aarch64-elf.exp
ld/testsuite/ld-aarch64/morello-sec-start_stop-round.d [new file with mode: 0644]
ld/testsuite/ld-aarch64/morello-sec-start_stop-round.s [new file with mode: 0644]

index 0b8c924943512b787c8bce757e9ff33adf991ff3..20025275636b10d18fb16f3b9396c42ade4ebf60 100644 (file)
@@ -6459,6 +6459,15 @@ c64_symbol_section_adjustment (struct elf_link_hash_entry *h, bfd_vma value,
        }
       return C64_SYM_LDSCRIPT_DEF;
     }
+
+  if (h->start_stop)
+    {
+      asection *s = h->u2.start_stop_section->output_section;
+      BFD_ASSERT (s != NULL);
+      *ret_sec = s;
+      return C64_SYM_LDSCRIPT_DEF;
+    }
+
   return C64_SYM_STANDARD;
 }
 
index 5c0f3a728368c0dd667bf0355ec95cc1e02ac6d1..e8149425afe01171fc9ff56d170c88a33459c93c 100644 (file)
@@ -271,6 +271,7 @@ run_dump_test_lp64 "morello-sec-round-include-relro"
 run_dump_test_lp64 "morello-pcc-bounds-include-readonly"
 run_dump_test_lp64 "morello-sec-round-choose-linker-syms"
 run_dump_test_lp64 "morello-entry-point"
+run_dump_test_lp64 "morello-sec-start_stop-round"
 run_dump_test_lp64 "morello-tlsdesc"
 run_dump_test_lp64 "morello-tlsdesc-static"
 run_dump_test_lp64 "morello-tlsdesc-staticpie"
diff --git a/ld/testsuite/ld-aarch64/morello-sec-start_stop-round.d b/ld/testsuite/ld-aarch64/morello-sec-start_stop-round.d
new file mode 100644 (file)
index 0000000..3987696
--- /dev/null
@@ -0,0 +1,26 @@
+#as: -march=morello+c64
+#ld: -static
+#objdump: -d -j .data -j __libc_atexit
+
+.*:     file format .*
+
+
+Disassembly of section \.data:
+
+[0-9a-f]+ <__data_start>:
+#record: START_LIBC_ADDR
+.*:    ([0-9a-f]+)     .*
+.*:    00000000        .*
+.*:    00000008        .*
+.*:    02000000        .*
+
+Disassembly of section __libc_atexit:
+
+# Use `string tolower` because we know we only have a number so it won't change
+# anything.  That's needed because the current record/check implementation
+# doesn't have a way to define a replacement which is just the existing
+# variable.
+#check: START_LIBC string tolower $START_LIBC_ADDR
+00000000START_LIBC <__start___libc_atexit>:
+.*:    0000002a        .*
+.*:    00000000        .*
diff --git a/ld/testsuite/ld-aarch64/morello-sec-start_stop-round.s b/ld/testsuite/ld-aarch64/morello-sec-start_stop-round.s
new file mode 100644 (file)
index 0000000..b89273e
--- /dev/null
@@ -0,0 +1,10 @@
+.section __libc_atexit,"aw"
+       .xword 42
+.data
+atexit_location:
+       .chericap __start___libc_atexit
+.text
+.globl _start
+.type _start STT_FUNC
+_start:
+       add c0, c0, :lo12:atexit_location