[ELF] Generalize symbol type handling.
authorDavide Italiano <davide@freebsd.org>
Fri, 4 Mar 2016 01:55:28 +0000 (01:55 +0000)
committerDavide Italiano <davide@freebsd.org>
Fri, 4 Mar 2016 01:55:28 +0000 (01:55 +0000)
SymbolBody constructor and friends take isFunc and isTLS boolean arguments.
ELF symbols have already a type so than be easily passed as argument.
If we want to support another type, this scheme is not good enough, that is,
the current code logic would require passing another `bool isObject` around.
Up to two argument, this stretching exercise was a little bit goofy but
still acceptable, but with more types to support, is just too much, IMHO.

Change the code so that the type is passed instead.

Differential Revision:   http://reviews.llvm.org/D17871

llvm-svn: 262684

lld/ELF/InputSection.cpp
lld/ELF/SymbolTable.cpp
lld/ELF/Symbols.cpp
lld/ELF/Symbols.h
lld/ELF/Target.cpp
lld/ELF/Writer.cpp

index 66fc79c..fef9bb8 100644 (file)
@@ -282,7 +282,7 @@ void InputSectionBase<ELFT>::relocate(uint8_t *Buf, uint8_t *BufEnd,
         SymVA = Out<ELFT>::Got->getMipsLocalFullAddr(*Body);
       else
         SymVA = Body->getGotVA<ELFT>();
-      if (Body->IsTls)
+      if (Body->isTls())
         Type = Target->getTlsGotRel(Type);
     } else if (!Target->needsCopyRel<ELFT>(Type, *Body) &&
                isa<SharedSymbol<ELFT>>(*Body)) {
index 589a91e..182be51 100644 (file)
@@ -270,7 +270,7 @@ template <class ELFT> void SymbolTable<ELFT>::resolve(SymbolBody *New) {
     return;
   }
 
-  if (New->IsTls != Existing->IsTls) {
+  if (New->isTls() != Existing->isTls()) {
     error("TLS attribute mismatch for symbol: " + conflictMsg(Existing, New));
     return;
   }
@@ -331,7 +331,8 @@ void SymbolTable<ELFT>::addMemberFile(Undefined *Undef, Lazy *L) {
     L->setWeak();
 
     // FIXME: Do we need to copy more?
-    L->IsTls = Undef->IsTls;
+    if (Undef->isTls())
+      L->setTls();
     return;
   }
 
index a1e936e..49304e4 100644 (file)
@@ -61,7 +61,7 @@ typename ELFFile<ELFT>::uintX_t SymbolBody::getVA() const {
     auto *SS = cast<SharedSymbol<ELFT>>(this);
     if (!SS->NeedsCopyOrPltAddr)
       return 0;
-    if (SS->IsFunc)
+    if (SS->isFunc())
       return getPltVA<ELFT>();
     else
       return Out<ELFT>::Bss->getVA() + SS->OffsetInBss;
@@ -161,25 +161,24 @@ template <class ELFT> int SymbolBody::compare(SymbolBody *Other) {
 }
 
 Defined::Defined(Kind K, StringRef Name, bool IsWeak, uint8_t Visibility,
-                 bool IsTls, bool IsFunction)
-    : SymbolBody(K, Name, IsWeak, Visibility, IsTls, IsFunction) {}
+                 uint8_t Type)
+    : SymbolBody(K, Name, IsWeak, Visibility, Type) {}
 
 DefinedBitcode::DefinedBitcode(StringRef Name, bool IsWeak)
-    : Defined(DefinedBitcodeKind, Name, IsWeak, STV_DEFAULT, false, false) {}
+    : Defined(DefinedBitcodeKind, Name, IsWeak, STV_DEFAULT, 0 /* Type */) {}
 
 bool DefinedBitcode::classof(const SymbolBody *S) {
   return S->kind() == DefinedBitcodeKind;
 }
 
 Undefined::Undefined(SymbolBody::Kind K, StringRef N, bool IsWeak,
-                     uint8_t Visibility, bool IsTls)
-    : SymbolBody(K, N, IsWeak, Visibility, IsTls, /*IsFunction*/ false),
+                     uint8_t Visibility, uint8_t Type)
+    : SymbolBody(K, N, IsWeak, Visibility, Type),
       CanKeepUndefined(false) {}
 
 Undefined::Undefined(StringRef N, bool IsWeak, uint8_t Visibility,
                      bool CanKeepUndefined)
-    : Undefined(SymbolBody::UndefinedKind, N, IsWeak, Visibility,
-                /*IsTls*/ false) {
+    : Undefined(SymbolBody::UndefinedKind, N, IsWeak, Visibility, 0 /* Type */) {
   this->CanKeepUndefined = CanKeepUndefined;
 }
 
@@ -187,7 +186,7 @@ template <typename ELFT>
 UndefinedElf<ELFT>::UndefinedElf(StringRef N, const Elf_Sym &Sym)
     : Undefined(SymbolBody::UndefinedElfKind, N,
                 Sym.getBinding() == llvm::ELF::STB_WEAK, Sym.getVisibility(),
-                Sym.getType() == llvm::ELF::STT_TLS),
+                Sym.getType()),
       Sym(Sym) {}
 
 template <typename ELFT>
@@ -195,13 +194,13 @@ DefinedSynthetic<ELFT>::DefinedSynthetic(StringRef N, uintX_t Value,
                                          OutputSectionBase<ELFT> &Section,
                                          uint8_t Visibility)
     : Defined(SymbolBody::DefinedSyntheticKind, N, false, Visibility,
-              /*IsTls*/ false, /*IsFunction*/ false),
+              0 /* Type */),
       Value(Value), Section(Section) {}
 
 DefinedCommon::DefinedCommon(StringRef N, uint64_t Size, uint64_t Alignment,
                              bool IsWeak, uint8_t Visibility)
     : Defined(SymbolBody::DefinedCommonKind, N, IsWeak, Visibility,
-              /*IsTls*/ false, /*IsFunction*/ false) {
+              0 /* Type */) {
   MaxAlignment = Alignment;
   this->Size = Size;
 }
