[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