[lld] r263386 - ELF: Redefine canBeDefined as a member function of SymbolBody.

Rui Ueyama via llvm-commits llvm-commits at lists.llvm.org
Sun Mar 13 12:48:19 PDT 2016


Author: ruiu
Date: Sun Mar 13 14:48:18 2016
New Revision: 263386

URL: http://llvm.org/viewvc/llvm-project?rev=263386&view=rev
Log:
ELF: Redefine canBeDefined as a member function of SymbolBody.

We want to make SymbolBody the central place to query symbol information.
This patch also renames canBePreempted to isPreemptible because I feel that
the latter is slightly better (the former is three words and the latter
is two words.)

Modified:
    lld/trunk/ELF/InputSection.cpp
    lld/trunk/ELF/OutputSections.cpp
    lld/trunk/ELF/OutputSections.h
    lld/trunk/ELF/Symbols.cpp
    lld/trunk/ELF/Symbols.h
    lld/trunk/ELF/Target.cpp
    lld/trunk/ELF/Writer.cpp

Modified: lld/trunk/ELF/InputSection.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/InputSection.cpp?rev=263386&r1=263385&r2=263386&view=diff
==============================================================================
--- lld/trunk/ELF/InputSection.cpp (original)
+++ lld/trunk/ELF/InputSection.cpp Sun Mar 13 14:48:18 2016
@@ -209,7 +209,7 @@ static uintX_t getMipsGotVA(const Symbol
       AHL += SignExtend64<16>(read32<E>(PairedLoc));
     return Out<ELFT>::Got->getMipsLocalPageAddr(SymVA + AHL);
   }
-  if (!canBePreempted(Body))
+  if (!Body.isPreemptible())
     // For non-local symbols GOT entries should contain their full
     // addresses. But if such symbol cannot be preempted, we do not
     // have to put them into the "global" part of GOT and use dynamic
@@ -274,7 +274,6 @@ void InputSectionBase<ELFT>::relocate(ui
     }
 
     uintX_t SymVA = Body.getVA<ELFT>(A);
-    bool CBP = canBePreempted(Body);
     uint8_t *PairedLoc = nullptr;
     if (Config->EMachine == EM_MIPS)
       PairedLoc = findMipsPairedReloc(Buf, &RI, Rels.end());
@@ -288,7 +287,7 @@ void InputSectionBase<ELFT>::relocate(ui
         SymVA = Body.getGotVA<ELFT>() + A;
       if (Body.IsTls)
         Type = Target->getTlsGotRel(Type);
-    } else if (Target->isSizeRel(Type) && CBP) {
+    } else if (Target->isSizeRel(Type) && Body.isPreemptible()) {
       // A SIZE relocation is supposed to set a symbol size, but if a symbol
       // can be preempted, the size at runtime may be different than link time.
       // If that's the case, we leave the field alone rather than filling it
@@ -296,7 +295,8 @@ void InputSectionBase<ELFT>::relocate(ui
       continue;
     } else if (Config->EMachine == EM_MIPS) {
       SymVA = adjustMipsSymVA<ELFT>(Type, *File, Body, AddrLoc, SymVA) + A;
-    } else if (!Target->needsCopyRel<ELFT>(Type, Body) && CBP) {
+    } else if (!Target->needsCopyRel<ELFT>(Type, Body) &&
+               Body.isPreemptible()) {
       continue;
     }
     uintX_t Size = Body.getSize<ELFT>();

Modified: lld/trunk/ELF/OutputSections.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/OutputSections.cpp?rev=263386&r1=263385&r2=263386&view=diff
==============================================================================
--- lld/trunk/ELF/OutputSections.cpp (original)
+++ lld/trunk/ELF/OutputSections.cpp Sun Mar 13 14:48:18 2016
@@ -182,7 +182,7 @@ template <class ELFT> void GotSection<EL
     // for detailed description:
     // ftp://www.linux-mips.org/pub/linux/mips/doc/ABI/mipsabi.pdf
     // As the first approach, we can just store addresses for all symbols.
-    if (Config->EMachine != EM_MIPS && canBePreempted(*B))
+    if (Config->EMachine != EM_MIPS && B->isPreemptible())
       continue; // The dynamic linker will take care of it.
     uintX_t VA = B->getVA<ELFT>();
     write<uintX_t, ELFT::TargetEndianness, sizeof(uintX_t)>(Entry, VA);
@@ -882,37 +882,6 @@ template <class ELFT> void OutputSection
   reassignOffsets();
 }
 
