[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[RFC v6 8/9] tests/tcg/multiarch: Add nativecall.c test
From: |
Yeqi Fu |
Subject: |
[RFC v6 8/9] tests/tcg/multiarch: Add nativecall.c test |
Date: |
Wed, 13 Sep 2023 05:28:41 +0800 |
Introduce a new test for native calls to ensure their functionality.
The process involves cross-compiling the test cases, building them
as dynamically linked binaries, and running these binaries which
necessitates the addition of the appropriate interpreter prefix.
Signed-off-by: Yeqi Fu <fufuyqqqqqq@gmail.com>
---
tests/tcg/multiarch/Makefile.target | 32 ++++++
tests/tcg/multiarch/native/nativecall.c | 132 ++++++++++++++++++++++++
2 files changed, 164 insertions(+)
create mode 100644 tests/tcg/multiarch/native/nativecall.c
diff --git a/tests/tcg/multiarch/Makefile.target
b/tests/tcg/multiarch/Makefile.target
index 43bddeaf21..8bad8ac0d5 100644
--- a/tests/tcg/multiarch/Makefile.target
+++ b/tests/tcg/multiarch/Makefile.target
@@ -12,7 +12,9 @@ VPATH += $(MULTIARCH_SRC)
MULTIARCH_SRCS = $(notdir $(wildcard $(MULTIARCH_SRC)/*.c))
ifeq ($(filter %-linux-user, $(TARGET)),$(TARGET))
VPATH += $(MULTIARCH_SRC)/linux
+VPATH += $(MULTIARCH_SRC)/native
MULTIARCH_SRCS += $(notdir $(wildcard $(MULTIARCH_SRC)/linux/*.c))
+MULTIARCH_SRCS += $(notdir $(wildcard $(MULTIARCH_SRC)/native/*.c))
endif
MULTIARCH_TESTS = $(MULTIARCH_SRCS:.c=)
@@ -138,5 +140,35 @@ run-plugin-semiconsole-with-%:
TESTS += semihosting semiconsole
endif
+nativecall: LDFLAGS+=-ldl
+nativecall: CFLAGS+=-D_GNU_SOURCE -fPIE
+nativecall: nativecall.c
+ $(CC) $(CFLAGS) $(EXTRA_CFLAGS) $< -o $@ $(filter-out
-static,$(LDFLAGS))
+
+ifneq ($(LD_PREFIX),)
+ifneq ($(LIBNATIVE),)
+run-nativecall: nativecall
+ $(call run-test, $<, $(QEMU) -L $(LD_PREFIX) \
+ --native-bypass $(LIBNATIVE) $<, "nativecall")
+
+run-plugin-nativecall-with-%:
+ $(call run-test, $@, $(QEMU) $(QEMU_OPTS) \
+ -L $(LD_PREFIX) --native-bypass $(LIBNATIVE) \
+ -plugin $(PLUGIN_LIB)/$(call extract-plugin,$@)$(PLUGIN_ARGS) \
+ $(call strip-plugin,$<) 2> $<.err, \
+ $< with $*)
+else
+run-nativecall: nativecall
+ $(call skip-test, $<, "no native library found")
+run-plugin-nativecall-with-%:
+ $(call skip-test, $<, "no native library found")
+endif
+else
+run-nativecall: nativecall
+ $(call skip-test, $<, "no elf interpreter prefix found")
+run-plugin-nativecall-with-%:
+ $(call skip-test, $<, "no elf interpreter prefix found")
+endif
+
# Update TESTS
TESTS += $(MULTIARCH_TESTS)
diff --git a/tests/tcg/multiarch/native/nativecall.c
b/tests/tcg/multiarch/native/nativecall.c
new file mode 100644
index 0000000000..de18718c61
--- /dev/null
+++ b/tests/tcg/multiarch/native/nativecall.c
@@ -0,0 +1,132 @@
+#include <assert.h>
+#include <dlfcn.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/mman.h>
+#include <unistd.h>
+
+void compare_memory(const void *a, const void *b, size_t n)
+{
+ const unsigned char *p1 = a;
+ const unsigned char *p2 = b;
+ for (size_t i = 0; i < n; i++) {
+ assert(p1[i] == p2[i]);
+ }
+}
+
+void test_memcpy(char *src)
+{
+ char dest[2000];
+ memcpy(dest, src, 2000);
+ compare_memory(dest, src, 2000);
+}
+
+void test_strncpy(char *src)
+{
+ char dest[2000];
+ strncpy(dest, src, 2000);
+ compare_memory(dest, src, 2000);
+}
+
+void test_strcpy(char *src)
+{
+ char dest[2000];
+ strcpy(dest, src);
+ compare_memory(dest, src, 2000);
+}
+
+void test_strcat()
+{
+ char src[30] = "Hello, ";
+ char dest[] = "world!";
+ char str[] = "Hello, world!";
+ strcat(src, dest);
+ compare_memory(src, str, 13);
+}
+
+void test_memcmp(char *str1, char *str2, char *str3)
+{
+ int result1 = memcmp(str1, str2, 3);
+ int result2 = memcmp(str1, str3, 3);
+ int result3 = memcmp(str3, str1, 3);
+ assert(result1 == 0);
+ assert(result2 < 0);
+ assert(result3 > 0);
+}
+
+void test_strncmp(char *str1, char *str2, char *str3)
+{
+ int result1 = strncmp(str1, str2, 3);
+ int result2 = strncmp(str1, str3, 3);
+ int result3 = strncmp(str3, str1, 3);
+ assert(result1 == 0);
+ assert(result2 < 0);
+ assert(result3 > 0);
+}
+
+void test_strcmp(char *str1, char *str2, char *str3)
+{
+ int result1 = strcmp(str1, str2);
+ int result2 = strcmp(str1, str3);
+ int result3 = strcmp(str3, str1);
+ assert(result1 == 0);
+ assert(result2 < 0);
+ assert(result3 > 0);
+}
+
+void test_memset(char *buffer)
+{
+ memset(buffer, 'A', 2000 - 1);
+ for (int i = 0; i < 2000 - 1; i++) {
+ assert(buffer[i] == 'A');
+ }
+}
+
+void test_libnative()
+{
+ Dl_info info;
+ void *memcpy_addr = (void *)memcpy;
+ if (dladdr(memcpy_addr, &info) != 0) {
+ assert(strstr(info.dli_fname, "libnative.so") != NULL);
+ }
+}
+
+/*
+ * When executing execv, an error may occur stating that the shared library
+ * cannot be preloaded.
+ */
+void test_execv(const char *cmd)
+{
+ char *argv[4];
+ argv[0] = (char *)"/bin/sh";
+ argv[1] = (char *)"-c";
+ argv[2] = (char *)cmd;
+ argv[3] = NULL;
+ execv("/bin/sh", argv);
+}
+
+int main()
+{
+ char buf[2000];
+ for (int i = 0; i < 2000 - 1; i++) {
+ buf[i] = 'A' + (i % 26);
+ }
+ buf[2000 - 1] = '\0';
+ char str1[4] = "abc\0";
+ char str2[4] = "abc\0";
+ char str3[4] = "def\0";
+
+ test_memcpy(buf);
+ test_strncpy(buf);
+ test_strcpy(buf);
+ test_memcmp(str1, str2, str3);
+ test_strncmp(str1, str2, str3);
+ test_strcmp(str1, str2, str3);
+ test_strcat();
+ test_memset(buf);
+ test_libnative();
+ test_execv("echo 111");
+
+ return EXIT_SUCCESS;
+}
--
2.34.1
- [RFC v6 0/9] Native Library Calls, Yeqi Fu, 2023/09/12
- [RFC v6 1/9] build: Implement logic for sharing cross-building config files, Yeqi Fu, 2023/09/12
- [RFC v6 2/9] build: Implement libnative library and the build machinery for libnative, Yeqi Fu, 2023/09/12
- [RFC v6 3/9] linux-user: Implement native-bypass option support, Yeqi Fu, 2023/09/12
- [RFC v6 4/9] tcg: Add tcg opcodes and helpers for native library calls, Yeqi Fu, 2023/09/12
- [RFC v6 7/9] target/arm: Add support for native library calls, Yeqi Fu, 2023/09/12
- [RFC v6 8/9] tests/tcg/multiarch: Add nativecall.c test,
Yeqi Fu <=
- [RFC v6 5/9] target/i386: Add support for native library calls, Yeqi Fu, 2023/09/12
- [RFC v6 6/9] target/mips: Add support for native library calls, Yeqi Fu, 2023/09/12
- [RFC v6 9/9] docs/user: Add doc for native library calls, Yeqi Fu, 2023/09/12