aboutsummaryrefslogtreecommitdiff
path: root/ELF/Writer.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'ELF/Writer.cpp')
-rw-r--r--ELF/Writer.cpp89
1 files changed, 15 insertions, 74 deletions
diff --git a/ELF/Writer.cpp b/ELF/Writer.cpp
index 3de2596af27c..7f00e37ce7b0 100644
--- a/ELF/Writer.cpp
+++ b/ELF/Writer.cpp
@@ -62,7 +62,6 @@ private:
void assignFileOffsets();
void assignFileOffsetsBinary();
void setPhdrs();
- void fixHeaders();
void fixSectionAlignments();
void fixPredefinedSymbols();
void openFile();
@@ -86,7 +85,6 @@ private:
uint64_t FileSize;
uint64_t SectionHeaderOff;
- bool AllocateHeader = true;
};
} // anonymous namespace
@@ -252,7 +250,7 @@ template <class ELFT> void Writer<ELFT>::run() {
} else {
if (!Script->Opt.HasSections) {
fixSectionAlignments();
- Script->fabricateDefaultCommands(AllocateHeader);
+ Script->fabricateDefaultCommands();
}
Script->synchronize();
Script->assignAddresses(Phdrs);
@@ -747,15 +745,12 @@ static bool compareSectionsNonScript(const OutputSection *A,
// Output section ordering is determined by this function.
template <class ELFT>
static bool compareSections(const OutputSection *A, const OutputSection *B) {
- // For now, put sections mentioned in a linker script first.
- int AIndex = Script->getSectionIndex(A->Name);
- int BIndex = Script->getSectionIndex(B->Name);
- bool AInScript = AIndex != INT_MAX;
- bool BInScript = BIndex != INT_MAX;
- if (AInScript != BInScript)
- return AInScript;
- // If both are in the script, use that order.
- if (AInScript)
+ // For now, put sections mentioned in a linker script
+ // first. Sections not on linker script will have a SectionIndex of
+ // INT_MAX.
+ int AIndex = A->SectionIndex;
+ int BIndex = B->SectionIndex;
+ if (AIndex != BIndex)
return AIndex < BIndex;
return compareSectionsNonScript<ELFT>(A, B);
@@ -1021,9 +1016,8 @@ template <class ELFT> void Writer<ELFT>::sortSections() {
auto I = OutputSections.begin();
auto E = OutputSections.end();
auto NonScriptI =
- std::find_if(OutputSections.begin(), E, [](OutputSection *S) {
- return Script->getSectionIndex(S->Name) == INT_MAX;
- });
+ std::find_if(OutputSections.begin(), E,
+ [](OutputSection *S) { return S->SectionIndex == INT_MAX; });
while (NonScriptI != E) {
auto BestPos = std::max_element(
I, NonScriptI, [&](OutputSection *&A, OutputSection *&B) {
@@ -1176,7 +1170,7 @@ template <class ELFT> void Writer<ELFT>::finalizeSections() {
if (!Config->Relocatable && !Config->OFormatBinary) {
Phdrs = Script->hasPhdrsCommands() ? Script->createPhdrs() : createPhdrs();
addPtArmExid(Phdrs);
- fixHeaders();
+ Out::ProgramHeaders->Size = sizeof(Elf_Phdr) * Phdrs.size();
}
// Dynamic section must be the last one in this list and dynamic
@@ -1321,6 +1315,11 @@ template <class ELFT> std::vector<PhdrEntry> Writer<ELFT>::createPhdrs() {
// Add the first PT_LOAD segment for regular output sections.
uint64_t Flags = computeFlags(PF_R);
PhdrEntry *Load = AddHdr(PT_LOAD, Flags);
+
+ // Add the headers. We will remove them if they don't fit.
+ Load->add(Out::ElfHeader);
+ Load->add(Out::ProgramHeaders);
+
for (OutputSection *Sec : OutputSections) {
if (!(Sec->Flags & SHF_ALLOC))
break;
@@ -1447,64 +1446,6 @@ template <class ELFT> void Writer<ELFT>::fixSectionAlignments() {
}
}
-bool elf::allocateHeaders(std::vector<PhdrEntry> &Phdrs,
- ArrayRef<OutputSection *> OutputSections,
- uint64_t Min) {
- auto FirstPTLoad =
- std::find_if(Phdrs.begin(), Phdrs.end(),
- [](const PhdrEntry &E) { return E.p_type == PT_LOAD; });
- if (FirstPTLoad == Phdrs.end())
- return false;
-
- uint64_t HeaderSize = getHeaderSize();
- if (HeaderSize > Min) {
- auto PhdrI =
- std::find_if(Phdrs.begin(), Phdrs.end(),
- [](const PhdrEntry &E) { return E.p_type == PT_PHDR; });
- if (PhdrI != Phdrs.end())
- Phdrs.erase(PhdrI);
- return false;
- }
- Min = alignDown(Min - HeaderSize, Config->MaxPageSize);
-
- if (!Script->Opt.HasSections)
- Config->ImageBase = Min = std::min(Min, Config->ImageBase);
-
- Out::ElfHeader->Addr = Min;
- Out::ProgramHeaders->Addr = Min + Out::ElfHeader->Size;
-
- if (Script->hasPhdrsCommands())
- return true;
-
- if (FirstPTLoad->First)
- for (OutputSection *Sec : OutputSections)
- if (Sec->FirstInPtLoad == FirstPTLoad->First)
- Sec->FirstInPtLoad = Out::ElfHeader;
- FirstPTLoad->First = Out::ElfHeader;
- if (!FirstPTLoad->Last)
- FirstPTLoad->Last = Out::ProgramHeaders;
- return true;
-}
-
-// We should set file offsets and VAs for elf header and program headers
-// sections. These are special, we do not include them into output sections
-// list, but have them to simplify the code.
-template <class ELFT> void Writer<ELFT>::fixHeaders() {
- Out::ProgramHeaders->Size = sizeof(Elf_Phdr) * Phdrs.size();
- // If the script has SECTIONS, assignAddresses will compute the values.
- if (Script->Opt.HasSections)
- return;
-
- // When -T<section> option is specified, lower the base to make room for those
- // sections.
- uint64_t Min = -1;
- if (!Config->SectionStartMap.empty())
- for (const auto &P : Config->SectionStartMap)
- Min = std::min(Min, P.second);
-
- AllocateHeader = allocateHeaders(Phdrs, OutputSections, Min);
-}
-
// Adjusts the file alignment for a given output section and returns
// its new file offset. The file offset must be the same with its
// virtual address (modulo the page size) so that the loader can load