Index: lld/trunk/ELF/LinkerScript.h =================================================================== --- lld/trunk/ELF/LinkerScript.h +++ lld/trunk/ELF/LinkerScript.h @@ -72,6 +72,7 @@ : BaseCommand(OutputSectionKind), Name(Name) {} static bool classof(const BaseCommand *C); StringRef Name; + Expr AddrExpr; std::vector> Commands; std::vector Phdrs; std::vector Filler; Index: lld/trunk/ELF/LinkerScript.cpp =================================================================== --- lld/trunk/ELF/LinkerScript.cpp +++ lld/trunk/ELF/LinkerScript.cpp @@ -194,6 +194,9 @@ if (Sec->getName() != Cmd->Name) continue; + if (Cmd->AddrExpr) + Dot = Cmd->AddrExpr(Dot); + if ((Sec->getFlags() & SHF_TLS) && Sec->getType() == SHT_NOBITS) { uintX_t TVA = Dot + ThreadBssOffset; TVA = alignTo(TVA, Sec->getAlignment()); @@ -648,6 +651,12 @@ void ScriptParser::readOutputSectionDescription(StringRef OutSec) { OutputSectionCommand *Cmd = new OutputSectionCommand(OutSec); Opt.Commands.emplace_back(Cmd); + + // Read an address expression. + // https://sourceware.org/binutils/docs/ld/Output-Section-Address.html#Output-Section-Address + if (peek() != ":") + Cmd->AddrExpr = readExpr(); + expect(":"); // Parse constraints. Index: lld/trunk/test/ELF/linkerscript-outsections-addr.s =================================================================== --- lld/trunk/test/ELF/linkerscript-outsections-addr.s +++ lld/trunk/test/ELF/linkerscript-outsections-addr.s @@ -0,0 +1,122 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t +# RUN: echo "SECTIONS { \ +# RUN: .aaa 0x2000 : \ +# RUN: { \ +# RUN: *(.aaa) \ +# RUN: } \ +# RUN: .bbb 0x1 ? 0x3000 : 0x4000 : \ +# RUN: { \ +# RUN: *(.bbb) \ +# RUN: } \ +# RUN: .ccc ALIGN(CONSTANT (MAXPAGESIZE)) + (. & (CONSTANT (MAXPAGESIZE) - 1)) : \ +# RUN: { \ +# RUN: *(.ccc) \ +# RUN: } \ +# RUN: .ddd 0x5001 : \ +# RUN: { \ +# RUN: *(.ddd) \ +# RUN: } \ +# RUN: }" > %t.script +# RUN: ld.lld %t --script %t.script -o %tout +# RUN: llvm-readobj -s %tout | FileCheck %s + +## Check: +## 1) Simple constant as address. +## 2) That something that contains ":" character, like ternary +## operator works as expression. +## 3) That complex expressions work. +## 4) That section alignment still applied to explicitly specified address. + +#CHECK:Sections [ +#CHECK: Section { +#CHECK: Index: 0 +#CHECK: Name: +#CHECK: Type: SHT_NULL +#CHECK: Flags [ +#CHECK: ] +#CHECK: Address: 0x0 +#CHECK: Offset: 0x0 +#CHECK: Size: 0 +#CHECK: Link: 0 +#CHECK: Info: 0 +#CHECK: AddressAlignment: 0 +#CHECK: EntrySize: 0 +#CHECK: } +#CHECK: Section { +#CHECK: Index: 1 +#CHECK: Name: .aaa +#CHECK: Type: SHT_PROGBITS +#CHECK: Flags [ +#CHECK: SHF_ALLOC +#CHECK: ] +#CHECK: Address: 0x2000 +#CHECK: Offset: 0x1000 +#CHECK: Size: 8 +#CHECK: Link: 0 +#CHECK: Info: 0 +#CHECK: AddressAlignment: 1 +#CHECK: EntrySize: 0 +#CHECK: } +#CHECK: Section { +#CHECK: Index: 2 +#CHECK: Name: .bbb +#CHECK: Type: SHT_PROGBITS +#CHECK: Flags [ +#CHECK: SHF_ALLOC +#CHECK: ] +#CHECK: Address: 0x3000 +#CHECK: Offset: 0x2000 +#CHECK: Size: 8 +#CHECK: Link: 0 +#CHECK: Info: 0 +#CHECK: AddressAlignment: 1 +#CHECK: EntrySize: 0 +#CHECK: } +#CHECK: Section { +#CHECK: Index: 3 +#CHECK: Name: .ccc +#CHECK: Type: SHT_PROGBITS +#CHECK: Flags [ +#CHECK: SHF_ALLOC +#CHECK: ] +#CHECK: Address: 0x4008 +#CHECK: Offset: 0x2008 +#CHECK: Size: 8 +#CHECK: Link: 0 +#CHECK: Info: 0 +#CHECK: AddressAlignment: 1 +#CHECK: EntrySize: 0 +#CHECK: } +#CHECK: Section { +#CHECK: Index: 4 +#CHECK: Name: .ddd +#CHECK: Type: SHT_PROGBITS +#CHECK: Flags [ +#CHECK: SHF_ALLOC +#CHECK: ] +#CHECK: Address: 0x5010 +#CHECK: Offset: 0x2010 +#CHECK: Size: 8 +#CHECK: Link: 0 +#CHECK: Info: 0 +#CHECK: AddressAlignment: 16 +#CHECK: EntrySize: 0 +#CHECK: } + +.globl _start +_start: +nop + +.section .aaa, "a" +.quad 0 + +.section .bbb, "a" +.quad 0 + +.section .ccc, "a" +.quad 0 + +.section .ddd, "a" +.align 16 +.quad 0 Index: lld/trunk/test/ELF/linkerscript/linkerscript-diagnostic.s =================================================================== --- lld/trunk/test/ELF/linkerscript/linkerscript-diagnostic.s +++ lld/trunk/test/ELF/linkerscript/linkerscript-diagnostic.s @@ -61,6 +61,6 @@ # RUN: echo "boom .temp : { *(.temp) } }" >> %t.script # RUN: not ld.lld -shared %t -o %t1 --script %t.script > %t.log 2>&1 # RUN: FileCheck -check-prefix=ERR7 %s < %t.log -# ERR7: line 4: : expected, but got .temp +# ERR7: line 4: malformed number: .temp # ERR7-NEXT: boom .temp : { *(.temp) } } # RUN: grep '^ ^' %t.log