[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:
George Rimar 2017-09-07 10:53:07 +00:00
parent 1a48ddb864
commit 582ede8922
4 changed files with 23 additions and 27 deletions

View File

@ -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,

View File

@ -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; });

View File

@ -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),

View File

@ -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)