index ac67bf6..fc240b1 100644 (file)
@@ -84,7 +84,8 @@ public:
   bool isLazy() const { return SymbolKind == LazyKind; }
   bool isShared() const { return SymbolKind == SharedKind; }
   bool isUsedInRegularObj() const { return IsUsedInRegularObj; }
-  bool isFunc() const { return IsFunc; }
+  bool isFunc() const { return Type == llvm::ELF::STT_FUNC; }
+  bool isTls() const { return Type == llvm::ELF::STT_TLS; }
 
   // Returns the symbol name.
   StringRef getName() const { return Name; }
@@ -128,10 +129,10 @@ public:
 
 protected:
   SymbolBody(Kind K, StringRef Name, bool IsWeak, uint8_t Visibility,
-             bool IsTls, bool IsFunc)
+             uint8_t Type)
       : SymbolKind(K), IsWeak(IsWeak), Visibility(Visibility),
-        MustBeInDynSym(false), NeedsCopyOrPltAddr(false), IsTls(IsTls),
-        IsFunc(IsFunc), Name(Name) {
+        MustBeInDynSym(false), NeedsCopyOrPltAddr(false),
+        Type(Type), Name(Name) {
     IsUsedInRegularObj = K != SharedKind && K != LazyKind;
   }
 
@@ -153,10 +154,8 @@ public:
   // symbol or if the symbol should point to its plt entry.
   unsigned NeedsCopyOrPltAddr : 1;
 
-  unsigned IsTls : 1;
-
 protected:
-  unsigned IsFunc : 1;
+  uint8_t Type;
 
   StringRef Name;
   Symbol *Backref = nullptr;
@@ -165,8 +164,8 @@ protected:
 // The base class for any defined symbols.
 class Defined : public SymbolBody {
 public:
-  Defined(Kind K, StringRef Name, bool IsWeak, uint8_t Visibility, bool IsTls,
-          bool IsFunction);
+  Defined(Kind K, StringRef Name, bool IsWeak, uint8_t Visibility,
+          uint8_t Type);
   static bool classof(const SymbolBody *S) { return S->isDefined(); }
 };
 
@@ -178,8 +177,7 @@ protected:
 public:
   DefinedElf(Kind K, StringRef N, const Elf_Sym &Sym)
       : Defined(K, N, Sym.getBinding() == llvm::ELF::STB_WEAK,
-                Sym.getVisibility(), Sym.getType() == llvm::ELF::STT_TLS,
-                Sym.getType() == llvm::ELF::STT_FUNC),
+                Sym.getVisibility(), Sym.getType()),
         Sym(Sym) {}
 
   const Elf_Sym &Sym;