-// Returns true if a symbol can be replaced at load-time by a symbol
-// with the same name defined in other ELF executable or DSO.
-bool elf::canBePreempted(const SymbolBody &Body) {
-  if (Body.isLocal())
-    return false;
-
-  if (Body.isShared())
-    return true;
-
-  if (Body.isUndefined()) {
-    if (!Body.isWeak())
-      return true;
-
-    // Ideally the static linker should see a definition for every symbol, but
-    // shared object are normally allowed to have undefined references that the
-    // static linker never sees a definition for.
-    if (Config->Shared)
-      return true;
-
-    // Otherwise, just resolve to 0.
-    return false;
-  }
-  if (!Config->Shared)
-    return false;
-  if (Body.getVisibility() != STV_DEFAULT)
-    return false;
-  if (Config->Bsymbolic || (Config->BsymbolicFunctions && Body.IsFunc))
-    return false;
-  return true;
-}
-
 static void fill(uint8_t *Buf, size_t Size, ArrayRef<uint8_t> A) {
   size_t I = 0;
   for (; I + A.size() < Size; I += A.size())

Modified: lld/trunk/ELF/OutputSections.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/OutputSections.h?rev=263386&r1=263385&r2=263386&view=diff
==============================================================================
--- lld/trunk/ELF/OutputSections.h (original)
+++ lld/trunk/ELF/OutputSections.h Sun Mar 13 14:48:18 2016
@@ -47,8 +47,6 @@ getAddend(const typename llvm::object::E
   return Rel.r_addend;
 }
 
-bool canBePreempted(const SymbolBody &Body);
-
 bool isValidCIdentifier(StringRef S);
 
 // This represents a section in an output file.

Modified: lld/trunk/ELF/Symbols.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Symbols.cpp?rev=263386&r1=263385&r2=263386&view=diff
==============================================================================
--- lld/trunk/ELF/Symbols.cpp (original)
+++ lld/trunk/ELF/Symbols.cpp Sun Mar 13 14:48:18 2016
@@ -81,6 +81,38 @@ getSymVA(const SymbolBody &Body, typenam
   llvm_unreachable("invalid symbol kind");
 }
 
+// Returns true if a symbol can be replaced at load-time by a symbol
+// with the same name defined in other ELF executable or DSO.
+bool SymbolBody::isPreemptible() const {
+  if (isLocal())
+    return false;
+
+  if (isShared())
+    return true;
+
+  if (isUndefined()) {
+    if (!isWeak())
+      return true;
+
+    // Ideally the static linker should see a definition for every symbol, but
+    // shared object are normally allowed to have undefined references that the
+    // static linker never sees a definition for.
+    if (Config->Shared)
+      return true;
+
+    // Otherwise, just resolve to 0.
+    return false;
+  }
+
+  if (!Config->Shared)
+    return false;
+  if (getVisibility() != STV_DEFAULT)
+    return false;
+  if (Config->Bsymbolic || (Config->BsymbolicFunctions && IsFunc))
+    return false;
+  return true;
+}
+
 template <class ELFT> bool SymbolBody::isGnuIfunc() const {
   if (auto *D = dyn_cast<DefinedElf<ELFT>>(this))
     return D->Sym.getType() == STT_GNU_IFUNC;

Modified: lld/trunk/ELF/Symbols.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Symbols.h?rev=263386&r1=263385&r2=263386&view=diff
==============================================================================
--- lld/trunk/ELF/Symbols.h (original)
+++ lld/trunk/ELF/Symbols.h Sun Mar 13 14:48:18 2016
@@ -75,7 +75,7 @@ public:
   bool isShared() const { return SymbolKind == SharedKind; }
   bool isLocal() const { return IsLocal; }
   bool isUsedInRegularObj() const { return IsUsedInRegularObj; }
-
+  bool isPreemptible() const;
   template <class ELFT> bool isGnuIfunc() const;
 
   // Returns the symbol name.

Modified: lld/trunk/ELF/Target.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Target.cpp?rev=263386&r1=263385&r2=263386&view=diff
==============================================================================
--- lld/trunk/ELF/Target.cpp (original)
+++ lld/trunk/ELF/Target.cpp Sun Mar 13 14:48:18 2016
@@ -272,7 +272,7 @@ bool TargetInfo::canRelaxTls(uint32_t Ty
   // Initial-Exec relocs can be relaxed to Local-Exec if the symbol is locally
   // defined.
   if (isTlsInitialExecRel(Type))
-    return !canBePreempted(*S);
+    return !S->isPreemptible();
 
   return false;
 }
@@ -311,7 +311,7 @@ TargetInfo::PltNeed TargetInfo::needsPlt
                                          const SymbolBody &S) const {
   if (S.isGnuIfunc<ELFT>())
     return Plt_Explicit;
-  if (canBePreempted(S) && needsPltImpl(Type))
+  if (S.isPreemptible() && needsPltImpl(Type))
     return Plt_Explicit;
 
   // This handles a non PIC program call to function in a shared library.
@@ -464,7 +464,7 @@ bool X86TargetInfo::needsCopyRelImpl(uin
 
 bool X86TargetInfo::needsGot(uint32_t Type, SymbolBody &S) const {
   if (S.IsTls && Type == R_386_TLS_GD)
-    return Target->canRelaxTls(Type, &S) && canBePreempted(S);
+    return Target->canRelaxTls(Type, &S) && S.isPreemptible();
   if (Type == R_386_TLS_GOTIE || Type == R_386_TLS_IE)
     return !canRelaxTls(Type, &S);
   return Type == R_386_GOT32 || needsPlt<ELF32LE>(Type, S);
@@ -542,7 +542,7 @@ size_t X86TargetInfo::relaxTls(uint8_t *
                                const SymbolBody &S) const {
   switch (Type) {
   case R_386_TLS_GD:
-    if (canBePreempted(S))
+    if (S.isPreemptible())
       relocateTlsGdToIe(Loc, BufEnd, P, SA);
     else
       relocateTlsGdToLe(Loc, BufEnd, P, SA);
@@ -726,7 +726,7 @@ bool X86_64TargetInfo::refersToGotEntry(
 
 bool X86_64TargetInfo::needsGot(uint32_t Type, SymbolBody &S) const {
   if (Type == R_X86_64_TLSGD)
-    return Target->canRelaxTls(Type, &S) && canBePreempted(S);
+    return Target->canRelaxTls(Type, &S) && S.isPreemptible();
   if (Type == R_X86_64_GOTTPOFF)
     return !canRelaxTls(Type, &S);
   return refersToGotEntry(Type) || needsPlt<ELF64LE>(Type, S);
@@ -896,7 +896,7 @@ size_t X86_64TargetInfo::relaxTls(uint8_
     relocateTlsIeToLe(Loc, BufEnd, P, SA);
     return 0;
   case R_X86_64_TLSGD: {
-    if (canBePreempted(S))
+    if (S.isPreemptible())
       relocateTlsGdToIe(Loc, BufEnd, P, SA);
     else
       relocateTlsGdToLe(Loc, BufEnd, P, SA);
@@ -1463,7 +1463,7 @@ size_t AArch64TargetInfo::relaxTls(uint8
   case R_AARCH64_TLSDESC_LD64_LO12_NC:
   case R_AARCH64_TLSDESC_ADD_LO12_NC:
   case R_AARCH64_TLSDESC_CALL: {
-    if (canBePreempted(S))
+    if (S.isPreemptible())
       fatal("unsupported TLS optimization");
     uint64_t X = S.getVA<ELF64LE>();
     relocateTlsGdToLe(Type, Loc, BufEnd, P, X);

Modified: lld/trunk/ELF/Writer.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Writer.cpp?rev=263386&r1=263385&r2=263386&view=diff
==============================================================================
--- lld/trunk/ELF/Writer.cpp (original)
+++ lld/trunk/ELF/Writer.cpp Sun Mar 13 14:48:18 2016
@@ -290,7 +290,7 @@ static bool handleTlsRelocation(uint32_t
       }
       return true;
     }
-    if (!canBePreempted(Body))
+    if (!Body.isPreemptible())
       return true;
   }
   return false;
@@ -332,7 +332,7 @@ void Writer<ELFT>::scanRelocs(InputSecti
       if (auto *S = dyn_cast<SharedSymbol<ELFT>>(&Body))
         S->File->IsUsed = true;
 
-    bool CBP = canBePreempted(Body);
+    bool Preemptible = Body.isPreemptible();
     if (handleTlsRelocation<ELFT>(Type, Body, C, RI))
       continue;
 
@@ -341,7 +341,7 @@ void Writer<ELFT>::scanRelocs(InputSecti
                                     &Body, getAddend<ELFT>(RI)});
 
     // MIPS has a special rule to create GOTs for local symbols.
-    if (Config->EMachine == EM_MIPS && !CBP &&
+    if (Config->EMachine == EM_MIPS && !Preemptible &&
         (Type == R_MIPS_GOT16 || Type == R_MIPS_CALL16)) {
       // FIXME (simon): Do not add so many redundant entries.
       Out<ELFT>::Got->addMipsLocalEntry();
@@ -371,13 +371,13 @@ void Writer<ELFT>::scanRelocs(InputSecti
       if (Target->UseLazyBinding) {
         Out<ELFT>::GotPlt->addEntry(Body);
         Out<ELFT>::RelaPlt->addReloc(
-            {CBP ? Target->PltRel : Target->IRelativeRel,
-             DynamicReloc<ELFT>::Off_GotPlt, !CBP, &Body});
+            {Preemptible ? Target->PltRel : Target->IRelativeRel,
+             DynamicReloc<ELFT>::Off_GotPlt, !Preemptible, &Body});
       } else {
         Out<ELFT>::Got->addEntry(Body);
         Out<ELFT>::RelaDyn->addReloc(
-            {CBP ? Target->PltRel : Target->IRelativeRel,
-             DynamicReloc<ELFT>::Off_Got, !CBP, &Body});
+            {Preemptible ? Target->PltRel : Target->IRelativeRel,
+             DynamicReloc<ELFT>::Off_Got, !Preemptible, &Body});
       }
       continue;
     }
@@ -424,16 +424,16 @@ void Writer<ELFT>::scanRelocs(InputSecti
 
       bool Dynrel = Config->Shared && !Target->isRelRelative(Type) &&
                     !Target->isSizeRel(Type);
-      if (CBP || Dynrel) {
+      if (Preemptible || Dynrel) {
         uint32_t DynType;
         if (Body.IsTls)
           DynType = Target->TlsGotRel;
-        else if (CBP)
+        else if (Preemptible)
           DynType = Target->GotRel;
         else
           DynType = Target->RelativeRel;
         Out<ELFT>::RelaDyn->addReloc(
-            {DynType, DynamicReloc<ELFT>::Off_Got, !CBP, &Body});
+            {DynType, DynamicReloc<ELFT>::Off_Got, !Preemptible, &Body});
       }
       continue;
     }
@@ -456,7 +456,7 @@ void Writer<ELFT>::scanRelocs(InputSecti
         continue;
     }
 
-    if (CBP) {
+    if (Preemptible) {
       // We don't know anything about the finaly symbol. Just ask the dynamic
       // linker to handle the relocation for us.
       Out<ELFT>::RelaDyn->addReloc({Target->getDynRel(Type), &C, RI.r_offset,




More information about the llvm-commits mailing list