public inbox for libc-alpha@sourceware.org
 help / color / mirror / Atom feed
From: Szabolcs Nagy <szabolcs.nagy@arm.com>
To: libc-alpha@sourceware.org
Subject: [PATCH] elf: work around a gcc bug in elf_get_dynamic_info
Date: Mon, 11 Jan 2021 15:11:46 +0000	[thread overview]
Message-ID: <20210111151146.27850-1-szabolcs.nagy@arm.com> (raw)

Since commit 2f056e8a5dd4dc0f075413f931e82cede37d1057
"aarch64: define PI_STATIC_AND_HIDDEN",
building glibc with gcc-8 on aarch64 fails with

/BLD/elf/librtld.os: in function `elf_get_dynamic_info':
/SRC/elf/get-dynamic-info.h:70:(.text+0xad8): relocation truncated to
 fit: R_AARCH64_ADR_PREL_PG_HI21 against symbol `_rtld_local' defined
 in .data section in /BLD/elf/librtld.os

This is a gcc bug:
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=98618

Rewriting the affected code in elf_get_dynamic_info
seems to make this issue go away on old gcc.

The change makes the logic a bit clearer too (by
separating the index computation and array update)
and drops an older gcc workaround (since gcc 4.6
is no longer supported).
---
note: with new gcc the code generation only changes
slightly on aarch64 (the code becomes a bit smaller),
with old gcc the change is not a robust fix for the
issue but it seems to be be sufficient in my testing.

the change only expected to have minor effect on
other targets, since it's mostly cosmetic.

 elf/get-dynamic-info.h | 41 ++++++++++++++++++-----------------------
 1 file changed, 18 insertions(+), 23 deletions(-)

diff --git a/elf/get-dynamic-info.h b/elf/get-dynamic-info.h
index 4f9aac63de..d8b071dff5 100644
--- a/elf/get-dynamic-info.h
+++ b/elf/get-dynamic-info.h
@@ -28,52 +28,47 @@ static
 auto
 #endif
 inline void __attribute__ ((unused, always_inline))
 elf_get_dynamic_info (struct link_map *l, ElfW(Dyn) *temp)
 {
-  ElfW(Dyn) *dyn = l->l_ld;
-  ElfW(Dyn) **info;
 #if __ELF_NATIVE_CLASS == 32
   typedef Elf32_Word d_tag_utype;
 #elif __ELF_NATIVE_CLASS == 64
   typedef Elf64_Xword d_tag_utype;
 #endif
 
 #if !defined RTLD_BOOTSTRAP && !defined STATIC_PIE_BOOTSTRAP
-  if (dyn == NULL)
+  if (l->l_ld == NULL)
     return;
 #endif
 
-  info = l->l_info;
+  ElfW(Dyn) **info = l->l_info;
 
-  while (dyn->d_tag != DT_NULL)
+  for (ElfW(Dyn) *dyn = l->l_ld; dyn->d_tag != DT_NULL; dyn++)
     {
+      d_tag_utype i;
+
       if ((d_tag_utype) dyn->d_tag < DT_NUM)
-	info[dyn->d_tag] = dyn;
+	i = dyn->d_tag;
       else if (dyn->d_tag >= DT_LOPROC
 	       && dyn->d_tag < DT_LOPROC + DT_THISPROCNUM)
-	{
-	  /* This does not violate the array bounds of l->l_info, but
-	     gcc 4.6 on sparc somehow does not see this.  */
-	  DIAG_PUSH_NEEDS_COMMENT;
-	  DIAG_IGNORE_NEEDS_COMMENT (4.6,
-				     "-Warray-bounds");
-	  info[dyn->d_tag - DT_LOPROC + DT_NUM] = dyn;
-	  DIAG_POP_NEEDS_COMMENT;
-	}
+	i = dyn->d_tag - DT_LOPROC + DT_NUM;
       else if ((d_tag_utype) DT_VERSIONTAGIDX (dyn->d_tag) < DT_VERSIONTAGNUM)
-	info[VERSYMIDX (dyn->d_tag)] = dyn;
+	i = DT_VERSIONTAGIDX (dyn->d_tag) + DT_NUM + DT_THISPROCNUM;
       else if ((d_tag_utype) DT_EXTRATAGIDX (dyn->d_tag) < DT_EXTRANUM)
-	info[DT_EXTRATAGIDX (dyn->d_tag) + DT_NUM + DT_THISPROCNUM
-	     + DT_VERSIONTAGNUM] = dyn;
+	i = DT_EXTRATAGIDX (dyn->d_tag) + DT_NUM + DT_THISPROCNUM
+	    + DT_VERSIONTAGNUM;
       else if ((d_tag_utype) DT_VALTAGIDX (dyn->d_tag) < DT_VALNUM)
-	info[DT_VALTAGIDX (dyn->d_tag) + DT_NUM + DT_THISPROCNUM
-	     + DT_VERSIONTAGNUM + DT_EXTRANUM] = dyn;
+	i = DT_VALTAGIDX (dyn->d_tag) + DT_NUM + DT_THISPROCNUM
+	    + DT_VERSIONTAGNUM + DT_EXTRANUM;
       else if ((d_tag_utype) DT_ADDRTAGIDX (dyn->d_tag) < DT_ADDRNUM)
-	info[DT_ADDRTAGIDX (dyn->d_tag) + DT_NUM + DT_THISPROCNUM
-	     + DT_VERSIONTAGNUM + DT_EXTRANUM + DT_VALNUM] = dyn;
-      ++dyn;
+	i = DT_ADDRTAGIDX (dyn->d_tag) + DT_NUM + DT_THISPROCNUM
+	    + DT_VERSIONTAGNUM + DT_EXTRANUM + DT_VALNUM;
+      else
+	continue;
+
+      info[i] = dyn;
     }
 
 #define DL_RO_DYN_TEMP_CNT	8
 
 #ifndef DL_RO_DYN_SECTION
-- 
2.17.1


             reply	other threads:[~2021-01-11 15:12 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-01-11 15:11 Szabolcs Nagy [this message]
2021-01-12 17:52 ` Adhemerval Zanella
2021-01-13  9:10   ` Szabolcs Nagy
2021-01-13 12:53     ` Adhemerval Zanella

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20210111151146.27850-1-szabolcs.nagy@arm.com \
    --to=szabolcs.nagy@arm.com \
    --cc=libc-alpha@sourceware.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).