[lld] 8f72b0c - [ELF] Fix INCLUDE cycle detection

Fangrui Song via llvm-commits llvm-commits at lists.llvm.org
Sat Jul 27 17:25:18 PDT 2024


Author: Fangrui Song
Date: 2024-07-27T17:25:13-07:00
New Revision: 8f72b0cb08d8b55ef13ed83af8dac2b7ac55208b

URL: https://github.com/llvm/llvm-project/commit/8f72b0cb08d8b55ef13ed83af8dac2b7ac55208b
DIFF: https://github.com/llvm/llvm-project/commit/8f72b0cb08d8b55ef13ed83af8dac2b7ac55208b.diff

LOG: [ELF] Fix INCLUDE cycle detection

Fix #93947: the cycle detection mechanism added by
https://reviews.llvm.org/D37524 also disallowed including a file twice,
which is an unnecessary limitation.

Now that we have an include stack #100493, supporting multiple inclusion
is trivial. Note: a filename can be referenced with many different
paths, e.g. a.lds, ./a.lds, ././a.lds. We don't attempt to detect the
cycle in the earliest point.

Added: 
    

Modified: 
    lld/ELF/ScriptLexer.cpp
    lld/ELF/ScriptLexer.h
    lld/ELF/ScriptParser.cpp
    lld/test/ELF/linkerscript/include-cycle.s

Removed: 
    


################################################################################
diff  --git a/lld/ELF/ScriptLexer.cpp b/lld/ELF/ScriptLexer.cpp
index 1a4eadbead1ba..9d31b2b226517 100644
--- a/lld/ELF/ScriptLexer.cpp
+++ b/lld/ELF/ScriptLexer.cpp
@@ -36,7 +36,9 @@ using namespace llvm;
 using namespace lld;
 using namespace lld::elf;
 
-ScriptLexer::ScriptLexer(MemoryBufferRef mb) : curBuf(mb), mbs(1, mb) {}
+ScriptLexer::ScriptLexer(MemoryBufferRef mb) : curBuf(mb), mbs(1, mb) {
+  activeFilenames.insert(mb.getBufferIdentifier());
+}
 
 // Returns a whole line containing the current token.
 StringRef ScriptLexer::getLine() {
@@ -81,6 +83,7 @@ void ScriptLexer::lex() {
         eof = true;
         return;
       }
+      activeFilenames.erase(curBuf.filename);
       curBuf = buffers.pop_back_val();
       continue;
     }

diff  --git a/lld/ELF/ScriptLexer.h b/lld/ELF/ScriptLexer.h
index c8efddcb65c0c..0c12b984c9e1b 100644
--- a/lld/ELF/ScriptLexer.h
+++ b/lld/ELF/ScriptLexer.h
@@ -10,6 +10,7 @@
 #define LLD_ELF_SCRIPT_LEXER_H
 
 #include "lld/Common/LLVM.h"
+#include "llvm/ADT/DenseSet.h"
 #include "llvm/ADT/SmallVector.h"
 #include "llvm/ADT/StringRef.h"
 #include "llvm/Support/MemoryBufferRef.h"
@@ -33,6 +34,9 @@ class ScriptLexer {
   Buffer curBuf;
   SmallVector<Buffer, 0> buffers;
 
+  // Used to detect INCLUDE() cycles.
+  llvm::DenseSet<StringRef> activeFilenames;
+
   struct Token {
     StringRef str;
     explicit operator bool() const { return !str.empty(); }

diff  --git a/lld/ELF/ScriptParser.cpp b/lld/ELF/ScriptParser.cpp
index 1b218fc95e6ae..68047e446bc76 100644
--- a/lld/ELF/ScriptParser.cpp
+++ b/lld/ELF/ScriptParser.cpp
@@ -24,7 +24,6 @@
 #include "lld/Common/CommonLinkerContext.h"
 #include "llvm/ADT/SmallString.h"
 #include "llvm/ADT/StringRef.h"
-#include "llvm/ADT/StringSet.h"
 #include "llvm/ADT/StringSwitch.h"
 #include "llvm/BinaryFormat/ELF.h"
 #include "llvm/Support/Casting.h"
@@ -139,9 +138,6 @@ class ScriptParser final : ScriptLexer {
   // True if a script being read is in the --sysroot directory.
   bool isUnderSysroot = false;
 
-  // A set to detect an INCLUDE() cycle.
-  StringSet<> seen;
-
   // If we are currently parsing a PROVIDE|PROVIDE_HIDDEN command,
   // then this member is set to the PROVIDE symbol name.
   std::optional<llvm::StringRef> activeProvideSym;
@@ -406,7 +402,7 @@ void ScriptParser::readGroup() {
 
 void ScriptParser::readInclude() {
   StringRef name = readName();
-  if (!seen.insert(name).second) {
+  if (!activeFilenames.insert(name).second) {
     setError("there is a cycle in linker script INCLUDEs");
     return;
   }

diff  --git a/lld/test/ELF/linkerscript/include-cycle.s b/lld/test/ELF/linkerscript/include-cycle.s
index bbd4cfb9b65d5..a87b079a36925 100644
--- a/lld/test/ELF/linkerscript/include-cycle.s
+++ b/lld/test/ELF/linkerscript/include-cycle.s
@@ -6,10 +6,12 @@
 # ERR1: error: 1.lds:1: there is a cycle in linker script INCLUDEs
 
 # RUN: not ld.lld a.o -T 2a.lds 2>&1 | FileCheck %s --check-prefix=ERR2
-# ERR2: error: 2a.lds:1: there is a cycle in linker script INCLUDEs
+# ERR2: error: 2b.lds:1: there is a cycle in linker script INCLUDEs
 
-# RUN: not ld.lld a.o -T 3.lds 2>&1 | FileCheck %s --check-prefix=ERR3
-# ERR3: error: 3.lds:2: there is a cycle in linker script INCLUDEs
+# RUN: ld.lld a.o -T 3.lds -o 3
+# RUN: llvm-objdump -s 3 | FileCheck %s --check-prefix=CHECK3
+# CHECK3:      Contents of section foo:
+# CHECK3-NEXT: 0000 2a2a                    **
 
 #--- 0.lds
 BYTE(42)


        


More information about the llvm-commits mailing list