[lld] r277710 - [ELF] - Linkerscript: implemented ASSERT() keyword.
George Rimar via llvm-commits
llvm-commits at lists.llvm.org
Thu Aug 4 02:29:31 PDT 2016
Author: grimar
Date: Thu Aug 4 04:29:31 2016
New Revision: 277710
URL: http://llvm.org/viewvc/llvm-project?rev=277710&view=rev
Log:
[ELF] - Linkerscript: implemented ASSERT() keyword.
ASSERT(exp, message)
Ensure that exp is non-zero. If it is zero, then exit the linker with an error
code, and print message.
ASSERT is useful and was seen in few projects in the wild.
Differential revision: https://reviews.llvm.org/D22912
Added:
lld/trunk/test/ELF/linkerscript/linkerscript-assert.s
Modified:
lld/trunk/ELF/LinkerScript.cpp
lld/trunk/ELF/LinkerScript.h
Modified: lld/trunk/ELF/LinkerScript.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/LinkerScript.cpp?rev=277710&r1=277709&r2=277710&view=diff
==============================================================================
--- lld/trunk/ELF/LinkerScript.cpp (original)
+++ lld/trunk/ELF/LinkerScript.cpp Thu Aug 4 04:29:31 2016
@@ -55,6 +55,10 @@ bool InputSectionDescription::classof(co
return C->Kind == InputSectionKind;
}
+bool AssertCommand::classof(const BaseCommand *C) {
+ return C->Kind == AssertKind;
+}
+
template <class ELFT> static bool isDiscarded(InputSectionBase<ELFT> *S) {
return !S || !S->Live;
}
@@ -249,6 +253,11 @@ void LinkerScript<ELFT>::assignAddresses
continue;
}
+ if (auto *Cmd = dyn_cast<AssertCommand>(Base.get())) {
+ Cmd->Expression(Dot);
+ continue;
+ }
+
// Find all the sections with required name. There can be more than
// one section with such name, if the alignment, flags or type
// attribute differs.
@@ -487,6 +496,7 @@ private:
SymbolAssignment *readProvide(bool Hidden);
Expr readAlign();
void readSort();
+ Expr readAssert();
Expr readExpr();
Expr readExpr1(Expr Lhs, int MinPrec);
@@ -693,6 +703,8 @@ void ScriptParser::readSections() {
Cmd = readProvide(false);
} else if (Tok == "PROVIDE_HIDDEN") {
Cmd = readProvide(true);
+ } else if (Tok == "ASSERT") {
+ Cmd = new AssertCommand(readAssert());
} else {
Cmd = readOutputSectionDescription(Tok);
}
@@ -796,6 +808,20 @@ void ScriptParser::readSort() {
expect(")");
}
+Expr ScriptParser::readAssert() {
+ expect("(");
+ Expr E = readExpr();
+ expect(",");
+ StringRef Msg = next();
+ expect(")");
+ return [=](uint64_t Dot) {
+ uint64_t V = E(Dot);
+ if (!V)
+ error(Msg);
+ return V;
+ };
+}
+
OutputSectionCommand *
ScriptParser::readOutputSectionDescription(StringRef OutSec) {
OutputSectionCommand *Cmd = new OutputSectionCommand(OutSec);
@@ -967,6 +993,8 @@ Expr ScriptParser::readPrimary() {
// Built-in functions are parsed here.
// https://sourceware.org/binutils/docs/ld/Builtin-Functions.html.
+ if (Tok == "ASSERT")
+ return readAssert();
if (Tok == "ALIGN") {
expect("(");
Expr E = readExpr();
Modified: lld/trunk/ELF/LinkerScript.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/LinkerScript.h?rev=277710&r1=277709&r2=277710&view=diff
==============================================================================
--- lld/trunk/ELF/LinkerScript.h (original)
+++ lld/trunk/ELF/LinkerScript.h Thu Aug 4 04:29:31 2016
@@ -41,7 +41,8 @@ template <class ELFT> class OutputSectio
enum SectionsCommandKind {
AssignmentKind,
OutputSectionKind,
- InputSectionKind
+ InputSectionKind,
+ AssertKind
};
struct BaseCommand {
@@ -98,6 +99,12 @@ struct InputSectionDescription : BaseCom
std::vector<StringRef> SectionPatterns;
};
+struct AssertCommand : BaseCommand {
+ AssertCommand(Expr E) : BaseCommand(AssertKind), Expression(E) {}
+ static bool classof(const BaseCommand *C);
+ Expr Expression;
+};
+
struct PhdrsCommand {
StringRef Name;
unsigned Type;
Added: lld/trunk/test/ELF/linkerscript/linkerscript-assert.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/linkerscript/linkerscript-assert.s?rev=277710&view=auto
==============================================================================
--- lld/trunk/test/ELF/linkerscript/linkerscript-assert.s (added)
+++ lld/trunk/test/ELF/linkerscript/linkerscript-assert.s Thu Aug 4 04:29:31 2016
@@ -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
More information about the llvm-commits
mailing list