forked from OSchip/llvm-project
Pass symbol attributes instead of ElfSym to Shared symbol ctor.
This change allows us to use less templates for Shared symbol and the functions that deals with shared symbols. llvm-svn: 316841
This commit is contained in:
parent
40f0584f08
commit
7f9694a42d
|
@ -514,11 +514,9 @@ template <class ELFT> void ObjFile<ELFT>::initializeSymbols() {
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class ELFT>
|
template <class ELFT>
|
||||||
InputSectionBase *ObjFile<ELFT>::getSection(const Elf_Sym &Sym) const {
|
InputSectionBase *ObjFile<ELFT>::getSection(uint32_t Index) const {
|
||||||
uint32_t Index = this->getSectionIndex(Sym);
|
|
||||||
if (Index == 0)
|
if (Index == 0)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
if (Index >= this->Sections.size())
|
if (Index >= this->Sections.size())
|
||||||
fatal(toString(this) + ": invalid section index: " + Twine(Index));
|
fatal(toString(this) + ": invalid section index: " + Twine(Index));
|
||||||
|
|
||||||
|
@ -533,7 +531,7 @@ InputSectionBase *ObjFile<ELFT>::getSection(const Elf_Sym &Sym) const {
|
||||||
template <class ELFT>
|
template <class ELFT>
|
||||||
SymbolBody *ObjFile<ELFT>::createSymbolBody(const Elf_Sym *Sym) {
|
SymbolBody *ObjFile<ELFT>::createSymbolBody(const Elf_Sym *Sym) {
|
||||||
int Binding = Sym->getBinding();
|
int Binding = Sym->getBinding();
|
||||||
InputSectionBase *Sec = getSection(*Sym);
|
InputSectionBase *Sec = getSection(this->getSectionIndex(*Sym));
|
||||||
|
|
||||||
uint8_t StOther = Sym->st_other;
|
uint8_t StOther = Sym->st_other;
|
||||||
uint8_t Type = Sym->getType();
|
uint8_t Type = Sym->getType();
|
||||||
|
@ -629,14 +627,6 @@ SharedFile<ELFT>::SharedFile(MemoryBufferRef M, StringRef DefaultSoName)
|
||||||
: ELFFileBase<ELFT>(Base::SharedKind, M), SoName(DefaultSoName),
|
: ELFFileBase<ELFT>(Base::SharedKind, M), SoName(DefaultSoName),
|
||||||
AsNeeded(Config->AsNeeded) {}
|
AsNeeded(Config->AsNeeded) {}
|
||||||
|
|
||||||
template <class ELFT>
|
|
||||||
const typename ELFT::Shdr *
|
|
||||||
SharedFile<ELFT>::getSection(const Elf_Sym &Sym) const {
|
|
||||||
return check(
|
|
||||||
this->getObj().getSection(&Sym, this->ELFSyms, this->SymtabSHNDX),
|
|
||||||
toString(this));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Partially parse the shared object file so that we can call
|
// Partially parse the shared object file so that we can call
|
||||||
// getSoName on this object.
|
// getSoName on this object.
|
||||||
template <class ELFT> void SharedFile<ELFT>::parseSoName() {
|
template <class ELFT> void SharedFile<ELFT>::parseSoName() {
|
||||||
|
@ -735,6 +725,10 @@ template <class ELFT> void SharedFile<ELFT>::parseRest() {
|
||||||
const Elf_Versym *Versym = nullptr;
|
const Elf_Versym *Versym = nullptr;
|
||||||
std::vector<const Elf_Verdef *> Verdefs = parseVerdefs(Versym);
|
std::vector<const Elf_Verdef *> Verdefs = parseVerdefs(Versym);
|
||||||
|
|
||||||
|
ArrayRef<Elf_Shdr> Sections =
|
||||||
|
check(this->getObj().sections(), toString(this));
|
||||||
|
|
||||||
|
// Add symbols to the symbol table.
|
||||||
Elf_Sym_Range Syms = this->getGlobalELFSyms();
|
Elf_Sym_Range Syms = this->getGlobalELFSyms();
|
||||||
for (const Elf_Sym &Sym : Syms) {
|
for (const Elf_Sym &Sym : Syms) {
|
||||||
unsigned VersymIndex = 0;
|
unsigned VersymIndex = 0;
|
||||||
|
@ -765,15 +759,25 @@ template <class ELFT> void SharedFile<ELFT>::parseRest() {
|
||||||
V = Verdefs[VersymIndex];
|
V = Verdefs[VersymIndex];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// We do not usually care about alignments of data in shared object
|
||||||
|
// files because the loader takes care of it. However, if we promote a
|
||||||
|
// DSO symbol to point to .bss due to copy relocation, we need to keep
|
||||||
|
// the original alignment requirements. We infer it here.
|
||||||
|
uint32_t Alignment = 1 << countTrailingZeros((uint64_t)Sym.st_value);
|
||||||
|
if (0 < Sym.st_shndx && Sym.st_shndx < Sections.size()) {
|
||||||
|
uint32_t SecAlign = Sections[Sym.st_shndx].sh_addralign;
|
||||||
|
Alignment = std::min(Alignment, SecAlign);
|
||||||
|
}
|
||||||
|
|
||||||
if (!Hidden)
|
if (!Hidden)
|
||||||
Symtab->addShared(Name, this, Sym, V);
|
Symtab->addShared(Name, this, Sym, Alignment, V);
|
||||||
|
|
||||||
// Also add the symbol with the versioned name to handle undefined symbols
|
// Also add the symbol with the versioned name to handle undefined symbols
|
||||||
// with explicit versions.
|
// with explicit versions.
|
||||||
if (V) {
|
if (V) {
|
||||||
StringRef VerName = this->StringTable.data() + V->getAux()->vda_name;
|
StringRef VerName = this->StringTable.data() + V->getAux()->vda_name;
|
||||||
Name = Saver.save(Name + "@" + VerName);
|
Name = Saver.save(Name + "@" + VerName);
|
||||||
Symtab->addShared(Name, this, Sym, V);
|
Symtab->addShared(Name, this, Sym, Alignment, V);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -167,7 +167,7 @@ public:
|
||||||
ObjFile(MemoryBufferRef M, StringRef ArchiveName);
|
ObjFile(MemoryBufferRef M, StringRef ArchiveName);
|
||||||
void parse(llvm::DenseSet<llvm::CachedHashStringRef> &ComdatGroups);
|
void parse(llvm::DenseSet<llvm::CachedHashStringRef> &ComdatGroups);
|
||||||
|
|
||||||
InputSectionBase *getSection(const Elf_Sym &Sym) const;
|
InputSectionBase *getSection(uint32_t Index) const;
|
||||||
|
|
||||||
SymbolBody &getSymbolBody(uint32_t SymbolIndex) const {
|
SymbolBody &getSymbolBody(uint32_t SymbolIndex) const {
|
||||||
if (SymbolIndex >= this->Symbols.size())
|
if (SymbolIndex >= this->Symbols.size())
|
||||||
|
@ -294,7 +294,6 @@ template <class ELFT> class SharedFile : public ELFFileBase<ELFT> {
|
||||||
public:
|
public:
|
||||||
std::string SoName;
|
std::string SoName;
|
||||||
|
|
||||||
const Elf_Shdr *getSection(const Elf_Sym &Sym) const;
|
|
||||||
llvm::ArrayRef<StringRef> getUndefinedSymbols() { return Undefs; }
|
llvm::ArrayRef<StringRef> getUndefinedSymbols() { return Undefs; }
|
||||||
|
|
||||||
static bool classof(const InputFile *F) {
|
static bool classof(const InputFile *F) {
|
||||||
|
|
|
@ -49,7 +49,7 @@ static void writeHeader(raw_ostream &OS, uint64_t Addr, uint64_t Size,
|
||||||
static std::string indent(int Depth) { return std::string(Depth * 8, ' '); }
|
static std::string indent(int Depth) { return std::string(Depth * 8, ' '); }
|
||||||
|
|
||||||
// Returns a list of all symbols that we want to print out.
|
// Returns a list of all symbols that we want to print out.
|
||||||
template <class ELFT> static std::vector<Defined *> getSymbols() {
|
static std::vector<Defined *> getSymbols() {
|
||||||
std::vector<Defined *> V;
|
std::vector<Defined *> V;
|
||||||
for (InputFile *File : ObjectFiles) {
|
for (InputFile *File : ObjectFiles) {
|
||||||
for (SymbolBody *B : File->getSymbols()) {
|
for (SymbolBody *B : File->getSymbols()) {
|
||||||
|
@ -90,13 +90,12 @@ static SymbolMapTy getSectionSyms(ArrayRef<Defined *> Syms) {
|
||||||
// Construct a map from symbols to their stringified representations.
|
// Construct a map from symbols to their stringified representations.
|
||||||
// Demangling symbols (which is what toString() does) is slow, so
|
// Demangling symbols (which is what toString() does) is slow, so
|
||||||
// we do that in batch using parallel-for.
|
// we do that in batch using parallel-for.
|
||||||
template <class ELFT>
|
|
||||||
static DenseMap<Defined *, std::string>
|
static DenseMap<Defined *, std::string>
|
||||||
getSymbolStrings(ArrayRef<Defined *> Syms) {
|
getSymbolStrings(ArrayRef<Defined *> Syms) {
|
||||||
std::vector<std::string> Str(Syms.size());
|
std::vector<std::string> Str(Syms.size());
|
||||||
parallelForEachN(0, Syms.size(), [&](size_t I) {
|
parallelForEachN(0, Syms.size(), [&](size_t I) {
|
||||||
raw_string_ostream OS(Str[I]);
|
raw_string_ostream OS(Str[I]);
|
||||||
writeHeader(OS, Syms[I]->getVA(), Syms[I]->template getSize<ELFT>(), 0);
|
writeHeader(OS, Syms[I]->getVA(), Syms[I]->getSize(), 0);
|
||||||
OS << indent(2) << toString(*Syms[I]);
|
OS << indent(2) << toString(*Syms[I]);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -106,7 +105,7 @@ getSymbolStrings(ArrayRef<Defined *> Syms) {
|
||||||
return Ret;
|
return Ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class ELFT> void elf::writeMapFile() {
|
void elf::writeMapFile() {
|
||||||
if (Config->MapFile.empty())
|
if (Config->MapFile.empty())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -119,12 +118,12 @@ template <class ELFT> void elf::writeMapFile() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Collect symbol info that we want to print out.
|
// Collect symbol info that we want to print out.
|
||||||
std::vector<Defined *> Syms = getSymbols<ELFT>();
|
std::vector<Defined *> Syms = getSymbols();
|
||||||
SymbolMapTy SectionSyms = getSectionSyms(Syms);
|
SymbolMapTy SectionSyms = getSectionSyms(Syms);
|
||||||
DenseMap<Defined *, std::string> SymStr = getSymbolStrings<ELFT>(Syms);
|
DenseMap<Defined *, std::string> SymStr = getSymbolStrings(Syms);
|
||||||
|
|
||||||
// Print out the header line.
|
// Print out the header line.
|
||||||
int W = ELFT::Is64Bits ? 16 : 8;
|
int W = Config->Is64 ? 16 : 8;
|
||||||
OS << left_justify("Address", W) << ' ' << left_justify("Size", W)
|
OS << left_justify("Address", W) << ' ' << left_justify("Size", W)
|
||||||
<< " Align Out In Symbol\n";
|
<< " Align Out In Symbol\n";
|
||||||
|
|
||||||
|
@ -148,8 +147,3 @@ template <class ELFT> void elf::writeMapFile() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template void elf::writeMapFile<ELF32LE>();
|
|
||||||
template void elf::writeMapFile<ELF32BE>();
|
|
||||||
template void elf::writeMapFile<ELF64LE>();
|
|
||||||
template void elf::writeMapFile<ELF64BE>();
|
|
||||||
|
|
|
@ -10,12 +10,9 @@
|
||||||
#ifndef LLD_ELF_MAPFILE_H
|
#ifndef LLD_ELF_MAPFILE_H
|
||||||
#define LLD_ELF_MAPFILE_H
|
#define LLD_ELF_MAPFILE_H
|
||||||
|
|
||||||
#include <llvm/ADT/ArrayRef.h>
|
|
||||||
|
|
||||||
namespace lld {
|
namespace lld {
|
||||||
namespace elf {
|
namespace elf {
|
||||||
class OutputSection;
|
void writeMapFile();
|
||||||
template <class ELFT> void writeMapFile();
|
|
||||||
} // namespace elf
|
} // namespace elf
|
||||||
} // namespace lld
|
} // namespace lld
|
||||||
|
|
||||||
|
|
|
@ -445,14 +445,13 @@ static RelExpr fromPlt(RelExpr Expr) {
|
||||||
// Returns true if a given shared symbol is in a read-only segment in a DSO.
|
// Returns true if a given shared symbol is in a read-only segment in a DSO.
|
||||||
template <class ELFT> static bool isReadOnly(SharedSymbol *SS) {
|
template <class ELFT> static bool isReadOnly(SharedSymbol *SS) {
|
||||||
typedef typename ELFT::Phdr Elf_Phdr;
|
typedef typename ELFT::Phdr Elf_Phdr;
|
||||||
uint64_t Value = SS->getValue<ELFT>();
|
|
||||||
|
|
||||||
// Determine if the symbol is read-only by scanning the DSO's program headers.
|
// Determine if the symbol is read-only by scanning the DSO's program headers.
|
||||||
const SharedFile<ELFT> *File = SS->getFile<ELFT>();
|
const SharedFile<ELFT> *File = SS->getFile<ELFT>();
|
||||||
for (const Elf_Phdr &Phdr : check(File->getObj().program_headers()))
|
for (const Elf_Phdr &Phdr : check(File->getObj().program_headers()))
|
||||||
if ((Phdr.p_type == ELF::PT_LOAD || Phdr.p_type == ELF::PT_GNU_RELRO) &&
|
if ((Phdr.p_type == ELF::PT_LOAD || Phdr.p_type == ELF::PT_GNU_RELRO) &&
|
||||||
!(Phdr.p_flags & ELF::PF_W) && Value >= Phdr.p_vaddr &&
|
!(Phdr.p_flags & ELF::PF_W) && SS->Value >= Phdr.p_vaddr &&
|
||||||
Value < Phdr.p_vaddr + Phdr.p_memsz)
|
SS->Value < Phdr.p_vaddr + Phdr.p_memsz)
|
||||||
return true;
|
return true;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -467,12 +466,10 @@ static std::vector<SharedSymbol *> getSymbolsAt(SharedSymbol *SS) {
|
||||||
typedef typename ELFT::Sym Elf_Sym;
|
typedef typename ELFT::Sym Elf_Sym;
|
||||||
|
|
||||||
SharedFile<ELFT> *File = SS->getFile<ELFT>();
|
SharedFile<ELFT> *File = SS->getFile<ELFT>();
|
||||||
uint64_t Shndx = SS->getShndx<ELFT>();
|
|
||||||
uint64_t Value = SS->getValue<ELFT>();
|
|
||||||
|
|
||||||
std::vector<SharedSymbol *> Ret;
|
std::vector<SharedSymbol *> Ret;
|
||||||
for (const Elf_Sym &S : File->getGlobalELFSyms()) {
|
for (const Elf_Sym &S : File->getGlobalELFSyms()) {
|
||||||
if (S.st_shndx != Shndx || S.st_value != Value)
|
if (S.st_shndx != SS->Shndx || S.st_value != SS->Value)
|
||||||
continue;
|
continue;
|
||||||
StringRef Name = check(S.getName(File->getStringTable()));
|
StringRef Name = check(S.getName(File->getStringTable()));
|
||||||
SymbolBody *Sym = Symtab->find(Name);
|
SymbolBody *Sym = Symtab->find(Name);
|
||||||
|
@ -526,7 +523,7 @@ static std::vector<SharedSymbol *> getSymbolsAt(SharedSymbol *SS) {
|
||||||
// define an accessor getV().
|
// define an accessor getV().
|
||||||
template <class ELFT> static void addCopyRelSymbol(SharedSymbol *SS) {
|
template <class ELFT> static void addCopyRelSymbol(SharedSymbol *SS) {
|
||||||
// Copy relocation against zero-sized symbol doesn't make sense.
|
// Copy relocation against zero-sized symbol doesn't make sense.
|
||||||
uint64_t SymSize = SS->template getSize<ELFT>();
|
uint64_t SymSize = SS->getSize();
|
||||||
if (SymSize == 0)
|
if (SymSize == 0)
|
||||||
fatal("cannot create a copy relocation for symbol " + toString(*SS));
|
fatal("cannot create a copy relocation for symbol " + toString(*SS));
|
||||||
|
|
||||||
|
@ -534,7 +531,7 @@ template <class ELFT> static void addCopyRelSymbol(SharedSymbol *SS) {
|
||||||
// memory protection by reserving space in the .bss.rel.ro section.
|
// memory protection by reserving space in the .bss.rel.ro section.
|
||||||
bool IsReadOnly = isReadOnly<ELFT>(SS);
|
bool IsReadOnly = isReadOnly<ELFT>(SS);
|
||||||
BssSection *Sec = make<BssSection>(IsReadOnly ? ".bss.rel.ro" : ".bss",
|
BssSection *Sec = make<BssSection>(IsReadOnly ? ".bss.rel.ro" : ".bss",
|
||||||
SymSize, SS->getAlignment<ELFT>());
|
SymSize, SS->Alignment);
|
||||||
if (IsReadOnly)
|
if (IsReadOnly)
|
||||||
InX::BssRelRo->getParent()->addSection(Sec);
|
InX::BssRelRo->getParent()->addSection(Sec);
|
||||||
else
|
else
|
||||||
|
@ -1014,7 +1011,7 @@ static void scanRelocs(InputSectionBase &Sec, ArrayRef<RelTy> Rels) {
|
||||||
|
|
||||||
// The size is not going to change, so we fold it in here.
|
// The size is not going to change, so we fold it in here.
|
||||||
if (Expr == R_SIZE)
|
if (Expr == R_SIZE)
|
||||||
Addend += Body.getSize<ELFT>();
|
Addend += Body.getSize();
|
||||||
|
|
||||||
// If the produced value is a constant, we just remember to write it
|
// If the produced value is a constant, we just remember to write it
|
||||||
// when outputting this section. We also have to do it if the format
|
// when outputting this section. We also have to do it if the format
|
||||||
|
|
|
@ -498,7 +498,7 @@ Symbol *SymbolTable::addRegular(StringRef Name, uint8_t StOther, uint8_t Type,
|
||||||
|
|
||||||
template <typename ELFT>
|
template <typename ELFT>
|
||||||
void SymbolTable::addShared(StringRef Name, SharedFile<ELFT> *File,
|
void SymbolTable::addShared(StringRef Name, SharedFile<ELFT> *File,
|
||||||
const typename ELFT::Sym &Sym,
|
const typename ELFT::Sym &Sym, uint32_t Alignment,
|
||||||
const typename ELFT::Verdef *Verdef) {
|
const typename ELFT::Verdef *Verdef) {
|
||||||
// DSO symbols do not affect visibility in the output, so we pass STV_DEFAULT
|
// DSO symbols do not affect visibility in the output, so we pass STV_DEFAULT
|
||||||
// as the visibility, which will leave the visibility in the symbol table
|
// as the visibility, which will leave the visibility in the symbol table
|
||||||
|
@ -516,8 +516,9 @@ void SymbolTable::addShared(StringRef Name, SharedFile<ELFT> *File,
|
||||||
// in the same DSO.
|
// in the same DSO.
|
||||||
if (WasInserted || ((Body->isUndefined() || Body->isLazy()) &&
|
if (WasInserted || ((Body->isUndefined() || Body->isLazy()) &&
|
||||||
Body->getVisibility() == STV_DEFAULT)) {
|
Body->getVisibility() == STV_DEFAULT)) {
|
||||||
replaceBody<SharedSymbol>(S, File, Name, Sym.st_other, Sym.getType(), &Sym,
|
replaceBody<SharedSymbol>(S, File, Name, Sym.st_other, Sym.getType(),
|
||||||
Verdef);
|
Sym.st_value, Sym.st_size, Alignment,
|
||||||
|
Sym.st_shndx, Verdef);
|
||||||
if (!S->isWeak())
|
if (!S->isWeak())
|
||||||
File->IsUsed = true;
|
File->IsUsed = true;
|
||||||
}
|
}
|
||||||
|
@ -881,15 +882,19 @@ template void SymbolTable::addLazyObject<ELF64BE>(StringRef, LazyObjFile &);
|
||||||
|
|
||||||
template void SymbolTable::addShared<ELF32LE>(StringRef, SharedFile<ELF32LE> *,
|
template void SymbolTable::addShared<ELF32LE>(StringRef, SharedFile<ELF32LE> *,
|
||||||
const typename ELF32LE::Sym &,
|
const typename ELF32LE::Sym &,
|
||||||
|
uint32_t Alignment,
|
||||||
const typename ELF32LE::Verdef *);
|
const typename ELF32LE::Verdef *);
|
||||||
template void SymbolTable::addShared<ELF32BE>(StringRef, SharedFile<ELF32BE> *,
|
template void SymbolTable::addShared<ELF32BE>(StringRef, SharedFile<ELF32BE> *,
|
||||||
const typename ELF32BE::Sym &,
|
const typename ELF32BE::Sym &,
|
||||||
|
uint32_t Alignment,
|
||||||
const typename ELF32BE::Verdef *);
|
const typename ELF32BE::Verdef *);
|
||||||
template void SymbolTable::addShared<ELF64LE>(StringRef, SharedFile<ELF64LE> *,
|
template void SymbolTable::addShared<ELF64LE>(StringRef, SharedFile<ELF64LE> *,
|
||||||
const typename ELF64LE::Sym &,
|
const typename ELF64LE::Sym &,
|
||||||
|
uint32_t Alignment,
|
||||||
const typename ELF64LE::Verdef *);
|
const typename ELF64LE::Verdef *);
|
||||||
template void SymbolTable::addShared<ELF64BE>(StringRef, SharedFile<ELF64BE> *,
|
template void SymbolTable::addShared<ELF64BE>(StringRef, SharedFile<ELF64BE> *,
|
||||||
const typename ELF64BE::Sym &,
|
const typename ELF64BE::Sym &,
|
||||||
|
uint32_t Alignment,
|
||||||
const typename ELF64BE::Verdef *);
|
const typename ELF64BE::Verdef *);
|
||||||
|
|
||||||
template void SymbolTable::fetchIfLazy<ELF32LE>(StringRef);
|
template void SymbolTable::fetchIfLazy<ELF32LE>(StringRef);
|
||||||
|
|
|
@ -60,7 +60,7 @@ public:
|
||||||
|
|
||||||
template <class ELFT>
|
template <class ELFT>
|
||||||
void addShared(StringRef Name, SharedFile<ELFT> *F,
|
void addShared(StringRef Name, SharedFile<ELFT> *F,
|
||||||
const typename ELFT::Sym &Sym,
|
const typename ELFT::Sym &Sym, uint32_t Alignment,
|
||||||
const typename ELFT::Verdef *Verdef);
|
const typename ELFT::Verdef *Verdef);
|
||||||
|
|
||||||
template <class ELFT>
|
template <class ELFT>
|
||||||
|
|
|
@ -174,13 +174,13 @@ uint64_t SymbolBody::getPltVA() const {
|
||||||
PltIndex * Target->PltEntrySize;
|
PltIndex * Target->PltEntrySize;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class ELFT> typename ELFT::uint SymbolBody::getSize() const {
|
uint64_t SymbolBody::getSize() const {
|
||||||
if (const auto *C = dyn_cast<DefinedCommon>(this))
|
if (const auto *C = dyn_cast<DefinedCommon>(this))
|
||||||
return C->Size;
|
return C->Size;
|
||||||
if (const auto *DR = dyn_cast<DefinedRegular>(this))
|
if (const auto *DR = dyn_cast<DefinedRegular>(this))
|
||||||
return DR->Size;
|
return DR->Size;
|
||||||
if (const auto *S = dyn_cast<SharedSymbol>(this))
|
if (const auto *S = dyn_cast<SharedSymbol>(this))
|
||||||
return S->getSize<ELFT>();
|
return S->Size;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -261,17 +261,6 @@ template <class ELFT> bool DefinedRegular::isMipsPIC() const {
|
||||||
(Hdr->e_flags & EF_MIPS_PIC);
|
(Hdr->e_flags & EF_MIPS_PIC);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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> uint32_t SharedSymbol::getAlignment() const {
|
|
||||||
SharedFile<ELFT> *File = getFile<ELFT>();
|
|
||||||
uint32_t SecAlign = File->getSection(getSym<ELFT>())->sh_addralign;
|
|
||||||
uint64_t SymValue = getSym<ELFT>().st_value;
|
|
||||||
uint32_t SymAlign = uint32_t(1) << countTrailingZeros(SymValue);
|
|
||||||
return std::min(SecAlign, SymAlign);
|
|
||||||
}
|
|
||||||
|
|
||||||
InputFile *Lazy::fetch() {
|
InputFile *Lazy::fetch() {
|
||||||
if (auto *S = dyn_cast<LazyArchive>(this))
|
if (auto *S = dyn_cast<LazyArchive>(this))
|
||||||
return S->fetch();
|
return S->fetch();
|
||||||
|
@ -346,17 +335,7 @@ std::string lld::toString(const SymbolBody &B) {
|
||||||
return B.getName();
|
return B.getName();
|
||||||
}
|
}
|
||||||
|
|
||||||
template uint32_t SymbolBody::template getSize<ELF32LE>() const;
|
|
||||||
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 bool DefinedRegular::template isMipsPIC<ELF32LE>() const;
|
template bool DefinedRegular::template isMipsPIC<ELF32LE>() const;
|
||||||
template bool DefinedRegular::template isMipsPIC<ELF32BE>() const;
|
template bool DefinedRegular::template isMipsPIC<ELF32BE>() const;
|
||||||
template bool DefinedRegular::template isMipsPIC<ELF64LE>() const;
|
template bool DefinedRegular::template isMipsPIC<ELF64LE>() const;
|
||||||
template bool DefinedRegular::template isMipsPIC<ELF64BE>() const;
|
template bool DefinedRegular::template isMipsPIC<ELF64BE>() const;
|
||||||
|
|
||||||
template uint32_t SharedSymbol::template getAlignment<ELF32LE>() const;
|
|
||||||
template uint32_t SharedSymbol::template getAlignment<ELF32BE>() const;
|
|
||||||
template uint32_t SharedSymbol::template getAlignment<ELF64LE>() const;
|
|
||||||
template uint32_t SharedSymbol::template getAlignment<ELF64BE>() const;
|
|
||||||
|
|
|
@ -93,7 +93,7 @@ public:
|
||||||
uint64_t getGotPltOffset() const;
|
uint64_t getGotPltOffset() const;
|
||||||
uint64_t getGotPltVA() const;
|
uint64_t getGotPltVA() const;
|
||||||
uint64_t getPltVA() const;
|
uint64_t getPltVA() const;
|
||||||
template <class ELFT> typename ELFT::uint getSize() const;
|
uint64_t getSize() const;
|
||||||
OutputSection *getOutputSection() const;
|
OutputSection *getOutputSection() const;
|
||||||
|
|
||||||
uint32_t DynsymIndex = 0;
|
uint32_t DynsymIndex = 0;
|
||||||
|
@ -218,10 +218,12 @@ class SharedSymbol : public Defined {
|
||||||
public:
|
public:
|
||||||
static bool classof(const SymbolBody *S) { return S->kind() == SharedKind; }
|
static bool classof(const SymbolBody *S) { return S->kind() == SharedKind; }
|
||||||
|
|
||||||
SharedSymbol(StringRef Name, uint8_t StOther, uint8_t Type,
|
SharedSymbol(StringRef Name, uint8_t StOther, uint8_t Type, uint64_t Value,
|
||||||
const void *ElfSym, const void *Verdef)
|
uint64_t Size, uint32_t Alignment, uint64_t Shndx,
|
||||||
|
const void *Verdef)
|
||||||
: Defined(SharedKind, Name, /*IsLocal=*/false, StOther, Type),
|
: Defined(SharedKind, Name, /*IsLocal=*/false, StOther, Type),
|
||||||
Verdef(Verdef), ElfSym(ElfSym) {
|
Verdef(Verdef), Value(Value), Size(Size), Shndx(Shndx),
|
||||||
|
Alignment(Alignment) {
|
||||||
// GNU ifunc is a mechanism to allow user-supplied functions to
|
// GNU ifunc is a mechanism to allow user-supplied functions to
|
||||||
// resolve PLT slot values at load-time. This is contrary to the
|
// resolve PLT slot values at load-time. This is contrary to the
|
||||||
// regualr symbol resolution scheme in which symbols are resolved just
|
// regualr symbol resolution scheme in which symbols are resolved just
|
||||||
|
@ -246,18 +248,6 @@ public:
|
||||||
return cast<SharedFile<ELFT>>(SymbolBody::getFile());
|
return cast<SharedFile<ELFT>>(SymbolBody::getFile());
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class ELFT> uint64_t getShndx() const {
|
|
||||||
return getSym<ELFT>().st_shndx;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class ELFT> uint64_t getValue() const {
|
|
||||||
return getSym<ELFT>().st_value;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class ELFT> uint64_t getSize() const {
|
|
||||||
return getSym<ELFT>().st_size;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class ELFT> uint32_t getAlignment() const;
|
template <class ELFT> uint32_t getAlignment() const;
|
||||||
|
|
||||||
// This field is a pointer to the symbol's version definition.
|
// This field is a pointer to the symbol's version definition.
|
||||||
|
@ -266,12 +256,10 @@ public:
|
||||||
// If not null, there is a copy relocation to this section.
|
// If not null, there is a copy relocation to this section.
|
||||||
InputSection *CopyRelSec = nullptr;
|
InputSection *CopyRelSec = nullptr;
|
||||||
|
|
||||||
private:
|
uint64_t Value; // st_value
|
||||||
template <class ELFT> const typename ELFT::Sym &getSym() const {
|
uint64_t Size; // st_size
|
||||||
return *(const typename ELFT::Sym *)ElfSym;
|
uint64_t Shndx; // st_shndx
|
||||||
}
|
uint32_t Alignment;
|
||||||
|
|
||||||
const void *ElfSym;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// This represents a symbol that is not yet in the link, but we know where to
|
// This represents a symbol that is not yet in the link, but we know where to
|
||||||
|
|
|
@ -82,7 +82,7 @@ template <class ELFT> void elf::createCommonSections() {
|
||||||
// don't have to care about DefinedCommon symbols beyond this point.
|
// don't have to care about DefinedCommon symbols beyond this point.
|
||||||
replaceBody<DefinedRegular>(S, Sym->getFile(), Sym->getName(),
|
replaceBody<DefinedRegular>(S, Sym->getFile(), Sym->getName(),
|
||||||
static_cast<bool>(Sym->isLocal()), Sym->StOther,
|
static_cast<bool>(Sym->isLocal()), Sym->StOther,
|
||||||
Sym->Type, 0, Sym->getSize<ELFT>(), Section);
|
Sym->Type, 0, Sym->getSize(), Section);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1615,7 +1615,7 @@ template <class ELFT> void SymbolTableSection<ELFT>::writeTo(uint8_t *Buf) {
|
||||||
if (ESym->st_shndx == SHN_UNDEF)
|
if (ESym->st_shndx == SHN_UNDEF)
|
||||||
ESym->st_size = 0;
|
ESym->st_size = 0;
|
||||||
else
|
else
|
||||||
ESym->st_size = Body->getSize<ELFT>();
|
ESym->st_size = Body->getSize();
|
||||||
|
|
||||||
// st_value is usually an address of a symbol, but that has a
|
// st_value is usually an address of a symbol, but that has a
|
||||||
// special meaining for uninstantiated common symbols (this can
|
// special meaining for uninstantiated common symbols (this can
|
||||||
|
|
|
@ -248,7 +248,7 @@ template <class ELFT> void Writer<ELFT>::run() {
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Handle -Map option.
|
// Handle -Map option.
|
||||||
writeMapFile<ELFT>();
|
writeMapFile();
|
||||||
if (errorCount())
|
if (errorCount())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue