summaryrefslogtreecommitdiffstats
path: root/lld/ELF/Symbols.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lld/ELF/Symbols.cpp')
-rw-r--r--lld/ELF/Symbols.cpp27
1 files changed, 19 insertions, 8 deletions
diff --git a/lld/ELF/Symbols.cpp b/lld/ELF/Symbols.cpp
index f0572d2e3ba..d1588834886 100644
--- a/lld/ELF/Symbols.cpp
+++ b/lld/ELF/Symbols.cpp
@@ -78,7 +78,7 @@ static typename ELFT::uint getSymVA(const SymbolBody &Body, int64_t &Addend) {
return In<ELFT>::Common->OutSec->Addr + In<ELFT>::Common->OutSecOff +
cast<DefinedCommon>(Body).Offset;
case SymbolBody::SharedKind: {
- auto &SS = cast<SharedSymbol<ELFT>>(Body);
+ auto &SS = cast<SharedSymbol>(Body);
if (SS.NeedsCopy)
return SS.Section->OutSec->Addr + SS.Section->OutSecOff;
if (SS.NeedsPltAddr)
@@ -167,8 +167,8 @@ template <class ELFT> typename ELFT::uint SymbolBody::getSize() const {
return C->Size;
if (const auto *DR = dyn_cast<DefinedRegular<ELFT>>(this))
return DR->Size;
- if (const auto *S = dyn_cast<SharedSymbol<ELFT>>(this))
- return S->Sym.st_size;
+ if (const auto *S = dyn_cast<SharedSymbol>(this))
+ return S->getSize<ELFT>();
return 0;
}
@@ -237,6 +237,17 @@ DefinedCommon::DefinedCommon(StringRef Name, uint64_t Size, uint64_t Alignment,
this->File = File;
}
+// If a shared symbol is referred via a copy relocation, its alignment
+// becomes part of the ABI. This function returns a symbol alignment.
+// Because symbols don't have alignment attributes, we need to infer that.
+template <class ELFT> uint64_t SharedSymbol::getAlignment() const {
+ auto *File = cast<SharedFile<ELFT>>(this->File);
+ uint64_t SecAlign = File->getSection(getSym<ELFT>())->sh_addralign;
+ uint64_t SymValue = getSym<ELFT>().st_value;
+ uint64_t SymAlign = uint64_t(1) << countTrailingZeros(SymValue);
+ return std::min(SecAlign, SymAlign);
+}
+
InputFile *Lazy::fetch() {
if (auto *S = dyn_cast<LazyArchive>(this))
return S->fetch();
@@ -348,12 +359,12 @@ template uint32_t SymbolBody::template getSize<ELF32BE>() const;
template uint64_t SymbolBody::template getSize<ELF64LE>() const;
template uint64_t SymbolBody::template getSize<ELF64BE>() const;
-template class elf::SharedSymbol<ELF32LE>;
-template class elf::SharedSymbol<ELF32BE>;
-template class elf::SharedSymbol<ELF64LE>;
-template class elf::SharedSymbol<ELF64BE>;
-
template class elf::DefinedRegular<ELF32LE>;
template class elf::DefinedRegular<ELF32BE>;
template class elf::DefinedRegular<ELF64LE>;
template class elf::DefinedRegular<ELF64BE>;
+
+template uint64_t SharedSymbol::template getAlignment<ELF32LE>() const;
+template uint64_t SharedSymbol::template getAlignment<ELF32BE>() const;
+template uint64_t SharedSymbol::template getAlignment<ELF64LE>() const;
+template uint64_t SharedSymbol::template getAlignment<ELF64BE>() const;
OpenPOWER on IntegriCloud