Index: ELF/LinkerScript.h =================================================================== --- ELF/LinkerScript.h +++ ELF/LinkerScript.h @@ -123,6 +123,8 @@ bool HasContents = false; + bool ManualHeadersSize = false; + llvm::BumpPtrAllocator Alloc; // List of section patterns specified with KEEP commands. They will @@ -150,6 +152,7 @@ void addScriptedSymbols(); bool hasPhdrsCommands(); uintX_t getOutputSectionSize(StringRef Name); + uintX_t getSizeOfHeaders(); private: std::vector> Index: ELF/LinkerScript.cpp =================================================================== --- ELF/LinkerScript.cpp +++ ELF/LinkerScript.cpp @@ -239,7 +239,7 @@ } // Assign addresses as instructed by linker script SECTIONS sub-commands. - Dot = Out::ElfHeader->getSize() + Out::ProgramHeaders->getSize(); + Dot = Opt.ManualHeadersSize ? 0 : getSizeOfHeaders(); uintX_t MinVA = std::numeric_limits::max(); uintX_t ThreadBssOffset = 0; @@ -431,6 +431,11 @@ return 0; } +template +typename ELFT::uint LinkerScript::getSizeOfHeaders() { + return Out::ElfHeader->getSize() + Out::ProgramHeaders->getSize(); +} + // Returns indices of ELF headers containing specific section, identified // by Name. Each index is a zero based number of ELF header listed within // PHDRS {} script block. @@ -933,6 +938,22 @@ return 0; } +static uint64_t getSizeOfHeaders() { + switch (Config->EKind) { + case ELF32LEKind: + return Script::X->getSizeOfHeaders(); + case ELF32BEKind: + return Script::X->getSizeOfHeaders(); + case ELF64LEKind: + return Script::X->getSizeOfHeaders(); + case ELF64BEKind: + return Script::X->getSizeOfHeaders(); + default: + llvm_unreachable("unsupported target"); + } + return 0; +} + SymbolAssignment *ScriptParser::readAssignment(StringRef Name) { StringRef Op = next(); assert(Op == "=" || Op == "+="); @@ -1047,6 +1068,10 @@ expect(")"); return [=](uint64_t Dot) { return getSectionSize(Name); }; } + if (Tok == "SIZEOF_HEADERS") { + Opt.ManualHeadersSize = true; + return [=](uint64_t Dot) { return getSizeOfHeaders(); }; + } // Parse a symbol name or a number literal. uint64_t V = 0;