Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 2 Oct 2018 21:20:45 +0000 (UTC)
From:      Mark Johnston <markj@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-11@freebsd.org
Subject:   svn commit: r339097 - in stable/11: contrib/llvm/tools/lld/ELF usr.bin/clang/lld
Message-ID:  <201810022120.w92LKjtA091967@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: markj
Date: Tue Oct  2 21:20:45 2018
New Revision: 339097
URL: https://svnweb.freebsd.org/changeset/base/339097

Log:
  MFC r338251:
  Add an lld option to emit PC-relative relocations for ifunc calls.

Modified:
  stable/11/contrib/llvm/tools/lld/ELF/Config.h
  stable/11/contrib/llvm/tools/lld/ELF/Driver.cpp
  stable/11/contrib/llvm/tools/lld/ELF/Relocations.cpp
  stable/11/contrib/llvm/tools/lld/ELF/Writer.cpp
  stable/11/usr.bin/clang/lld/ld.lld.1
Directory Properties:
  stable/11/   (props changed)

Modified: stable/11/contrib/llvm/tools/lld/ELF/Config.h
==============================================================================
--- stable/11/contrib/llvm/tools/lld/ELF/Config.h	Tue Oct  2 21:19:42 2018	(r339096)
+++ stable/11/contrib/llvm/tools/lld/ELF/Config.h	Tue Oct  2 21:20:45 2018	(r339097)
@@ -152,6 +152,7 @@ struct Configuration {
   bool ZCombreloc;
   bool ZExecstack;
   bool ZHazardplt;
+  bool ZIfuncnoplt;
   bool ZNocopyreloc;
   bool ZNodelete;
   bool ZNodlopen;

Modified: stable/11/contrib/llvm/tools/lld/ELF/Driver.cpp
==============================================================================
--- stable/11/contrib/llvm/tools/lld/ELF/Driver.cpp	Tue Oct  2 21:19:42 2018	(r339096)
+++ stable/11/contrib/llvm/tools/lld/ELF/Driver.cpp	Tue Oct  2 21:20:45 2018	(r339097)
@@ -669,6 +669,7 @@ void LinkerDriver::readConfigs(opt::InputArgList &Args
   Config->ZCombreloc = !hasZOption(Args, "nocombreloc");
   Config->ZExecstack = hasZOption(Args, "execstack");
   Config->ZHazardplt = hasZOption(Args, "hazardplt");
+  Config->ZIfuncnoplt = hasZOption(Args, "ifunc-noplt");
   Config->ZNocopyreloc = hasZOption(Args, "nocopyreloc");
   Config->ZNodelete = hasZOption(Args, "nodelete");
   Config->ZNodlopen = hasZOption(Args, "nodlopen");

Modified: stable/11/contrib/llvm/tools/lld/ELF/Relocations.cpp
==============================================================================
--- stable/11/contrib/llvm/tools/lld/ELF/Relocations.cpp	Tue Oct  2 21:19:42 2018	(r339096)
+++ stable/11/contrib/llvm/tools/lld/ELF/Relocations.cpp	Tue Oct  2 21:20:45 2018	(r339097)
@@ -374,6 +374,9 @@ static bool isStaticLinkTimeConstant(RelExpr E, RelTyp
                      R_PPC_PLT_OPD, R_TLSDESC_CALL, R_TLSDESC_PAGE, R_HINT>(E))
     return true;
 
+  if (Sym.isGnuIFunc() && Config->ZIfuncnoplt)
+    return false;
+
   // These never do, except if the entire file is position dependent or if
   // only the low bits are used.
   if (E == R_GOT || E == R_PLT || E == R_TLSDESC)
@@ -921,7 +924,9 @@ static void scanRelocs(InputSectionBase &Sec, ArrayRef
     // Strenghten or relax a PLT access.
     //
     // GNU ifunc symbols must be accessed via PLT because their addresses
-    // are determined by runtime.
+    // are determined by runtime. If the -z ifunc-noplt option is specified,
+    // we permit the optimization of ifunc calls by omitting the PLT entry
+    // and preserving relocations at ifunc call sites.
     //
     // On the other hand, if we know that a PLT entry will be resolved within
     // the same ELF module, we can skip PLT access and directly jump to the
@@ -929,7 +934,7 @@ static void scanRelocs(InputSectionBase &Sec, ArrayRef
     // all dynamic symbols that can be resolved within the executable will
     // actually be resolved that way at runtime, because the main exectuable
     // is always at the beginning of a search list. We can leverage that fact.
-    if (Sym.isGnuIFunc())
+    if (Sym.isGnuIFunc() && !Config->ZIfuncnoplt)
       Expr = toPlt(Expr);
     else if (!Preemptible && Expr == R_GOT_PC && !isAbsoluteValue(Sym))
       Expr =
@@ -1031,6 +1036,16 @@ static void scanRelocs(InputSectionBase &Sec, ArrayRef
     // uses Elf_Rel, since in that case the written value is the addend.
     if (IsConstant) {
       Sec.Relocations.push_back({Expr, Type, Offset, Addend, &Sym});
+      continue;
+    }
+
+    // Preserve relocations against ifuncs if we were asked to do so.
+    if (Sym.isGnuIFunc() && Config->ZIfuncnoplt) {
+      if (Config->IsRela)
+        InX::RelaDyn->addReloc({Type, &Sec, Offset, false, &Sym, Addend});
+      else
+        // Preserve the existing addend.
+        InX::RelaDyn->addReloc({Type, &Sec, Offset, false, &Sym, 0});
       continue;
     }
 

Modified: stable/11/contrib/llvm/tools/lld/ELF/Writer.cpp
==============================================================================
--- stable/11/contrib/llvm/tools/lld/ELF/Writer.cpp	Tue Oct  2 21:19:42 2018	(r339096)
+++ stable/11/contrib/llvm/tools/lld/ELF/Writer.cpp	Tue Oct  2 21:20:45 2018	(r339097)
@@ -1400,8 +1400,11 @@ template <class ELFT> void Writer<ELFT>::finalizeSecti
   applySynthetic({InX::EhFrame},
                  [](SyntheticSection *SS) { SS->finalizeContents(); });
 
-  for (Symbol *S : Symtab->getSymbols())
+  for (Symbol *S : Symtab->getSymbols()) {
     S->IsPreemptible |= computeIsPreemptible(*S);
+    if (S->isGnuIFunc() && Config->ZIfuncnoplt)
+      S->ExportDynamic = true;
+  }
 
   // Scan relocations. This must be done after every symbol is declared so that
   // we can correctly decide if a dynamic relocation is needed.

Modified: stable/11/usr.bin/clang/lld/ld.lld.1
==============================================================================
--- stable/11/usr.bin/clang/lld/ld.lld.1	Tue Oct  2 21:19:42 2018	(r339096)
+++ stable/11/usr.bin/clang/lld/ld.lld.1	Tue Oct  2 21:20:45 2018	(r339097)
@@ -25,7 +25,7 @@
 .\"
 .\" $FreeBSD$
 .\"
-.Dd February 7, 2018
+.Dd August 22, 2018
 .Dt LD.LLD 1
 .Os
 .Sh NAME
@@ -443,6 +443,13 @@ Make the main stack executable.
 Stack permissions are recorded in the
 .Dv PT_GNU_STACK
 segment.
+.It Cm ifunc-noplt
+Do not emit PLT entries for GNU ifuncs.
+Instead, preserve relocations for ifunc call sites so that they may
+be applied by a run-time loader.
+Note that this feature requires special loader support and will
+generally result in application crashes when used outside of freestanding
+environments.
 .It Cm muldefs
 Do not error if a symbol is defined multiple times.
 The first definition will be used.



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201810022120.w92LKjtA091967>