Index: lld/ELF/Config.h =================================================================== --- lld/ELF/Config.h +++ lld/ELF/Config.h @@ -213,6 +213,7 @@ uint16_t DefaultSymbolVersion = llvm::ELF::VER_NDX_GLOBAL; uint16_t EMachine = llvm::ELF::EM_NONE; llvm::Optional ImageBase; + uint64_t CommonPageSize; uint64_t MaxPageSize; uint64_t MipsGotSize; uint64_t ZStackSize; Index: lld/ELF/Driver.cpp =================================================================== --- lld/ELF/Driver.cpp +++ lld/ELF/Driver.cpp @@ -355,7 +355,8 @@ S == "nokeep-text-section-prefix" || S == "norelro" || S == "notext" || S == "now" || S == "origin" || S == "relro" || S == "retpolineplt" || S == "rodynamic" || S == "text" || S == "wxneeded" || - S.startswith("max-page-size=") || S.startswith("stack-size="); + S.startswith("max-page-size=") || S.startswith("stack-size=") || + S.startswith("common-page-size="); } // Report an error for an unknown -z option. @@ -1178,6 +1179,15 @@ return Val; } +// Parse -z common-page-size=. The default value 4096 +static uint64_t getCommonPageSize(opt::InputArgList &Args) { + uint64_t Val = args::getZOptionValue(Args, OPT_z, "common-page-size", + Target->PageSize); + if (!isPowerOf2_64(Val)) + error("common-page-size: value isn't a power of 2"); + return Val; +} + // Parses -image-base option. static Optional getImageBase(opt::InputArgList &Args) { // Because we are using "Config->MaxPageSize" here, this function has to be @@ -1443,6 +1453,7 @@ InX::VerSym = nullptr; InX::VerNeed = nullptr; + Config->CommonPageSize = getCommonPageSize(Args); Config->MaxPageSize = getMaxPageSize(Args); Config->ImageBase = getImageBase(Args); Index: lld/ELF/ScriptParser.cpp =================================================================== --- lld/ELF/ScriptParser.cpp +++ lld/ELF/ScriptParser.cpp @@ -1047,6 +1047,8 @@ Expr ScriptParser::getPageSize() { std::string Location = getCurrentLocation(); return [=]() -> uint64_t { + if (Target && Config) + return Config->CommonPageSize; if (Target) return Target->PageSize; error(Location + ": unable to calculate page size"); Index: lld/test/ELF/linkerscript/common-page-size.s =================================================================== --- /dev/null +++ lld/test/ELF/linkerscript/common-page-size.s @@ -0,0 +1,66 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t + +# RUN: ld.lld -z common-page-size=0x1000 %t -o %t2 +# RUN: llvm-readobj -program-headers %t2 | FileCheck %s + +# CHECK: ProgramHeaders [ +# CHECK: ProgramHeader { +# CHECK: Type: PT_LOAD +# CHECK-NEXT: Offset: 0x0 +# CHECK-NEXT: VirtualAddress: 0x200000 +# CHECK-NEXT: PhysicalAddress: 0x200000 +# CHECK-NEXT: FileSize: 344 +# CHECK-NEXT: MemSize: 344 +# CHECK-NEXT: Flags [ +# CHECK-NEXT: PF_R +# CHECK-NEXT: ] +# CHECK-NEXT: Alignment: 4096 +# CHECK-NEXT: } +# CHECK-NEXT: ProgramHeader { +# CHECK-NEXT: Type: PT_LOAD (0x1) +# CHECK-NEXT: Offset: 0x1000 +# CHECK-NEXT: VirtualAddress: 0x201000 +# CHECK-NEXT: PhysicalAddress: 0x201000 +# CHECK-NEXT: FileSize: 1 +# CHECK-NEXT: MemSize: 1 +# CHECK-NEXT: Flags [ +# CHECK-NEXT: PF_R +# CHECK-NEXT: PF_X +# CHECK-NEXT: ] +# CHECK-NEXT: Alignment: 4096 +# CHECK-NEXT: } +# CHECK-NEXT: ProgramHeader { +# CHECK-NEXT: Type: PT_LOAD (0x1) +# CHECK-NEXT: Offset: 0x2000 +# CHECK-NEXT: VirtualAddress: 0x202000 +# CHECK-NEXT: PhysicalAddress: 0x202000 +# CHECK-NEXT: FileSize: 8 +# CHECK-NEXT: MemSize: 8 +# CHECK-NEXT: Flags [ +# CHECK-NEXT: PF_R +# CHECK-NEXT: PF_W +# CHECK-NEXT: ] +# CHECK-NEXT: Alignment: 4096 +# CHECK-NEXT: } + +# RUN: echo "SECTIONS { symbol = CONSTANT(MAXPAGESIZE); }" > %t.script +# RUN: ld.lld -z common-page-size=0x1000 -o %t1 --script %t.script %t +# RUN: llvm-objdump -t %t1 | FileCheck -check-prefix CHECK-SCRIPT %s + +# CHECK-SCRIPT: 0000000000001000 *ABS* 00000000 symbol + +# RUN: not ld.lld -z common-page-size=0x1001 -o %t1 --script %t.script %t 2>&1 \ +# RUN: | FileCheck -check-prefix=ERR1 %s +# ERR1: common-page-size: value isn't a power of 2 + +# RUN: not ld.lld -z common-page-size=-0x1000 -o %t1 --script %t.script %t 2>&1 \ +# RUN: | FileCheck -check-prefix=ERR2 %s +# ERR2: invalid common-page-size: -0x1000 + +.global _start +_start: + nop + +.section .a, "aw" +.quad 0