[lld] r299615 - Create GOT and PLT entries early in scanRelocs().

Rui Ueyama via llvm-commits llvm-commits at lists.llvm.org
Wed Apr 5 20:30:51 PDT 2017


Author: ruiu
Date: Wed Apr  5 22:30:51 2017
New Revision: 299615

URL: http://llvm.org/viewvc/llvm-project?rev=299615&view=rev
Log:
Create GOT and PLT entries early in scanRelocs().

scanRelocs() does a lot of things. It fills InputSection's Relocations vector,
making a decision whether a TLS relocation should be relaxed or not,
and making a decision whether a GOT/PLT slot needs to be created or not.

They don't actually have to be done in a single loop. I want to separate
them so that some of them can be run concurently. As a first step, this
patch moves PLT/GOT slot assignment to beginning of the loop, so that
they just fall through to the next statements. This should make it clear
that that code doesn't affect other parts of the loop.

Modified:
    lld/trunk/ELF/Relocations.cpp

Modified: lld/trunk/ELF/Relocations.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Relocations.cpp?rev=299615&r1=299614&r2=299615&view=diff
==============================================================================
--- lld/trunk/ELF/Relocations.cpp (original)
+++ lld/trunk/ELF/Relocations.cpp Wed Apr  5 22:30:51 2017
@@ -81,9 +81,8 @@ static std::string getLocation(InputSect
 
 static bool refersToGotEntry(RelExpr Expr) {
   return isRelExprOneOf<R_GOT, R_GOT_OFF, R_MIPS_GOT_LOCAL_PAGE, R_MIPS_GOT_OFF,
-                        R_MIPS_GOT_OFF32, R_MIPS_TLSGD, R_MIPS_TLSLD,
-                        R_GOT_PAGE_PC, R_GOT_PC, R_GOT_FROM_END, R_TLSGD,
-                        R_TLSGD_PC, R_TLSDESC, R_TLSDESC_PAGE>(Expr);
+                        R_MIPS_GOT_OFF32, R_GOT_PAGE_PC, R_GOT_PC,
+                        R_GOT_FROM_END>(Expr);
 }
 
 static bool isPreemptible(const SymbolBody &Body, uint32_t Type) {
@@ -250,6 +249,9 @@ handleTlsRelocation(uint32_t Type, Symbo
         {R_RELAX_TLS_IE_TO_LE, Type, Offset, Addend, &Body});
     return 1;
   }
+
+  if (Expr == R_TLSDESC_CALL)
+    return 1;
   return 0;
 }
 
@@ -817,18 +819,47 @@ static void scanRelocs(InputSectionBase
                        R_GOTREL_FROM_END, R_PPC_TOC>(Expr))
       In<ELFT>::Got->HasGotOffRel = true;
 
+    // Read an addend.
     int64_t Addend = computeAddend<ELFT>(Rel, Sec.Data.data());
     if (Config->EMachine == EM_MIPS)
       Addend += computeMipsAddend<ELFT>(Rel, Sec, Expr, Body, End);
 
+    // Process some TLS relocations, including relaxing TLS relocations.
+    // Note that this function does not handle all TLS relocations.
     if (unsigned Processed =
             handleTlsRelocation<ELFT>(Type, Body, Sec, Offset, Addend, Expr)) {
       I += (Processed - 1);
       continue;
     }
 
