#include "SyntheticSections.h"
#include "Config.h"
#include "DWARF.h"
#include "EhFrame.h"
#include "InputFiles.h"
#include "LinkerScript.h"
#include "OutputSections.h"
#include "SymbolTable.h"
#include "Symbols.h"
#include "Target.h"
#include "Thunks.h"
#include "Writer.h"
#include "lld/Common/CommonLinkerContext.h"
#include "lld/Common/DWARF.h"
#include "lld/Common/Strings.h"
#include "lld/Common/Version.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/Sequence.h"
#include "llvm/ADT/SetOperations.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/BinaryFormat/Dwarf.h"
#include "llvm/BinaryFormat/ELF.h"
#include "llvm/DebugInfo/DWARF/DWARFAcceleratorTable.h"
#include "llvm/DebugInfo/DWARF/DWARFDebugPubTable.h"
#include "llvm/Support/DJB.h"
#include "llvm/Support/Endian.h"
#include "llvm/Support/LEB128.h"
#include "llvm/Support/Parallel.h"
#include "llvm/Support/TimeProfiler.h"
#include <cinttypes>
#include <cstdlib>
usingnamespacellvm;
usingnamespacellvm::dwarf;
usingnamespacellvm::ELF;
usingnamespacellvm::object;
usingnamespacellvm::support;
usingnamespacelld;
usingnamespacelld::elf;
read32le;
write32le;
write64le;
constexpr size_t MergeNoTailSection::numShards;
static uint64_t readUint(Ctx &ctx, uint8_t *buf) { … }
static void writeUint(uint8_t *buf, uint64_t val) { … }
static ArrayRef<uint8_t> getVersion() { … }
MergeInputSection *elf::createCommentSection() { … }
template <class ELFT>
MipsAbiFlagsSection<ELFT>::MipsAbiFlagsSection(Ctx &ctx,
Elf_Mips_ABIFlags flags)
: … { … }
template <class ELFT> void MipsAbiFlagsSection<ELFT>::writeTo(uint8_t *buf) { … }
template <class ELFT>
std::unique_ptr<MipsAbiFlagsSection<ELFT>>
MipsAbiFlagsSection<ELFT>::create(Ctx &ctx) { … }
template <class ELFT>
MipsOptionsSection<ELFT>::MipsOptionsSection(Ctx &ctx, Elf_Mips_RegInfo reginfo)
: … { … }
template <class ELFT> void MipsOptionsSection<ELFT>::writeTo(uint8_t *buf) { … }
template <class ELFT>
std::unique_ptr<MipsOptionsSection<ELFT>>
MipsOptionsSection<ELFT>::create(Ctx &ctx) { … }
template <class ELFT>
MipsReginfoSection<ELFT>::MipsReginfoSection(Ctx &ctx, Elf_Mips_RegInfo reginfo)
: … { … }
template <class ELFT> void MipsReginfoSection<ELFT>::writeTo(uint8_t *buf) { … }
template <class ELFT>
std::unique_ptr<MipsReginfoSection<ELFT>>
MipsReginfoSection<ELFT>::create(Ctx &ctx) { … }
InputSection *elf::createInterpSection(Ctx &) { … }
Defined *elf::addSyntheticLocal(StringRef name, uint8_t type, uint64_t value,
uint64_t size, InputSectionBase §ion) { … }
static size_t getHashSize() { … }
GnuPropertySection::GnuPropertySection(Ctx &ctx)
: … { … }
void GnuPropertySection::writeTo(uint8_t *buf) { … }
size_t GnuPropertySection::getSize() const { … }
BuildIdSection::BuildIdSection(Ctx &ctx)
: … { … }
void BuildIdSection::writeTo(uint8_t *buf) { … }
void BuildIdSection::writeBuildId(ArrayRef<uint8_t> buf) { … }
BssSection::BssSection(Ctx &ctx, StringRef name, uint64_t size,
uint32_t alignment)
: … { … }
EhFrameSection::EhFrameSection(Ctx &ctx)
: … { … }
template <class ELFT, class RelTy>
CieRecord *EhFrameSection::addCie(EhSectionPiece &cie, ArrayRef<RelTy> rels) { … }
template <class ELFT, class RelTy>
Defined *EhFrameSection::isFdeLive(EhSectionPiece &fde, ArrayRef<RelTy> rels) { … }
template <class ELFT, class RelTy>
void EhFrameSection::addRecords(EhInputSection *sec, ArrayRef<RelTy> rels) { … }
template <class ELFT>
void EhFrameSection::addSectionAux(EhInputSection *sec) { … }
template <class ELFT, class RelTy>
void EhFrameSection::iterateFDEWithLSDAAux(
EhInputSection &sec, ArrayRef<RelTy> rels, DenseSet<size_t> &ciesWithLSDA,
llvm::function_ref<void(InputSection &)> fn) { … }
template <class ELFT>
void EhFrameSection::iterateFDEWithLSDA(
llvm::function_ref<void(InputSection &)> fn) { … }
static void writeCieFde(uint8_t *buf, ArrayRef<uint8_t> d) { … }
void EhFrameSection::finalizeContents() { … }
SmallVector<EhFrameSection::FdeData, 0> EhFrameSection::getFdeData() const { … }
static uint64_t readFdeAddr(Ctx &ctx, uint8_t *buf, int size) { … }
uint64_t EhFrameSection::getFdePc(uint8_t *buf, size_t fdeOff,
uint8_t enc) const { … }
void EhFrameSection::writeTo(uint8_t *buf) { … }
GotSection::GotSection(Ctx &ctx)
: … { … }
void GotSection::addConstant(const Relocation &r) { … }
void GotSection::addEntry(const Symbol &sym) { … }
bool GotSection::addTlsDescEntry(const Symbol &sym) { … }
bool GotSection::addDynTlsEntry(const Symbol &sym) { … }
bool GotSection::addTlsIndex() { … }
uint32_t GotSection::getTlsDescOffset(const Symbol &sym) const { … }
uint64_t GotSection::getTlsDescAddr(const Symbol &sym) const { … }
uint64_t GotSection::getGlobalDynAddr(const Symbol &b) const { … }
uint64_t GotSection::getGlobalDynOffset(const Symbol &b) const { … }
void GotSection::finalizeContents() { … }
bool GotSection::isNeeded() const { … }
void GotSection::writeTo(uint8_t *buf) { … }
static uint64_t getMipsPageAddr(uint64_t addr) { … }
static uint64_t getMipsPageCount(uint64_t size) { … }
MipsGotSection::MipsGotSection(Ctx &ctx)
: … { … }
void MipsGotSection::addEntry(InputFile &file, Symbol &sym, int64_t addend,
RelExpr expr) { … }
void MipsGotSection::addDynTlsEntry(InputFile &file, Symbol &sym) { … }
void MipsGotSection::addTlsIndex(InputFile &file) { … }
size_t MipsGotSection::FileGot::getEntriesNum() const { … }
size_t MipsGotSection::FileGot::getPageEntriesNum() const { … }
size_t MipsGotSection::FileGot::getIndexedEntriesNum() const { … }
MipsGotSection::FileGot &MipsGotSection::getGot(InputFile &f) { … }
uint64_t MipsGotSection::getPageEntryOffset(const InputFile *f,
const Symbol &sym,
int64_t addend) const { … }
uint64_t MipsGotSection::getSymEntryOffset(const InputFile *f, const Symbol &s,
int64_t addend) const { … }
uint64_t MipsGotSection::getTlsIndexOffset(const InputFile *f) const { … }
uint64_t MipsGotSection::getGlobalDynOffset(const InputFile *f,
const Symbol &s) const { … }
const Symbol *MipsGotSection::getFirstGlobalEntry() const { … }
unsigned MipsGotSection::getLocalEntriesNum() const { … }
bool MipsGotSection::tryMergeGots(FileGot &dst, FileGot &src, bool isPrimary) { … }
void MipsGotSection::finalizeContents() { … }
bool MipsGotSection::updateAllocSize(Ctx &ctx) { … }
void MipsGotSection::build() { … }
bool MipsGotSection::isNeeded() const { … }
uint64_t MipsGotSection::getGp(const InputFile *f) const { … }
void MipsGotSection::writeTo(uint8_t *buf) { … }
GotPltSection::GotPltSection(Ctx &ctx)
: … { … }
void GotPltSection::addEntry(Symbol &sym) { … }
size_t GotPltSection::getSize() const { … }
void GotPltSection::writeTo(uint8_t *buf) { … }
bool GotPltSection::isNeeded() const { … }
static StringRef getIgotPltName() { … }
IgotPltSection::IgotPltSection(Ctx &ctx)
: … { … }
void IgotPltSection::addEntry(Symbol &sym) { … }
size_t IgotPltSection::getSize() const { … }
void IgotPltSection::writeTo(uint8_t *buf) { … }
StringTableSection::StringTableSection(Ctx &ctx, StringRef name, bool dynamic)
: … { … }
unsigned StringTableSection::addString(StringRef s, bool hashIt) { … }
void StringTableSection::writeTo(uint8_t *buf) { … }
static unsigned getVerDefNum() { … }
template <class ELFT>
DynamicSection<ELFT>::DynamicSection(Ctx &ctx)
: … { … }
static uint64_t addRelaSz(const RelocationBaseSection &relaDyn) { … }
static uint64_t addPltRelSz() { … }
template <class ELFT>
std::vector<std::pair<int32_t, uint64_t>>
DynamicSection<ELFT>::computeContents() { … }
template <class ELFT> void DynamicSection<ELFT>::finalizeContents() { … }
template <class ELFT> void DynamicSection<ELFT>::writeTo(uint8_t *buf) { … }
uint64_t DynamicReloc::getOffset() const { … }
int64_t DynamicReloc::computeAddend() const { … }
uint32_t DynamicReloc::getSymIndex(SymbolTableBaseSection *symTab) const { … }
RelocationBaseSection::RelocationBaseSection(Ctx &ctx, StringRef name,
uint32_t type, int32_t dynamicTag,
int32_t sizeDynamicTag,
bool combreloc,
unsigned concurrency)
: … { … }
void RelocationBaseSection::addSymbolReloc(
RelType dynType, InputSectionBase &isec, uint64_t offsetInSec, Symbol &sym,
int64_t addend, std::optional<RelType> addendRelType) { … }
void RelocationBaseSection::addAddendOnlyRelocIfNonPreemptible(
RelType dynType, InputSectionBase &isec, uint64_t offsetInSec, Symbol &sym,
RelType addendRelType) { … }
void RelocationBaseSection::mergeRels() { … }
void RelocationBaseSection::partitionRels() { … }
void RelocationBaseSection::finalizeContents() { … }
void DynamicReloc::computeRaw(SymbolTableBaseSection *symt) { … }
void RelocationBaseSection::computeRels() { … }
template <class ELFT>
RelocationSection<ELFT>::RelocationSection(Ctx &ctx, StringRef name,
bool combreloc, unsigned concurrency)
: … { … }
template <class ELFT> void RelocationSection<ELFT>::writeTo(uint8_t *buf) { … }
RelrBaseSection::RelrBaseSection(Ctx &ctx, unsigned concurrency,
bool isAArch64Auth)
: … { … }
void RelrBaseSection::mergeRels() { … }
template <class ELFT>
AndroidPackedRelocationSection<ELFT>::AndroidPackedRelocationSection(
Ctx &ctx, StringRef name, unsigned concurrency)
: … { … }
template <class ELFT>
bool AndroidPackedRelocationSection<ELFT>::updateAllocSize(Ctx &ctx) { … }
template <class ELFT>
RelrSection<ELFT>::RelrSection(Ctx &ctx, unsigned concurrency,
bool isAArch64Auth)
: … { … }
template <class ELFT> bool RelrSection<ELFT>::updateAllocSize(Ctx &ctx) { … }
SymbolTableBaseSection::SymbolTableBaseSection(Ctx &ctx,
StringTableSection &strTabSec)
: … { … }
static bool sortMipsSymbols(const SymbolTableEntry &l,
const SymbolTableEntry &r) { … }
void SymbolTableBaseSection::finalizeContents() { … }
void SymbolTableBaseSection::sortSymTabSymbols() { … }
void SymbolTableBaseSection::addSymbol(Symbol *b) { … }
size_t SymbolTableBaseSection::getSymbolIndex(const Symbol &sym) { … }
template <class ELFT>
SymbolTableSection<ELFT>::SymbolTableSection(Ctx &ctx,
StringTableSection &strTabSec)
: … { … }
static BssSection *getCommonSec(Symbol *sym) { … }
static uint32_t getSymSectionIndex(Symbol *sym) { … }
template <class ELFT> void SymbolTableSection<ELFT>::writeTo(uint8_t *buf) { … }
SymtabShndxSection::SymtabShndxSection(Ctx &ctx)
: … { … }
void SymtabShndxSection::writeTo(uint8_t *buf) { … }
bool SymtabShndxSection::isNeeded() const { … }
void SymtabShndxSection::finalizeContents() { … }
size_t SymtabShndxSection::getSize() const { … }
GnuHashTableSection::GnuHashTableSection(Ctx &ctx)
: … { … }
void GnuHashTableSection::finalizeContents() { … }
void GnuHashTableSection::writeTo(uint8_t *buf) { … }
void GnuHashTableSection::addSymbols(SmallVectorImpl<SymbolTableEntry> &v) { … }
HashTableSection::HashTableSection(Ctx &ctx)
: … { … }
void HashTableSection::finalizeContents() { … }
void HashTableSection::writeTo(uint8_t *buf) { … }
PltSection::PltSection(Ctx &ctx)
: … { … }
void PltSection::writeTo(uint8_t *buf) { … }
void PltSection::addEntry(Symbol &sym) { … }
size_t PltSection::getSize() const { … }
bool PltSection::isNeeded() const { … }
void PltSection::addSymbols() { … }
IpltSection::IpltSection(Ctx &ctx)
: … { … }
void IpltSection::writeTo(uint8_t *buf) { … }
size_t IpltSection::getSize() const { … }
void IpltSection::addEntry(Symbol &sym) { … }
void IpltSection::addSymbols() { … }
PPC32GlinkSection::PPC32GlinkSection(Ctx &ctx) : … { … }
void PPC32GlinkSection::writeTo(uint8_t *buf) { … }
size_t PPC32GlinkSection::getSize() const { … }
IBTPltSection::IBTPltSection(Ctx &ctx)
: … { … }
void IBTPltSection::writeTo(uint8_t *buf) { … }
size_t IBTPltSection::getSize() const { … }
bool IBTPltSection::isNeeded() const { … }
RelroPaddingSection::RelroPaddingSection(Ctx &ctx)
: … { … }
static uint32_t computeGdbHash(StringRef s) { … }
DebugNamesBaseSection::DebugNamesBaseSection(Ctx &ctx)
: … { … }
static uint32_t getDebugNamesHeaderSize(uint32_t augmentationStringSize) { … }
static Expected<DebugNamesBaseSection::IndexEntry *>
readEntry(uint64_t &offset, const DWARFDebugNames::NameIndex &ni,
uint64_t entriesBase, DWARFDataExtractor &namesExtractor,
const LLDDWARFSection &namesSec) { … }
void DebugNamesBaseSection::parseDebugNames(
InputChunk &inputChunk, OutputChunk &chunk,
DWARFDataExtractor &namesExtractor, DataExtractor &strExtractor,
function_ref<SmallVector<uint32_t, 0>(
uint32_t numCus, const DWARFDebugNames::Header &,
const DWARFDebugNames::DWARFDebugNamesOffsets &)>
readOffsets) { … }
std::pair<uint8_t, dwarf::Form> static getMergedCuCountForm(
uint32_t compUnitCount) { … }
void DebugNamesBaseSection::computeHdrAndAbbrevTable(
MutableArrayRef<InputChunk> inputChunks) { … }
void DebugNamesBaseSection::Abbrev::Profile(FoldingSetNodeID &id) const { … }
std::pair<uint32_t, uint32_t> DebugNamesBaseSection::computeEntryPool(
MutableArrayRef<InputChunk> inputChunks) { … }
void DebugNamesBaseSection::init(
function_ref<void(InputFile *, InputChunk &, OutputChunk &)> parseFile) { … }
template <class ELFT>
DebugNamesSection<ELFT>::DebugNamesSection(Ctx &ctx)
: … { … }
template <class ELFT>
template <class RelTy>
void DebugNamesSection<ELFT>::getNameRelocs(
const InputFile &file, DenseMap<uint32_t, uint32_t> &relocs,
Relocs<RelTy> rels) { … }
template <class ELFT> void DebugNamesSection<ELFT>::finalizeContents() { … }
template <class ELFT> void DebugNamesSection<ELFT>::writeTo(uint8_t *buf) { … }
GdbIndexSection::GdbIndexSection(Ctx &ctx)
: … { … }
size_t GdbIndexSection::computeSymtabSize() const { … }
static SmallVector<GdbIndexSection::CuEntry, 0>
readCuList(DWARFContext &dwarf) { … }
static SmallVector<GdbIndexSection::AddressEntry, 0>
readAddressAreas(DWARFContext &dwarf, InputSection *sec) { … }
template <class ELFT>
static SmallVector<GdbIndexSection::NameAttrEntry, 0>
readPubNamesAndTypes(const LLDDwarfObj<ELFT> &obj,
const SmallVectorImpl<GdbIndexSection::CuEntry> &cus) { … }
static std::pair<SmallVector<GdbIndexSection::GdbSymbol, 0>, size_t>
createSymbols(
ArrayRef<SmallVector<GdbIndexSection::NameAttrEntry, 0>> nameAttrs,
const SmallVector<GdbIndexSection::GdbChunk, 0> &chunks) { … }
template <class ELFT>
std::unique_ptr<GdbIndexSection> GdbIndexSection::create(Ctx &ctx) { … }
void GdbIndexSection::writeTo(uint8_t *buf) { … }
bool GdbIndexSection::isNeeded() const { … }
EhFrameHeader::EhFrameHeader(Ctx &ctx)
: … { … }
void EhFrameHeader::writeTo(uint8_t *buf) { … }
void EhFrameHeader::write() { … }
size_t EhFrameHeader::getSize() const { … }
bool EhFrameHeader::isNeeded() const { … }
VersionDefinitionSection::VersionDefinitionSection(Ctx &ctx)
: … { … }
StringRef VersionDefinitionSection::getFileDefName() { … }
void VersionDefinitionSection::finalizeContents() { … }
void VersionDefinitionSection::writeOne(uint8_t *buf, uint32_t index,
StringRef name, size_t nameOff) { … }
void VersionDefinitionSection::writeTo(uint8_t *buf) { … }
size_t VersionDefinitionSection::getSize() const { … }
VersionTableSection::VersionTableSection(Ctx &ctx)
: … { … }
void VersionTableSection::finalizeContents() { … }
size_t VersionTableSection::getSize() const { … }
void VersionTableSection::writeTo(uint8_t *buf) { … }
bool VersionTableSection::isNeeded() const { … }
void elf::addVerneed(Symbol *ss) { … }
template <class ELFT>
VersionNeedSection<ELFT>::VersionNeedSection(Ctx &ctx)
: … { … }
template <class ELFT> void VersionNeedSection<ELFT>::finalizeContents() { … }
template <class ELFT> void VersionNeedSection<ELFT>::writeTo(uint8_t *buf) { … }
template <class ELFT> size_t VersionNeedSection<ELFT>::getSize() const { … }
template <class ELFT> bool VersionNeedSection<ELFT>::isNeeded() const { … }
void MergeSyntheticSection::addSection(MergeInputSection *ms) { … }
MergeTailSection::MergeTailSection(Ctx &ctx, StringRef name, uint32_t type,
uint64_t flags, uint32_t alignment)
: … { … }
size_t MergeTailSection::getSize() const { … }
void MergeTailSection::writeTo(uint8_t *buf) { … }
void MergeTailSection::finalizeContents() { … }
void MergeNoTailSection::writeTo(uint8_t *buf) { … }
void MergeNoTailSection::finalizeContents() { … }
template <class ELFT> void elf::splitSections(Ctx &ctx) { … }
void elf::combineEhSections(Ctx &ctx) { … }
MipsRldMapSection::MipsRldMapSection(Ctx &ctx)
: … { … }
ARMExidxSyntheticSection::ARMExidxSyntheticSection(Ctx &ctx)
: … { … }
static InputSection *findExidxSection(InputSection *isec) { … }
static bool isValidExidxSectionDep(InputSection *isec) { … }
bool ARMExidxSyntheticSection::addSection(InputSection *isec) { … }
static bool isExtabRef(uint32_t unwind) { … }
static bool isDuplicateArmExidxSec(InputSection *prev, InputSection *cur) { … }
void ARMExidxSyntheticSection::finalizeContents() { … }
InputSection *ARMExidxSyntheticSection::getLinkOrderDep() const { … }
void ARMExidxSyntheticSection::writeTo(uint8_t *buf) { … }
bool ARMExidxSyntheticSection::isNeeded() const { … }
ThunkSection::ThunkSection(Ctx &ctx, OutputSection *os, uint64_t off)
: … { … }
size_t ThunkSection::getSize() const { … }
void ThunkSection::addThunk(Thunk *t) { … }
void ThunkSection::writeTo(uint8_t *buf) { … }
InputSection *ThunkSection::getTargetInputSection() const { … }
bool ThunkSection::assignOffsets() { … }
PPC32Got2Section::PPC32Got2Section(Ctx &ctx)
: … { … }
bool PPC32Got2Section::isNeeded() const { … }
void PPC32Got2Section::finalizeContents() { … }
PPC64LongBranchTargetSection::PPC64LongBranchTargetSection(Ctx &ctx)
: … { … }
uint64_t PPC64LongBranchTargetSection::getEntryVA(const Symbol *sym,
int64_t addend) { … }
std::optional<uint32_t>
PPC64LongBranchTargetSection::addEntry(const Symbol *sym, int64_t addend) { … }
size_t PPC64LongBranchTargetSection::getSize() const { … }
void PPC64LongBranchTargetSection::writeTo(uint8_t *buf) { … }
bool PPC64LongBranchTargetSection::isNeeded() const { … }
static uint8_t getAbiVersion(Ctx &ctx) { … }
template <typename ELFT> void elf::writeEhdr(uint8_t *buf, Partition &part) { … }
template <typename ELFT> void elf::writePhdrs(uint8_t *buf, Partition &part) { … }
template <typename ELFT>
PartitionElfHeaderSection<ELFT>::PartitionElfHeaderSection(Ctx &ctx)
: … { … }
template <typename ELFT>
size_t PartitionElfHeaderSection<ELFT>::getSize() const { … }
template <typename ELFT>
void PartitionElfHeaderSection<ELFT>::writeTo(uint8_t *buf) { … }
template <typename ELFT>
PartitionProgramHeadersSection<ELFT>::PartitionProgramHeadersSection(Ctx &ctx)
: … { … }
template <typename ELFT>
size_t PartitionProgramHeadersSection<ELFT>::getSize() const { … }
template <typename ELFT>
void PartitionProgramHeadersSection<ELFT>::writeTo(uint8_t *buf) { … }
PartitionIndexSection::PartitionIndexSection(Ctx &ctx)
: … { … }
size_t PartitionIndexSection::getSize() const { … }
void PartitionIndexSection::finalizeContents() { … }
void PartitionIndexSection::writeTo(uint8_t *buf) { … }
void InStruct::reset() { … }
static bool needsInterpSection(Ctx &ctx) { … }
bool elf::hasMemtag(Ctx &ctx) { … }
bool elf::canHaveMemtagGlobals(Ctx &ctx) { … }
constexpr char kMemtagAndroidNoteName[] = …;
void MemtagAndroidNote::writeTo(uint8_t *buf) { … }
size_t MemtagAndroidNote::getSize() const { … }
void PackageMetadataNote::writeTo(uint8_t *buf) { … }
size_t PackageMetadataNote::getSize() const { … }
static size_t computeOrWriteULEB128(uint64_t v, uint8_t *buf, size_t offset) { … }
constexpr uint64_t kMemtagStepSizeBits = …;
constexpr uint64_t kMemtagGranuleSize = …;
static size_t
createMemtagGlobalDescriptors(Ctx &ctx,
const SmallVector<const Symbol *, 0> &symbols,
uint8_t *buf = nullptr) { … }
bool MemtagGlobalDescriptors::updateAllocSize(Ctx &ctx) { … }
void MemtagGlobalDescriptors::writeTo(uint8_t *buf) { … }
size_t MemtagGlobalDescriptors::getSize() const { … }
static OutputSection *findSection(StringRef name) { … }
static Defined *addOptionalRegular(Ctx &ctx, StringRef name, SectionBase *sec,
uint64_t val, uint8_t stOther = STV_HIDDEN) { … }
template <class ELFT> void elf::createSyntheticSections(Ctx &ctx) { … }
template void elf::splitSections<ELF32LE>(Ctx &);
template void elf::splitSections<ELF32BE>(Ctx &);
template void elf::splitSections<ELF64LE>(Ctx &);
template void elf::splitSections<ELF64BE>(Ctx &);
template void EhFrameSection::iterateFDEWithLSDA<ELF32LE>(
function_ref<void(InputSection &)>);
template void EhFrameSection::iterateFDEWithLSDA<ELF32BE>(
function_ref<void(InputSection &)>);
template void EhFrameSection::iterateFDEWithLSDA<ELF64LE>(
function_ref<void(InputSection &)>);
template void EhFrameSection::iterateFDEWithLSDA<ELF64BE>(
function_ref<void(InputSection &)>);
template class elf::SymbolTableSection<ELF32LE>;
template class elf::SymbolTableSection<ELF32BE>;
template class elf::SymbolTableSection<ELF64LE>;
template class elf::SymbolTableSection<ELF64BE>;
template void elf::writeEhdr<ELF32LE>(uint8_t *Buf, Partition &Part);
template void elf::writeEhdr<ELF32BE>(uint8_t *Buf, Partition &Part);
template void elf::writeEhdr<ELF64LE>(uint8_t *Buf, Partition &Part);
template void elf::writeEhdr<ELF64BE>(uint8_t *Buf, Partition &Part);
template void elf::writePhdrs<ELF32LE>(uint8_t *Buf, Partition &Part);
template void elf::writePhdrs<ELF32BE>(uint8_t *Buf, Partition &Part);
template void elf::writePhdrs<ELF64LE>(uint8_t *Buf, Partition &Part);
template void elf::writePhdrs<ELF64BE>(uint8_t *Buf, Partition &Part);
template void elf::createSyntheticSections<ELF32LE>(Ctx &);
template void elf::createSyntheticSections<ELF32BE>(Ctx &);
template void elf::createSyntheticSections<ELF64LE>(Ctx &);
template void elf::createSyntheticSections<ELF64BE>(Ctx &);