[ELF] Make Partition members unique_ptr and remove associate make<XXX>

See D116143 for benefits. My lld executable (x86-64) is 103+KiB smaller.
This commit is contained in:
Fangrui Song
2021-12-22 21:34:25 -08:00
parent 9f3aca7eae
commit e48b1c8a27
5 changed files with 62 additions and 56 deletions

View File

@@ -99,7 +99,8 @@ bool elf::link(ArrayRef<const char *> args, bool canExitEarly,
tar = nullptr;
memset(&in, 0, sizeof(in));
partitions = {Partition()};
partitions.clear();
partitions.emplace_back();
SharedFile::vernauxNum = 0;
};
@@ -116,7 +117,8 @@ bool elf::link(ArrayRef<const char *> args, bool canExitEarly,
script = std::make_unique<LinkerScript>();
symtab = std::make_unique<SymbolTable>();
partitions = {Partition()};
partitions.clear();
partitions.emplace_back();
config->progName = args[0];

View File

@@ -561,15 +561,15 @@ LinkerScript::computeInputSections(const InputSectionDescription *cmd,
}
void LinkerScript::discard(InputSectionBase &s) {
if (&s == in.shStrTab.get() || &s == mainPart->relrDyn)
if (&s == in.shStrTab.get() || &s == mainPart->relrDyn.get())
error("discarding " + s.name + " section is not allowed");
// You can discard .hash and .gnu.hash sections by linker scripts. Since
// they are synthesized sections, we need to handle them differently than
// other regular sections.
if (&s == mainPart->gnuHashTab)
if (&s == mainPart->gnuHashTab.get())
mainPart->gnuHashTab = nullptr;
if (&s == mainPart->hashTab)
if (&s == mainPart->hashTab.get())
mainPart->hashTab = nullptr;
s.markDead();

View File

@@ -1265,11 +1265,11 @@ DynamicSection<ELFT>::DynamicSection()
// .rela.dyn
//
// DT_RELASZ is the total size of the included sections.
static uint64_t addRelaSz(RelocationBaseSection *relaDyn) {
size_t size = relaDyn->getSize();
if (in.relaIplt->getParent() == relaDyn->getParent())
static uint64_t addRelaSz(const RelocationBaseSection &relaDyn) {
size_t size = relaDyn.getSize();
if (in.relaIplt->getParent() == relaDyn.getParent())
size += in.relaIplt->getSize();
if (in.relaPlt->getParent() == relaDyn->getParent())
if (in.relaPlt->getParent() == relaDyn.getParent())
size += in.relaPlt->getSize();
return size;
}
@@ -1375,7 +1375,8 @@ DynamicSection<ELFT>::computeContents() {
(in.relaIplt->isNeeded() &&
part.relaDyn->getParent() == in.relaIplt->getParent())) {
addInSec(part.relaDyn->dynamicTag, *part.relaDyn);
entries.emplace_back(part.relaDyn->sizeDynamicTag, addRelaSz(part.relaDyn));
entries.emplace_back(part.relaDyn->sizeDynamicTag,
addRelaSz(*part.relaDyn));
bool isRela = config->isRela;
addInt(isRela ? DT_RELAENT : DT_RELENT,
@@ -1626,7 +1627,7 @@ void RelocationBaseSection::addReloc(const DynamicReloc &reloc) {
}
void RelocationBaseSection::finalizeContents() {
SymbolTableBaseSection *symTab = getPartition().dynSymTab;
SymbolTableBaseSection *symTab = getPartition().dynSymTab.get();
// When linking glibc statically, .rel{,a}.plt contains R_*_IRELATIVE
// relocations due to IFUNC (e.g. strcpy). sh_link will be set to 0 in that
@@ -1677,7 +1678,7 @@ RelocationSection<ELFT>::RelocationSection(StringRef name, bool sort)
}
template <class ELFT> void RelocationSection<ELFT>::writeTo(uint8_t *buf) {
SymbolTableBaseSection *symTab = getPartition().dynSymTab;
SymbolTableBaseSection *symTab = getPartition().dynSymTab.get();
parallelForEach(relocs,
[symTab](DynamicReloc &rel) { rel.computeRaw(symTab); });
@@ -1772,8 +1773,8 @@ bool AndroidPackedRelocationSection<ELFT>::updateAllocSize() {
for (const DynamicReloc &rel : relocs) {
Elf_Rela r;
r.r_offset = rel.getOffset();
r.setSymbolAndType(rel.getSymIndex(getPartition().dynSymTab), rel.type,
false);
r.setSymbolAndType(rel.getSymIndex(getPartition().dynSymTab.get()),
rel.type, false);
if (config->isRela)
r.r_addend = rel.computeAddend();
@@ -2099,7 +2100,7 @@ void SymbolTableBaseSection::finalizeContents() {
// Only the main partition's dynsym indexes are stored in the symbols
// themselves. All other partitions use a lookup table.
if (this == mainPart->dynSymTab) {
if (this == mainPart->dynSymTab.get()) {
size_t i = 0;
for (const SymbolTableEntry &s : symbols)
s.sym->dynsymIndex = ++i;
@@ -2146,7 +2147,7 @@ void SymbolTableBaseSection::addSymbol(Symbol *b) {
}
size_t SymbolTableBaseSection::getSymbolIndex(Symbol *sym) {
if (this == mainPart->dynSymTab)
if (this == mainPart->dynSymTab.get())
return sym->dynsymIndex;
// Initializes symbol lookup tables lazily. This is used only for -r,
@@ -2481,7 +2482,7 @@ HashTableSection::HashTableSection()
}
void HashTableSection::finalizeContents() {
SymbolTableBaseSection *symTab = getPartition().dynSymTab;
SymbolTableBaseSection *symTab = getPartition().dynSymTab.get();
if (OutputSection *sec = symTab->getParent())
getParent()->link = sec->sectionIndex;
@@ -2495,7 +2496,7 @@ void HashTableSection::finalizeContents() {
}
void HashTableSection::writeTo(uint8_t *buf) {
SymbolTableBaseSection *symTab = getPartition().dynSymTab;
SymbolTableBaseSection *symTab = getPartition().dynSymTab.get();
// See comment in GnuHashTableSection::writeTo.
memset(buf, 0, size);
@@ -3803,7 +3804,7 @@ void PartitionIndexSection::writeTo(uint8_t *buf) {
SyntheticSection *next = i == partitions.size() - 1
? in.partEnd.get()
: partitions[i + 1].elfHeader;
: partitions[i + 1].elfHeader.get();
write32(buf + 8, next->getVA() - partitions[i].elfHeader->getVA());
va += 12;

View File

@@ -1203,24 +1203,24 @@ struct Partition {
StringRef name;
uint64_t nameStrTab;
SyntheticSection *elfHeader;
SyntheticSection *programHeaders;
std::unique_ptr<SyntheticSection> elfHeader;
std::unique_ptr<SyntheticSection> programHeaders;
std::vector<PhdrEntry *> phdrs;
ARMExidxSyntheticSection *armExidx;
BuildIdSection *buildId;
SyntheticSection *dynamic;
StringTableSection *dynStrTab;
SymbolTableBaseSection *dynSymTab;
EhFrameHeader *ehFrameHdr;
EhFrameSection *ehFrame;
GnuHashTableSection *gnuHashTab;
HashTableSection *hashTab;
RelocationBaseSection *relaDyn;
RelrBaseSection *relrDyn;
VersionDefinitionSection *verDef;
SyntheticSection *verNeed;
VersionTableSection *verSym;
std::unique_ptr<ARMExidxSyntheticSection> armExidx;
std::unique_ptr<BuildIdSection> buildId;
std::unique_ptr<SyntheticSection> dynamic;
std::unique_ptr<StringTableSection> dynStrTab;
std::unique_ptr<SymbolTableBaseSection> dynSymTab;
std::unique_ptr<EhFrameHeader> ehFrameHdr;
std::unique_ptr<EhFrameSection> ehFrame;
std::unique_ptr<GnuHashTableSection> gnuHashTab;
std::unique_ptr<HashTableSection> hashTab;
std::unique_ptr<RelocationBaseSection> relaDyn;
std::unique_ptr<RelrBaseSection> relrDyn;
std::unique_ptr<VersionDefinitionSection> verDef;
std::unique_ptr<SyntheticSection> verNeed;
std::unique_ptr<VersionTableSection> verSym;
unsigned getNumber() const { return this - &partitions[0] + 1; }
};

View File

@@ -345,49 +345,52 @@ template <class ELFT> void elf::createSyntheticSections() {
};
if (!part.name.empty()) {
part.elfHeader = make<PartitionElfHeaderSection<ELFT>>();
part.elfHeader = std::make_unique<PartitionElfHeaderSection<ELFT>>();
part.elfHeader->name = part.name;
add(*part.elfHeader);
part.programHeaders = make<PartitionProgramHeadersSection<ELFT>>();
part.programHeaders =
std::make_unique<PartitionProgramHeadersSection<ELFT>>();
add(*part.programHeaders);
}
if (config->buildId != BuildIdKind::None) {
part.buildId = make<BuildIdSection>();
part.buildId = std::make_unique<BuildIdSection>();
add(*part.buildId);
}
part.dynStrTab = make<StringTableSection>(".dynstr", true);
part.dynSymTab = make<SymbolTableSection<ELFT>>(*part.dynStrTab);
part.dynamic = make<DynamicSection<ELFT>>();
part.dynStrTab = std::make_unique<StringTableSection>(".dynstr", true);
part.dynSymTab =
std::make_unique<SymbolTableSection<ELFT>>(*part.dynStrTab);
part.dynamic = std::make_unique<DynamicSection<ELFT>>();
if (config->androidPackDynRelocs)
part.relaDyn = make<AndroidPackedRelocationSection<ELFT>>(relaDynName);
else
part.relaDyn =
make<RelocationSection<ELFT>>(relaDynName, config->zCombreloc);
std::make_unique<AndroidPackedRelocationSection<ELFT>>(relaDynName);
else
part.relaDyn = std::make_unique<RelocationSection<ELFT>>(
relaDynName, config->zCombreloc);
if (config->hasDynSymTab) {
add(*part.dynSymTab);
part.verSym = make<VersionTableSection>();
part.verSym = std::make_unique<VersionTableSection>();
add(*part.verSym);
if (!namedVersionDefs().empty()) {
part.verDef = make<VersionDefinitionSection>();
part.verDef = std::make_unique<VersionDefinitionSection>();
add(*part.verDef);
}
part.verNeed = make<VersionNeedSection<ELFT>>();
part.verNeed = std::make_unique<VersionNeedSection<ELFT>>();
add(*part.verNeed);
if (config->gnuHash) {
part.gnuHashTab = make<GnuHashTableSection>();
part.gnuHashTab = std::make_unique<GnuHashTableSection>();
add(*part.gnuHashTab);
}
if (config->sysvHash) {
part.hashTab = make<HashTableSection>();
part.hashTab = std::make_unique<HashTableSection>();
add(*part.hashTab);
}
@@ -397,23 +400,23 @@ template <class ELFT> void elf::createSyntheticSections() {
}
if (config->relrPackDynRelocs) {
part.relrDyn = make<RelrSection<ELFT>>();
part.relrDyn = std::make_unique<RelrSection<ELFT>>();
add(*part.relrDyn);
}
if (!config->relocatable) {
if (config->ehFrameHdr) {
part.ehFrameHdr = make<EhFrameHeader>();
part.ehFrameHdr = std::make_unique<EhFrameHeader>();
add(*part.ehFrameHdr);
}
part.ehFrame = make<EhFrameSection>();
part.ehFrame = std::make_unique<EhFrameSection>();
add(*part.ehFrame);
}
if (config->emachine == EM_ARM && !config->relocatable) {
// The ARMExidxsyntheticsection replaces all the individual .ARM.exidx
// InputSections.
part.armExidx = make<ARMExidxSyntheticSection>();
part.armExidx = std::make_unique<ARMExidxSyntheticSection>();
add(*part.armExidx);
}
}
@@ -1886,9 +1889,9 @@ template <class ELFT> void Writer<ELFT>::finalizeSections() {
// Even the author of gold doesn't remember why gold behaves that way.
// https://sourceware.org/ml/binutils/2002-03/msg00360.html
if (mainPart->dynamic->parent)
symtab->addSymbol(Defined{/*file=*/nullptr, "_DYNAMIC", STB_WEAK,
STV_HIDDEN, STT_NOTYPE,
/*value=*/0, /*size=*/0, mainPart->dynamic});
symtab->addSymbol(
Defined{/*file=*/nullptr, "_DYNAMIC", STB_WEAK, STV_HIDDEN, STT_NOTYPE,
/*value=*/0, /*size=*/0, mainPart->dynamic.get()});
// Define __rel[a]_iplt_{start,end} symbols if needed.
addRelIpltSymbols();