From dccd3ea159b03cc1972cf47ee3cf8bda73ec0c5a Mon Sep 17 00:00:00 2001
From: Ben Gamari <ben@smart-cactus.org>
Date: Wed, 3 Apr 2024 17:41:37 -0400
Subject: [PATCH] testsuite: Add test for lookupSymbolInNativeObj

---
 .../linker/lookupSymbolInNativeObj/Makefile   |  9 ++++
 .../rts/linker/lookupSymbolInNativeObj/all.T  |  5 ++
 .../lookupSymbolInNativeObj1.c                | 54 +++++++++++++++++++
 .../lookupSymbolInNativeObj1.stdout           |  1 +
 .../rts/linker/lookupSymbolInNativeObj/obj.c  |  5 ++
 5 files changed, 74 insertions(+)
 create mode 100644 testsuite/tests/rts/linker/lookupSymbolInNativeObj/Makefile
 create mode 100644 testsuite/tests/rts/linker/lookupSymbolInNativeObj/all.T
 create mode 100644 testsuite/tests/rts/linker/lookupSymbolInNativeObj/lookupSymbolInNativeObj1.c
 create mode 100644 testsuite/tests/rts/linker/lookupSymbolInNativeObj/lookupSymbolInNativeObj1.stdout
 create mode 100644 testsuite/tests/rts/linker/lookupSymbolInNativeObj/obj.c

diff --git a/testsuite/tests/rts/linker/lookupSymbolInNativeObj/Makefile b/testsuite/tests/rts/linker/lookupSymbolInNativeObj/Makefile
new file mode 100644
index 000000000000..63c4bbc6bc82
--- /dev/null
+++ b/testsuite/tests/rts/linker/lookupSymbolInNativeObj/Makefile
@@ -0,0 +1,9 @@
+TOP=../../../..
+include $(TOP)/mk/boilerplate.mk
+include $(TOP)/mk/test.mk
+
+lookupSymbolInNativeObj1:
+	'$(TEST_HC)' -shared -dynamic obj.c -o libobj.so
+	'$(TEST_HC)' -no-hs-main -dynamic lookupSymbolInNativeObj1.c -o main
+	./main
+
diff --git a/testsuite/tests/rts/linker/lookupSymbolInNativeObj/all.T b/testsuite/tests/rts/linker/lookupSymbolInNativeObj/all.T
new file mode 100644
index 000000000000..04562c806281
--- /dev/null
+++ b/testsuite/tests/rts/linker/lookupSymbolInNativeObj/all.T
@@ -0,0 +1,5 @@
+test('lookupSymbolInNativeObj1',
+     [unless(have_dynamic(), skip),
+      extra_files(['obj.c'])],
+     makefile_test, [])
+
diff --git a/testsuite/tests/rts/linker/lookupSymbolInNativeObj/lookupSymbolInNativeObj1.c b/testsuite/tests/rts/linker/lookupSymbolInNativeObj/lookupSymbolInNativeObj1.c
new file mode 100644
index 000000000000..fe02c321be7a
--- /dev/null
+++ b/testsuite/tests/rts/linker/lookupSymbolInNativeObj/lookupSymbolInNativeObj1.c
@@ -0,0 +1,54 @@
+#include "Rts.h"
+
+#if defined(mingw32_HOST_OS)
+#define PATH_STR(str) L##str
+#else
+#define PATH_STR(str) str
+#endif
+
+typedef void (*hello_t)();
+
+int main(int argc, char *argv[])
+{
+  RtsConfig conf = defaultRtsConfig;
+  conf.rts_opts_enabled = RtsOptsAll;
+  hs_init_ghc(&argc, &argv, conf);
+
+  initLinker_(0);
+
+  int ok;
+  char *errmsg;
+  void *obj = loadNativeObj("./libobj.so", &errmsg);
+  if (!obj) {
+     barf("loadNativeObj failed: %s", errmsg);
+  }
+
+  hello_t sym;
+  const char* lbl;
+
+#if defined(darwin_HOST_OS)
+  // mach-o symbols are prefixed with _
+  lbl = "_hello";
+#else
+  lbl = "hello";
+#endif
+
+  sym = lookupSymbolInNativeObj(obj, lbl);
+  if (sym == NULL) {
+     barf("lookupSymbolInNativeObj failed unexpectedly");
+  }
+  sym();
+
+#if defined(darwin_HOST_OS)
+  lbl = "_hello_world";
+#else
+  lbl = "hello_world";
+#endif
+
+  sym = lookupSymbolInNativeObj(obj, lbl);
+  if (sym != NULL) {
+     barf("lookupSymbolInNativeObj succeeded unexpectedly");
+  }
+
+  return 0;
+}
diff --git a/testsuite/tests/rts/linker/lookupSymbolInNativeObj/lookupSymbolInNativeObj1.stdout b/testsuite/tests/rts/linker/lookupSymbolInNativeObj/lookupSymbolInNativeObj1.stdout
new file mode 100644
index 000000000000..3b18e512dba7
--- /dev/null
+++ b/testsuite/tests/rts/linker/lookupSymbolInNativeObj/lookupSymbolInNativeObj1.stdout
@@ -0,0 +1 @@
+hello world
diff --git a/testsuite/tests/rts/linker/lookupSymbolInNativeObj/obj.c b/testsuite/tests/rts/linker/lookupSymbolInNativeObj/obj.c
new file mode 100644
index 000000000000..152d820fb883
--- /dev/null
+++ b/testsuite/tests/rts/linker/lookupSymbolInNativeObj/obj.c
@@ -0,0 +1,5 @@
+#include <stdio.h>
+
+void hello() {
+  printf("hello world\n");
+}
-- 
GitLab