Make OutputSectionBase a class instead of class template.

The disadvantage is that we use uint64_t instad of uint32_t for some
value in 32 bit files. The advantage is a substantially simpler code,
faster builds and less code duplication.

llvm-svn: 286414
This commit is contained in:
Rafael Espindola 2016-11-09 23:23:45 +00:00
parent 2ef442c639
commit e08e78df6d
11 changed files with 291 additions and 298 deletions

View File

@ -29,7 +29,7 @@ template <class ELFT> class ICF;
template <class ELFT> class DefinedRegular;
template <class ELFT> class ObjectFile;
template <class ELFT> class OutputSection;
template <class ELFT> class OutputSectionBase;
class OutputSectionBase;
// We need non-template input section class to store symbol layout
// in linker script parser structures, where we do not have ELFT
@ -104,7 +104,7 @@ public:
uintX_t Entsize, uint32_t Link, uint32_t Info,
uintX_t Addralign, ArrayRef<uint8_t> Data, StringRef Name,
Kind SectionKind);
OutputSectionBase<ELFT> *OutSec = nullptr;
OutputSectionBase *OutSec = nullptr;
// This pointer points to the "real" instance of this instance.
// Usually Repl == this. However, if ICF merges two sections,

View File

@ -229,7 +229,7 @@ void LinkerScript<ELFT>::computeInputSections(InputSectionDescription *I) {
// section for now.
for (InputSectionData *S : I->Sections) {
auto *S2 = static_cast<InputSectionBase<ELFT> *>(S);
S2->OutSec = (OutputSectionBase<ELFT> *)-1;
S2->OutSec = (OutputSectionBase *)-1;
}
}
@ -298,7 +298,7 @@ template <class ELFT>
void LinkerScript<ELFT>::addSection(OutputSectionFactory<ELFT> &Factory,
InputSectionBase<ELFT> *Sec,
StringRef Name) {
OutputSectionBase<ELFT> *OutSec;
OutputSectionBase *OutSec;
bool IsNew;
std::tie(OutSec, IsNew) = Factory.create(createKey(Sec, Name), Sec);
if (IsNew)
@ -373,8 +373,7 @@ void LinkerScript<ELFT>::createSections(OutputSectionFactory<ELFT> &Factory) {
// is an offset from beginning of section and regular
// symbols whose value is absolute.
template <class ELFT>
static void assignSectionSymbol(SymbolAssignment *Cmd,
OutputSectionBase<ELFT> *Sec,
static void assignSectionSymbol(SymbolAssignment *Cmd, OutputSectionBase *Sec,
typename ELFT::uint Value) {
if (!Cmd->Sym)
return;
@ -388,14 +387,14 @@ static void assignSectionSymbol(SymbolAssignment *Cmd,
Body->Value = Cmd->Expression(Value);
}
template <class ELFT> static bool isTbss(OutputSectionBase<ELFT> *Sec) {
template <class ELFT> static bool isTbss(OutputSectionBase *Sec) {
return (Sec->Flags & SHF_TLS) && Sec->Type == SHT_NOBITS;
}
template <class ELFT> void LinkerScript<ELFT>::output(InputSection<ELFT> *S) {
if (!AlreadyOutputIS.insert(S).second)
return;
bool IsTbss = isTbss(CurOutSec);
bool IsTbss = isTbss<ELFT>(CurOutSec);
uintX_t Pos = IsTbss ? Dot + ThreadBssOffset : Dot;
Pos = alignTo(Pos, S->Alignment);
@ -425,7 +424,7 @@ template <class ELFT> void LinkerScript<ELFT>::flush() {
}
template <class ELFT>
void LinkerScript<ELFT>::switchTo(OutputSectionBase<ELFT> *Sec) {
void LinkerScript<ELFT>::switchTo(OutputSectionBase *Sec) {
if (CurOutSec == Sec)
return;
if (AlreadyOutputOS.count(Sec))
@ -435,7 +434,7 @@ void LinkerScript<ELFT>::switchTo(OutputSectionBase<ELFT> *Sec) {
CurOutSec = Sec;
Dot = alignTo(Dot, CurOutSec->Addralign);
CurOutSec->Addr = isTbss(CurOutSec) ? Dot + ThreadBssOffset : Dot;
CurOutSec->Addr = isTbss<ELFT>(CurOutSec) ? Dot + ThreadBssOffset : Dot;
// If neither AT nor AT> is specified for an allocatable section, the linker
// will set the LMA such that the difference between VMA and LMA for the
@ -480,11 +479,10 @@ template <class ELFT> void LinkerScript<ELFT>::process(BaseCommand &Base) {
}
template <class ELFT>
static std::vector<OutputSectionBase<ELFT> *>
findSections(StringRef Name,
const std::vector<OutputSectionBase<ELFT> *> &Sections) {
std::vector<OutputSectionBase<ELFT> *> Ret;
for (OutputSectionBase<ELFT> *Sec : Sections)
static std::vector<OutputSectionBase *>
findSections(StringRef Name, const std::vector<OutputSectionBase *> &Sections) {
std::vector<OutputSectionBase *> Ret;
for (OutputSectionBase *Sec : Sections)
if (Sec->getName() == Name)
Ret.push_back(Sec);
return Ret;
@ -494,8 +492,8 @@ template <class ELFT>
void LinkerScript<ELFT>::assignOffsets(OutputSectionCommand *Cmd) {
if (Cmd->LMAExpr)
LMAOffset = Cmd->LMAExpr(Dot) - Dot;
std::vector<OutputSectionBase<ELFT> *> Sections =
findSections(Cmd->Name, *OutputSections);
std::vector<OutputSectionBase *> Sections =
findSections<ELFT>(Cmd->Name, *OutputSections);
if (Sections.empty())
return;
switchTo(Sections[0]);
@ -508,7 +506,7 @@ void LinkerScript<ELFT>::assignOffsets(OutputSectionCommand *Cmd) {
.base();
for (auto I = Cmd->Commands.begin(); I != E; ++I)
process(**I);
for (OutputSectionBase<ELFT> *Base : Sections)
for (OutputSectionBase *Base : Sections)
switchTo(Base);
flush();
std::for_each(E, Cmd->Commands.end(),
@ -528,8 +526,8 @@ template <class ELFT> void LinkerScript<ELFT>::adjustSectionsBeforeSorting() {
auto *Cmd = dyn_cast<OutputSectionCommand>(Base.get());
if (!Cmd)
return false;
std::vector<OutputSectionBase<ELFT> *> Secs =
findSections(Cmd->Name, *OutputSections);
std::vector<OutputSectionBase *> Secs =
findSections<ELFT>(Cmd->Name, *OutputSections);
if (!Secs.empty())
return false;
for (const std::unique_ptr<BaseCommand> &I : Cmd->Commands)
@ -549,8 +547,8 @@ template <class ELFT> void LinkerScript<ELFT>::adjustSectionsBeforeSorting() {
auto *Cmd = dyn_cast<OutputSectionCommand>(Base.get());
if (!Cmd)
continue;
std::vector<OutputSectionBase<ELFT> *> Secs =
findSections(Cmd->Name, *OutputSections);
std::vector<OutputSectionBase *> Secs =
findSections<ELFT>(Cmd->Name, *OutputSections);
if (!Secs.empty()) {
Flags = Secs[0]->Flags;
Type = Secs[0]->Type;
@ -597,7 +595,7 @@ void LinkerScript<ELFT>::assignAddresses(std::vector<PhdrEntry<ELFT>> &Phdrs) {
// This loops creates or moves commands as needed so that they are in the
// correct order.
int CmdIndex = 0;
for (OutputSectionBase<ELFT> *Sec : *OutputSections) {
for (OutputSectionBase *Sec : *OutputSections) {
StringRef Name = Sec->getName();
// Find the last spot where we can insert a command and still get the
@ -633,8 +631,8 @@ void LinkerScript<ELFT>::assignAddresses(std::vector<PhdrEntry<ELFT>> &Phdrs) {
if (Cmd->Name == ".") {
Dot = Cmd->Expression(Dot);
} else if (Cmd->Sym) {
assignSectionSymbol(Cmd, CurOutSec ? CurOutSec : (*OutputSections)[0],
Dot);
assignSectionSymbol<ELFT>(
Cmd, CurOutSec ? CurOutSec : (*OutputSections)[0], Dot);
}
continue;
}
@ -653,9 +651,9 @@ void LinkerScript<ELFT>::assignAddresses(std::vector<PhdrEntry<ELFT>> &Phdrs) {
}
uintX_t MinVA = std::numeric_limits<uintX_t>::max();
for (OutputSectionBase<ELFT> *Sec : *OutputSections) {
for (OutputSectionBase *Sec : *OutputSections) {
if (Sec->Flags & SHF_ALLOC)
MinVA = std::min(MinVA, Sec->Addr);
MinVA = std::min<uint64_t>(MinVA, Sec->Addr);
else
Sec->Addr = 0;
}
@ -730,7 +728,7 @@ std::vector<PhdrEntry<ELFT>> LinkerScript<ELFT>::createPhdrs() {
}
// Add output sections to program headers.
for (OutputSectionBase<ELFT> *Sec : *OutputSections) {
for (OutputSectionBase *Sec : *OutputSections) {
if (!(Sec->Flags & SHF_ALLOC))
break;
@ -831,7 +829,7 @@ template <class ELFT> bool LinkerScript<ELFT>::hasPhdrsCommands() {
template <class ELFT>
uint64_t LinkerScript<ELFT>::getOutputSectionAddress(StringRef Name) {
for (OutputSectionBase<ELFT> *Sec : *OutputSections)
for (OutputSectionBase *Sec : *OutputSections)
if (Sec->getName() == Name)
return Sec->Addr;
error("undefined section " + Name);
@ -840,7 +838,7 @@ uint64_t LinkerScript<ELFT>::getOutputSectionAddress(StringRef Name) {
template <class ELFT>
uint64_t LinkerScript<ELFT>::getOutputSectionLMA(StringRef Name) {
for (OutputSectionBase<ELFT> *Sec : *OutputSections)
for (OutputSectionBase *Sec : *OutputSections)
if (Sec->getName() == Name)
return Sec->getLMA();
error("undefined section " + Name);
@ -849,7 +847,7 @@ uint64_t LinkerScript<ELFT>::getOutputSectionLMA(StringRef Name) {
template <class ELFT>
uint64_t LinkerScript<ELFT>::getOutputSectionSize(StringRef Name) {
for (OutputSectionBase<ELFT> *Sec : *OutputSections)
for (OutputSectionBase *Sec : *OutputSections)
if (Sec->getName() == Name)
return Sec->Size;
error("undefined section " + Name);
@ -858,7 +856,7 @@ uint64_t LinkerScript<ELFT>::getOutputSectionSize(StringRef Name) {
template <class ELFT>
uint64_t LinkerScript<ELFT>::getOutputSectionAlign(StringRef Name) {
for (OutputSectionBase<ELFT> *Sec : *OutputSections)
for (OutputSectionBase *Sec : *OutputSections)
if (Sec->getName() == Name)
return Sec->Addralign;
error("undefined section " + Name);

View File

@ -32,7 +32,7 @@ class ScriptParser;
class SymbolBody;
template <class ELFT> class InputSectionBase;
template <class ELFT> class InputSection;
template <class ELFT> class OutputSectionBase;
class OutputSectionBase;
template <class ELFT> class OutputSectionFactory;
class InputSectionData;
@ -240,7 +240,7 @@ public:
bool isDefined(StringRef S) override;
bool isAbsolute(StringRef S) override;
std::vector<OutputSectionBase<ELFT> *> *OutputSections;
std::vector<OutputSectionBase *> *OutputSections;
int getSectionIndex(StringRef Name);
@ -262,13 +262,13 @@ private:
uintX_t Dot;
uintX_t LMAOffset = 0;
OutputSectionBase<ELFT> *CurOutSec = nullptr;
OutputSectionBase *CurOutSec = nullptr;
uintX_t ThreadBssOffset = 0;
void switchTo(OutputSectionBase<ELFT> *Sec);
void switchTo(OutputSectionBase *Sec);
void flush();
void output(InputSection<ELFT> *Sec);
void process(BaseCommand &Base);
llvm::DenseSet<OutputSectionBase<ELFT> *> AlreadyOutputOS;
llvm::DenseSet<OutputSectionBase *> AlreadyOutputOS;
llvm::DenseSet<InputSectionData *> AlreadyOutputIS;
};

View File

@ -32,16 +32,15 @@ using namespace llvm::ELF;
using namespace lld;
using namespace lld::elf;
template <class ELFT>
OutputSectionBase<ELFT>::OutputSectionBase(StringRef Name, uint32_t Type,
uintX_t Flags)
OutputSectionBase::OutputSectionBase(StringRef Name, uint32_t Type,
uint64_t Flags)
: Name(Name) {
this->Type = Type;
this->Flags = Flags;
this->Addralign = 1;
}
template <class ELFT> uint32_t OutputSectionBase<ELFT>::getPhdrFlags() const {
uint32_t OutputSectionBase::getPhdrFlags() const {
uint32_t Ret = PF_R;
if (Flags & SHF_WRITE)
Ret |= PF_W;
@ -51,7 +50,7 @@ template <class ELFT> uint32_t OutputSectionBase<ELFT>::getPhdrFlags() const {
}
template <class ELFT>
void OutputSectionBase<ELFT>::writeHeaderTo(Elf_Shdr *Shdr) {
void OutputSectionBase::writeHeaderTo(typename ELFT::Shdr *Shdr) {
Shdr->sh_entsize = Entsize;
Shdr->sh_addralign = Addralign;
Shdr->sh_type = Type;
@ -66,7 +65,7 @@ void OutputSectionBase<ELFT>::writeHeaderTo(Elf_Shdr *Shdr) {
template <class ELFT>
GdbIndexSection<ELFT>::GdbIndexSection()
: OutputSectionBase<ELFT>(".gdb_index", SHT_PROGBITS, 0) {}
: OutputSectionBase(".gdb_index", SHT_PROGBITS, 0) {}
template <class ELFT> void GdbIndexSection<ELFT>::parseDebugSections() {
std::vector<InputSection<ELFT> *> &IS =
@ -110,7 +109,7 @@ template <class ELFT> void GdbIndexSection<ELFT>::writeTo(uint8_t *Buf) {
template <class ELFT>
GotPltSection<ELFT>::GotPltSection()
: OutputSectionBase<ELFT>(".got.plt", SHT_PROGBITS, SHF_ALLOC | SHF_WRITE) {
: OutputSectionBase(".got.plt", SHT_PROGBITS, SHF_ALLOC | SHF_WRITE) {
this->Addralign = Target->GotPltEntrySize;
}
@ -139,7 +138,7 @@ template <class ELFT> void GotPltSection<ELFT>::writeTo(uint8_t *Buf) {
template <class ELFT>
GotSection<ELFT>::GotSection()
: OutputSectionBase<ELFT>(".got", SHT_PROGBITS, SHF_ALLOC | SHF_WRITE) {
: OutputSectionBase(".got", SHT_PROGBITS, SHF_ALLOC | SHF_WRITE) {
if (Config->EMachine == EM_MIPS)
this->Flags |= SHF_MIPS_GPREL;
this->Addralign = Target->GotEntrySize;
@ -313,7 +312,7 @@ template <class ELFT> void GotSection<ELFT>::finalize() {
// Take into account MIPS GOT header.
// See comment in the GotSection::writeTo.
MipsPageEntries += 2;
for (const OutputSectionBase<ELFT> *OutSec : MipsOutSections) {
for (const OutputSectionBase *OutSec : MipsOutSections) {
// Calculate an upper bound of MIPS GOT entries required to store page
// addresses of local symbols. We assume the worst case - each 64kb
// page of the output section has at least one GOT relocation against it.
@ -408,7 +407,7 @@ template <class ELFT> void GotSection<ELFT>::writeTo(uint8_t *Buf) {
template <class ELFT>
PltSection<ELFT>::PltSection()
: OutputSectionBase<ELFT>(".plt", SHT_PROGBITS, SHF_ALLOC | SHF_EXECINSTR) {
: OutputSectionBase(".plt", SHT_PROGBITS, SHF_ALLOC | SHF_EXECINSTR) {
this->Addralign = 16;
}
@ -440,8 +439,7 @@ template <class ELFT> void PltSection<ELFT>::finalize() {
template <class ELFT>
RelocationSection<ELFT>::RelocationSection(StringRef Name, bool Sort)
: OutputSectionBase<ELFT>(Name, Config->Rela ? SHT_RELA : SHT_REL,
SHF_ALLOC),
: OutputSectionBase(Name, Config->Rela ? SHT_RELA : SHT_REL, SHF_ALLOC),
Sort(Sort) {
this->Entsize = Config->Rela ? sizeof(Elf_Rela) : sizeof(Elf_Rel);
this->Addralign = sizeof(uintX_t);
@ -504,7 +502,7 @@ template <class ELFT> void RelocationSection<ELFT>::finalize() {
template <class ELFT>
HashTableSection<ELFT>::HashTableSection()
: OutputSectionBase<ELFT>(".hash", SHT_HASH, SHF_ALLOC) {
: OutputSectionBase(".hash", SHT_HASH, SHF_ALLOC) {
this->Entsize = sizeof(Elf_Word);
this->Addralign = sizeof(Elf_Word);
}
@ -550,7 +548,7 @@ static uint32_t hashGnu(StringRef Name) {
template <class ELFT>
GnuHashTableSection<ELFT>::GnuHashTableSection()
: OutputSectionBase<ELFT>(".gnu.hash", SHT_GNU_HASH, SHF_ALLOC) {
: OutputSectionBase(".gnu.hash", SHT_GNU_HASH, SHF_ALLOC) {
this->Entsize = ELFT::Is64Bits ? 0 : 4;
this->Addralign = sizeof(uintX_t);
}
@ -695,7 +693,7 @@ static unsigned getVerDefNum() { return Config->VersionDefinitions.size() + 1; }
template <class ELFT>
DynamicSection<ELFT>::DynamicSection()
: OutputSectionBase<ELFT>(".dynamic", SHT_DYNAMIC, SHF_ALLOC | SHF_WRITE) {
: OutputSectionBase(".dynamic", SHT_DYNAMIC, SHF_ALLOC | SHF_WRITE) {
this->Addralign = sizeof(uintX_t);
this->Entsize = ELFT::Is64Bits ? 16 : 8;
@ -863,7 +861,7 @@ template <class ELFT> void DynamicSection<ELFT>::writeTo(uint8_t *Buf) {
template <class ELFT>
EhFrameHeader<ELFT>::EhFrameHeader()
: OutputSectionBase<ELFT>(".eh_frame_hdr", SHT_PROGBITS, SHF_ALLOC) {}
: OutputSectionBase(".eh_frame_hdr", SHT_PROGBITS, SHF_ALLOC) {}
// .eh_frame_hdr contains a binary search table of pointers to FDEs.
// Each entry of the search table consists of two values,
@ -925,7 +923,7 @@ template <class ELFT> static uint64_t getEntsize(uint32_t Type) {
template <class ELFT>
OutputSection<ELFT>::OutputSection(StringRef Name, uint32_t Type, uintX_t Flags)
: OutputSectionBase<ELFT>(Name, Type, Flags) {
: OutputSectionBase(Name, Type, Flags) {
this->Entsize = getEntsize<ELFT>(Type);
}
@ -956,7 +954,7 @@ template <class ELFT> void OutputSection<ELFT>::finalize() {
}
template <class ELFT>
void OutputSection<ELFT>::addSection(InputSectionBase<ELFT> *C) {
void OutputSection<ELFT>::addSection(InputSectionData *C) {
assert(C->Live);
auto *S = cast<InputSection<ELFT>>(C);
Sections.push_back(S);
@ -1085,7 +1083,7 @@ template <class ELFT> void OutputSection<ELFT>::writeTo(uint8_t *Buf) {
template <class ELFT>
EhOutputSection<ELFT>::EhOutputSection()
: OutputSectionBase<ELFT>(".eh_frame", SHT_PROGBITS, SHF_ALLOC) {}
: OutputSectionBase(".eh_frame", SHT_PROGBITS, SHF_ALLOC) {}
// Search for an existing CIE record or create a new one.
// CIE records from input object files are uniquified by their contents
@ -1170,7 +1168,7 @@ void EhOutputSection<ELFT>::addSectionAux(EhInputSection<ELFT> *Sec,
}
template <class ELFT>
void EhOutputSection<ELFT>::addSection(InputSectionBase<ELFT> *C) {
void EhOutputSection<ELFT>::addSection(InputSectionData *C) {
auto *Sec = cast<EhInputSection<ELFT>>(C);
Sec->OutSec = this;
this->updateAlignment(Sec->Alignment);
@ -1290,7 +1288,7 @@ template <class ELFT> void EhOutputSection<ELFT>::writeTo(uint8_t *Buf) {
template <class ELFT>
MergeOutputSection<ELFT>::MergeOutputSection(StringRef Name, uint32_t Type,
uintX_t Flags, uintX_t Alignment)
: OutputSectionBase<ELFT>(Name, Type, Flags),
: OutputSectionBase(Name, Type, Flags),
Builder(StringTableBuilder::RAW, Alignment) {}
template <class ELFT> void MergeOutputSection<ELFT>::writeTo(uint8_t *Buf) {
@ -1298,7 +1296,7 @@ template <class ELFT> void MergeOutputSection<ELFT>::writeTo(uint8_t *Buf) {
}
template <class ELFT>
void MergeOutputSection<ELFT>::addSection(InputSectionBase<ELFT> *C) {
void MergeOutputSection<ELFT>::addSection(InputSectionData *C) {
auto *Sec = cast<MergeInputSection<ELFT>>(C);
Sec->OutSec = this;
this->updateAlignment(Sec->Alignment);
@ -1344,8 +1342,7 @@ template <class ELFT> void MergeOutputSection<ELFT>::finalizePieces() {
template <class ELFT>
StringTableSection<ELFT>::StringTableSection(StringRef Name, bool Dynamic)
: OutputSectionBase<ELFT>(Name, SHT_STRTAB,
Dynamic ? (uintX_t)SHF_ALLOC : 0),
: OutputSectionBase(Name, SHT_STRTAB, Dynamic ? (uintX_t)SHF_ALLOC : 0),
Dynamic(Dynamic) {
// ELF string tables start with a NUL byte, so 1.
this->Size = 1;
@ -1400,7 +1397,7 @@ template <class ELFT> uint32_t DynamicReloc<ELFT>::getSymIndex() const {
template <class ELFT>
SymbolTableSection<ELFT>::SymbolTableSection(
StringTableSection<ELFT> &StrTabSec)
: OutputSectionBase<ELFT>(StrTabSec.isDynamic() ? ".dynsym" : ".symtab",
: OutputSectionBase(StrTabSec.isDynamic() ? ".dynsym" : ".symtab",
StrTabSec.isDynamic() ? SHT_DYNSYM : SHT_SYMTAB,
StrTabSec.isDynamic() ? (uintX_t)SHF_ALLOC : 0),
StrTabSec(StrTabSec) {
@ -1501,7 +1498,7 @@ void SymbolTableSection<ELFT>::writeLocalSymbols(uint8_t *&Buf) {
ESym->st_shndx = SHN_ABS;
ESym->st_value = Body.Value;
} else {
const OutputSectionBase<ELFT> *OutSec = Section->OutSec;
const OutputSectionBase *OutSec = Section->OutSec;
ESym->st_shndx = OutSec->SectionIndex;
ESym->st_value = OutSec->Addr + Section->getOffset(Body);
}
@ -1531,7 +1528,7 @@ void SymbolTableSection<ELFT>::writeGlobalSymbols(uint8_t *Buf) {
ESym->setVisibility(Body->symbol()->Visibility);
ESym->st_value = Body->getVA<ELFT>();
if (const OutputSectionBase<ELFT> *OutSec = getOutputSection(Body))
if (const OutputSectionBase *OutSec = getOutputSection(Body))
ESym->st_shndx = OutSec->SectionIndex;
else if (isa<DefinedRegular<ELFT>>(Body))
ESym->st_shndx = SHN_ABS;
@ -1554,7 +1551,7 @@ void SymbolTableSection<ELFT>::writeGlobalSymbols(uint8_t *Buf) {
}
template <class ELFT>
const OutputSectionBase<ELFT> *
const OutputSectionBase *
SymbolTableSection<ELFT>::getOutputSection(SymbolBody *Sym) {
switch (Sym->kind()) {
case SymbolBody::DefinedSyntheticKind:
@ -1581,7 +1578,7 @@ SymbolTableSection<ELFT>::getOutputSection(SymbolBody *Sym) {
template <class ELFT>
VersionDefinitionSection<ELFT>::VersionDefinitionSection()
: OutputSectionBase<ELFT>(".gnu.version_d", SHT_GNU_verdef, SHF_ALLOC) {
: OutputSectionBase(".gnu.version_d", SHT_GNU_verdef, SHF_ALLOC) {
this->Addralign = sizeof(uint32_t);
}
@ -1638,7 +1635,7 @@ void VersionDefinitionSection<ELFT>::writeTo(uint8_t *Buf) {
template <class ELFT>
VersionTableSection<ELFT>::VersionTableSection()
: OutputSectionBase<ELFT>(".gnu.version", SHT_GNU_versym, SHF_ALLOC) {
: OutputSectionBase(".gnu.version", SHT_GNU_versym, SHF_ALLOC) {
this->Addralign = sizeof(uint16_t);
}
@ -1661,7 +1658,7 @@ template <class ELFT> void VersionTableSection<ELFT>::writeTo(uint8_t *Buf) {
template <class ELFT>
VersionNeedSection<ELFT>::VersionNeedSection()
: OutputSectionBase<ELFT>(".gnu.version_r", SHT_GNU_verneed, SHF_ALLOC) {
: OutputSectionBase(".gnu.version_r", SHT_GNU_verneed, SHF_ALLOC) {
this->Addralign = sizeof(uint32_t);
// Identifiers in verneed section start at 2 because 0 and 1 are reserved
@ -1764,7 +1761,7 @@ static SectionKey<ELFT::Is64Bits> createKey(InputSectionBase<ELFT> *C,
}
template <class ELFT>
std::pair<OutputSectionBase<ELFT> *, bool>
std::pair<OutputSectionBase *, bool>
OutputSectionFactory<ELFT>::create(InputSectionBase<ELFT> *C,
StringRef OutsecName) {
SectionKey<ELFT::Is64Bits> Key = createKey(C, OutsecName);
@ -1772,11 +1769,11 @@ OutputSectionFactory<ELFT>::create(InputSectionBase<ELFT> *C,
}
template <class ELFT>
std::pair<OutputSectionBase<ELFT> *, bool>
std::pair<OutputSectionBase *, bool>
OutputSectionFactory<ELFT>::create(const SectionKey<ELFT::Is64Bits> &Key,
InputSectionBase<ELFT> *C) {
uintX_t Flags = getOutFlags(C);
OutputSectionBase<ELFT> *&Sec = Map[Key];
OutputSectionBase *&Sec = Map[Key];
if (Sec) {
Sec->Flags |= Flags;
return {Sec, false};
@ -1830,10 +1827,11 @@ template struct DenseMapInfo<SectionKey<false>>;
namespace lld {
namespace elf {
template class OutputSectionBase<ELF32LE>;
template class OutputSectionBase<ELF32BE>;
template class OutputSectionBase<ELF64LE>;
template class OutputSectionBase<ELF64BE>;
template void OutputSectionBase::writeHeaderTo<ELF32LE>(ELF32LE::Shdr *Shdr);
template void OutputSectionBase::writeHeaderTo<ELF32BE>(ELF32BE::Shdr *Shdr);
template void OutputSectionBase::writeHeaderTo<ELF64LE>(ELF64LE::Shdr *Shdr);
template void OutputSectionBase::writeHeaderTo<ELF64BE>(ELF64BE::Shdr *Shdr);
template class EhFrameHeader<ELF32LE>;
template class EhFrameHeader<ELF32BE>;

View File

@ -42,10 +42,8 @@ template <class ELFT> class DefinedRegular;
// input sections, others are created by the linker.
// The writer creates multiple OutputSections and assign them unique,
// non-overlapping file offsets and VAs.
template <class ELFT> class OutputSectionBase {
class OutputSectionBase {
public:
typedef typename ELFT::uint uintX_t;
typedef typename ELFT::Shdr Elf_Shdr;
enum Kind {
Base,
Dynamic,
@ -66,15 +64,15 @@ public:
VersTable
};
OutputSectionBase(StringRef Name, uint32_t Type, uintX_t Flags);
void setLMAOffset(uintX_t LMAOff) { LMAOffset = LMAOff; }
uintX_t getLMA() const { return Addr + LMAOffset; }
void writeHeaderTo(Elf_Shdr *SHdr);
OutputSectionBase(StringRef Name, uint32_t Type, uint64_t Flags);
void setLMAOffset(uint64_t LMAOff) { LMAOffset = LMAOff; }
uint64_t getLMA() const { return Addr + LMAOffset; }
template <typename ELFT> void writeHeaderTo(typename ELFT::Shdr *SHdr);
StringRef getName() const { return Name; }
virtual void addSection(InputSectionBase<ELFT> *C) {}
virtual void addSection(InputSectionData *C) {}
virtual Kind getKind() const { return Base; }
static bool classof(const OutputSectionBase<ELFT> *B) {
static bool classof(const OutputSectionBase *B) {
return B->getKind() == Base;
}
@ -82,7 +80,7 @@ public:
uint32_t getPhdrFlags() const;
void updateAlignment(uintX_t Alignment) {
void updateAlignment(uint64_t Alignment) {
if (Alignment > Addralign)
Addralign = Alignment;
}
@ -97,7 +95,7 @@ public:
// between their file offsets should be equal to difference between their
// virtual addresses. To compute some section offset we use the following
// formula: Off = Off_first + VA - VA_first.
OutputSectionBase<ELFT> *FirstInPtLoad = nullptr;
OutputSectionBase *FirstInPtLoad = nullptr;
virtual void finalize() {}
virtual void finalizePieces() {}
@ -108,21 +106,20 @@ public:
StringRef Name;
// The following fields correspond to Elf_Shdr members.
uintX_t Size = 0;
uintX_t Entsize = 0;
uintX_t Addralign = 0;
uintX_t Offset = 0;
uintX_t Flags = 0;
uintX_t LMAOffset = 0;
uintX_t Addr = 0;
uint64_t Size = 0;
uint64_t Entsize = 0;
uint64_t Addralign = 0;
uint64_t Offset = 0;
uint64_t Flags = 0;
uint64_t LMAOffset = 0;
uint64_t Addr = 0;
uint32_t ShName = 0;
uint32_t Type = 0;
uint32_t Info = 0;
uint32_t Link = 0;
};
template <class ELFT>
class GdbIndexSection final : public OutputSectionBase<ELFT> {
template <class ELFT> class GdbIndexSection final : public OutputSectionBase {
typedef typename ELFT::uint uintX_t;
const unsigned OffsetTypeSize = 4;
@ -146,8 +143,7 @@ private:
uint32_t CuTypesOffset;
};
template <class ELFT> class GotSection final : public OutputSectionBase<ELFT> {
typedef OutputSectionBase<ELFT> Base;
template <class ELFT> class GotSection final : public OutputSectionBase {
typedef typename ELFT::uint uintX_t;
public:
@ -163,8 +159,10 @@ public:
uintX_t getMipsGotOffset(const SymbolBody &B, uintX_t Addend) const;
uintX_t getGlobalDynAddr(const SymbolBody &B) const;
uintX_t getGlobalDynOffset(const SymbolBody &B) const;
typename Base::Kind getKind() const override { return Base::Got; }
static bool classof(const Base *B) { return B->getKind() == Base::Got; }
Kind getKind() const override { return Got; }
static bool classof(const OutputSectionBase *B) {
return B->getKind() == Got;
}
// Returns the symbol which corresponds to the first entry of the global part
// of GOT on MIPS platform. It is required to fill up MIPS-specific dynamic
@ -192,7 +190,7 @@ private:
uint32_t TlsIndexOff = -1;
uint32_t MipsPageEntries = 0;
// Output sections referenced by MIPS GOT relocations.
llvm::SmallPtrSet<const OutputSectionBase<ELFT> *, 10> MipsOutSections;
llvm::SmallPtrSet<const OutputSectionBase *, 10> MipsOutSections;
llvm::DenseMap<uintX_t, size_t> MipsLocalGotPos;
// MIPS ABI requires to create unique GOT entry for each Symbol/Addend
@ -213,10 +211,8 @@ private:
void writeMipsGot(uint8_t *Buf);
};
template <class ELFT>
class GotPltSection final : public OutputSectionBase<ELFT> {
template <class ELFT> class GotPltSection final : public OutputSectionBase {
typedef typename ELFT::uint uintX_t;
typedef OutputSectionBase<ELFT> Base;
public:
GotPltSection();
@ -224,15 +220,16 @@ public:
void writeTo(uint8_t *Buf) override;
void addEntry(SymbolBody &Sym);
bool empty() const;
typename Base::Kind getKind() const override { return Base::GotPlt; }
static bool classof(const Base *B) { return B->getKind() == Base::GotPlt; }
Kind getKind() const override { return GotPlt; }
static bool classof(const OutputSectionBase *B) {
return B->getKind() == GotPlt;
}
private:
std::vector<const SymbolBody *> Entries;
};
template <class ELFT> class PltSection final : public OutputSectionBase<ELFT> {
typedef OutputSectionBase<ELFT> Base;
template <class ELFT> class PltSection final : public OutputSectionBase {
typedef typename ELFT::uint uintX_t;
public:
@ -241,8 +238,10 @@ public:
void writeTo(uint8_t *Buf) override;
void addEntry(SymbolBody &Sym);
bool empty() const { return Entries.empty(); }
typename Base::Kind getKind() const override { return Base::Plt; }
static bool classof(const Base *B) { return B->getKind() == Base::Plt; }
Kind getKind() const override { return Plt; }
static bool classof(const OutputSectionBase *B) {
return B->getKind() == Plt;
}
private:
std::vector<std::pair<const SymbolBody *, unsigned>> Entries;
@ -258,7 +257,7 @@ public:
: Type(Type), Sym(Sym), InputSec(InputSec), OffsetInSec(OffsetInSec),
UseSymVA(UseSymVA), Addend(Addend) {}
DynamicReloc(uint32_t Type, const OutputSectionBase<ELFT> *OutputSec,
DynamicReloc(uint32_t Type, const OutputSectionBase *OutputSec,
uintX_t OffsetInSec, bool UseSymVA, SymbolBody *Sym,
uintX_t Addend)
: Type(Type), Sym(Sym), OutputSec(OutputSec), OffsetInSec(OffsetInSec),
@ -267,14 +266,14 @@ public:
uintX_t getOffset() const;
uintX_t getAddend() const;
uint32_t getSymIndex() const;
const OutputSectionBase<ELFT> *getOutputSec() const { return OutputSec; }
const OutputSectionBase *getOutputSec() const { return OutputSec; }
uint32_t Type;
private:
SymbolBody *Sym;
const InputSectionBase<ELFT> *InputSec = nullptr;
const OutputSectionBase<ELFT> *OutputSec = nullptr;
const OutputSectionBase *OutputSec = nullptr;
uintX_t OffsetInSec;
bool UseSymVA;
uintX_t Addend;
@ -286,8 +285,8 @@ struct SymbolTableEntry {
};
template <class ELFT>
class SymbolTableSection final : public OutputSectionBase<ELFT> {
typedef OutputSectionBase<ELFT> Base;
class SymbolTableSection final : public OutputSectionBase {
typedef OutputSectionBase Base;
public:
typedef typename ELFT::Shdr Elf_Shdr;
@ -313,7 +312,7 @@ private:
void writeLocalSymbols(uint8_t *&Buf);
void writeGlobalSymbols(uint8_t *Buf);
const OutputSectionBase<ELFT> *getOutputSection(SymbolBody *Sym);
const OutputSectionBase *getOutputSection(SymbolBody *Sym);
// A vector of symbols and their string table offsets.
std::vector<SymbolTableEntry> Symbols;
@ -328,17 +327,18 @@ private:
// The section shall contain an array of Elf_Verdef structures, optionally
// followed by an array of Elf_Verdaux structures.
template <class ELFT>
class VersionDefinitionSection final : public OutputSectionBase<ELFT> {
class VersionDefinitionSection final : public OutputSectionBase {
typedef typename ELFT::Verdef Elf_Verdef;
typedef typename ELFT::Verdaux Elf_Verdaux;
typedef OutputSectionBase<ELFT> Base;
public:
VersionDefinitionSection();
void finalize() override;
void writeTo(uint8_t *Buf) override;
typename Base::Kind getKind() const override { return Base::VersDef; }
static bool classof(const Base *B) { return B->getKind() == Base::VersDef; }
Kind getKind() const override { return VersDef; }
static bool classof(const OutputSectionBase *B) {
return B->getKind() == VersDef;
}
private:
void writeOne(uint8_t *Buf, uint32_t Index, StringRef Name, size_t NameOff);
@ -353,16 +353,17 @@ private:
// The values 0 and 1 are reserved. All other values are used for versions in
// the own object or in any of the dependencies.
template <class ELFT>
class VersionTableSection final : public OutputSectionBase<ELFT> {
typedef OutputSectionBase<ELFT> Base;
class VersionTableSection final : public OutputSectionBase {
typedef typename ELFT::Versym Elf_Versym;
public:
VersionTableSection();
void finalize() override;
void writeTo(uint8_t *Buf) override;
typename Base::Kind getKind() const override { return Base::VersTable; }
static bool classof(const Base *B) { return B->getKind() == Base::VersTable; }
Kind getKind() const override { return VersTable; }
static bool classof(const OutputSectionBase *B) {
return B->getKind() == VersTable;
}
};
// The .gnu.version_r section defines the version identifiers used by
@ -371,8 +372,7 @@ public:
// a reference to a linked list of Elf_Vernaux data structures which define the
// mapping from version identifiers to version names.
template <class ELFT>
class VersionNeedSection final : public OutputSectionBase<ELFT> {
typedef OutputSectionBase<ELFT> Base;
class VersionNeedSection final : public OutputSectionBase {
typedef typename ELFT::Verneed Elf_Verneed;
typedef typename ELFT::Vernaux Elf_Vernaux;
@ -389,16 +389,16 @@ public:
void finalize() override;
void writeTo(uint8_t *Buf) override;
size_t getNeedNum() const { return Needed.size(); }
typename Base::Kind getKind() const override { return Base::VersNeed; }
static bool classof(const Base *B) { return B->getKind() == Base::VersNeed; }
Kind getKind() const override { return VersNeed; }
static bool classof(const OutputSectionBase *B) {
return B->getKind() == VersNeed;
}
};
template <class ELFT>
class RelocationSection final : public OutputSectionBase<ELFT> {
template <class ELFT> class RelocationSection final : public OutputSectionBase {
typedef typename ELFT::Rel Elf_Rel;
typedef typename ELFT::Rela Elf_Rela;
typedef typename ELFT::uint uintX_t;
typedef OutputSectionBase<ELFT> Base;
public:
RelocationSection(StringRef Name, bool Sort);
@ -407,9 +407,11 @@ public:
void finalize() override;
void writeTo(uint8_t *Buf) override;
bool hasRelocs() const { return !Relocs.empty(); }
typename Base::Kind getKind() const override { return Base::Reloc; }
Kind getKind() const override { return Reloc; }
size_t getRelativeRelocCount() const { return NumRelativeRelocs; }
static bool classof(const Base *B) { return B->getKind() == Base::Reloc; }
static bool classof(const OutputSectionBase *B) {
return B->getKind() == Reloc;
}
private:
bool Sort;
@ -417,9 +419,7 @@ private:
std::vector<DynamicReloc<ELFT>> Relocs;
};
template <class ELFT>
class OutputSection final : public OutputSectionBase<ELFT> {
typedef OutputSectionBase<ELFT> Base;
template <class ELFT> class OutputSection final : public OutputSectionBase {
public:
typedef typename ELFT::Shdr Elf_Shdr;
@ -428,33 +428,36 @@ public:
typedef typename ELFT::Rela Elf_Rela;
typedef typename ELFT::uint uintX_t;
OutputSection(StringRef Name, uint32_t Type, uintX_t Flags);
void addSection(InputSectionBase<ELFT> *C) override;
void addSection(InputSectionData *C) override;
void sortInitFini();
void sortCtorsDtors();
void writeTo(uint8_t *Buf) override;
void finalize() override;
void assignOffsets() override;
typename Base::Kind getKind() const override { return Base::Regular; }
static bool classof(const Base *B) { return B->getKind() == Base::Regular; }
Kind getKind() const override { return Regular; }
static bool classof(const OutputSectionBase *B) {
return B->getKind() == Regular;
}
std::vector<InputSection<ELFT> *> Sections;
};
template <class ELFT>
class MergeOutputSection final : public OutputSectionBase<ELFT> {
class MergeOutputSection final : public OutputSectionBase {
typedef typename ELFT::uint uintX_t;
typedef OutputSectionBase<ELFT> Base;
public:
MergeOutputSection(StringRef Name, uint32_t Type, uintX_t Flags,
uintX_t Alignment);
void addSection(InputSectionBase<ELFT> *S) override;
void addSection(InputSectionData *S) override;
void writeTo(uint8_t *Buf) override;
unsigned getOffset(llvm::CachedHashStringRef Val);
void finalize() override;
void finalizePieces() override;
bool shouldTailMerge() const;
typename Base::Kind getKind() const override { return Base::Merge; }
static bool classof(const Base *B) { return B->getKind() == Base::Merge; }
Kind getKind() const override { return Merge; }
static bool classof(const OutputSectionBase *B) {
return B->getKind() == Merge;
}
private:
llvm::StringTableBuilder Builder;
@ -467,13 +470,11 @@ struct CieRecord {
};
// Output section for .eh_frame.
template <class ELFT>
class EhOutputSection final : public OutputSectionBase<ELFT> {
template <class ELFT> class EhOutputSection final : public OutputSectionBase {
typedef typename ELFT::uint uintX_t;
typedef typename ELFT::Shdr Elf_Shdr;
typedef typename ELFT::Rel Elf_Rel;
typedef typename ELFT::Rela Elf_Rela;
typedef OutputSectionBase<ELFT> Base;
public:
EhOutputSection();
@ -481,9 +482,11 @@ public:
void finalize() override;
bool empty() const { return Sections.empty(); }
void addSection(InputSectionBase<ELFT> *S) override;
typename Base::Kind getKind() const override { return Base::EHFrame; }
static bool classof(const Base *B) { return B->getKind() == Base::EHFrame; }
void addSection(InputSectionData *S) override;
Kind getKind() const override { return EHFrame; }
static bool classof(const OutputSectionBase *B) {
return B->getKind() == EHFrame;
}
size_t NumFdes = 0;
@ -509,8 +512,7 @@ private:
};
template <class ELFT>
class StringTableSection final : public OutputSectionBase<ELFT> {
typedef OutputSectionBase<ELFT> Base;
class StringTableSection final : public OutputSectionBase {
public:
typedef typename ELFT::uint uintX_t;
@ -518,8 +520,10 @@ public:
unsigned addString(StringRef S, bool HashIt = true);
void writeTo(uint8_t *Buf) override;
bool isDynamic() const { return Dynamic; }
typename Base::Kind getKind() const override { return Base::StrTable; }
static bool classof(const Base *B) { return B->getKind() == Base::StrTable; }
Kind getKind() const override { return StrTable; }
static bool classof(const OutputSectionBase *B) {
return B->getKind() == StrTable;
}
private:
const bool Dynamic;
@ -527,27 +531,26 @@ private:
std::vector<StringRef> Strings;
};
template <class ELFT>
class HashTableSection final : public OutputSectionBase<ELFT> {
template <class ELFT> class HashTableSection final : public OutputSectionBase {
typedef typename ELFT::Word Elf_Word;
typedef OutputSectionBase<ELFT> Base;
public:
HashTableSection();
void finalize() override;
void writeTo(uint8_t *Buf) override;
typename Base::Kind getKind() const override { return Base::HashTable; }
static bool classof(const Base *B) { return B->getKind() == Base::HashTable; }
Kind getKind() const override { return HashTable; }
static bool classof(const OutputSectionBase *B) {
return B->getKind() == HashTable;
}
};
// Outputs GNU Hash section. For detailed explanation see:
// https://blogs.oracle.com/ali/entry/gnu_hash_elf_sections
template <class ELFT>
class GnuHashTableSection final : public OutputSectionBase<ELFT> {
class GnuHashTableSection final : public OutputSectionBase {
typedef typename ELFT::Off Elf_Off;
typedef typename ELFT::Word Elf_Word;
typedef typename ELFT::uint uintX_t;
typedef OutputSectionBase<ELFT> Base;
public:
GnuHashTableSection();
@ -557,9 +560,9 @@ public:
// Adds symbols to the hash table.
// Sorts the input to satisfy GNU hash section requirements.
void addSymbols(std::vector<SymbolTableEntry> &Symbols);
typename Base::Kind getKind() const override { return Base::GnuHashTable; }
static bool classof(const Base *B) {
return B->getKind() == Base::GnuHashTable;
Kind getKind() const override { return GnuHashTable; }
static bool classof(const OutputSectionBase *B) {
return B->getKind() == GnuHashTable;
}
private:
@ -583,9 +586,7 @@ private:
unsigned Shift2;
};
template <class ELFT>
class DynamicSection final : public OutputSectionBase<ELFT> {
typedef OutputSectionBase<ELFT> Base;
template <class ELFT> class DynamicSection final : public OutputSectionBase {
typedef typename ELFT::Dyn Elf_Dyn;
typedef typename ELFT::Rel Elf_Rel;
typedef typename ELFT::Rela Elf_Rela;
@ -600,12 +601,12 @@ class DynamicSection final : public OutputSectionBase<ELFT> {
struct Entry {
int32_t Tag;
union {
OutputSectionBase<ELFT> *OutSec;
OutputSectionBase *OutSec;
uint64_t Val;
const SymbolBody *Sym;
};
enum KindT { SecAddr, SecSize, SymAddr, PlainInt } Kind;
Entry(int32_t Tag, OutputSectionBase<ELFT> *OutSec, KindT Kind = SecAddr)
Entry(int32_t Tag, OutputSectionBase *OutSec, KindT Kind = SecAddr)
: Tag(Tag), OutSec(OutSec), Kind(Kind) {}
Entry(int32_t Tag, uint64_t Val) : Tag(Tag), Val(Val), Kind(PlainInt) {}
Entry(int32_t Tag, const SymbolBody *Sym)
@ -621,8 +622,10 @@ public:
DynamicSection();
void finalize() override;
void writeTo(uint8_t *Buf) override;
typename Base::Kind getKind() const override { return Base::Dynamic; }
static bool classof(const Base *B) { return B->getKind() == Base::Dynamic; }
Kind getKind() const override { return Dynamic; }
static bool classof(const OutputSectionBase *B) {
return B->getKind() == Dynamic;
}
private:
void addEntries();
@ -638,19 +641,17 @@ private:
// Detailed info about internals can be found in Ian Lance Taylor's blog:
// http://www.airs.com/blog/archives/460 (".eh_frame")
// http://www.airs.com/blog/archives/462 (".eh_frame_hdr")
template <class ELFT>
class EhFrameHeader final : public OutputSectionBase<ELFT> {
template <class ELFT> class EhFrameHeader final : public OutputSectionBase {
typedef typename ELFT::uint uintX_t;
typedef OutputSectionBase<ELFT> Base;
public:
EhFrameHeader();
void finalize() override;
void writeTo(uint8_t *Buf) override;
void addFde(uint32_t Pc, uint32_t FdeVA);
typename Base::Kind getKind() const override { return Base::EHFrameHdr; }
static bool classof(const Base *B) {
return B->getKind() == Base::EHFrameHdr;
Kind getKind() const override { return EHFrameHdr; }
static bool classof(const OutputSectionBase *B) {
return B->getKind() == EHFrameHdr;
}
private:
@ -680,7 +681,7 @@ template <class ELFT> struct Out {
static HashTableSection<ELFT> *HashTab;
static OutputSection<ELFT> *Bss;
static OutputSection<ELFT> *MipsRldMap;
static OutputSectionBase<ELFT> *Opd;
static OutputSectionBase *Opd;
static uint8_t *OpdBuf;
static PltSection<ELFT> *Plt;
static RelocationSection<ELFT> *RelaDyn;
@ -694,12 +695,12 @@ template <class ELFT> struct Out {
static VersionTableSection<ELFT> *VerSym;
static VersionNeedSection<ELFT> *VerNeed;
static Elf_Phdr *TlsPhdr;
static OutputSectionBase<ELFT> *DebugInfo;
static OutputSectionBase<ELFT> *ElfHeader;
static OutputSectionBase<ELFT> *ProgramHeaders;
static OutputSectionBase<ELFT> *PreinitArray;
static OutputSectionBase<ELFT> *InitArray;
static OutputSectionBase<ELFT> *FiniArray;
static OutputSectionBase *DebugInfo;
static OutputSectionBase *ElfHeader;
static OutputSectionBase *ProgramHeaders;
static OutputSectionBase *PreinitArray;
static OutputSectionBase *InitArray;
static OutputSectionBase *FiniArray;
};
template <bool Is64Bits> struct SectionKey {
@ -720,13 +721,13 @@ template <class ELFT> class OutputSectionFactory {
typedef typename elf::SectionKey<ELFT::Is64Bits> Key;
public:
std::pair<OutputSectionBase<ELFT> *, bool> create(InputSectionBase<ELFT> *C,
std::pair<OutputSectionBase *, bool> create(InputSectionBase<ELFT> *C,
StringRef OutsecName);
std::pair<OutputSectionBase<ELFT> *, bool>
std::pair<OutputSectionBase *, bool>
create(const SectionKey<ELFT::Is64Bits> &Key, InputSectionBase<ELFT> *C);
private:
llvm::SmallDenseMap<Key, OutputSectionBase<ELFT> *> Map;
llvm::SmallDenseMap<Key, OutputSectionBase *> Map;
};
template <class ELFT> uint64_t getHeaderSize() {
@ -746,7 +747,7 @@ template <class ELFT> GotSection<ELFT> *Out<ELFT>::Got;
template <class ELFT> HashTableSection<ELFT> *Out<ELFT>::HashTab;
template <class ELFT> OutputSection<ELFT> *Out<ELFT>::Bss;
template <class ELFT> OutputSection<ELFT> *Out<ELFT>::MipsRldMap;
template <class ELFT> OutputSectionBase<ELFT> *Out<ELFT>::Opd;
template <class ELFT> OutputSectionBase *Out<ELFT>::Opd;
template <class ELFT> uint8_t *Out<ELFT>::OpdBuf;
template <class ELFT> PltSection<ELFT> *Out<ELFT>::Plt;
template <class ELFT> RelocationSection<ELFT> *Out<ELFT>::RelaDyn;
@ -760,12 +761,12 @@ template <class ELFT> VersionDefinitionSection<ELFT> *Out<ELFT>::VerDef;
template <class ELFT> VersionTableSection<ELFT> *Out<ELFT>::VerSym;
template <class ELFT> VersionNeedSection<ELFT> *Out<ELFT>::VerNeed;
template <class ELFT> typename ELFT::Phdr *Out<ELFT>::TlsPhdr;
template <class ELFT> OutputSectionBase<ELFT> *Out<ELFT>::DebugInfo;
template <class ELFT> OutputSectionBase<ELFT> *Out<ELFT>::ElfHeader;
template <class ELFT> OutputSectionBase<ELFT> *Out<ELFT>::ProgramHeaders;
template <class ELFT> OutputSectionBase<ELFT> *Out<ELFT>::PreinitArray;
template <class ELFT> OutputSectionBase<ELFT> *Out<ELFT>::InitArray;
template <class ELFT> OutputSectionBase<ELFT> *Out<ELFT>::FiniArray;
template <class ELFT> OutputSectionBase *Out<ELFT>::DebugInfo;
template <class ELFT> OutputSectionBase *Out<ELFT>::ElfHeader;
template <class ELFT> OutputSectionBase *Out<ELFT>::ProgramHeaders;
template <class ELFT> OutputSectionBase *Out<ELFT>::PreinitArray;
template <class ELFT> OutputSectionBase *Out<ELFT>::InitArray;
template <class ELFT> OutputSectionBase *Out<ELFT>::FiniArray;
} // namespace elf
} // namespace lld

View File

@ -429,8 +429,7 @@ Symbol *SymbolTable<ELFT>::addRegular(StringRef Name, uint8_t StOther,
}
template <typename ELFT>
Symbol *SymbolTable<ELFT>::addSynthetic(StringRef N,
OutputSectionBase<ELFT> *Section,
Symbol *SymbolTable<ELFT>::addSynthetic(StringRef N, OutputSectionBase *Section,
uintX_t Value, uint8_t StOther) {
Symbol *S;
bool WasInserted;

View File

@ -19,7 +19,7 @@
namespace lld {
namespace elf {
class Lazy;
template <class ELFT> class OutputSectionBase;
class OutputSectionBase;
struct Symbol;
typedef llvm::CachedHashStringRef SymName;
@ -67,8 +67,8 @@ public:
Symbol *addRegular(StringRef Name, uint8_t StOther,
InputSectionBase<ELFT> *Section, uint8_t Binding,
uint8_t Type, uintX_t Value);
Symbol *addSynthetic(StringRef N, OutputSectionBase<ELFT> *Section,
uintX_t Value, uint8_t StOther);
Symbol *addSynthetic(StringRef N, OutputSectionBase *Section, uintX_t Value,
uint8_t StOther);
void addShared(SharedFile<ELFT> *F, StringRef Name, const Elf_Sym &Sym,
const typename ELFT::Verdef *Verdef);

View File

@ -33,7 +33,7 @@ static typename ELFT::uint getSymVA(const SymbolBody &Body,
switch (Body.kind()) {
case SymbolBody::DefinedSyntheticKind: {
auto &D = cast<DefinedSynthetic<ELFT>>(Body);
const OutputSectionBase<ELFT> *Sec = D.Section;
const OutputSectionBase *Sec = D.Section;
if (!Sec)
return D.Value;
if (D.Value == DefinedSynthetic<ELFT>::SectionEnd)
@ -216,7 +216,7 @@ Undefined::Undefined(uint32_t NameOffset, uint8_t StOther, uint8_t Type,
template <typename ELFT>
DefinedSynthetic<ELFT>::DefinedSynthetic(StringRef N, uintX_t Value,
OutputSectionBase<ELFT> *Section)
OutputSectionBase *Section)
: Defined(SymbolBody::DefinedSyntheticKind, N, STV_HIDDEN, 0 /* Type */),
Value(Value), Section(Section) {}

View File

@ -31,7 +31,7 @@ class LazyObjectFile;
class SymbolBody;
template <class ELFT> class ObjectFile;
template <class ELFT> class OutputSection;
template <class ELFT> class OutputSectionBase;
class OutputSectionBase;
template <class ELFT> class SharedFile;
struct Symbol;
@ -249,8 +249,7 @@ InputSectionBase<ELFT> *DefinedRegular<ELFT>::NullInputSection;
template <class ELFT> class DefinedSynthetic : public Defined {
public:
typedef typename ELFT::uint uintX_t;
DefinedSynthetic(StringRef N, uintX_t Value,
OutputSectionBase<ELFT> *Section);
DefinedSynthetic(StringRef N, uintX_t Value, OutputSectionBase *Section);
static bool classof(const SymbolBody *S) {
return S->kind() == SymbolBody::DefinedSyntheticKind;
@ -261,7 +260,7 @@ public:
static const uintX_t SectionEnd = uintX_t(-1);
uintX_t Value;
const OutputSectionBase<ELFT> *Section;
const OutputSectionBase *Section;
};
class Undefined : public SymbolBody {

View File

@ -77,13 +77,13 @@ private:
std::unique_ptr<FileOutputBuffer> Buffer;
std::vector<OutputSectionBase<ELFT> *> OutputSections;
std::vector<OutputSectionBase *> OutputSections;
OutputSectionFactory<ELFT> Factory;
void addRelIpltSymbols();
void addStartEndSymbols();
void addStartStopSymbols(OutputSectionBase<ELFT> *Sec);
OutputSectionBase<ELFT> *findSection(StringRef Name);
void addStartStopSymbols(OutputSectionBase *Sec);
OutputSectionBase *findSection(StringRef Name);
std::vector<Phdr> Phdrs;
@ -221,9 +221,9 @@ template <class ELFT> void Writer<ELFT>::createSyntheticSections() {
Out<ELFT>::VerSym = make<VersionTableSection<ELFT>>();
Out<ELFT>::VerNeed = make<VersionNeedSection<ELFT>>();
Out<ELFT>::ElfHeader = make<OutputSectionBase<ELFT>>("", 0, SHF_ALLOC);
Out<ELFT>::ElfHeader = make<OutputSectionBase>("", 0, SHF_ALLOC);
Out<ELFT>::ElfHeader->Size = sizeof(Elf_Ehdr);
Out<ELFT>::ProgramHeaders = make<OutputSectionBase<ELFT>>("", 0, SHF_ALLOC);
Out<ELFT>::ProgramHeaders = make<OutputSectionBase>("", 0, SHF_ALLOC);
Out<ELFT>::ProgramHeaders->updateAlignment(sizeof(uintX_t));
if (needsInterpSection<ELFT>()) {
@ -411,11 +411,10 @@ static int getPPC64SectionRank(StringRef SectionName) {
.Default(1);
}
template <class ELFT>
bool elf::isRelroSection(const OutputSectionBase<ELFT> *Sec) {
template <class ELFT> bool elf::isRelroSection(const OutputSectionBase *Sec) {
if (!Config->ZRelro)
return false;
typename ELFT::uint Flags = Sec->Flags;
uint64_t Flags = Sec->Flags;
if (!(Flags & SHF_ALLOC) || !(Flags & SHF_WRITE))
return false;
if (Flags & SHF_TLS)
@ -434,8 +433,8 @@ bool elf::isRelroSection(const OutputSectionBase<ELFT> *Sec) {
}
template <class ELFT>
static bool compareSectionsNonScript(const OutputSectionBase<ELFT> *A,
const OutputSectionBase<ELFT> *B) {
static bool compareSectionsNonScript(const OutputSectionBase *A,
const OutputSectionBase *B) {
// Put .interp first because some loaders want to see that section
// on the first page of the executable file when loaded into memory.
bool AIsInterp = A->getName() == ".interp";
@ -496,8 +495,8 @@ static bool compareSectionsNonScript(const OutputSectionBase<ELFT> *A,
return BIsNoBits;
// We place RelRo section before plain r/w ones.
bool AIsRelRo = isRelroSection(A);
bool BIsRelRo = isRelroSection(B);
bool AIsRelRo = isRelroSection<ELFT>(A);
bool BIsRelRo = isRelroSection<ELFT>(B);
if (AIsRelRo != BIsRelRo)
return AIsRelRo;
@ -512,8 +511,8 @@ static bool compareSectionsNonScript(const OutputSectionBase<ELFT> *A,
// Output section ordering is determined by this function.
template <class ELFT>
static bool compareSections(const OutputSectionBase<ELFT> *A,
const OutputSectionBase<ELFT> *B) {
static bool compareSections(const OutputSectionBase *A,
const OutputSectionBase *B) {
// For now, put sections mentioned in a linker script first.
int AIndex = Script<ELFT>::X->getSectionIndex(A->getName());
int BIndex = Script<ELFT>::X->getSectionIndex(B->getName());
@ -525,7 +524,7 @@ static bool compareSections(const OutputSectionBase<ELFT> *A,
if (AInScript)
return AIndex < BIndex;
return compareSectionsNonScript(A, B);
return compareSectionsNonScript<ELFT>(A, B);
}
// Program header entry
@ -535,7 +534,7 @@ PhdrEntry<ELFT>::PhdrEntry(unsigned Type, unsigned Flags) {
H.p_flags = Flags;
}
template <class ELFT> void PhdrEntry<ELFT>::add(OutputSectionBase<ELFT> *Sec) {
template <class ELFT> void PhdrEntry<ELFT>::add(OutputSectionBase *Sec) {
Last = Sec;
if (!First)
First = Sec;
@ -545,9 +544,9 @@ template <class ELFT> void PhdrEntry<ELFT>::add(OutputSectionBase<ELFT> *Sec) {
}
template <class ELFT>
static Symbol *
addOptionalSynthetic(StringRef Name, OutputSectionBase<ELFT> *Sec,
typename ELFT::uint Val, uint8_t StOther = STV_HIDDEN) {
static Symbol *addOptionalSynthetic(StringRef Name, OutputSectionBase *Sec,
typename ELFT::uint Val,
uint8_t StOther = STV_HIDDEN) {
SymbolBody *S = Symtab<ELFT>::X->find(Name);
if (!S)
return nullptr;
@ -566,10 +565,10 @@ template <class ELFT> void Writer<ELFT>::addRelIpltSymbols() {
if (Out<ELFT>::DynSymTab || !Out<ELFT>::RelaPlt)
return;
StringRef S = Config->Rela ? "__rela_iplt_start" : "__rel_iplt_start";
addOptionalSynthetic(S, Out<ELFT>::RelaPlt, 0);
addOptionalSynthetic<ELFT>(S, Out<ELFT>::RelaPlt, 0);
S = Config->Rela ? "__rela_iplt_end" : "__rel_iplt_end";
addOptionalSynthetic(S, Out<ELFT>::RelaPlt,
addOptionalSynthetic<ELFT>(S, Out<ELFT>::RelaPlt,
DefinedSynthetic<ELFT>::SectionEnd);
}
@ -587,7 +586,7 @@ template <class ELFT> void Writer<ELFT>::addReservedSymbols() {
// On MIPS O32 ABI, _gp_disp is a magic symbol designates offset between
// start of function and 'gp' pointer into GOT.
Symbol *Sym =
addOptionalSynthetic("_gp_disp", Out<ELFT>::Got, MipsGPOffset);
addOptionalSynthetic<ELFT>("_gp_disp", Out<ELFT>::Got, MipsGPOffset);
if (Sym)
ElfSym<ELFT>::MipsGpDisp = Sym->body();
@ -595,7 +594,7 @@ template <class ELFT> void Writer<ELFT>::addReservedSymbols() {
// pointer. This symbol is used in the code generated by .cpload pseudo-op
// in case of using -mno-shared option.
// https://sourceware.org/ml/binutils/2004-12/msg00094.html
addOptionalSynthetic("__gnu_local_gp", Out<ELFT>::Got, MipsGPOffset);
addOptionalSynthetic<ELFT>("__gnu_local_gp", Out<ELFT>::Got, MipsGPOffset);
}
// In the assembly for 32 bit x86 the _GLOBAL_OFFSET_TABLE_ symbol
@ -649,13 +648,13 @@ template <class ELFT> void Writer<ELFT>::addReservedSymbols() {
// Sort input sections by section name suffixes for
// __attribute__((init_priority(N))).
template <class ELFT> static void sortInitFini(OutputSectionBase<ELFT> *S) {
template <class ELFT> static void sortInitFini(OutputSectionBase *S) {
if (S)
reinterpret_cast<OutputSection<ELFT> *>(S)->sortInitFini();
}
// Sort input sections by the special rule for .ctors and .dtors.
template <class ELFT> static void sortCtorsDtors(OutputSectionBase<ELFT> *S) {
template <class ELFT> static void sortCtorsDtors(OutputSectionBase *S) {
if (S)
reinterpret_cast<OutputSection<ELFT> *>(S)->sortCtorsDtors();
}
@ -691,7 +690,7 @@ void Writer<ELFT>::addInputSec(InputSectionBase<ELFT> *IS) {
reportDiscarded(IS);
return;
}
OutputSectionBase<ELFT> *Sec;
OutputSectionBase *Sec;
bool IsNew;
StringRef OutsecName = getOutputSectionName(IS->Name);
std::tie(Sec, IsNew) = Factory.create(IS, OutsecName);
@ -704,18 +703,18 @@ template <class ELFT> void Writer<ELFT>::createSections() {
for (InputSectionBase<ELFT> *IS : Symtab<ELFT>::X->Sections)
addInputSec(IS);
sortInitFini(findSection(".init_array"));
sortInitFini(findSection(".fini_array"));
sortCtorsDtors(findSection(".ctors"));
sortCtorsDtors(findSection(".dtors"));
sortInitFini<ELFT>(findSection(".init_array"));
sortInitFini<ELFT>(findSection(".fini_array"));
sortCtorsDtors<ELFT>(findSection(".ctors"));
sortCtorsDtors<ELFT>(findSection(".dtors"));
for (OutputSectionBase<ELFT> *Sec : OutputSections)
for (OutputSectionBase *Sec : OutputSections)
Sec->assignOffsets();
}
template <class ELFT>
static bool canSharePtLoad(const OutputSectionBase<ELFT> &S1,
const OutputSectionBase<ELFT> &S2) {
static bool canSharePtLoad(const OutputSectionBase &S1,
const OutputSectionBase &S2) {
if (!(S1.Flags & SHF_ALLOC) || !(S2.Flags & SHF_ALLOC))
return false;
@ -767,15 +766,14 @@ template <class ELFT> void Writer<ELFT>::sortSections() {
auto I = OutputSections.begin();
auto E = OutputSections.end();
auto NonScriptI =
std::find_if(OutputSections.begin(), E, [](OutputSectionBase<ELFT> *S) {
std::find_if(OutputSections.begin(), E, [](OutputSectionBase *S) {
return Script<ELFT>::X->getSectionIndex(S->getName()) == INT_MAX;
});
while (NonScriptI != E) {
auto BestPos =
std::max_element(I, NonScriptI, [&](OutputSectionBase<ELFT> *&A,
OutputSectionBase<ELFT> *&B) {
bool ACanSharePtLoad = canSharePtLoad(**NonScriptI, *A);
bool BCanSharePtLoad = canSharePtLoad(**NonScriptI, *B);
auto BestPos = std::max_element(
I, NonScriptI, [&](OutputSectionBase *&A, OutputSectionBase *&B) {
bool ACanSharePtLoad = canSharePtLoad<ELFT>(**NonScriptI, *A);
bool BCanSharePtLoad = canSharePtLoad<ELFT>(**NonScriptI, *B);
if (ACanSharePtLoad != BCanSharePtLoad)
return BCanSharePtLoad;
@ -812,7 +810,7 @@ template <class ELFT> void Writer<ELFT>::finalizeSections() {
// addresses of each section by section name. Add such symbols.
if (!Config->Relocatable) {
addStartEndSymbols();
for (OutputSectionBase<ELFT> *Sec : OutputSections)
for (OutputSectionBase *Sec : OutputSections)
addStartStopSymbols(Sec);
}
@ -865,7 +863,7 @@ template <class ELFT> void Writer<ELFT>::finalizeSections() {
sortSections();
unsigned I = 1;
for (OutputSectionBase<ELFT> *Sec : OutputSections) {
for (OutputSectionBase *Sec : OutputSections) {
Sec->SectionIndex = I++;
Sec->ShName = Out<ELFT>::ShStrTab->addString(Sec->getName());
}
@ -878,7 +876,7 @@ template <class ELFT> void Writer<ELFT>::finalizeSections() {
// Fill other section headers. The dynamic table is finalized
// at the end because some tags like RELSZ depend on result
// of finalizing other sections.
for (OutputSectionBase<ELFT> *Sec : OutputSections)
for (OutputSectionBase *Sec : OutputSections)
if (Sec != Out<ELFT>::Dynamic)
Sec->finalize();
@ -887,7 +885,7 @@ template <class ELFT> void Writer<ELFT>::finalizeSections() {
// Now that all output offsets are fixed. Finalize mergeable sections
// to fix their maps from input offsets to output offsets.
for (OutputSectionBase<ELFT> *Sec : OutputSections)
for (OutputSectionBase *Sec : OutputSections)
Sec->finalizePieces();
}
@ -907,7 +905,7 @@ template <class ELFT> bool Writer<ELFT>::needsGot() {
// This function add Out<ELFT>::* sections to OutputSections.
template <class ELFT> void Writer<ELFT>::addPredefinedSections() {
auto Add = [&](OutputSectionBase<ELFT> *OS) {
auto Add = [&](OutputSectionBase *OS) {
if (OS)
OutputSections.push_back(OS);
};
@ -958,11 +956,11 @@ template <class ELFT> void Writer<ELFT>::addPredefinedSections() {
// The linker is expected to define SECNAME_start and SECNAME_end
// symbols for a few sections. This function defines them.
template <class ELFT> void Writer<ELFT>::addStartEndSymbols() {
auto Define = [&](StringRef Start, StringRef End,
OutputSectionBase<ELFT> *OS) {
auto Define = [&](StringRef Start, StringRef End, OutputSectionBase *OS) {
// These symbols resolve to the image base if the section does not exist.
addOptionalSynthetic(Start, OS, 0);
addOptionalSynthetic(End, OS, OS ? DefinedSynthetic<ELFT>::SectionEnd : 0);
addOptionalSynthetic<ELFT>(Start, OS, 0);
addOptionalSynthetic<ELFT>(End, OS,
OS ? DefinedSynthetic<ELFT>::SectionEnd : 0);
};
Define("__preinit_array_start", "__preinit_array_end",
@ -970,7 +968,7 @@ template <class ELFT> void Writer<ELFT>::addStartEndSymbols() {
Define("__init_array_start", "__init_array_end", Out<ELFT>::InitArray);
Define("__fini_array_start", "__fini_array_end", Out<ELFT>::FiniArray);
if (OutputSectionBase<ELFT> *Sec = findSection(".ARM.exidx"))
if (OutputSectionBase *Sec = findSection(".ARM.exidx"))
Define("__exidx_start", "__exidx_end", Sec);
}
@ -980,24 +978,24 @@ template <class ELFT> void Writer<ELFT>::addStartEndSymbols() {
// respectively. This is not requested by the ELF standard, but GNU ld and
// gold provide the feature, and used by many programs.
template <class ELFT>
void Writer<ELFT>::addStartStopSymbols(OutputSectionBase<ELFT> *Sec) {
void Writer<ELFT>::addStartStopSymbols(OutputSectionBase *Sec) {
StringRef S = Sec->getName();
if (!isValidCIdentifier(S))
return;
addOptionalSynthetic(Saver.save("__start_" + S), Sec, 0, STV_DEFAULT);
addOptionalSynthetic(Saver.save("__stop_" + S), Sec,
addOptionalSynthetic<ELFT>(Saver.save("__start_" + S), Sec, 0, STV_DEFAULT);
addOptionalSynthetic<ELFT>(Saver.save("__stop_" + S), Sec,
DefinedSynthetic<ELFT>::SectionEnd, STV_DEFAULT);
}
template <class ELFT>
OutputSectionBase<ELFT> *Writer<ELFT>::findSection(StringRef Name) {
for (OutputSectionBase<ELFT> *Sec : OutputSections)
OutputSectionBase *Writer<ELFT>::findSection(StringRef Name) {
for (OutputSectionBase *Sec : OutputSections)
if (Sec->getName() == Name)
return Sec;
return nullptr;
}
template <class ELFT> static bool needsPtLoad(OutputSectionBase<ELFT> *Sec) {
template <class ELFT> static bool needsPtLoad(OutputSectionBase *Sec) {
if (!(Sec->Flags & SHF_ALLOC))
return false;
@ -1034,7 +1032,7 @@ template <class ELFT> std::vector<PhdrEntry<ELFT>> Writer<ELFT>::createPhdrs() {
Hdr.add(Out<ELFT>::ProgramHeaders);
// PT_INTERP must be the second entry if exists.
if (OutputSectionBase<ELFT> *Sec = findSection(".interp")) {
if (OutputSectionBase *Sec = findSection(".interp")) {
Phdr &Hdr = *AddHdr(PT_INTERP, Sec->getPhdrFlags());
Hdr.add(Sec);
}
@ -1051,7 +1049,7 @@ template <class ELFT> std::vector<PhdrEntry<ELFT>> Writer<ELFT>::createPhdrs() {
Phdr RelRo(PT_GNU_RELRO, PF_R);
Phdr Note(PT_NOTE, PF_R);
Phdr ARMExidx(PT_ARM_EXIDX, PF_R);
for (OutputSectionBase<ELFT> *Sec : OutputSections) {
for (OutputSectionBase *Sec : OutputSections) {
if (!(Sec->Flags & SHF_ALLOC))
break;
@ -1061,7 +1059,7 @@ template <class ELFT> std::vector<PhdrEntry<ELFT>> Writer<ELFT>::createPhdrs() {
if (Sec->Flags & SHF_TLS)
TlsHdr.add(Sec);
if (!needsPtLoad(Sec))
if (!needsPtLoad<ELFT>(Sec))
continue;
// Segments are contiguous memory regions that has the same attributes
@ -1077,7 +1075,7 @@ template <class ELFT> std::vector<PhdrEntry<ELFT>> Writer<ELFT>::createPhdrs() {
Load->add(Sec);
if (isRelroSection(Sec))
if (isRelroSection<ELFT>(Sec))
RelRo.add(Sec);
if (Sec->Type == SHT_NOTE)
Note.add(Sec);
@ -1109,7 +1107,7 @@ template <class ELFT> std::vector<PhdrEntry<ELFT>> Writer<ELFT>::createPhdrs() {
// PT_OPENBSD_RANDOMIZE specifies the location and size of a part of the
// memory image of the program that must be filled with random data before any
// code in the object is executed.
if (OutputSectionBase<ELFT> *Sec = findSection(".openbsd.randomdata")) {
if (OutputSectionBase *Sec = findSection(".openbsd.randomdata")) {
Phdr &Hdr = *AddHdr(PT_OPENBSD_RANDOMIZE, Sec->getPhdrFlags());
Hdr.add(Sec);
}
@ -1154,8 +1152,8 @@ template <class ELFT> void Writer<ELFT>::fixSectionAlignments() {
auto I = std::find(OutputSections.begin(), End, P.Last);
if (I == End || (I + 1) == End)
continue;
OutputSectionBase<ELFT> *Sec = *(I + 1);
if (needsPtLoad(Sec))
OutputSectionBase *Sec = *(I + 1);
if (needsPtLoad<ELFT>(Sec))
Sec->PageAlign = true;
}
}
@ -1175,7 +1173,7 @@ template <class ELFT> void Writer<ELFT>::fixHeaders() {
template <class ELFT> void Writer<ELFT>::assignAddresses() {
uintX_t VA = Config->ImageBase + getHeaderSize<ELFT>();
uintX_t ThreadBssOffset = 0;
for (OutputSectionBase<ELFT> *Sec : OutputSections) {
for (OutputSectionBase *Sec : OutputSections) {
uintX_t Alignment = Sec->Addralign;
if (Sec->PageAlign)
Alignment = std::max<uintX_t>(Alignment, Config->MaxPageSize);
@ -1185,7 +1183,7 @@ template <class ELFT> void Writer<ELFT>::assignAddresses() {
VA = I->second;
// We only assign VAs to allocated sections.
if (needsPtLoad(Sec)) {
if (needsPtLoad<ELFT>(Sec)) {
VA = alignTo(VA, Alignment);
Sec->Addr = VA;
VA += Sec->Size;
@ -1203,13 +1201,13 @@ template <class ELFT> void Writer<ELFT>::assignAddresses() {
// virtual address (modulo the page size) so that the loader can load
// executables without any address adjustment.
template <class ELFT, class uintX_t>
static uintX_t getFileAlignment(uintX_t Off, OutputSectionBase<ELFT> *Sec) {
static uintX_t getFileAlignment(uintX_t Off, OutputSectionBase *Sec) {
uintX_t Alignment = Sec->Addralign;
if (Sec->PageAlign)
Alignment = std::max<uintX_t>(Alignment, Config->MaxPageSize);
Off = alignTo(Off, Alignment);
OutputSectionBase<ELFT> *First = Sec->FirstInPtLoad;
OutputSectionBase *First = Sec->FirstInPtLoad;
// If the section is not in a PT_LOAD, we have no other constraint.
if (!First)
return Off;
@ -1222,7 +1220,7 @@ static uintX_t getFileAlignment(uintX_t Off, OutputSectionBase<ELFT> *Sec) {
}
template <class ELFT, class uintX_t>
void setOffset(OutputSectionBase<ELFT> *Sec, uintX_t &Off) {
void setOffset(OutputSectionBase *Sec, uintX_t &Off) {
if (Sec->Type == SHT_NOBITS) {
Sec->Offset = Off;
return;
@ -1235,20 +1233,20 @@ void setOffset(OutputSectionBase<ELFT> *Sec, uintX_t &Off) {
template <class ELFT> void Writer<ELFT>::assignFileOffsetsBinary() {
uintX_t Off = 0;
for (OutputSectionBase<ELFT> *Sec : OutputSections)
for (OutputSectionBase *Sec : OutputSections)
if (Sec->Flags & SHF_ALLOC)
setOffset(Sec, Off);
setOffset<ELFT>(Sec, Off);
FileSize = alignTo(Off, sizeof(uintX_t));
}
// Assign file offsets to output sections.
template <class ELFT> void Writer<ELFT>::assignFileOffsets() {
uintX_t Off = 0;
setOffset(Out<ELFT>::ElfHeader, Off);
setOffset(Out<ELFT>::ProgramHeaders, Off);
setOffset<ELFT>(Out<ELFT>::ElfHeader, Off);
setOffset<ELFT>(Out<ELFT>::ProgramHeaders, Off);
for (OutputSectionBase<ELFT> *Sec : OutputSections)
setOffset(Sec, Off);
for (OutputSectionBase *Sec : OutputSections)
setOffset<ELFT>(Sec, Off);
SectionHeaderOff = alignTo(Off, sizeof(uintX_t));
FileSize = SectionHeaderOff + (OutputSections.size() + 1) * sizeof(Elf_Shdr);
@ -1259,8 +1257,8 @@ template <class ELFT> void Writer<ELFT>::assignFileOffsets() {
template <class ELFT> void Writer<ELFT>::setPhdrs() {
for (Phdr &P : Phdrs) {
Elf_Phdr &H = P.H;
OutputSectionBase<ELFT> *First = P.First;
OutputSectionBase<ELFT> *Last = P.Last;
OutputSectionBase *First = P.First;
OutputSectionBase *Last = P.Last;
if (First) {
H.p_filesz = Last->Offset - First->Offset;
if (Last->Type != SHT_NOBITS)
@ -1382,8 +1380,8 @@ template <class ELFT> void Writer<ELFT>::writeHeader() {
// Write the section header table. Note that the first table entry is null.
auto *SHdrs = reinterpret_cast<Elf_Shdr *>(Buf + EHdr->e_shoff);
for (OutputSectionBase<ELFT> *Sec : OutputSections)
Sec->writeHeaderTo(++SHdrs);
for (OutputSectionBase *Sec : OutputSections)
Sec->writeHeaderTo<ELFT>(++SHdrs);
}
template <class ELFT> void Writer<ELFT>::openFile() {
@ -1398,7 +1396,7 @@ template <class ELFT> void Writer<ELFT>::openFile() {
template <class ELFT> void Writer<ELFT>::writeSectionsBinary() {
uint8_t *Buf = Buffer->getBufferStart();
for (OutputSectionBase<ELFT> *Sec : OutputSections)
for (OutputSectionBase *Sec : OutputSections)
if (Sec->Flags & SHF_ALLOC)
Sec->writeTo(Buf + Sec->Offset);
}
@ -1477,11 +1475,11 @@ template <class ELFT> void Writer<ELFT>::writeSections() {
Out<ELFT>::Opd->writeTo(Buf + Out<ELFT>::Opd->Offset);
}
for (OutputSectionBase<ELFT> *Sec : OutputSections)
for (OutputSectionBase *Sec : OutputSections)
if (Sec != Out<ELFT>::Opd && Sec != Out<ELFT>::EhFrameHdr)
Sec->writeTo(Buf + Sec->Offset);
OutputSectionBase<ELFT> *ARMExidx = findSection(".ARM.exidx");
OutputSectionBase *ARMExidx = findSection(".ARM.exidx");
if (!Config->Relocatable)
if (auto *OS = dyn_cast_or_null<OutputSection<ELFT>>(ARMExidx))
sortARMExidx(Buf + OS->Offset, OS->Addr, OS->Size);
@ -1512,10 +1510,10 @@ template struct elf::PhdrEntry<ELF32BE>;
template struct elf::PhdrEntry<ELF64LE>;
template struct elf::PhdrEntry<ELF64BE>;
template bool elf::isRelroSection<ELF32LE>(const OutputSectionBase<ELF32LE> *);
template bool elf::isRelroSection<ELF32BE>(const OutputSectionBase<ELF32BE> *);
template bool elf::isRelroSection<ELF64LE>(const OutputSectionBase<ELF64LE> *);
template bool elf::isRelroSection<ELF64BE>(const OutputSectionBase<ELF64BE> *);
template bool elf::isRelroSection<ELF32LE>(const OutputSectionBase *);
template bool elf::isRelroSection<ELF32BE>(const OutputSectionBase *);
template bool elf::isRelroSection<ELF64LE>(const OutputSectionBase *);
template bool elf::isRelroSection<ELF64BE>(const OutputSectionBase *);
template void elf::reportDiscarded<ELF32LE>(InputSectionBase<ELF32LE> *);
template void elf::reportDiscarded<ELF32BE>(InputSectionBase<ELF32BE> *);

View File

@ -17,24 +17,24 @@
namespace lld {
namespace elf {
class InputFile;
template <class ELFT> class OutputSectionBase;
class OutputSectionBase;
template <class ELFT> class InputSectionBase;
template <class ELFT> class ObjectFile;
template <class ELFT> class SymbolTable;
template <class ELFT> void writeResult();
template <class ELFT> void markLive();
template <class ELFT> bool isRelroSection(const OutputSectionBase<ELFT> *Sec);
template <class ELFT> bool isRelroSection(const OutputSectionBase *Sec);
// This describes a program header entry.
// Each contains type, access flags and range of output sections that will be
// placed in it.
template <class ELFT> struct PhdrEntry {
PhdrEntry(unsigned Type, unsigned Flags);
void add(OutputSectionBase<ELFT> *Sec);
void add(OutputSectionBase *Sec);
typename ELFT::Phdr H = {};
OutputSectionBase<ELFT> *First = nullptr;
OutputSectionBase<ELFT> *Last = nullptr;
OutputSectionBase *First = nullptr;
OutputSectionBase *Last = nullptr;
bool HasLMA = false;
};