Index: ELF/InputSection.cpp =================================================================== --- ELF/InputSection.cpp +++ ELF/InputSection.cpp @@ -485,9 +485,9 @@ // 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, Index: ELF/LinkerScript.cpp =================================================================== --- ELF/LinkerScript.cpp +++ ELF/LinkerScript.cpp @@ -726,6 +726,13 @@ 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 @@ 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; }); Index: ELF/OutputSections.h =================================================================== --- ELF/OutputSections.h +++ ELF/OutputSections.h @@ -61,13 +61,14 @@ 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), Index: ELF/Writer.cpp =================================================================== --- ELF/Writer.cpp +++ ELF/Writer.cpp @@ -749,7 +749,7 @@ First = Sec; p_align = std::max(p_align, Sec->Alignment); if (p_type == PT_LOAD) - Sec->FirstInPtLoad = First; + Sec->PtLoad = this; } template @@ -1660,11 +1660,11 @@ // 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)