[PATCH] D22912: [ELF] - Linkerscript: implemented ASSERT() keyword.

George Rimar via llvm-commits llvm-commits at lists.llvm.org
Fri Jul 29 02:51:07 PDT 2016


grimar updated this revision to Diff 66102.
grimar added a comment.

- Addressed review comments.

I found there are 2 forms of ASSERT that can be used in scripts:

1. Like common assert: ASSERT(1, "true")
2. Like expression that assigns result to something: xxx = ASSERT(1, "true");

I updated the code to support first form as well.


https://reviews.llvm.org/D22912

Files:
  ELF/LinkerScript.cpp
  test/ELF/linkerscript/linkerscript-assert.s

Index: test/ELF/linkerscript/linkerscript-assert.s
===================================================================
--- test/ELF/linkerscript/linkerscript-assert.s
+++ test/ELF/linkerscript/linkerscript-assert.s
@@ -0,0 +1,27 @@
+# REQUIRES: x86
+# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t1.o
+
+# RUN: echo "SECTIONS {     \
+# RUN:   ASSERT(1, \"true\") \
+# RUN:  }" > %t1.script
+# RUN: ld.lld -shared -o %t1 --script %t1.script %t1.o
+# RUN: llvm-readobj %t1 > /dev/null
+
+# RUN: echo "SECTIONS {                                  \
+# RUN:   ASSERT(ASSERT(42, \"true\") == 42, \"true\") \
+# RUN:  }" > %t2.script
+# RUN: ld.lld -shared -o %t2 --script %t2.script %t1.o
+# RUN: llvm-readobj %t2 > /dev/null
+
+# RUN: echo "SECTIONS {     \
+# RUN:   ASSERT(0,\ "fail\") \
+# RUN:  }" > %t3.script
+# RUN: not ld.lld -shared -o %t3 --script %t3.script %t1.o > %t.log 2>&1
+# RUN: FileCheck %s -check-prefix=FAIL < %t.log
+# FAIL: fail
+
+# RUN: echo "SECTIONS {     \
+# RUN:   . = ASSERT(0x1000, \"true\"); \
+# RUN:  }" > %t4.script
+# RUN: ld.lld -shared -o %t4 --script %t4.script %t1.o
+# RUN: llvm-readobj %t4 > /dev/null
Index: ELF/LinkerScript.cpp
===================================================================
--- ELF/LinkerScript.cpp
+++ ELF/LinkerScript.cpp
@@ -363,7 +363,7 @@
 template <class ELFT> void LinkerScript<ELFT>::addScriptedSymbols() {
   for (const std::unique_ptr<BaseCommand> &Base : Opt.Commands) {
     auto *Cmd = dyn_cast<SymbolAssignment>(Base.get());
-    if (!Cmd || Cmd->Name == ".")
+    if (!Cmd || Cmd->Name == "." || Cmd->Name.empty())
       continue;
 
     // If a symbol was in PROVIDE(), define it only when it is an
@@ -447,6 +447,7 @@
   void readInputSectionRules(InputSectionDescription *InCmd, bool Keep);
   unsigned readPhdrType();
   void readProvide(bool Hidden);
+  void readAssert();
   void readAlign(OutputSectionCommand *Cmd);
   void readSort();
 
@@ -644,6 +645,11 @@
   Opt.HasContents = true;
   expect("{");
   while (!Error && !skip("}")) {
+    if (peek() == "ASSERT") {
+      readAssert();
+      continue;
+    }
+
     StringRef Tok = next();
     if (peek() == "=" || peek() == "+=") {
       readAssignment(Tok);
@@ -812,6 +818,11 @@
   return 0;
 }
 
+void ScriptParser::readAssert() {
+  auto *Cmd = new SymbolAssignment("", readExpr());
+  Opt.Commands.emplace_back(Cmd);
+}
+
 SymbolAssignment *ScriptParser::readAssignment(StringRef Name) {
   StringRef Op = next();
   assert(Op == "=" || Op == "+=");
@@ -920,6 +931,19 @@
     expect(")");
     return [](uint64_t Dot) { return alignTo(Dot, Target->PageSize); };
   }
+  if (Tok == "ASSERT") {
+    expect("(");
+    Expr E = readExpr();
+    expect(",");
+    StringRef Msg = next();
+    expect(")");
+    return [=](uint64_t Dot) {
+      uint64_t V = E(Dot);
+      if (!V)
+        error(Msg);
+      return V;
+    };
+  }
 
   // Parse a symbol name or a number literal.
   uint64_t V = 0;


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D22912.66102.patch
Type: text/x-patch
Size: 3045 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20160729/bec5910d/attachment.bin>


More information about the llvm-commits mailing list