RISC-V: Fix linker problems with tls copy relocs.

Message ID 20190901042607.9445-1-jimw@sifive.com
State New
Headers show
  • RISC-V: Fix linker problems with tls copy relocs.
Related show

Commit Message

Jim Wilson Sept. 1, 2019, 4:26 a.m.
The linker doesn't allocate memory space for sections that are only SEC_ALLOC
and SEC_THREAD_LOCAL.  See the IS_TBSS test in ld/ldlang.c.  So we need to
pretend that .tdata.dyn sections have contents to get the right result.  It
will be marked this way anyways if there is a .tdata section to merge with.

Tested with cross binutils 32/64 elf/linux make and check with no regression.
Also tested with native binutils and glibc builds and checks, with no
regressions, and the glibc elf/tst-tls12 failure is fixed.



	PR 23825
	* elfnn-riscv.c (riscv_elf_create_dynamic_sections): Add SEC_LOAD,
	SEC_DATA, and SEC_HAS_CONTENTS to .tdata.dyn section.
 bfd/elfnn-riscv.c | 14 ++++++++++++++
 1 file changed, 14 insertions(+)



diff --git a/bfd/elfnn-riscv.c b/bfd/elfnn-riscv.c
index ef2471eb99..1d04ae9b7e 100644
--- a/bfd/elfnn-riscv.c
+++ b/bfd/elfnn-riscv.c
@@ -373,9 +373,23 @@  riscv_elf_create_dynamic_sections (bfd *dynobj,
   if (!bfd_link_pic (info))
+      /* Technically, this section doesn't have contents.  It is used as the
+	 target of TLS copy relocs, to copy TLS data from shared libraries into
+	 the executable.  However, if we don't mark it as loadable, then it
+	 matches the IS_TBSS test in ldlang.c, and there is no run-time address
+	 space allocated for it even though it has SEC_ALLOC.  That test is
+	 correct for .tbss, but not correct for this section.  There is also
+	 a second problem that having a section with no contents can only work
+	 if it comes after all sections with contents in the same segment,
+	 but the linker script does not guarantee that.  This is just mixed in
+	 with other .tdata.* sections.  We can fix both problems by lying and
+	 saying that there are contents.  This section is expected to be small
+	 so this should not cause a significant extra program startup cost.  */
       htab->sdyntdata =
 	bfd_make_section_anyway_with_flags (dynobj, ".tdata.dyn",
+					     | SEC_LOAD | SEC_DATA
+					     | SEC_HAS_CONTENTS
 					     | SEC_LINKER_CREATED));