[lld] r246326 - Add support for weak absolute symbols.
Rafael Espindola via llvm-commits
llvm-commits at lists.llvm.org
Fri Aug 28 13:19:35 PDT 2015
Author: rafael
Date: Fri Aug 28 15:19:34 2015
New Revision: 246326
URL: http://llvm.org/viewvc/llvm-project?rev=246326&view=rev
Log:
Add support for weak absolute symbols.
On ELF being weak is independent of what we call the kind of the symbol. So
this also makes the code simpler.
Modified:
lld/trunk/ELF/InputFiles.cpp
lld/trunk/ELF/Symbols.cpp
lld/trunk/ELF/Symbols.h
lld/trunk/ELF/Writer.cpp
lld/trunk/test/elf2/Inputs/resolution.s
lld/trunk/test/elf2/resolution.s
Modified: lld/trunk/ELF/InputFiles.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/InputFiles.cpp?rev=246326&r1=246325&r2=246326&view=diff
==============================================================================
--- lld/trunk/ELF/InputFiles.cpp (original)
+++ lld/trunk/ELF/InputFiles.cpp Fri Aug 28 15:19:34 2015
@@ -113,13 +113,10 @@ SymbolBody *elf2::ObjectFile<ELFT>::crea
default:
error("unexpected binding");
case STB_GLOBAL:
+ case STB_WEAK:
if (Sym->isUndefined())
return new (Alloc) Undefined<ELFT>(Name, *Sym);
return new (Alloc) DefinedRegular<ELFT>(Name, *Sym, *Chunks[SecIndex]);
- case STB_WEAK:
- if (Sym->isUndefined())
- return new (Alloc) UndefinedWeak<ELFT>(Name, *Sym);
- return new (Alloc) DefinedWeak<ELFT>(Name, *Sym, *Chunks[SecIndex]);
}
}
Modified: lld/trunk/ELF/Symbols.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Symbols.cpp?rev=246326&r1=246325&r2=246326&view=diff
==============================================================================
--- lld/trunk/ELF/Symbols.cpp (original)
+++ lld/trunk/ELF/Symbols.cpp Fri Aug 28 15:19:34 2015
@@ -20,27 +20,17 @@ using namespace lld::elf2;
// Returns 1, 0 or -1 if this symbol should take precedence
// over the Other, tie or lose, respectively.
int SymbolBody::compare(SymbolBody *Other) {
- Kind LK = kind();
- Kind RK = Other->kind();
+ std::pair<bool, bool> L(isDefined(), isWeak());
+ std::pair<bool, bool> R(Other->isDefined(), Other->isWeak());
- // Normalize so that the smaller kind is on the left.
- if (LK > RK)
+ // Normalize
+ if (L > R)
return -Other->compare(this);
- // First handle comparisons between two different kinds.
- if (LK != RK)
- return 1;
+ if (L != R)
+ return -1;
- // Now handle the case where the kinds are the same.
- switch (LK) {
- case DefinedAbsoluteKind:
- case DefinedRegularKind:
+ if (L.first && !L.second)
return 0;
- case DefinedWeakKind:
- case UndefinedKind:
- case UndefinedWeakKind:
- case UndefinedSyntheticKind:
- return 1;
- }
- llvm_unreachable("unknown symbol kind");
+ return 1;
}
Modified: lld/trunk/ELF/Symbols.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Symbols.h?rev=246326&r1=246325&r2=246326&view=diff
==============================================================================
--- lld/trunk/ELF/Symbols.h (original)
+++ lld/trunk/ELF/Symbols.h Fri Aug 28 15:19:34 2015
@@ -40,18 +40,19 @@ public:
DefinedFirst = 0,
DefinedRegularKind = 0,
DefinedAbsoluteKind = 1,
- DefinedWeakKind = 2,
- DefinedLast = 2,
- UndefinedWeakKind = 3,
- UndefinedKind = 4,
- UndefinedSyntheticKind = 5
+ DefinedLast = 1,
+ UndefinedKind = 2,
+ UndefinedSyntheticKind = 3
};
Kind kind() const { return static_cast<Kind>(SymbolKind); }
- bool isStrongUndefined() {
+ bool isWeak() const { return IsWeak; }
+ bool isUndefined() const {
return SymbolKind == UndefinedKind || SymbolKind == UndefinedSyntheticKind;
}
+ bool isDefined() const { return !isUndefined(); }
+ bool isStrongUndefined() { return !IsWeak && isUndefined(); }
// Returns the symbol name.
StringRef getName() const { return Name; }
@@ -71,10 +72,12 @@ public:
int compare(SymbolBody *Other);
protected:
- SymbolBody(Kind K, StringRef Name) : SymbolKind(K), Name(Name) {}
+ SymbolBody(Kind K, StringRef Name, bool IsWeak)
+ : SymbolKind(K), IsWeak(IsWeak), Name(Name) {}
protected:
const unsigned SymbolKind : 8;
+ const unsigned IsWeak : 1;
StringRef Name;
Symbol *Backref = nullptr;
};
@@ -90,7 +93,8 @@ template <class ELFT> class ELFSymbolBod
protected:
typedef typename llvm::object::ELFFile<ELFT>::Elf_Sym Elf_Sym;
ELFSymbolBody(Kind K, StringRef Name, const Elf_Sym &Sym)
- : SymbolBody(K, Name), Sym(Sym) {}
+ : SymbolBody(K, Name, Sym.getBinding() == llvm::ELF::STB_WEAK), Sym(Sym) {
+ }
public:
const Elf_Sym &Sym;
@@ -113,6 +117,8 @@ protected:
public:
explicit Defined(Kind K, StringRef N, const Elf_Sym &Sym)
: ELFSymbolBody<ELFT>(K, N, Sym) {}
+
+ static bool classof(const SymbolBody *S) { return S->isDefined(); }
};
template <class ELFT> class DefinedAbsolute : public Defined<ELFT> {
@@ -122,63 +128,37 @@ template <class ELFT> class DefinedAbsol
public:
explicit DefinedAbsolute(StringRef N, const Elf_Sym &Sym)
: Defined<ELFT>(Base::DefinedAbsoluteKind, N, Sym) {}
-};
-
-template <class ELFT> class DefinedInSection : public Defined<ELFT> {
- typedef ELFSymbolBody<ELFT> Base;
- typedef typename Base::Kind Kind;
-
-public:
- typedef typename Base::Elf_Sym Elf_Sym;
-
- explicit DefinedInSection(Kind K, StringRef N, const Elf_Sym &Sym,
- SectionChunk<ELFT> &Section)
- : Defined<ELFT>(K, N, Sym), Section(Section) {}
static bool classof(const SymbolBody *S) {
- Kind K = S->kind();
- return Base::DefinedFirst <= K && K <= Base::DefinedLast;
+ return S->kind() == Base::DefinedAbsoluteKind;
}
-
- const SectionChunk<ELFT> &Section;
};
// Regular defined symbols read from object file symbol tables.
-template <class ELFT> class DefinedRegular : public DefinedInSection<ELFT> {
+template <class ELFT> class DefinedRegular : public Defined<ELFT> {
typedef Defined<ELFT> Base;
typedef typename Base::Elf_Sym Elf_Sym;
public:
explicit DefinedRegular(StringRef N, const Elf_Sym &Sym,
SectionChunk<ELFT> &Section)
- : DefinedInSection<ELFT>(Base::DefinedRegularKind, N, Sym, Section) {}
+ : Defined<ELFT>(Base::DefinedRegularKind, N, Sym), Section(Section) {}
static bool classof(const SymbolBody *S) {
return S->kind() == Base::DefinedRegularKind;
}
-};
-template <class ELFT> class DefinedWeak : public DefinedInSection<ELFT> {
- typedef Defined<ELFT> Base;
- typedef typename Base::Elf_Sym Elf_Sym;
-
-public:
- explicit DefinedWeak(StringRef N, const Elf_Sym &Sym,
- SectionChunk<ELFT> &Section)
- : DefinedInSection<ELFT>(Base::DefinedWeakKind, N, Sym, Section) {}
-
- static bool classof(const SymbolBody *S) {
- return S->kind() == Base::DefinedWeakKind;
- }
+ const SectionChunk<ELFT> &Section;
};
// Undefined symbols.
class SyntheticUndefined : public SymbolBody {
public:
- explicit SyntheticUndefined(StringRef N) : SymbolBody(UndefinedKind, N) {}
+ explicit SyntheticUndefined(StringRef N)
+ : SymbolBody(UndefinedKind, N, false) {}
static bool classof(const SymbolBody *S) {
- return S->kind() == UndefinedKind;
+ return S->kind() == UndefinedSyntheticKind;
}
};
@@ -195,19 +175,6 @@ public:
}
};
-template <class ELFT> class UndefinedWeak : public ELFSymbolBody<ELFT> {
- typedef ELFSymbolBody<ELFT> Base;
- typedef typename Base::Elf_Sym Elf_Sym;
-
-public:
- explicit UndefinedWeak(StringRef N, const Elf_Sym &Sym)
- : ELFSymbolBody<ELFT>(Base::UndefinedWeakKind, N, Sym) {}
-
- static bool classof(const SymbolBody *S) {
- return S->kind() == Base::UndefinedWeakKind;
- }
-};
-
} // namespace elf2
} // namespace lld
Modified: lld/trunk/ELF/Writer.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Writer.cpp?rev=246326&r1=246325&r2=246326&view=diff
==============================================================================
--- lld/trunk/ELF/Writer.cpp (original)
+++ lld/trunk/ELF/Writer.cpp Fri Aug 28 15:19:34 2015
@@ -246,7 +246,7 @@ template <class ELFT> void OutputSection
if (!Body)
continue;
// Skip undefined weak for now.
- if (isa<UndefinedWeak<ELFT>>(Body))
+ if (isa<Undefined<ELFT>>(Body) && Body->isWeak())
continue;
if (!isa<DefinedRegular<ELFT>>(Body))
error(Twine("Can't relocate symbol ") + Body->getName());
@@ -300,18 +300,17 @@ template <class ELFT> void SymbolTableSe
const Elf_Sym *InputSym = nullptr;
switch (Body->kind()) {
- case SymbolBody::UndefinedKind:
case SymbolBody::UndefinedSyntheticKind:
llvm_unreachable("Should be defined by now");
- case SymbolBody::DefinedWeakKind:
case SymbolBody::DefinedRegularKind: {
- auto *Def = cast<DefinedInSection<ELFT>>(Body);
+ auto *Def = cast<DefinedRegular<ELFT>>(Body);
InputSym = &Def->Sym;
Section = &Def->Section;
break;
}
+ case SymbolBody::UndefinedKind:
+ assert(Body->isWeak() && "Should be defined by now");
case SymbolBody::DefinedAbsoluteKind:
- case SymbolBody::UndefinedWeakKind:
InputSym = &cast<ELFSymbolBody<ELFT>>(Body)->Sym;
break;
}
Modified: lld/trunk/test/elf2/Inputs/resolution.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf2/Inputs/resolution.s?rev=246326&r1=246325&r2=246326&view=diff
==============================================================================
--- lld/trunk/test/elf2/Inputs/resolution.s (original)
+++ lld/trunk/test/elf2/Inputs/resolution.s Fri Aug 28 15:19:34 2015
@@ -8,3 +8,6 @@ _start:
.weak bar
bar:
+
+.weak abs
+abs = 123
Modified: lld/trunk/test/elf2/resolution.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf2/resolution.s?rev=246326&r1=246325&r2=246326&view=diff
==============================================================================
--- lld/trunk/test/elf2/resolution.s (original)
+++ lld/trunk/test/elf2/resolution.s Fri Aug 28 15:19:34 2015
@@ -16,3 +16,6 @@ foo:
.weak zed
.long zed
+
+.global abs
+abs = 123
More information about the llvm-commits
mailing list