[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