RISC-V: Fix linker problems with tls copy relocs.
authorJim Wilson <jimw@sifive.com>
Sun, 1 Sep 2019 04:22:36 +0000 (21:22 -0700)
committerJim Wilson <jimw@sifive.com>
Sun, 1 Sep 2019 04:22:36 +0000 (21:22 -0700)
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.

bfd/
PR 23825
* elfnn-riscv.c (riscv_elf_create_dynamic_sections): Add SEC_LOAD,
SEC_DATA, and SEC_HAS_CONTENTS to .tdata.dyn section.

bfd/ChangeLog
bfd/elfnn-riscv.c

index 1fc39dce5fd0acc23471d2dda48a1f2193474add..2b063837683660bea5bc7081cadfca6c35e7a887 100644 (file)
@@ -1,3 +1,9 @@
+2019-08-31  Jim Wilson  <jimw@sifive.com>
+
+       PR 23825
+       * elfnn-riscv.c (riscv_elf_create_dynamic_sections): Add SEC_LOAD,
+       SEC_DATA, and SEC_HAS_CONTENTS to .tdata.dyn section.
+
 2019-08-30  Jim Wilson  <jimw@sifive.com>
 
        * elfnn-riscv.c (riscv_elf_relocate_section): For unresolvable reloc
index ef2471eb9996667f9dd9dc1da8fc0b7280851ac3..1d04ae9b7eff7d3479c3aaf0401ac4badf31d096 100644 (file)
@@ -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_ALLOC | SEC_THREAD_LOCAL
+                                            | SEC_LOAD | SEC_DATA
+                                            | SEC_HAS_CONTENTS
                                             | SEC_LINKER_CREATED));
     }