[ELF] - Store pointer to PT_LOAD instead of pointer to first section in OutputSection
It is a bit more convinent and helps to simplify logic of program headers allocation a little. Differential revision: https://reviews.llvm.org/D34956 llvm-svn: 312711
This commit is contained in:
parent
1a48ddb864
commit
582ede8922
|
@ -485,9 +485,9 @@ static uint64_t getAArch64UndefinedRelativeWeakVA(uint64_t Type, uint64_t A,
|
|||
// of the RW segment.
|
||||
static uint64_t getARMStaticBase(const SymbolBody &Body) {
|
||||
OutputSection *OS = Body.getOutputSection();
|
||||
if (!OS || !OS->FirstInPtLoad)
|
||||
if (!OS || !OS->PtLoad || !OS->PtLoad->First)
|
||||
fatal("SBREL relocation to " + Body.getName() + " without static base");
|
||||
return OS->FirstInPtLoad->Addr;
|
||||
return OS->PtLoad->First->Addr;
|
||||
}
|
||||
|
||||
static uint64_t getRelocTargetVA(uint32_t Type, int64_t A, uint64_t P,
|
||||
|
|
|
@ -726,6 +726,13 @@ void LinkerScript::adjustSectionsAfterSorting() {
|
|||
removeEmptyCommands();
|
||||
}
|
||||
|
||||
static OutputSection *findFirstSection(PhdrEntry *Load) {
|
||||
for (OutputSection *Sec : OutputSections)
|
||||
if (Sec->PtLoad == Load)
|
||||
return Sec;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Try to find an address for the file and program headers output sections,
|
||||
// which were unconditionally added to the first PT_LOAD segment earlier.
|
||||
//
|
||||
|
@ -761,21 +768,9 @@ void LinkerScript::allocateHeaders(std::vector<PhdrEntry *> &Phdrs) {
|
|||
return;
|
||||
}
|
||||
|
||||
OutputSection *ActualFirst = nullptr;
|
||||
for (OutputSection *Sec : OutputSections) {
|
||||
if (Sec->FirstInPtLoad == Out::ElfHeader) {
|
||||
ActualFirst = Sec;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (ActualFirst) {
|
||||
for (OutputSection *Sec : OutputSections)
|
||||
if (Sec->FirstInPtLoad == Out::ElfHeader)
|
||||
Sec->FirstInPtLoad = ActualFirst;
|
||||
FirstPTLoad->First = ActualFirst;
|
||||
} else {
|
||||
Phdrs.erase(It);
|
||||
}
|
||||
Out::ElfHeader->PtLoad = nullptr;
|
||||
Out::ProgramHeaders->PtLoad = nullptr;
|
||||
FirstPTLoad->First = findFirstSection(FirstPTLoad);
|
||||
|
||||
llvm::erase_if(Phdrs,
|
||||
[](const PhdrEntry *E) { return E->p_type == PT_PHDR; });
|
||||
|
|
|
@ -61,13 +61,14 @@ public:
|
|||
Alignment = Val;
|
||||
}
|
||||
|
||||
// Pointer to the first section in PT_LOAD segment, which this section
|
||||
// also resides in. This field is used to correctly compute file offset
|
||||
// of a section. When two sections share the same load segment, difference
|
||||
// between their file offsets should be equal to difference between their
|
||||
// virtual addresses. To compute some section offset we use the following
|
||||
// formula: Off = Off_first + VA - VA_first.
|
||||
OutputSection *FirstInPtLoad = nullptr;
|
||||
// Pointer to the PT_LOAD segment, which this section resides in. This field
|
||||
// is used to correctly compute file offset of a section. When two sections
|
||||
// share the same load segment, difference between their file offsets should
|
||||
// be equal to difference between their virtual addresses. To compute some
|
||||
// section offset we use the following formula: Off = Off_first + VA -
|
||||
// VA_first, where Off_first and VA_first is file offset and VA of first
|
||||
// section in PT_LOAD.
|
||||
PhdrEntry *PtLoad = nullptr;
|
||||
|
||||
// Pointer to a relocation section for this section. Usually nullptr because
|
||||
// we consume relocations, but if --emit-relocs is specified (which is rare),
|
||||
|
|
|
@ -746,7 +746,7 @@ void PhdrEntry::add(OutputSection *Sec) {
|
|||
First = Sec;
|
||||
p_align = std::max(p_align, Sec->Alignment);
|
||||
if (p_type == PT_LOAD)
|
||||
Sec->FirstInPtLoad = First;
|
||||
Sec->PtLoad = this;
|
||||
}
|
||||
|
||||
template <class ELFT>
|
||||
|
@ -1660,11 +1660,11 @@ template <class ELFT> void Writer<ELFT>::fixSectionAlignments() {
|
|||
// virtual address (modulo the page size) so that the loader can load
|
||||
// executables without any address adjustment.
|
||||
static uint64_t getFileAlignment(uint64_t Off, OutputSection *Cmd) {
|
||||
OutputSection *First = Cmd->FirstInPtLoad;
|
||||
// If the section is not in a PT_LOAD, we just have to align it.
|
||||
if (!First)
|
||||
if (!Cmd->PtLoad)
|
||||
return alignTo(Off, Cmd->Alignment);
|
||||
|
||||
OutputSection *First = Cmd->PtLoad->First;
|
||||
// The first section in a PT_LOAD has to have congruent offset and address
|
||||
// module the page size.
|
||||
if (Cmd == First)
|
||||
|
|
Loading…
Reference in New Issue