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: [COMMITTED] elf: work around a gcc bug in elf_get_dynamic_info
Date: Wed, 13 Jan 2021 13:38:38 +0000	[thread overview]
Message-ID: <20210113133838.9334-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
The bug is fixed on gcc-10 and not yet backported. gcc-9 is affected,
but the issue happens to not trigger in glibc, gcc-8 and older seems
to miscompile rtld.os.

Rewriting the affected code in elf_get_dynamic_info seems to make the
issue go away on <= gcc-9.

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).

Reviewed-by: Adhemerval Zanella  <adhemerval.zanella@linaro.org>
---
 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..d8ec32377d 100644
--- a/elf/get-dynamic-info.h
+++ b/elf/get-dynamic-info.h
@@ -30,8 +30,6 @@ auto
 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
@@ -39,39 +37,36 @@ elf_get_dynamic_info (struct link_map *l, ElfW(Dyn) *temp)
 #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 = VERSYMIDX (dyn->d_tag);
       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
-- 
2.17.1


                 reply	other threads:[~2021-01-13 13:38 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

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=20210113133838.9334-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).