[lld] r277035 - [ELF] - Linkerscript: implemented += operator.

George Rimar via llvm-commits llvm-commits at lists.llvm.org
Thu Jul 28 14:08:56 PDT 2016


Author: grimar
Date: Thu Jul 28 16:08:56 2016
New Revision: 277035

URL: http://llvm.org/viewvc/llvm-project?rev=277035&view=rev
Log:
[ELF] - Linkerscript: implemented += operator.

Sometimes += is used to move the location counter.
Example from the wild is:

.dbg_excpt _DBG_EXCPT_ADDR (NOLOAD) :
{
  . += (DEFINED (_DEBUGGER) ? 0x8 : 0x0);
https://github.com/chipKIT32/pic32-Arduino-USB-Bootloader-original/blob/master/boot-linkerscript.ld

Patch implements it and opens way for others type of assignments (-= *= etc), though I think only += is
actual to support.

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

Modified:
    lld/trunk/ELF/LinkerScript.cpp
    lld/trunk/test/ELF/linkerscript/linkerscript-locationcounter.s

Modified: lld/trunk/ELF/LinkerScript.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/LinkerScript.cpp?rev=277035&r1=277034&r2=277035&view=diff
==============================================================================
--- lld/trunk/ELF/LinkerScript.cpp (original)
+++ lld/trunk/ELF/LinkerScript.cpp Thu Jul 28 16:08:56 2016
@@ -643,7 +643,7 @@ void ScriptParser::readSections() {
   expect("{");
   while (!Error && !skip("}")) {
     StringRef Tok = next();
-    if (peek() == "=") {
+    if (peek() == "=" || peek() == "+=") {
       readAssignment(Tok);
       expect(";");
     } else if (Tok == "PROVIDE") {
@@ -777,19 +777,10 @@ void ScriptParser::readProvide(bool Hidd
   expect(";");
 }
 
-SymbolAssignment *ScriptParser::readAssignment(StringRef Name) {
-  expect("=");
-  Expr E = readExpr();
-  auto *Cmd = new SymbolAssignment(Name, E);
-  Opt.Commands.emplace_back(Cmd);
-  return Cmd;
-}
+static uint64_t getSymbolValue(StringRef S, uint64_t Dot) {
+  if (S == ".")
+    return Dot;
 
-// This is an operator-precedence parser to parse a linker
-// script expression.
-Expr ScriptParser::readExpr() { return readExpr1(readPrimary(), 0); }
-
-static uint64_t getSymbolValue(StringRef S) {
   switch (Config->EKind) {
   case ELF32LEKind:
     if (SymbolBody *B = Symtab<ELF32LE>::X->find(S))
@@ -814,6 +805,21 @@ static uint64_t getSymbolValue(StringRef
   return 0;
 }
 
+SymbolAssignment *ScriptParser::readAssignment(StringRef Name) {
+  StringRef Op = next();
+  assert(Op == "=" || Op == "+=");
+  Expr E = readExpr();
+  if (Op == "+=")
+    E = [=](uint64_t Dot) { return getSymbolValue(Name, Dot) + E(Dot); };
+  auto *Cmd = new SymbolAssignment(Name, E);
+  Opt.Commands.emplace_back(Cmd);
+  return Cmd;
+}
+
+// This is an operator-precedence parser to parse a linker
+// script expression.
+Expr ScriptParser::readExpr() { return readExpr1(readPrimary(), 0); }
+
 // This is a part of the operator-precedence parser. This function
 // assumes that the remaining token stream starts with an operator.
 Expr ScriptParser::readExpr1(Expr Lhs, int MinPrec) {
@@ -853,9 +859,6 @@ uint64_t static getConstant(StringRef S)
 Expr ScriptParser::readPrimary() {
   StringRef Tok = next();
 
-  if (Tok == ".")
-    return [](uint64_t Dot) { return Dot; };
-
   if (Tok == "(") {
     Expr E = readExpr();
     expect(")");
@@ -914,9 +917,9 @@ Expr ScriptParser::readPrimary() {
   // Parse a symbol name or a number literal.
   uint64_t V = 0;
   if (Tok.getAsInteger(0, V)) {
-    if (!isValidCIdentifier(Tok))
+    if (Tok != "." && !isValidCIdentifier(Tok))
       setError("malformed number: " + Tok);
-    return [=](uint64_t Dot) { return getSymbolValue(Tok); };
+    return [=](uint64_t Dot) { return getSymbolValue(Tok, Dot); };
   }
   return [=](uint64_t Dot) { return V; };
 }

Modified: lld/trunk/test/ELF/linkerscript/linkerscript-locationcounter.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/linkerscript/linkerscript-locationcounter.s?rev=277035&r1=277034&r2=277035&view=diff
==============================================================================
--- lld/trunk/test/ELF/linkerscript/linkerscript-locationcounter.s (original)
+++ lld/trunk/test/ELF/linkerscript/linkerscript-locationcounter.s Thu Jul 28 16:08:56 2016
@@ -37,6 +37,9 @@
 # RUN:  . = DATA_SEGMENT_ALIGN (CONSTANT (MAXPAGESIZE), CONSTANT (COMMONPAGESIZE)); \
 # RUN:  .datasegmentalign : { *(.datasegmentalign) } \
 # RUN:  . = DATA_SEGMENT_END (.); \
+# RUN:  . = 0x27000; \
+# RUN:  . += 0x1000; \
+# RUN:  .plusassign : { *(.plusassign) } \
 # RUN: }" > %t.script
 # RUN: ld.lld %t --script %t.script -o %t2
 # RUN: llvm-readobj -s %t2 | FileCheck %s
@@ -296,6 +299,21 @@
 # CHECK-NEXT:   AddressAlignment:
 # CHECK-NEXT:   EntrySize:
 # CHECK-NEXT: }
+# CHECK-NEXT: Section {
+# CHECK-NEXT:   Index:
+# CHECK-NEXT:   Name: .plusassign
+# CHECK-NEXT:   Type: SHT_PROGBITS
+# CHECK-NEXT:   Flags [
+# CHECK-NEXT:     SHF_ALLOC
+# CHECK-NEXT:   ]
+# CHECK-NEXT:   Address: 0x28000
+# 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 { \
@@ -399,3 +417,6 @@ nop
 
 .section .datasegmentalign, "a"
 .quad 0
+
+.section .plusassign, "a"
+.quad 0




More information about the llvm-commits mailing list