Index: ELF/LinkerScript.cpp =================================================================== --- ELF/LinkerScript.cpp +++ ELF/LinkerScript.cpp @@ -1231,6 +1231,12 @@ // and decimal numbers. Decimal numbers may have "K" (kilo) or // "M" (mega) prefixes. static bool readInteger(StringRef Tok, uint64_t &Result) { + if (Tok.startswith("-")) { + if (!readInteger(Tok.substr(1), Result)) + return false; + Result = -Result; + return true; + } if (Tok.startswith_lower("0x")) return !Tok.substr(2).getAsInteger(16, Result); if (Tok.endswith_lower("H")) @@ -1256,6 +1262,15 @@ StringRef Tok = next(); + if (Tok == "~") { + Expr E = readPrimary(); + return [=](uint64_t Dot) { return ~E(Dot); }; + } + if (Tok == "-") { + Expr E = readPrimary(); + return [=](uint64_t Dot) { return -E(Dot); }; + } + // Built-in functions are parsed here. // https://sourceware.org/binutils/docs/ld/Builtin-Functions.html. if (Tok == "ADDR") { Index: test/ELF/linkerscript/locationcounter.s =================================================================== --- test/ELF/linkerscript/locationcounter.s +++ test/ELF/linkerscript/locationcounter.s @@ -40,6 +40,8 @@ # RUN: . = 0x27000; \ # RUN: . += 0x1000; \ # RUN: .plusassign : { *(.plusassign) } \ +# RUN: . = ((. + 0x1fff) & ~(0x1000 + -1)); \ +# RUN: .unary : { *(.unary) } \ # RUN: }" > %t.script # RUN: ld.lld %t --script %t.script -o %t2 # RUN: llvm-readobj -s %t2 | FileCheck %s @@ -314,6 +316,21 @@ # CHECK-NEXT: AddressAlignment: # CHECK-NEXT: EntrySize: # CHECK-NEXT: } +# CHECK-NEXT: Section { +# CHECK-NEXT: Index: +# CHECK-NEXT: Name: .unary +# CHECK-NEXT: Type: SHT_PROGBITS +# CHECK-NEXT: Flags [ +# CHECK-NEXT: SHF_ALLOC +# CHECK-NEXT: ] +# CHECK-NEXT: Address: 0x2A000 +# CHECK-NEXT: Offset: +# CHECK-NEXT: Size: +# CHECK-NEXT: Link: +# CHECK-NEXT: Info: +# CHECK-NEXT: AddressAlignment: +# CHECK-NEXT: EntrySize: +# CHECK-NEXT: } ## Mailformed number error. # RUN: echo "SECTIONS { \ @@ -420,3 +437,6 @@ .section .plusassign, "a" .quad 0 + +.section .unary, "a" +.quad 0 Index: test/ELF/linkerscript/symbol-assignexpr.s =================================================================== --- test/ELF/linkerscript/symbol-assignexpr.s +++ test/ELF/linkerscript/symbol-assignexpr.s @@ -5,6 +5,14 @@ # RUN: symbol = CONSTANT(MAXPAGESIZE); \ # RUN: symbol2 = symbol + 0x1234; \ # RUN: symbol3 = symbol2; \ +# RUN: symbol4 = symbol + -4; \ +# RUN: symbol5 = symbol - ~ 0xfffb; \ +# RUN: symbol6 = symbol - ~(0xfff0 + 0xb); \ +# RUN: symbol7 = symbol - ~ 0xfffb + 4; \ +# RUN: symbol8 = ~ 0xffff + 4; \ +# RUN: symbol9 = - 4; \ +# RUN: symbol10 = 0xfedcba9876543210; \ +# RUN: symbol11 = ((0x28000 + 0x1fff) & ~(0x1000 + -1)); \ # RUN: }" > %t.script # RUN: ld.lld -o %t1 --script %t.script %t # RUN: llvm-objdump -t %t1 | FileCheck %s @@ -16,6 +24,14 @@ # CHECK-NEXT: 0000000000200000 *ABS* 00000000 symbol # CHECK-NEXT: 0000000000201234 *ABS* 00000000 symbol2 # CHECK-NEXT: 0000000000201234 *ABS* 00000000 symbol3 +# CHECK-NEXT: 00000000001ffffc *ABS* 00000000 symbol4 +# CHECK-NEXT: 000000000020fffc *ABS* 00000000 symbol5 +# CHECK-NEXT: 000000000020fffc *ABS* 00000000 symbol6 +# CHECK-NEXT: 0000000000210000 *ABS* 00000000 symbol7 +# CHECK-NEXT: ffffffffffff0004 *ABS* 00000000 symbol8 +# CHECK-NEXT: fffffffffffffffc *ABS* 00000000 symbol9 +# CHECK-NEXT: fedcba9876543210 *ABS* 00000000 symbol10 +# CHECK-NEXT: 0000000000029000 *ABS* 00000000 symbol11 # RUN: echo "SECTIONS { \ # RUN: symbol2 = symbol; \