diff options
Diffstat (limited to 'lld/ELF/Symbols.cpp')
-rw-r--r-- | lld/ELF/Symbols.cpp | 27 |
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; |