[ELF] PR30221 - linker script expression parser does not accept '~'

The patch adds support for both '-' and '~' unary expressions. Also it
brings support for signed numbers is expressions.

https://llvm.org/bugs/show_bug.cgi?id=30221

Differential revision: https://reviews.llvm.org/D24128

llvm-svn: 280546
This commit is contained in:
Simon Atanasyan 2016-09-02 21:54:35 +00:00
parent 7b104d4721
commit eaeafb2b4f
3 changed files with 51 additions and 0 deletions

View File

@ -1231,6 +1231,12 @@ uint64_t static getConstant(StringRef S) {
// 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 @@ Expr ScriptParser::readPrimary() {
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") {

View File

@ -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 @@ nop
.section .plusassign, "a"
.quad 0
.section .unary, "a"
.quad 0

View File

@ -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; \