From ab9390664ff9a70def8ca3efb24fa2aca1874c7a Mon Sep 17 00:00:00 2001 From: George Rimar Date: Mon, 25 Apr 2016 08:14:41 +0000 Subject: [PATCH] [ELF] - Implemented comparsion operators for linkerscript. Patch adds support of <,>,!=,==,>=,<= operators. Differential revision: http://reviews.llvm.org/D19419 llvm-svn: 267382 --- lld/ELF/LinkerScript.cpp | 32 ++++++-- lld/ELF/ScriptParser.cpp | 2 +- lld/test/ELF/linkerscript-locationcounter.s | 120 ++++++++++++++++++++++++++++ 3 files changed, 146 insertions(+), 8 deletions(-) diff --git a/lld/ELF/LinkerScript.cpp b/lld/ELF/LinkerScript.cpp index cabd82f..4156f08 100644 --- a/lld/ELF/LinkerScript.cpp +++ b/lld/ELF/LinkerScript.cpp @@ -63,9 +63,15 @@ private: static int precedence(StringRef Op) { return StringSwitch(Op) .Case("*", 4) - .Case("/", 3) - .Case("+", 2) - .Case("-", 2) + .Case("/", 4) + .Case("+", 3) + .Case("-", 3) + .Case("<", 2) + .Case(">", 2) + .Case(">=", 2) + .Case("<=", 2) + .Case("==", 2) + .Case("!=", 2) .Case("&", 1) .Default(-1); } @@ -115,10 +121,6 @@ uint64_t ExprParser::parseTernary(uint64_t Cond) { } uint64_t ExprParser::apply(StringRef Op, uint64_t L, uint64_t R) { - if (Op == "+") - return L + R; - if (Op == "-") - return L - R; if (Op == "*") return L * R; if (Op == "/") { @@ -128,6 +130,22 @@ uint64_t ExprParser::apply(StringRef Op, uint64_t L, uint64_t R) { } return L / R; } + if (Op == "+") + return L + R; + if (Op == "-") + return L - R; + if (Op == "<") + return L < R; + if (Op == ">") + return L > R; + if (Op == ">=") + return L >= R; + if (Op == "<=") + return L <= R; + if (Op == "==") + return L == R; + if (Op == "!=") + return L != R; if (Op == "&") return L & R; llvm_unreachable("invalid operator"); diff --git a/lld/ELF/ScriptParser.cpp b/lld/ELF/ScriptParser.cpp index 2bc0bbc..937b8a1 100644 --- a/lld/ELF/ScriptParser.cpp +++ b/lld/ELF/ScriptParser.cpp @@ -75,7 +75,7 @@ std::vector ScriptParserBase::tokenize(StringRef S) { // Unquoted token size_t Pos = S.find_first_not_of( "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" - "0123456789_.$/\\~=+[]*?-:"); + "0123456789_.$/\\~=+[]*?-:!<>"); // A character that cannot start a word (which is usually a // punctuation) forms a single character token. if (Pos == 0) diff --git a/lld/test/ELF/linkerscript-locationcounter.s b/lld/test/ELF/linkerscript-locationcounter.s index cda104b..96dde12 100644 --- a/lld/test/ELF/linkerscript-locationcounter.s +++ b/lld/test/ELF/linkerscript-locationcounter.s @@ -18,6 +18,18 @@ # RUN: .ternary1 : { *(.ternary1) } \ # RUN: . = 0x0 ? 0x999999 : 0x17000; \ # RUN: .ternary2 : { *(.ternary2) } \ +# RUN: . = 0x0 < 0x1 ? 0x18000 : 0x999999; \ +# RUN: .less : { *(.less) } \ +# RUN: . = 0x1 <= 0x1 ? 0x19000 : 0x999999; \ +# RUN: .lesseq : { *(.lesseq) } \ +# RUN: . = 0x1 > 0x0 ? 0x20000 : 0x999999; \ +# RUN: .great : { *(.great) } \ +# RUN: . = 0x1 >= 0x1 ? 0x21000 : 0x999999; \ +# RUN: .greateq : { *(.greateq) } \ +# RUN: . = 0x1 == 0x1 ? 0x22000 : 0x999999; \ +# RUN: .eq : { *(.eq) } \ +# RUN: . = 0x2 != 0x1 ? 0x23000 : 0x999999; \ +# RUN: .neq : { *(.neq) } \ # RUN: }" > %t.script # RUN: ld.lld %t --script %t.script -o %t2 # RUN: llvm-readobj -s %t2 | FileCheck %s @@ -142,6 +154,96 @@ # CHECK-NEXT: AddressAlignment: # CHECK-NEXT: EntrySize: # CHECK-NEXT: } +# CHECK-NEXT: Section { +# CHECK-NEXT: Index: +# CHECK-NEXT: Name: .less +# CHECK-NEXT: Type: SHT_PROGBITS +# CHECK-NEXT: Flags [ +# CHECK-NEXT: SHF_ALLOC +# CHECK-NEXT: ] +# CHECK-NEXT: Address: 0x18000 +# CHECK-NEXT: Offset: +# CHECK-NEXT: Size: +# CHECK-NEXT: Link: +# CHECK-NEXT: Info: +# CHECK-NEXT: AddressAlignment: +# CHECK-NEXT: EntrySize: +# CHECK-NEXT: } +# CHECK-NEXT: Section { +# CHECK-NEXT: Index: +# CHECK-NEXT: Name: .lesseq +# CHECK-NEXT: Type: SHT_PROGBITS +# CHECK-NEXT: Flags [ +# CHECK-NEXT: SHF_ALLOC +# CHECK-NEXT: ] +# CHECK-NEXT: Address: 0x19000 +# CHECK-NEXT: Offset: +# CHECK-NEXT: Size: +# CHECK-NEXT: Link: +# CHECK-NEXT: Info: +# CHECK-NEXT: AddressAlignment: +# CHECK-NEXT: EntrySize: +# CHECK-NEXT: } +# CHECK-NEXT: Section { +# CHECK-NEXT: Index: +# CHECK-NEXT: Name: .great +# CHECK-NEXT: Type: SHT_PROGBITS +# CHECK-NEXT: Flags [ +# CHECK-NEXT: SHF_ALLOC +# CHECK-NEXT: ] +# CHECK-NEXT: Address: 0x20000 +# CHECK-NEXT: Offset: +# CHECK-NEXT: Size: +# CHECK-NEXT: Link: +# CHECK-NEXT: Info: +# CHECK-NEXT: AddressAlignment: +# CHECK-NEXT: EntrySize: +# CHECK-NEXT: } +# CHECK-NEXT: Section { +# CHECK-NEXT: Index: +# CHECK-NEXT: Name: .greateq +# CHECK-NEXT: Type: SHT_PROGBITS +# CHECK-NEXT: Flags [ +# CHECK-NEXT: SHF_ALLOC +# CHECK-NEXT: ] +# CHECK-NEXT: Address: 0x21000 +# CHECK-NEXT: Offset: +# CHECK-NEXT: Size: +# CHECK-NEXT: Link: +# CHECK-NEXT: Info: +# CHECK-NEXT: AddressAlignment: +# CHECK-NEXT: EntrySize: +# CHECK-NEXT: } +# CHECK-NEXT: Section { +# CHECK-NEXT: Index: +# CHECK-NEXT: Name: .eq +# CHECK-NEXT: Type: SHT_PROGBITS +# CHECK-NEXT: Flags [ +# CHECK-NEXT: SHF_ALLOC +# CHECK-NEXT: ] +# CHECK-NEXT: Address: 0x22000 +# CHECK-NEXT: Offset: +# CHECK-NEXT: Size: +# CHECK-NEXT: Link: +# CHECK-NEXT: Info: +# CHECK-NEXT: AddressAlignment: +# CHECK-NEXT: EntrySize: +# CHECK-NEXT: } +# CHECK-NEXT: Section { +# CHECK-NEXT: Index: +# CHECK-NEXT: Name: .neq +# CHECK-NEXT: Type: SHT_PROGBITS +# CHECK-NEXT: Flags [ +# CHECK-NEXT: SHF_ALLOC +# CHECK-NEXT: ] +# CHECK-NEXT: Address: 0x23000 +# 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 { \ @@ -218,3 +320,21 @@ nop .section .ternary2, "a" .quad 0 + +.section .less, "a" +.quad 0 + +.section .lesseq, "a" +.quad 0 + +.section .great, "a" +.quad 0 + +.section .greateq, "a" +.quad 0 + +.section .eq, "a" +.quad 0 + +.section .neq, "a" +.quad 0 -- 2.7.4