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

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.
This commit is contained in:
Jim Wilson
2019-08-31 21:22:36 -07:00
parent 5d2c57a3b7
commit 3e7bd7f241
2 changed files with 20 additions and 0 deletions

View 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

View 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));
}