Sec->Addr = 0;
}
- uintX_t HeaderSize = getHeaderSize();
- // If the linker script doesn't have PHDRS, add ElfHeader and ProgramHeaders
- // now that we know we have space.
- if (HeaderSize <= MinVA && !hasPhdrsCommands())
- allocateHeaders<ELFT>(Phdrs, *OutputSections);
-
- // ELF and Program headers need to be right before the first section in
- // memory. Set their addresses accordingly.
- MinVA = alignDown(MinVA - HeaderSize, Config->MaxPageSize);
- Out<ELFT>::ElfHeader->Addr = MinVA;
- Out<ELFT>::ProgramHeaders->Addr = Out<ELFT>::ElfHeader->Size + MinVA;
+ allocateHeaders<ELFT>(Phdrs, *OutputSections, MinVA);
}
// Creates program headers as instructed by PHDRS linker script command.
}
template <class ELFT>
-void elf::allocateHeaders(MutableArrayRef<PhdrEntry> Phdrs,
- ArrayRef<OutputSectionBase *> OutputSections) {
+bool elf::allocateHeaders(MutableArrayRef<PhdrEntry> Phdrs,
+ ArrayRef<OutputSectionBase *> 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;
+ return false;
+
+ uint64_t HeaderSize = getHeaderSize<ELFT>();
+ if (HeaderSize > Min)
+ return false;
+ Min = alignDown(Min - HeaderSize, Config->MaxPageSize);
+
+ if (!ScriptConfig->HasSections)
+ Config->ImageBase = Min = std::min(Min, Config->ImageBase);
+
+ Out<ELFT>::ElfHeader->Addr = Min;
+ Out<ELFT>::ProgramHeaders->Addr = Min + Out<ELFT>::ElfHeader->Size;
+
+ if (Script<ELFT>::X->hasPhdrsCommands())
+ return true;
+
if (FirstPTLoad->First)
for (OutputSectionBase *Sec : OutputSections)
if (Sec->FirstInPtLoad == FirstPTLoad->First)
FirstPTLoad->First = Out<ELFT>::ElfHeader;
if (!FirstPTLoad->Last)
FirstPTLoad->Last = Out<ELFT>::ProgramHeaders;
+ return true;
}
// We should set file offsets and VAs for elf header and program headers
if (ScriptConfig->HasSections)
return;
- uintX_t HeaderSize = getHeaderSize<ELFT>();
// When -T<section> option is specified, lower the base to make room for those
// sections.
- if (!Config->SectionStartMap.empty()) {
- uint64_t Min = -1;
+ uint64_t Min = -1;
+ if (!Config->SectionStartMap.empty())
for (const auto &P : Config->SectionStartMap)
Min = std::min(Min, P.second);
- if (HeaderSize < Min)
- Min -= HeaderSize;
- else
- AllocateHeader = false;
- if (Min < Config->ImageBase)
- Config->ImageBase = alignDown(Min, Config->MaxPageSize);
- }
-
- if (AllocateHeader)
- allocateHeaders<ELFT>(Phdrs, OutputSections);
- uintX_t BaseVA = Config->ImageBase;
- Out<ELFT>::ElfHeader->Addr = BaseVA;
- Out<ELFT>::ProgramHeaders->Addr = BaseVA + Out<ELFT>::ElfHeader->Size;
+ AllocateHeader = allocateHeaders<ELFT>(Phdrs, OutputSections, Min);
}
// Assign VAs (addresses at run-time) to output sections.
template void elf::writeResult<ELF64LE>();
template void elf::writeResult<ELF64BE>();
-template void elf::allocateHeaders<ELF32LE>(MutableArrayRef<PhdrEntry>,
- ArrayRef<OutputSectionBase *>);
-template void elf::allocateHeaders<ELF32BE>(MutableArrayRef<PhdrEntry>,
- ArrayRef<OutputSectionBase *>);
-template void elf::allocateHeaders<ELF64LE>(MutableArrayRef<PhdrEntry>,
- ArrayRef<OutputSectionBase *>);
-template void elf::allocateHeaders<ELF64BE>(MutableArrayRef<PhdrEntry>,
- ArrayRef<OutputSectionBase *>);
+template bool elf::allocateHeaders<ELF32LE>(MutableArrayRef<PhdrEntry>,
+ ArrayRef<OutputSectionBase *>,
+ uint64_t);
+template bool elf::allocateHeaders<ELF32BE>(MutableArrayRef<PhdrEntry>,
+ ArrayRef<OutputSectionBase *>,
+ uint64_t);
+template bool elf::allocateHeaders<ELF64LE>(MutableArrayRef<PhdrEntry>,
+ ArrayRef<OutputSectionBase *>,
+ uint64_t);
+template bool elf::allocateHeaders<ELF64BE>(MutableArrayRef<PhdrEntry>,
+ ArrayRef<OutputSectionBase *>,
+ uint64_t);
template bool elf::isRelroSection<ELF32LE>(const OutputSectionBase *);
template bool elf::isRelroSection<ELF32BE>(const OutputSectionBase *);