[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
Tue Sep 5 03:26:03 PDT 2017


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

Thanks for comments, Peter ! 
I applied both your suggestions.


https://reviews.llvm.org/D37440

Files:
  ELF/ScriptLexer.cpp
  ELF/ScriptLexer.h
  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/ScriptLexer.h
===================================================================
--- ELF/ScriptLexer.h
+++ ELF/ScriptLexer.h
@@ -35,7 +35,7 @@
   bool consumeLabel(StringRef Tok);
   std::string getCurrentLocation();
 
-  std::vector<MemoryBufferRef> MBs;
+  std::vector<std::pair<MemoryBufferRef, uint8_t>> MBs;
   std::vector<StringRef> Tokens;
   bool InExpr = false;
   size_t Pos = 0;
@@ -47,6 +47,7 @@
   size_t getColumnNumber();
 
   MemoryBufferRef getCurrentMB();
+  uint8_t getCurrentMBDepth();
 };
 
 } // namespace elf
Index: ELF/ScriptLexer.cpp
===================================================================
--- ELF/ScriptLexer.cpp
+++ ELF/ScriptLexer.cpp
@@ -88,7 +88,11 @@
 // Split S into linker script tokens.
 void ScriptLexer::tokenize(MemoryBufferRef MB) {
   std::vector<StringRef> Vec;
-  MBs.push_back(MB);
+  uint8_t Depth = getCurrentMBDepth();
+  if (++Depth > 10)
+    setError("maximum include nesting level of 10 exceeded");
+
+  MBs.push_back({MB, Depth});
   StringRef S = MB.getBuffer();
   StringRef Begin = S;
 
@@ -272,14 +276,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.113824.patch
Type: text/x-patch
Size: 2721 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20170905/2fce11e6/attachment.bin>


More information about the llvm-commits mailing list