@@ -267,7 +265,7 @@ class Undefined : public SymbolBody {
   bool CanKeepUndefined;
 
 protected:
-  Undefined(Kind K, StringRef N, bool IsWeak, uint8_t Visibility, bool IsTls);
+  Undefined(Kind K, StringRef N, bool IsWeak, uint8_t Visibility, uint8_t Type);
 
 public:
   Undefined(StringRef N, bool IsWeak, uint8_t Visibility,
@@ -307,7 +305,7 @@ public:
   // OffsetInBss is significant only when needsCopy() is true.
   uintX_t OffsetInBss = 0;
 
-  bool needsCopy() const { return this->NeedsCopyOrPltAddr && !this->IsFunc; }
+  bool needsCopy() const { return this->NeedsCopyOrPltAddr && !this->isFunc(); }
 };
 
 // This class represents a symbol defined in an archive file. It is
@@ -319,7 +317,7 @@ class Lazy : public SymbolBody {
 public:
   Lazy(ArchiveFile *F, const llvm::object::Archive::Symbol S)
       : SymbolBody(LazyKind, S.getName(), false, llvm::ELF::STV_DEFAULT,
-                   /*IsTls*/ false, /*IsFunction*/ false),
+                   /* Type */ 0),
         File(F), Sym(S) {}
 
   static bool classof(const SymbolBody *S) { return S->kind() == LazyKind; }
@@ -328,6 +326,7 @@ public:
   // was already returned.
   std::unique_ptr<InputFile> getMember();
 
+  void setTls() { this->Type = llvm::ELF::STT_TLS; }
   void setWeak() { IsWeak = true; }
   void setUsedInRegularObj() { IsUsedInRegularObj = true; }
 
index 9672723..fd4647b 100644 (file)
@@ -452,7 +452,7 @@ bool X86TargetInfo::needsCopyRelImpl(uint32_t Type) const {
 }
 
 bool X86TargetInfo::needsGot(uint32_t Type, SymbolBody &S) const {
-  if (S.IsTls && Type == R_386_TLS_GD)
+  if (S.isTls() && Type == R_386_TLS_GD)
     return Target->canRelaxTls(Type, &S) && canBePreempted(&S);
   if (Type == R_386_TLS_GOTIE || Type == R_386_TLS_IE)
     return !canRelaxTls(Type, &S);
@@ -523,7 +523,7 @@ void X86TargetInfo::relocateOne(uint8_t *Loc, uint8_t *BufEnd, uint32_t Type,
 }
 
 bool X86TargetInfo::canRelaxTls(unsigned Type, const SymbolBody *S) const {
-  if (Config->Shared || (S && !S->IsTls))
+  if (Config->Shared || (S && !S->isTls()))
     return false;
   return Type == R_386_TLS_LDO_32 || Type == R_386_TLS_LDM ||
          Type == R_386_TLS_GD || (Type == R_386_TLS_IE && !canBePreempted(S)) ||
@@ -772,7 +772,7 @@ bool X86_64TargetInfo::isSizeRel(uint32_t Type) const {
 }
 
 bool X86_64TargetInfo::canRelaxTls(unsigned Type, const SymbolBody *S) const {
-  if (Config->Shared || (S && !S->IsTls))
+  if (Config->Shared || (S && !S->isTls()))
     return false;
   return Type == R_X86_64_TLSGD || Type == R_X86_64_TLSLD ||
          Type == R_X86_64_DTPOFF32 ||
@@ -1457,7 +1457,7 @@ void AArch64TargetInfo::relocateOne(uint8_t *Loc, uint8_t *BufEnd,
 }
 
 bool AArch64TargetInfo::canRelaxTls(unsigned Type, const SymbolBody *S) const {
-  if (Config->Shared || (S && !S->IsTls))
+  if (Config->Shared || (S && !S->isTls()))
     return false;
 
   // Global-Dynamic relocs can be relaxed to Initial-Exec if the target is
index 886883b..68c1007 100644 (file)
@@ -268,7 +268,7 @@ static bool handleTlsRelocation(unsigned Type, SymbolBody *Body,
     return true;
   }
 
-  if (!Body || !Body->IsTls)
+  if (!Body || !Body->isTls())
     return false;
 
   if (Target->isTlsGlobalDynamicRel(Type)) {
@@ -424,7 +424,7 @@ void Writer<ELFT>::scanRelocs(
       if (CBP || Dynrel) {
         uint32_t DynType;
         if (CBP)
-          DynType = Body->IsTls ? Target->TlsGotRel : Target->GotRel;
+          DynType = Body->isTls() ? Target->TlsGotRel : Target->GotRel;
         else
           DynType = Target->RelativeRel;
         Out<ELFT>::RelaDyn->addReloc(