forked from OSchip/llvm-project
Reduce code duplication when allocating program headers.
This will simplify a bug fix. llvm-svn: 292642
This commit is contained in:
parent
3bb4d01db9
commit
8c495e20bd
|
@ -733,17 +733,7 @@ void LinkerScript<ELFT>::assignAddresses(std::vector<PhdrEntry> &Phdrs) {
|
|||
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.
|
||||
|
|
|
@ -1330,13 +1330,29 @@ template <class ELFT> void Writer<ELFT>::fixSectionAlignments() {
|
|||
}
|
||||
|
||||
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)
|
||||
|
@ -1344,6 +1360,7 @@ void elf::allocateHeaders(MutableArrayRef<PhdrEntry> Phdrs,
|
|||
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
|
||||
|
@ -1355,27 +1372,14 @@ template <class ELFT> void Writer<ELFT>::fixHeaders() {
|
|||
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.
|
||||
|
@ -1740,14 +1744,18 @@ template void elf::writeResult<ELF32BE>();
|
|||
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 *);
|
||||
|
|
|
@ -50,8 +50,8 @@ struct PhdrEntry {
|
|||
llvm::StringRef getOutputSectionName(llvm::StringRef Name);
|
||||
|
||||
template <class ELFT>
|
||||
void allocateHeaders(llvm::MutableArrayRef<PhdrEntry>,
|
||||
llvm::ArrayRef<OutputSectionBase *>);
|
||||
bool allocateHeaders(llvm::MutableArrayRef<PhdrEntry>,
|
||||
llvm::ArrayRef<OutputSectionBase *>, uint64_t Min);
|
||||
template <class ELFT> void reportDiscarded(InputSectionBase<ELFT> *IS);
|
||||
|
||||
template <class ELFT> uint32_t getMipsEFlags();
|
||||
|
|
Loading…
Reference in New Issue