[PATCH] RISC-V: Optimize lui and auipc relaxations for undefweak symbols

Jim Wilson jimw@sifive.com
Fri Sep 20 22:26:00 GMT 2019


On Thu, Sep 19, 2019 at 11:24 PM Nelson Chu <nelson.chu@sifive.com> wrote:
> This patch remove the most redundant `undefined_weak` checking, and
> the uninitialized function problem is also resolved when building on
> Ubuntu 18.04.

This patch looks good.

When doing some last minute testing, I got some LTO errors that were
difficult to reproduce.  The problem turns out to be the part of the
patch that does
-         else if (h->root.u.def.section->output_section == NULL
-                  || (h->root.type != bfd_link_hash_defined
-                      && h->root.type != bfd_link_hash_defweak))
+         else if (!undefined_weak
+                  && (h->root.u.def.section->output_section == NULL
+                      || (h->root.type != bfd_link_hash_defined
+                          && h->root.type != bfd_link_hash_defweak)))
This causes us to fall through to code that does
    sym_sec = h->root.u.def.section
but this isn't valid for an undefined variable.  def.section happens
to overlap undef.abfd, and we end up with a abfd pointer instead of a
section pointer, which can cause a crash we end up with the wrong
garbage values there.  Usually it works, sometimes it crashes.  I
changed the code to add an explicit else if for undefined_weak to set
symval and sym_sec to reasonable values.

I committed the patch with my change, which is attached below.

I also rewrote the ChangeLog entries.  They are supposed to describe
the textual changes you are making.  I'm old school; I prefer
ChangeLog entries written like the ones I checked in.

Jim
-------------- next part --------------
diff --git a/bfd/elfnn-riscv.c b/bfd/elfnn-riscv.c
index 8d60d0ec99..4ffe6a36e6 100644
--- a/bfd/elfnn-riscv.c
+++ b/bfd/elfnn-riscv.c
@@ -4097,10 +4097,14 @@ _bfd_riscv_relax_section (bfd *abfd, asection *sec,
 	      sym_sec = htab->elf.splt;
 	      symval = h->plt.offset;
 	    }
-	  else if (!undefined_weak
-		   && (h->root.u.def.section->output_section == NULL
-		       || (h->root.type != bfd_link_hash_defined
-			   && h->root.type != bfd_link_hash_defweak)))
+	  else if (undefined_weak)
+	    {
+	      symval = 0;
+	      sym_sec = bfd_und_section_ptr;
+	    }
+	  else if (h->root.u.def.section->output_section == NULL
+		   || (h->root.type != bfd_link_hash_defined
+		       && h->root.type != bfd_link_hash_defweak))
 	    continue;
 	  else
 	    {


More information about the Binutils mailing list