Index: lld/trunk/ELF/LinkerScript.h =================================================================== --- lld/trunk/ELF/LinkerScript.h +++ lld/trunk/ELF/LinkerScript.h @@ -127,6 +127,7 @@ public: virtual uint64_t getOutputSectionAddress(StringRef Name) = 0; virtual uint64_t getOutputSectionSize(StringRef Name) = 0; + virtual uint64_t getOutputSectionAlign(StringRef Name) = 0; virtual uint64_t getHeaderSize() = 0; virtual uint64_t getSymbolValue(StringRef S) = 0; }; @@ -173,6 +174,7 @@ bool hasPhdrsCommands(); uint64_t getOutputSectionAddress(StringRef Name) override; uint64_t getOutputSectionSize(StringRef Name) override; + uint64_t getOutputSectionAlign(StringRef Name) override; uint64_t getHeaderSize() override; uint64_t getSymbolValue(StringRef S) override; Index: lld/trunk/ELF/LinkerScript.cpp =================================================================== --- lld/trunk/ELF/LinkerScript.cpp +++ lld/trunk/ELF/LinkerScript.cpp @@ -572,6 +572,15 @@ return 0; } +template +uint64_t LinkerScript::getOutputSectionAlign(StringRef Name) { + for (OutputSectionBase *Sec : *OutputSections) + if (Sec->getName() == Name) + return Sec->getAlignment(); + error("undefined section " + Name); + return 0; +} + template uint64_t LinkerScript::getHeaderSize() { return Out::ElfHeader->getSize() + Out::ProgramHeaders->getSize(); } @@ -1306,6 +1315,13 @@ expect(")"); return [=](uint64_t Dot) { return ScriptBase->getOutputSectionSize(Name); }; } + if (Tok == "ALIGNOF") { + expect("("); + StringRef Name = next(); + expect(")"); + return + [=](uint64_t Dot) { return ScriptBase->getOutputSectionAlign(Name); }; + } if (Tok == "SIZEOF_HEADERS") return [=](uint64_t Dot) { return ScriptBase->getHeaderSize(); }; Index: lld/trunk/test/ELF/linkerscript/alignof.s =================================================================== --- lld/trunk/test/ELF/linkerscript/alignof.s +++ lld/trunk/test/ELF/linkerscript/alignof.s @@ -0,0 +1,41 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t + +# RUN: echo "SECTIONS { \ +# RUN: .aaa : { *(.aaa) } \ +# RUN: .bbb : { *(.bbb) } \ +# RUN: .ccc : { *(.ccc) } \ +# RUN: _aaa = ALIGNOF(.aaa); \ +# RUN: _bbb = ALIGNOF(.bbb); \ +# RUN: _ccc = ALIGNOF(.ccc); \ +# RUN: }" > %t.script +# RUN: ld.lld -o %t1 --script %t.script %t +# RUN: llvm-objdump -t %t1 | FileCheck %s +# CHECK: SYMBOL TABLE: +# CHECK: 0000000000000008 *ABS* 00000000 _aaa +# CHECK-NEXT: 0000000000000010 *ABS* 00000000 _bbb +# CHECK-NEXT: 0000000000000020 *ABS* 00000000 _ccc + +## Check that we error out if trying to get alignment of +## section that does not exist. +# RUN: echo "SECTIONS { \ +# RUN: _aaa = ALIGNOF(.foo); \ +# RUN: }" > %t.script +# RUN: not ld.lld -o %t1 --script %t.script %t 2>&1 \ +# RUN: | FileCheck -check-prefix=ERR %s +# ERR: undefined section .foo +.global _start +_start: + nop + +.section .aaa,"a" + .align 8 + .quad 0 + +.section .bbb,"a" + .align 16 + .quad 0 + +.section .ccc,"a" + .align 32 + .quad 0