Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

addpatch: binutils #2770

Merged
merged 1 commit into from
Jun 28, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
103 changes: 103 additions & 0 deletions binutils/riscv-dynamic-tls-reloc-pie.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
From f491758f183592cbf8113e02a2bebbd412ff7358 Mon Sep 17 00:00:00 2001
From: Nelson Chu <nelson@nelson.ba.rivosinc.com>
Date: Thu, 4 May 2023 17:08:50 +0800
Subject: [PATCH] [PR ld/22263][PR ld/25694] RISC-V: Avoid dynamic TLS relocs
in PIE.

Lots of targets already fixed the TEXTREL problem for TLS in PIE.

* For PR ld/25694,
In the check_reloc, refer to spare and loongarch, they don't need to reserve
any local dynamic reloc for TLS LE in pie/pde, and similar to other targets.
So it seems like riscv was too conservative to estimate the TLS LE before.
Just break and don't goto static_reloc for TLS LE in pie/pde can fix the
TEXTREL problem.

* For PR ld/22263,
The risc-v code for TLS GD/IE in the relocate_section seems same as MIPS port.
So similar to MIPS, pr22570, commits 9143e72c6d4d and 1cb83cac9a89, it seems
also the right way to do the same thing for risc-v.

On risc-v, fixes
FAIL: Build pr22263-1

RISC-V haven't supported the TLS transitions, so will need the same fix (use
bfd_link_dll) in the future.

bfd/
PR ld/22263
PR ld/25694
* elfnn-riscv.c (riscv_elf_check_relocs): Replace bfd_link_pic with
bfd_link_dll for TLS IE. Don't need to reserve the local dynamic
relocation for TLS LE in pie/pde, and report error in pic just like
before.
(riscv_elf_relocate_section): For TLS GD/IE, use bfd_link_dll rather
than !bfd_link_pic in determining the dynamic symbol index. Avoid
the index of -1.
---
bfd/elfnn-riscv.c | 25 +++++++++++--------------
1 file changed, 11 insertions(+), 14 deletions(-)

diff --git a/bfd/elfnn-riscv.c b/bfd/elfnn-riscv.c
index 4a5da7df3fe..ee2d19f7699 100644
--- a/bfd/elfnn-riscv.c
+++ b/bfd/elfnn-riscv.c
@@ -732,7 +732,7 @@ riscv_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
break;

case R_RISCV_TLS_GOT_HI20:
- if (bfd_link_pic (info))
+ if (bfd_link_dll (info))
info->flags |= DF_STATIC_TLS;
if (!riscv_elf_record_got_reference (abfd, info, h, r_symndx)
|| !riscv_elf_record_tls_type (abfd, h, r_symndx, GOT_TLS_IE))
@@ -787,11 +787,12 @@ riscv_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
goto static_reloc;

case R_RISCV_TPREL_HI20:
+ /* This is not allowed in the pic, but okay in pie. */
if (!bfd_link_executable (info))
return bad_static_reloc (abfd, r_type, h);
if (h != NULL)
riscv_elf_record_tls_type (abfd, h, r_symndx, GOT_TLS_LE);
- goto static_reloc;
+ break;

case R_RISCV_HI20:
if (bfd_link_pic (info))
@@ -2689,24 +2690,20 @@ riscv_elf_relocate_section (bfd *output_bfd,
if (htab->elf.srelgot == NULL)
abort ();

- if (h != NULL)
- {
- bool dyn, pic;
- dyn = htab->elf.dynamic_sections_created;
- pic = bfd_link_pic (info);
-
- if (WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, pic, h)
- && (!pic || !SYMBOL_REFERENCES_LOCAL (info, h)))
- indx = h->dynindx;
- }
+ bool dyn = elf_hash_table (info)->dynamic_sections_created;
+ if (h != NULL
+ && h->dynindx != -1
+ && WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, bfd_link_pic (info), h)
+ && (bfd_link_dll (info) || !SYMBOL_REFERENCES_LOCAL (info, h)))
+ indx = h->dynindx;

