[llvm] 9eccc6c - [JITLink] Add a predicate to test for C-string blocks.
Lang Hames via llvm-commits
llvm-commits at lists.llvm.org
Sat Feb 11 10:52:08 PST 2023
Author: Lang Hames
Date: 2023-02-11T10:51:50-08:00
New Revision: 9eccc6cce07b2af29db1836dabf3e2118908ee8d
URL: https://github.com/llvm/llvm-project/commit/9eccc6cce07b2af29db1836dabf3e2118908ee8d
DIFF: https://github.com/llvm/llvm-project/commit/9eccc6cce07b2af29db1836dabf3e2118908ee8d.diff
LOG: [JITLink] Add a predicate to test for C-string blocks.
Added:
Modified:
llvm/include/llvm/ExecutionEngine/JITLink/JITLink.h
llvm/lib/ExecutionEngine/JITLink/JITLink.cpp
llvm/lib/ExecutionEngine/JITLink/MachOLinkGraphBuilder.cpp
llvm/unittests/ExecutionEngine/JITLink/LinkGraphTests.cpp
Removed:
################################################################################
diff --git a/llvm/include/llvm/ExecutionEngine/JITLink/JITLink.h b/llvm/include/llvm/ExecutionEngine/JITLink/JITLink.h
index f0528064c09c..902c5eff5a66 100644
--- a/llvm/include/llvm/ExecutionEngine/JITLink/JITLink.h
+++ b/llvm/include/llvm/ExecutionEngine/JITLink/JITLink.h
@@ -362,6 +362,11 @@ inline orc::ExecutorAddr alignToBlock(orc::ExecutorAddr Addr, Block &B) {
return orc::ExecutorAddr(alignToBlock(Addr.getValue(), B));
}
+// Returns true if the given blocks contains exactly one valid c-string.
+// Zero-fill blocks of size 1 count as valid empty strings. Content blocks
+// must end with a zero, and contain no zeros before the end.
+bool isCStringBlock(Block &B);
+
/// Describes symbol linkage. This can be used to make resolve definition
/// clashes.
enum class Linkage : uint8_t {
diff --git a/llvm/lib/ExecutionEngine/JITLink/JITLink.cpp b/llvm/lib/ExecutionEngine/JITLink/JITLink.cpp
index bd5b4d585550..bc359a310ed0 100644
--- a/llvm/lib/ExecutionEngine/JITLink/JITLink.cpp
+++ b/llvm/lib/ExecutionEngine/JITLink/JITLink.cpp
@@ -88,6 +88,21 @@ const char *getScopeName(Scope S) {
llvm_unreachable("Unrecognized llvm.jitlink.Scope enum");
}
+bool isCStringBlock(Block &B) {
+ if (B.getSize() == 0) // Empty blocks are not valid C-strings.
+ return false;
+
+ // Zero-fill blocks of size one are valid empty strings.
+ if (B.isZeroFill())
+ return B.getSize() == 1;
+
+ for (size_t I = 0; I != B.getSize() - 1; ++I)
+ if (B.getContent()[I] == '\0')
+ return false;
+
+ return B.getContent()[B.getSize() - 1] == '\0';
+}
+
raw_ostream &operator<<(raw_ostream &OS, const Block &B) {
return OS << B.getAddress() << " -- " << (B.getAddress() + B.getSize())
<< ": "
diff --git a/llvm/lib/ExecutionEngine/JITLink/MachOLinkGraphBuilder.cpp b/llvm/lib/ExecutionEngine/JITLink/MachOLinkGraphBuilder.cpp
index a520008aeb00..fb32c024480d 100644
--- a/llvm/lib/ExecutionEngine/JITLink/MachOLinkGraphBuilder.cpp
+++ b/llvm/lib/ExecutionEngine/JITLink/MachOLinkGraphBuilder.cpp
@@ -660,7 +660,7 @@ Error MachOLinkGraphBuilder::graphifyCStringSection(
orc::ExecutorAddrDiff BlockStart = 0;
// Scan section for null characters.
- for (size_t I = 0; I != NSec.Size; ++I)
+ for (size_t I = 0; I != NSec.Size; ++I) {
if (NSec.Data[I] == '\0') {
size_t BlockSize = I + 1 - BlockStart;
// Create a block for this null terminated string.
@@ -727,6 +727,11 @@ Error MachOLinkGraphBuilder::graphifyCStringSection(
BlockStart += BlockSize;
}
+ }
+
+ assert(llvm::all_of(NSec.GraphSection->blocks(),
+ [](Block *B) { return isCStringBlock(*B); }) &&
+ "All blocks in section should hold single c-strings");
return Error::success();
}
diff --git a/llvm/unittests/ExecutionEngine/JITLink/LinkGraphTests.cpp b/llvm/unittests/ExecutionEngine/JITLink/LinkGraphTests.cpp
index 6569bb0fd2dd..86fc7bddaee3 100644
--- a/llvm/unittests/ExecutionEngine/JITLink/LinkGraphTests.cpp
+++ b/llvm/unittests/ExecutionEngine/JITLink/LinkGraphTests.cpp
@@ -711,3 +711,28 @@ TEST(LinkGraphTest, SplitBlock) {
EXPECT_EQ(E2->getOffset(), 4U);
}
}
+
+TEST(LinkGraphTest, IsCStringBlockTest) {
+ // Check that the LinkGraph::splitBlock test works as expected.
+ LinkGraph G("foo", Triple("x86_64-apple-darwin"), 8, support::little,
+ getGenericEdgeKindName);
+ auto &Sec =
+ G.createSection("__data", orc::MemProt::Read | orc::MemProt::Write);
+
+ ArrayRef<char> CString = "hello, world!";
+ ArrayRef<char> NotACString = {0, 1, 0, 1, 0};
+
+ auto &CStringBlock =
+ G.createContentBlock(Sec, CString, orc::ExecutorAddr(), 1, 0);
+ auto &NotACStringBlock =
+ G.createContentBlock(Sec, NotACString, orc::ExecutorAddr(), 1, 0);
+ auto &SizeOneZeroFillBlock =
+ G.createZeroFillBlock(Sec, 1, orc::ExecutorAddr(), 1, 0);
+ auto &LargerZeroFillBlock =
+ G.createZeroFillBlock(Sec, 2, orc::ExecutorAddr(), 1, 0);
+
+ EXPECT_TRUE(isCStringBlock(CStringBlock));
+ EXPECT_FALSE(isCStringBlock(NotACStringBlock));
+ EXPECT_TRUE(isCStringBlock(SizeOneZeroFillBlock));
+ EXPECT_FALSE(isCStringBlock(LargerZeroFillBlock));
+}
More information about the llvm-commits
mailing list