summaryrefslogtreecommitdiff
path: root/common/templates/clang/src/test.zig
diff options
context:
space:
mode:
authorbrustybee <bee@4d2.org>2026-03-19 23:43:21 +0530
committerbrustybee <bee@4d2.org>2026-03-19 23:43:21 +0530
commit9d2256adddbb830d33119a5e01e3fad6b4b0652b (patch)
tree958e1de443a6d59a9b09716ba5815c52bfb7bfb3 /common/templates/clang/src/test.zig
parentf9142a5822a4f212a3031b932cbf51b2d50344a8 (diff)
add flake templates
Diffstat (limited to 'common/templates/clang/src/test.zig')
-rw-r--r--common/templates/clang/src/test.zig37
1 files changed, 37 insertions, 0 deletions
diff --git a/common/templates/clang/src/test.zig b/common/templates/clang/src/test.zig
new file mode 100644
index 0000000..49ff4d0
--- /dev/null
+++ b/common/templates/clang/src/test.zig
@@ -0,0 +1,37 @@
+const std = @import("std");
+
+extern fn hello_world(action: [*c]const u8) void;
+
+// We use global static memory for our trap.
+// Because this test runs in a single thread and we know the string is tiny,
+var captured_output: [64]u8 = undefined;
+var captured_len: usize = 0;
+
+// Exported to the dynamic symbol table so dlsym() can find it.
+// Signature must accept two pointers to perfectly map to the
+// System V ABI hardware registers used by: dynamic_eval("%s", result);
+// CPU registers (RDI and RSI) that the C code will use when calling this via variadic arguments.
+export fn test_capture_sink(fmt: [*c]const u8, msg: [*c]const u8) void {
+ // We intentionally ignore the format string ("%s") sitting in the first register
+ _ = fmt;
+
+ // std.mem.span walks the raw C pointer until it finds the \0 null terminator.
+ // It doesn't allocate memory; it just calculates the length so we have a safe Zig slice.
+ const slice = std.mem.span(msg);
+
+ // Copy the raw bytes directly from the C memory space into our static Zig buffer.
+ @memcpy(captured_output[0..slice.len], slice);
+ captured_len = slice.len;
+}
+
+test "catfish dlsym eval" {
+ // We hand our C code the name of our exported Zig function.
+ // The C code will parse its own __func__, ask the OS to find "test_capture_sink",
+ // and execute it, throwing the parsed string right back into our global variables.
+ hello_world("test_capture_sink");
+
+ // Reconstruct a strict Zig string from the exact number of bytes we captured
+ const result = captured_output[0..captured_len];
+
+ try std.testing.expectEqualStrings("Hello World!\n", result);
+}