[lld] r260453 - Split the creation of program headers in a few steps.
Rafael Espindola via llvm-commits
llvm-commits at lists.llvm.org
Wed Feb 10 14:43:14 PST 2016
Author: rafael
Date: Wed Feb 10 16:43:13 2016
New Revision: 260453
URL: http://llvm.org/viewvc/llvm-project?rev=260453&view=rev
Log:
Split the creation of program headers in a few steps.
IMHO this makes the code easier to read and should help with linker
scripts.
This is strongly based on D16575. The main differences are:
We record a range of sections, not every section in a program header.
scanHeaders takes case of deciding what goes in every program header,
including PT_GNU_RELRO
We create dummy sections for the start of the file
With this, program header creation has 3 isolated stages:
Map sections to program headers.
Assign addresses to *sections*
Looking at sections find the address and size of each program header.
Thanks to George Rimar for the initial version.
Modified:
lld/trunk/ELF/OutputSections.h
lld/trunk/ELF/Writer.cpp
Modified: lld/trunk/ELF/OutputSections.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/OutputSections.h?rev=260453&r1=260452&r2=260453&view=diff
==============================================================================
--- lld/trunk/ELF/OutputSections.h (original)
+++ lld/trunk/ELF/OutputSections.h Wed Feb 10 16:43:13 2016
@@ -94,7 +94,7 @@ public:
}
virtual void finalize() {}
- virtual void writeTo(uint8_t *Buf) = 0;
+ virtual void writeTo(uint8_t *Buf) {}
virtual ~OutputSectionBase() = default;
protected:
@@ -540,6 +540,8 @@ template <class ELFT> struct Out {
static SymbolTableSection<ELFT> *DynSymTab;
static SymbolTableSection<ELFT> *SymTab;
static Elf_Phdr *TlsPhdr;
+ static OutputSectionBase<ELFT> *ElfHeader;
+ static OutputSectionBase<ELFT> *ProgramHeaders;
};
template <class ELFT> DynamicSection<ELFT> *Out<ELFT>::Dynamic;
@@ -562,6 +564,8 @@ template <class ELFT> StringTableSection
template <class ELFT> SymbolTableSection<ELFT> *Out<ELFT>::DynSymTab;
template <class ELFT> SymbolTableSection<ELFT> *Out<ELFT>::SymTab;
template <class ELFT> typename Out<ELFT>::Elf_Phdr *Out<ELFT>::TlsPhdr;
+template <class ELFT> OutputSectionBase<ELFT> *Out<ELFT>::ElfHeader;
+template <class ELFT> OutputSectionBase<ELFT> *Out<ELFT>::ProgramHeaders;
} // namespace elf2
} // namespace lld
Modified: lld/trunk/ELF/Writer.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Writer.cpp?rev=260453&r1=260452&r2=260453&view=diff
==============================================================================
--- lld/trunk/ELF/Writer.cpp (original)
+++ lld/trunk/ELF/Writer.cpp Wed Feb 10 16:43:13 2016
@@ -13,6 +13,7 @@
#include "SymbolTable.h"
#include "Target.h"
+#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringSwitch.h"
#include "llvm/Support/FileOutputBuffer.h"
@@ -41,6 +42,19 @@ public:
void run();
private:
+ // This describes a program header entry.
+ // Each contains type, access flags and range of output sections that will be
+ // placed in it.
+ struct Phdr {
+ Phdr(unsigned Type, unsigned Flags) {
+ H.p_type = Type;
+ H.p_flags = Flags;
+ }
+ Elf_Phdr H = {};
+ OutputSectionBase<ELFT> *First = nullptr;
+ OutputSectionBase<ELFT> *Last = nullptr;
+ };
+
void copyLocalSymbols();
void addReservedSymbols();
bool createSections();
@@ -52,7 +66,7 @@ private:
void scanRelocs(InputSection<ELFT> &C);
void scanRelocs(InputSectionBase<ELFT> &S, const Elf_Shdr &RelSec);
- void updateRelro(Elf_Phdr *Cur, Elf_Phdr *GnuRelroPhdr, uintX_t VA);
+ void createPhdrs();
void assignAddresses();
void buildSectionMap();
void fixAbsoluteSymbols();
@@ -67,7 +81,6 @@ private:
bool isOutputDynamic() const {
return !Symtab.getSharedFiles().empty() || Config->Shared;
}
- int getPhdrsNum() const;
OutputSection<ELFT> *getBss();
void addCommonSymbols(std::vector<DefinedCommon *> &Syms);
@@ -78,18 +91,22 @@ private:
BumpPtrAllocator Alloc;
std::vector<OutputSectionBase<ELFT> *> OutputSections;
std::vector<std::unique_ptr<OutputSectionBase<ELFT>>> OwningSections;
- unsigned getNumSections() const { return OutputSections.size() + 1; }
+
+ // We create a section for the ELF header and one for the program headers.
+ const unsigned NumDummySections = 2;
+ ArrayRef<OutputSectionBase<ELFT> *> getSections() const {
+ return makeArrayRef(OutputSections).slice(NumDummySections);
+ }
+ unsigned getNumSections() const {
+ return OutputSections.size() + 1 - NumDummySections;
+ }
void addRelIpltSymbols();
void addStartEndSymbols();
void addStartStopSymbols(OutputSectionBase<ELFT> *Sec);
- void setPhdr(Elf_Phdr *PH, uint32_t Type, uint32_t Flags, uintX_t FileOff,
- uintX_t VA, uintX_t Size, uintX_t Align);
- void copyPhdr(Elf_Phdr *PH, OutputSectionBase<ELFT> *From);
- bool HasRelro = false;
SymbolTable<ELFT> &Symtab;
- std::vector<Elf_Phdr> Phdrs;
+ std::vector<Phdr> Phdrs;
uintX_t FileSize;
uintX_t SectionHeaderOff;
@@ -105,6 +122,8 @@ private:
template <class ELFT> static bool shouldUseRela() { return ELFT::Is64Bits; }
template <class ELFT> void elf2::writeResult(SymbolTable<ELFT> *Symtab) {
+ typedef typename ELFFile<ELFT>::uintX_t uintX_t;
+
// Create singleton output sections.
bool IsRela = shouldUseRela<ELFT>();
DynamicSection<ELFT> Dynamic(*Symtab);
@@ -117,6 +136,10 @@ template <class ELFT> void elf2::writeRe
StringTableSection<ELFT> ShStrTab(".shstrtab", false);
SymbolTableSection<ELFT> DynSymTab(*Symtab, DynStrTab);
+ OutputSectionBase<ELFT> ElfHeader("", 0, SHF_ALLOC);
+ OutputSectionBase<ELFT> ProgramHeaders("", 0, SHF_ALLOC);
+ ProgramHeaders.updateAlign(sizeof(uintX_t));
+
// Instantiate optional output sections if they are needed.
std::unique_ptr<GnuHashTableSection<ELFT>> GnuHashTab;
std::unique_ptr<GotPltSection<ELFT>> GotPlt;
@@ -159,6 +182,8 @@ template <class ELFT> void elf2::writeRe
Out<ELFT>::Opd = nullptr;
Out<ELFT>::OpdBuf = nullptr;
Out<ELFT>::TlsPhdr = nullptr;
+ Out<ELFT>::ElfHeader = &ElfHeader;
+ Out<ELFT>::ProgramHeaders = &ProgramHeaders;
Writer<ELFT>(*Symtab).run();
}
@@ -171,6 +196,7 @@ template <class ELFT> void Writer<ELFT>:
addReservedSymbols();
if (!createSections())
return;
+ createPhdrs();
assignAddresses();
fixAbsoluteSymbols();
if (!openFile())
@@ -547,6 +573,8 @@ static int getPPC64SectionRank(StringRef
}
template <class ELFT> static bool isRelroSection(OutputSectionBase<ELFT> *Sec) {
+ if (!Config->ZRelro)
+ return false;
typename OutputSectionBase<ELFT>::uintX_t Flags = Sec->getFlags();
if (!(Flags & SHF_ALLOC) || !(Flags & SHF_WRITE))
return false;
@@ -889,6 +917,9 @@ template <class ELFT> void Writer<ELFT>:
// Create output section objects and add them to OutputSections.
template <class ELFT> bool Writer<ELFT>::createSections() {
+ OutputSections.push_back(Out<ELFT>::ElfHeader);
+ OutputSections.push_back(Out<ELFT>::ProgramHeaders);
+
// Add .interp first because some loaders want to see that section
// on the first page of the executable file when loaded into memory.
if (needsInterpSection())
@@ -994,12 +1025,10 @@ template <class ELFT> bool Writer<ELFT>:
std::stable_sort(OutputSections.begin(), OutputSections.end(),
compareSections<ELFT>);
- for (unsigned I = 0, N = OutputSections.size(); I < N; ++I) {
- OutputSections[I]->SectionIndex = I + 1;
- HasRelro |= (Config->ZRelro && isRelroSection(OutputSections[I]));
- }
+ for (unsigned I = NumDummySections, N = OutputSections.size(); I < N; ++I)
+ OutputSections[I]->SectionIndex = I + 1 - NumDummySections;
- for (OutputSectionBase<ELFT> *Sec : OutputSections)
+ for (OutputSectionBase<ELFT> *Sec : getSections())
Sec->setSHName(Out<ELFT>::ShStrTab->addString(Sec->getName()));
// Finalizers fix each section's size.
@@ -1165,141 +1194,150 @@ static uint32_t getAmdgpuPhdr(OutputSect
return PT_LOAD;
}
-template <class ELFT>
-void Writer<ELFT>::updateRelro(Elf_Phdr *Cur, Elf_Phdr *GnuRelroPhdr,
- uintX_t VA) {
- if (!GnuRelroPhdr->p_type)
- setPhdr(GnuRelroPhdr, PT_GNU_RELRO, PF_R, Cur->p_offset, Cur->p_vaddr,
- VA - Cur->p_vaddr, 1 /*p_align*/);
- GnuRelroPhdr->p_filesz = VA - Cur->p_vaddr;
- GnuRelroPhdr->p_memsz = VA - Cur->p_vaddr;
-}
-
-// Visits all sections to create PHDRs and to assign incremental,
-// non-overlapping addresses to output sections.
-template <class ELFT> void Writer<ELFT>::assignAddresses() {
- uintX_t VA = Target->getVAStart() + sizeof(Elf_Ehdr);
- uintX_t FileOff = sizeof(Elf_Ehdr);
+// Decide which program headers to create and which sections to include in each
+// one.
+template <class ELFT> void Writer<ELFT>::createPhdrs() {
+ auto AddHdr = [this](unsigned Type, unsigned Flags) {
+ return &*Phdrs.emplace(Phdrs.end(), Type, Flags);
+ };
- // Calculate and reserve the space for the program header first so that
- // the first section can start right after the program header.
- Phdrs.resize(getPhdrsNum());
- size_t PhdrSize = sizeof(Elf_Phdr) * Phdrs.size();
+ auto AddSec = [](Phdr &Hdr, OutputSectionBase<ELFT> *Sec) {
+ Hdr.Last = Sec;
+ if (!Hdr.First)
+ Hdr.First = Sec;
+ Hdr.H.p_align = std::max<uintX_t>(Hdr.H.p_align, Sec->getAlign());
+ };
// The first phdr entry is PT_PHDR which describes the program header itself.
- setPhdr(&Phdrs[0], PT_PHDR, PF_R, FileOff, VA, PhdrSize,
- /*Align=*/sizeof(uintX_t));
- FileOff += PhdrSize;
- VA += PhdrSize;
+ Phdr &Hdr = *AddHdr(PT_PHDR, PF_R);
+ AddSec(Hdr, Out<ELFT>::ProgramHeaders);
// PT_INTERP must be the second entry if exists.
- int PhdrIdx = 0;
- Elf_Phdr *Interp = nullptr;
- if (needsInterpSection())
- Interp = &Phdrs[++PhdrIdx];
+ if (needsInterpSection()) {
+ Phdr &Hdr = *AddHdr(PT_INTERP, toPhdrFlags(Out<ELFT>::Interp->getFlags()));
+ AddSec(Hdr, Out<ELFT>::Interp);
+ }
// Add the first PT_LOAD segment for regular output sections.
- setPhdr(&Phdrs[++PhdrIdx], PT_LOAD, PF_R, 0, Target->getVAStart(), FileOff,
- Target->PageSize);
+ uintX_t Flags = PF_R;
+ Phdr *Load = AddHdr(PT_LOAD, Flags);
+ AddSec(*Load, Out<ELFT>::ElfHeader);
- Elf_Phdr GnuRelroPhdr = {};
- Elf_Phdr TlsPhdr{};
- bool RelroAligned = false;
- uintX_t ThreadBssOffset = 0;
- // Create phdrs as we assign VAs and file offsets to all output sections.
+ Phdr TlsHdr(PT_TLS, PF_R);
+ Phdr RelRo(PT_GNU_RELRO, PF_R);
for (OutputSectionBase<ELFT> *Sec : OutputSections) {
- Elf_Phdr *PH = &Phdrs[PhdrIdx];
- if (needsPhdr<ELFT>(Sec)) {
- uintX_t Flags = toPhdrFlags(Sec->getFlags());
- bool InRelRo = Config->ZRelro && (Flags & PF_W) && isRelroSection(Sec);
- bool FirstNonRelRo = GnuRelroPhdr.p_type && !InRelRo && !RelroAligned;
- if (FirstNonRelRo || PH->p_flags != Flags) {
- VA = alignTo(VA, Target->PageSize);
- FileOff = alignTo(FileOff, Target->PageSize);
- if (FirstNonRelRo)
- RelroAligned = true;
- }
-
- if (PH->p_flags != Flags) {
- // Flags changed. Create a new PT_LOAD.
- PH = &Phdrs[++PhdrIdx];
- uint32_t PTType = (Config->EMachine != EM_AMDGPU) ? (uint32_t)PT_LOAD
- : getAmdgpuPhdr(Sec);
- setPhdr(PH, PTType, Flags, FileOff, VA, 0, Target->PageSize);
- }
+ if (!needsPhdr<ELFT>(Sec))
+ break;
- if (Sec->getFlags() & SHF_TLS) {
- if (!TlsPhdr.p_vaddr)
- setPhdr(&TlsPhdr, PT_TLS, PF_R, FileOff, VA, 0, Sec->getAlign());
- if (Sec->getType() != SHT_NOBITS)
- VA = alignTo(VA, Sec->getAlign());
- uintX_t TVA = alignTo(VA + ThreadBssOffset, Sec->getAlign());
- Sec->setVA(TVA);
- TlsPhdr.p_memsz += Sec->getSize();
- if (Sec->getType() == SHT_NOBITS) {
- ThreadBssOffset = TVA - VA + Sec->getSize();
- } else {
- TlsPhdr.p_filesz += Sec->getSize();
- VA += Sec->getSize();
- }
- TlsPhdr.p_align = std::max<uintX_t>(TlsPhdr.p_align, Sec->getAlign());
- } else {
- VA = alignTo(VA, Sec->getAlign());
- Sec->setVA(VA);
- VA += Sec->getSize();
- }
- if (InRelRo)
- updateRelro(PH, &GnuRelroPhdr, VA);
+ // If flags changed then we want new load segment.
+ uintX_t NewFlags = toPhdrFlags(Sec->getFlags());
+ if (Flags != NewFlags) {
+ uint32_t LoadType = (Config->EMachine == EM_AMDGPU) ? getAmdgpuPhdr(Sec)
+ : (uint32_t)PT_LOAD;
+ Load = AddHdr(LoadType, NewFlags);
+ Flags = NewFlags;
}
-
- FileOff = alignTo(FileOff, Sec->getAlign());
- Sec->setFileOffset(FileOff);
- if (Sec->getType() != SHT_NOBITS)
- FileOff += Sec->getSize();
- if (needsPhdr<ELFT>(Sec)) {
- PH->p_filesz = FileOff - PH->p_offset;
- PH->p_memsz = VA - PH->p_vaddr;
+ // If we meet TLS section then we create TLS header
+ // and put all TLS sections inside for futher use when
+ // assign addresses.
+ if (Sec->getFlags() & SHF_TLS) {
+ AddSec(TlsHdr, Sec);
+ if (Sec->getType() == SHT_NOBITS)
+ continue;
}
- }
- if (TlsPhdr.p_vaddr) {
- // The TLS pointer goes after PT_TLS. At least glibc will align it,
- // so round up the size to make sure the offsets are correct.
- TlsPhdr.p_memsz = alignTo(TlsPhdr.p_memsz, TlsPhdr.p_align);
- Phdrs[++PhdrIdx] = TlsPhdr;
- Out<ELFT>::TlsPhdr = &Phdrs[PhdrIdx];
+ AddSec(*Load, Sec);
+
+ if (isRelroSection(Sec))
+ AddSec(RelRo, Sec);
}
+ // Add the TLS segment unless it's empty.
+ if (TlsHdr.First)
+ Phdrs.push_back(std::move(TlsHdr));
+
// Add an entry for .dynamic.
if (isOutputDynamic()) {
- Elf_Phdr *PH = &Phdrs[++PhdrIdx];
- PH->p_type = PT_DYNAMIC;
- copyPhdr(PH, Out<ELFT>::Dynamic);
+ Phdr &H = *AddHdr(PT_DYNAMIC, toPhdrFlags(Out<ELFT>::Dynamic->getFlags()));
+ AddSec(H, Out<ELFT>::Dynamic);
}
- if (HasRelro) {
- Elf_Phdr *PH = &Phdrs[++PhdrIdx];
- *PH = GnuRelroPhdr;
- }
+ // PT_GNU_RELRO includes all sections that should be marked as
+ // read-only by dynamic linker after proccessing relocations.
+ if (RelRo.First)
+ Phdrs.push_back(std::move(RelRo));
+ // PT_GNU_EH_FRAME is a special section pointing on .eh_frame_hdr.
if (Out<ELFT>::EhFrameHdr->Live) {
- Elf_Phdr *PH = &Phdrs[++PhdrIdx];
- PH->p_type = PT_GNU_EH_FRAME;
- copyPhdr(PH, Out<ELFT>::EhFrameHdr);
+ Phdr &Hdr = *AddHdr(PT_GNU_EH_FRAME,
+ toPhdrFlags(Out<ELFT>::EhFrameHdr->getFlags()));
+ AddSec(Hdr, Out<ELFT>::EhFrameHdr);
}
// PT_GNU_STACK is a special section to tell the loader to make the
// pages for the stack non-executable.
- if (!Config->ZExecStack) {
- Elf_Phdr *PH = &Phdrs[++PhdrIdx];
- PH->p_type = PT_GNU_STACK;
- PH->p_flags = PF_R | PF_W;
+ if (!Config->ZExecStack)
+ AddHdr(PT_GNU_STACK, PF_R | PF_W);
+}
+
+// Visits all headers in PhdrTable and assigns the adresses to
+// the output sections. Also creates common and special headers.
+template <class ELFT> void Writer<ELFT>::assignAddresses() {
+ Out<ELFT>::ElfHeader->setSize(sizeof(Elf_Ehdr));
+ size_t PhdrSize = sizeof(Elf_Phdr) * Phdrs.size();
+ Out<ELFT>::ProgramHeaders->setSize(PhdrSize);
+
+ // The first section of each PT_LOAD and the first section after PT_GNU_RELRO
+ // have to be page aligned so that the dynamic linker can set the permissions.
+ SmallPtrSet<OutputSectionBase<ELFT> *, 4> PageAlign;
+ for (const Phdr &P : Phdrs) {
+ if (P.H.p_type == PT_GNU_RELRO) {
+ // Find the first section after PT_GNU_RELRO. If it is in a PT_LOAD
+ // and is not tls, we have to align it to a page. We don't have to
+ // align tls since TLS NOBITS takes no space.
+ auto I = std::find(OutputSections.begin(), OutputSections.end(), P.Last);
+ ++I;
+ if (I != OutputSections.end() && needsPhdr(*I) &&
+ !((*I)->getFlags() & SHF_TLS))
+ PageAlign.insert(*I);
+ }
+
+ // FIXME: why create empty PT_LOAD?
+ if (P.H.p_type == PT_LOAD && P.First)
+ PageAlign.insert(P.First);
}
- // Fix up PT_INTERP as we now know the address of .interp section.
- if (Interp) {
- Interp->p_type = PT_INTERP;
- copyPhdr(Interp, Out<ELFT>::Interp);
+ uintX_t ThreadBssOffset = 0;
+ uintX_t VA = Target->getVAStart();
+ uintX_t FileOff = 0;
+
+ for (OutputSectionBase<ELFT> *Sec : OutputSections) {
+ uintX_t Align = Sec->getAlign();
+ if (PageAlign.count(Sec))
+ Align = std::max<uintX_t>(Align, Target->PageSize);
+
+ FileOff = alignTo(FileOff, Align);
+ Sec->setFileOffset(FileOff);
+ if (Sec->getType() != SHT_NOBITS)
+ FileOff += Sec->getSize();
+
+ // We only assign VAs to allocated sections.
+ if (needsPhdr<ELFT>(Sec)) {
+ // Don't allocate VA space for TLS NOBITS sections. The PT_TLS PHDR is
+ // responsible for allocating space for them, not the PT_LOAD that
+ // contains the TLS initialization image.
+ bool IsTls = Sec->getFlags() & SHF_TLS;
+ if (IsTls && Sec->getType() == SHT_NOBITS) {
+ uintX_t TVA = VA + ThreadBssOffset;
+ TVA = alignTo(TVA, Align);
+ Sec->setVA(TVA);
+ ThreadBssOffset = TVA - VA + Sec->getSize();
+ } else {
+ VA = alignTo(VA, Align);
+ Sec->setVA(VA);
+ VA += Sec->getSize();
+ }
+ }
}
// Add space for section headers.
@@ -1309,37 +1347,31 @@ template <class ELFT> void Writer<ELFT>:
// Update "_end" and "end" symbols so that they
// point to the end of the data segment.
ElfSym<ELFT>::End.st_value = VA;
-}
-// Returns the number of PHDR entries.
-template <class ELFT> int Writer<ELFT>::getPhdrsNum() const {
- bool Tls = false;
- int I = 2; // 2 for PT_PHDR and first PT_LOAD
- if (needsInterpSection())
- ++I;
- if (isOutputDynamic())
- ++I;
- if (!Config->ZExecStack)
- ++I;
- uintX_t Last = PF_R;
- for (OutputSectionBase<ELFT> *Sec : OutputSections) {
- if (!needsPhdr<ELFT>(Sec))
- continue;
- if (Sec->getFlags() & SHF_TLS)
- Tls = true;
- uintX_t Flags = toPhdrFlags(Sec->getFlags());
- if (Last != Flags) {
- Last = Flags;
- ++I;
+ for (Phdr &PHdr : Phdrs) {
+ Elf_Phdr &H = PHdr.H;
+ if (PHdr.First) {
+ OutputSectionBase<ELFT> *Last = PHdr.Last;
+ H.p_filesz = Last->getFileOff() - PHdr.First->getFileOff();
+ if (Last->getType() != SHT_NOBITS)
+ H.p_filesz += Last->getSize();
+ H.p_memsz = Last->getVA() + Last->getSize() - PHdr.First->getVA();
+ H.p_offset = PHdr.First->getFileOff();
+ H.p_vaddr = PHdr.First->getVA();
+ }
+ if (PHdr.H.p_type == PT_LOAD)
+ H.p_align = Target->PageSize;
+ else if (PHdr.H.p_type == PT_GNU_RELRO)
+ H.p_align = 1;
+ H.p_paddr = H.p_vaddr;
+
+ // The TLS pointer goes after PT_TLS. At least glibc will align it,
+ // so round up the size to make sure the offsets are correct.
+ if (PHdr.H.p_type == PT_TLS) {
+ Out<ELFT>::TlsPhdr = &H;
+ H.p_memsz = alignTo(H.p_memsz, H.p_align);
}
}
- if (Tls)
- ++I;
- if (HasRelro)
- ++I;
- if (Out<ELFT>::EhFrameHdr->Live)
- ++I;
- return I;
}
static uint32_t getELFFlags() {
@@ -1412,11 +1444,13 @@ template <class ELFT> void Writer<ELFT>:
EHdr->e_shstrndx = Out<ELFT>::ShStrTab->SectionIndex;
// Write the program header table.
- memcpy(Buf + EHdr->e_phoff, &Phdrs[0], Phdrs.size() * sizeof(Phdrs[0]));
+ auto *HBuf = reinterpret_cast<Elf_Phdr *>(Buf + EHdr->e_phoff);
+ for (Phdr &P : Phdrs)
+ *HBuf++ = P.H;
// 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)
+ for (OutputSectionBase<ELFT> *Sec : getSections())
Sec->writeHeaderTo(++SHdrs);
}
@@ -1446,31 +1480,6 @@ template <class ELFT> void Writer<ELFT>:
Sec->writeTo(Buf + Sec->getFileOff());
}
-template <class ELFT>
-void Writer<ELFT>::setPhdr(Elf_Phdr *PH, uint32_t Type, uint32_t Flags,
- uintX_t FileOff, uintX_t VA, uintX_t Size,
- uintX_t Align) {
- PH->p_type = Type;
- PH->p_flags = Flags;
- PH->p_offset = FileOff;
- PH->p_vaddr = VA;
- PH->p_paddr = VA;
- PH->p_filesz = Size;
- PH->p_memsz = Size;
- PH->p_align = Align;
-}
-
-template <class ELFT>
-void Writer<ELFT>::copyPhdr(Elf_Phdr *PH, OutputSectionBase<ELFT> *From) {
- PH->p_flags = toPhdrFlags(From->getFlags());
- PH->p_offset = From->getFileOff();
- PH->p_vaddr = From->getVA();
- PH->p_paddr = From->getVA();
- PH->p_filesz = From->getSize();
- PH->p_memsz = From->getSize();
- PH->p_align = From->getAlign();
-}
-
template <class ELFT> void Writer<ELFT>::buildSectionMap() {
for (const std::pair<StringRef, std::vector<StringRef>> &OutSec :
Config->OutputSections)
More information about the llvm-commits
mailing list