-    if (Expr == R_TLSDESC_CALL)
-      continue;
+    // If a relocation needs PLT, we create PLT and GOTPLT slots for the symbol.
+    if (needsPlt(Expr) && !Body.isInPlt()) {
+      if (Body.isGnuIFunc() && !Preemptible)
+        addPltEntry(InX::Iplt, In<ELFT>::IgotPlt, In<ELFT>::RelaIplt,
+                    Target->IRelativeRel, Body, true);
+      else
+        addPltEntry(InX::Plt, In<ELFT>::GotPlt, In<ELFT>::RelaPlt,
+                    Target->PltRel, Body, !Preemptible);
+    }
+
+    // Create a GOT slot if a relocation needs GOT.
+    if (refersToGotEntry(Expr)) {
+      if (Config->EMachine == EM_MIPS) {
+        // MIPS ABI has special rules to process GOT entries and doesn't
+        // require relocation entries for them. A special case is TLS
+        // relocations. In that case dynamic loader applies dynamic
+        // relocations to initialize TLS GOT entries.
+        // See "Global Offset Table" in Chapter 5 in the following document
+        // for detailed description:
+        // ftp://www.linux-mips.org/pub/linux/mips/doc/ABI/mipsabi.pdf
+        In<ELFT>::MipsGot->addEntry(Body, Addend, Expr);
+        if (Body.isTls() && Body.isPreemptible())
+          In<ELFT>::RelaDyn->addReloc({Target->TlsGotRel, In<ELFT>::MipsGot,
+                                       Body.getGotOffset(), false, &Body, 0});
+      } else if (!Body.isInGot()) {
+        addGotEntry<ELFT>(Body, Preemptible);
+      }
+    }
 
     if (!needsPlt(Expr) && !refersToGotEntry(Expr) &&
         isPreemptible(Body, Type)) {
@@ -863,7 +894,7 @@ static void scanRelocs(InputSectionBase
     }
 
     // If the relocation points to something in the file, we can process it.
-    bool Constant =
+    bool IsConstant =
         isStaticLinkTimeConstant<ELFT>(Expr, Type, Body, Sec, Rel.r_offset);
 
     // If the output being produced is position independent, the final value
@@ -871,53 +902,15 @@ static void scanRelocs(InputSectionBase
     // dynamic linker. We can however do better than just copying the incoming
     // relocation. We can process some of it and and just ask the dynamic
     // linker to add the load address.
-    if (!Constant)
+    if (!IsConstant)
       In<ELFT>::RelaDyn->addReloc(
           {Target->RelativeRel, &Sec, Offset, true, &Body, Addend});
 
     // If the produced value is a constant, we just remember to write it
     // when outputting this section. We also have to do it if the format
     // uses Elf_Rel, since in that case the written value is the addend.
-    if (Constant || !RelTy::IsRela)
+    if (IsConstant || !RelTy::IsRela)
       Sec.Relocations.push_back({Expr, Type, Offset, Addend, &Body});
-
-    // At this point we are done with the relocated position. Some relocations
-    // also require us to create a got or plt entry.
-
-    // If a relocation needs PLT, we create a PLT and a GOT slot for the symbol.
-    if (needsPlt(Expr)) {
-      if (Body.isInPlt())
-        continue;
-
-      if (Body.isGnuIFunc() && !Preemptible)
-        addPltEntry(InX::Iplt, In<ELFT>::IgotPlt, In<ELFT>::RelaIplt,
-                    Target->IRelativeRel, Body, true);
-      else
-        addPltEntry(InX::Plt, In<ELFT>::GotPlt, In<ELFT>::RelaPlt,
-                    Target->PltRel, Body, !Preemptible);
-      continue;
-    }
-
-    if (refersToGotEntry(Expr)) {
-      if (Config->EMachine == EM_MIPS) {
-        // MIPS ABI has special rules to process GOT entries and doesn't
-        // require relocation entries for them. A special case is TLS
-        // relocations. In that case dynamic loader applies dynamic
-        // relocations to initialize TLS GOT entries.
-        // See "Global Offset Table" in Chapter 5 in the following document
-        // for detailed description:
-        // ftp://www.linux-mips.org/pub/linux/mips/doc/ABI/mipsabi.pdf
-        In<ELFT>::MipsGot->addEntry(Body, Addend, Expr);
-        if (Body.isTls() && Body.isPreemptible())
-          In<ELFT>::RelaDyn->addReloc({Target->TlsGotRel, In<ELFT>::MipsGot,
-                                       Body.getGotOffset(), false, &Body, 0});
-        continue;
-      }
-
-      if (!Body.isInGot())
-        addGotEntry<ELFT>(Body, Preemptible);
-      continue;
-    }
   }
 }
 




More information about the llvm-commits mailing list