[PATCH] D37440: [ELF] - Linkerscript: do not hang linker on infinite nested INCLUDE command.
George Rimar via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Wed Sep 6 03:36:10 PDT 2017
grimar updated this revision to Diff 113982.
grimar added a comment.
- Addressed review comments.
https://reviews.llvm.org/D37440
Files:
ELF/ScriptLexer.cpp
ELF/ScriptLexer.h
ELF/ScriptParser.cpp
test/ELF/linkerscript/linkerscript.s
Index: test/ELF/linkerscript/linkerscript.s
===================================================================
--- test/ELF/linkerscript/linkerscript.s
+++ test/ELF/linkerscript/linkerscript.s
@@ -44,9 +44,13 @@
# RUN: echo "FOO(BAR)" > %t.script
# RUN: not ld.lld -o foo %t.script > %t.log 2>&1
# RUN: FileCheck -check-prefix=ERR1 %s < %t.log
-
# ERR1: unknown directive: FOO
+# RUN: echo "INCLUDE \"%t.script3\"" > %t.script3
+# RUN: not ld.lld %t.script3 -o %t3 2>&1 | \
+# RUN: FileCheck -check-prefix=ERR2 %s
+# ERR2: error: {{.*}}:1: maximum include nesting level of 10 exceeded
+
.globl _start, _label
_start:
ret
Index: ELF/ScriptParser.cpp
===================================================================
--- ELF/ScriptParser.cpp
+++ ELF/ScriptParser.cpp
@@ -315,8 +315,11 @@
}
void ScriptParser::readInclude() {
- StringRef Tok = unquote(next());
+ uint8_t Depth = getCurrentMBDepth();
+ if (Depth == 10)
+ setError("maximum include nesting level of 10 exceeded");
+ StringRef Tok = unquote(next());
// https://sourceware.org/binutils/docs/ld/File-Commands.html:
// The file will be searched for in the current directory, and in any
// directory specified with the -L option.
Index: ELF/ScriptLexer.h
===================================================================
--- ELF/ScriptLexer.h
+++ ELF/ScriptLexer.h
@@ -34,8 +34,9 @@
void expect(StringRef Expect);
bool consumeLabel(StringRef Tok);
std::string getCurrentLocation();
+ uint8_t getCurrentMBDepth();
- std::vector<MemoryBufferRef> MBs;
+ std::vector<std::pair<MemoryBufferRef, uint8_t>> MBs;
std::vector<StringRef> Tokens;
bool InExpr = false;
size_t Pos = 0;
Index: ELF/ScriptLexer.cpp
===================================================================
--- ELF/ScriptLexer.cpp
+++ ELF/ScriptLexer.cpp
@@ -88,7 +88,7 @@
// Split S into linker script tokens.
void ScriptLexer::tokenize(MemoryBufferRef MB) {
std::vector<StringRef> Vec;
- MBs.push_back(MB);
+ MBs.push_back({MB, getCurrentMBDepth() + 1});
StringRef S = MB.getBuffer();
StringRef Begin = S;
@@ -272,14 +272,24 @@
return S.bytes_begin() <= T.bytes_begin() && T.bytes_end() <= S.bytes_end();
}
-MemoryBufferRef ScriptLexer::getCurrentMB() {
+static std::pair<MemoryBufferRef, uint8_t>
+getEnclosingMB(ArrayRef<std::pair<MemoryBufferRef, uint8_t>> V, StringRef Tok) {
// Find input buffer containing the current token.
+ for (const std::pair<MemoryBufferRef, int8_t> &MB : V)
+ if (encloses(MB.first.getBuffer(), Tok))
+ return MB;
+ llvm_unreachable("getCurrentMB: failed to find a token");
+}
+
+MemoryBufferRef ScriptLexer::getCurrentMB() {
assert(!MBs.empty());
if (!Pos)
- return MBs[0];
+ return MBs[0].first;
+ return getEnclosingMB(MBs, Tokens[Pos - 1]).first;
+}
- for (MemoryBufferRef MB : MBs)
- if (encloses(MB.getBuffer(), Tokens[Pos - 1]))
- return MB;
- llvm_unreachable("getCurrentMB: failed to find a token");
+uint8_t ScriptLexer::getCurrentMBDepth() {
+ if (MBs.empty() || !Pos)
+ return 0;
+ return getEnclosingMB(MBs, Tokens[Pos - 1]).second;
}
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D37440.113982.patch
Type: text/x-patch
Size: 3126 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20170906/68f98b05/attachment.bin>
More information about the llvm-commits
mailing list