/* The GOT entries have not been initialized yet. Do it
now, and emit any relocations. */
- if ((bfd_link_pic (info) || indx != 0)
+ if ((bfd_link_dll (info) || indx != 0)
&& (h == NULL
|| ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
|| h->root.type != bfd_link_hash_undefweak))
- need_relocs = true;
+ need_relocs = true;

if (tls_type & GOT_TLS_GD)
{
--
2.40.1

108 changes: 108 additions & 0 deletions binutils/riscv-pr22263-1.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
From 53e0482788fa665f532936ba3637bc0fcde6db2c Mon Sep 17 00:00:00 2001
From: Nelson Chu <nelson@rivosinc.com>
Date: Sat, 27 May 2023 09:36:20 +0800
Subject: [PATCH] RISC-V: Avoid spurious R_RISCV_NONE for pr22263-1 test.

For TLS GD/IE, add the same condition with the relocate_section in the
allocate_dynrelocs, to make sure we won't reserve redundant spaces
for dynamic relocations since the conservative estimatation.

After applying this patch, ld seems no longer generate the spurious
R_RISCV_NONE for pr22263-1 test.

bfd/
PR ld/22263
* elfnn-riscv.c (RISCV_TLS_GD_IE_NEED_DYN_RELOC): New defined.
Set NEED_RELOC to true if TLS GD/IE needs dynamic relocations,
and INDX will be the dynamic index.
(allocate_dynrelocs): Don't reserve extra spaces in the rela.got
if RISCV_TLS_GD_IE_NEED_DYN_RELOC set need_reloc to false. This
condition needs to be same as relocate_section.
(relocate_section): Likewise, use the same condition as
allocate_dynrelocs.
---
bfd/elfnn-riscv.c | 41 ++++++++++++++++++++++++++++-------------
1 file changed, 28 insertions(+), 13 deletions(-)

diff --git a/bfd/elfnn-riscv.c b/bfd/elfnn-riscv.c
index ee2d19f7699..d02c4a29324 100644
--- a/bfd/elfnn-riscv.c
+++ b/bfd/elfnn-riscv.c
@@ -38,6 +38,25 @@
#define CHAR_BIT 8
#endif

+/* Set NEED_RELOC to true if TLS GD/IE needs dynamic relocations, and INDX will
+ be the dynamic index. PR22263, use the same check in allocate_dynrelocs and
+ riscv_elf_relocate_section for TLS GD/IE. */
+#define RISCV_TLS_GD_IE_NEED_DYN_RELOC(INFO, DYN, H, INDX, NEED_RELOC) \
+ do \
+ { \
+ if ((H) != NULL \
+ && (H)->dynindx != -1 \
+ && WILL_CALL_FINISH_DYNAMIC_SYMBOL ((DYN), bfd_link_pic (INFO), (H)) \
+ && (bfd_link_dll (INFO) || !SYMBOL_REFERENCES_LOCAL ((INFO), (H)))) \
+ (INDX) = (H)->dynindx; \
+ if ((bfd_link_dll (INFO) || (INDX) != 0) \
+ && ((H) == NULL \
+ || ELF_ST_VISIBILITY ((H)->other) == STV_DEFAULT \
+ || (H)->root.type != bfd_link_hash_undefweak)) \
+ (NEED_RELOC) = true; \
+ } \
+ while (0)
+
/* Internal relocations used exclusively by the relaxation pass. */
#define R_RISCV_DELETE (R_RISCV_max + 1)

@@ -1186,18 +1205,24 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
dyn = htab->elf.dynamic_sections_created;
if (tls_type & (GOT_TLS_GD | GOT_TLS_IE))
{
+ int indx = 0;
+ bool need_reloc = false;
+ RISCV_TLS_GD_IE_NEED_DYN_RELOC(info, dyn, h, indx, need_reloc);
+
/* TLS_GD needs two dynamic relocs and two GOT slots. */
if (tls_type & GOT_TLS_GD)
{
s->size += 2 * RISCV_ELF_WORD_BYTES;
- htab->elf.srelgot->size += 2 * sizeof (ElfNN_External_Rela);
+ if (need_reloc)
+ htab->elf.srelgot->size += 2 * sizeof (ElfNN_External_Rela);
}

/* TLS_IE needs one dynamic reloc and one GOT slot. */
if (tls_type & GOT_TLS_IE)
{
s->size += RISCV_ELF_WORD_BYTES;
- htab->elf.srelgot->size += sizeof (ElfNN_External_Rela);
+ if (need_reloc)
+ htab->elf.srelgot->size += sizeof (ElfNN_External_Rela);
}
}
else
@@ -2691,20 +2716,10 @@ riscv_elf_relocate_section (bfd *output_bfd,
abort ();

bool dyn = elf_hash_table (info)->dynamic_sections_created;
- if (h != NULL
- && h->dynindx != -1
- && WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, bfd_link_pic (info), h)
- && (bfd_link_dll (info) || !SYMBOL_REFERENCES_LOCAL (info, h)))
- indx = h->dynindx;
+ RISCV_TLS_GD_IE_NEED_DYN_RELOC (info, dyn, h, indx, need_relocs);

/* The GOT entries have not been initialized yet. Do it
now, and emit any relocations. */
- if ((bfd_link_dll (info) || indx != 0)
- && (h == NULL
- || ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
- || h->root.type != bfd_link_hash_undefweak))
- need_relocs = true;
-
if (tls_type & GOT_TLS_GD)
{
if (need_relocs)
--
2.40.1

33 changes: 33 additions & 0 deletions binutils/riscv64.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
diff --git PKGBUILD PKGBUILD
index de66f93..aa3c768 100644
--- PKGBUILD
+++ PKGBUILD
@@ -22,9 +22,13 @@ replaces=(binutils-multilib)
backup=('etc/gprofng.rc')
options=(staticlibs !distcc !ccache)
source=(git+https://sourceware.org/git/binutils-gdb.git#commit=${_commit}
- gold-warn-unsupported.patch)
+ gold-warn-unsupported.patch
+ riscv-dynamic-tls-reloc-pie.patch
+ riscv-pr22263-1.patch)
sha256sums=('SKIP'
- '2d430b66f84a19c154725ec535280c493be1d34f1a90f95208dce02fecd0e4e4')
+ '2d430b66f84a19c154725ec535280c493be1d34f1a90f95208dce02fecd0e4e4'
+ '2cc818549e86f56046bf6ee8ab9d2d067b81232c14c1f43c65075a7566da23cb'
+ '36135dd42bfd1c13796611e755f2d4e643b8db8871e6e4d8ed4f65fd19b4f4aa')
validpgpkeys=(3A24BC1E8FB409FA9F14371813FCEF89DD9E3C4F)

prepare() {
@@ -41,6 +45,12 @@ prepare() {
# unsupported targets. This allows the binutils to be built with
# BPF support enabled.
patch -Np1 -i "${srcdir}"/gold-warn-unsupported.patch
+
+ # Avoid dynamic TLS relocs in RISC-V
+ patch -Np1 -i "${srcdir}"/riscv-dynamic-tls-reloc-pie.patch
+
+ # Avoid spurious R_RISCV_NONE for pr22263-1 test
+ patch -Np1 -i "${srcdir}"/riscv-pr22263-1.patch
}

build() {