[Concept,06/18] sandbox: Split main() into separate file

Message ID 20250904130459.848794-7-sjg@u-boot.org
State New
Headers
Series ulib: Introduce building U-Boot as a shared library |

Commit Message

Simon Glass Sept. 4, 2025, 1:04 p.m. UTC
  From: Simon Glass <sjg@chromium.org>

Normally sandbox includes a main() function so that it can be started
correctly.

When fuzzing is enabled, main() is not required.

When sandbox is built as a library, the main program will be somewhere
else so must not be in the library.

Split the main() function out into a new main.c file. Split the fuzzing
code into a new fuzz.c file.

Co-developed-by: Claude <noreply@anthropic.com>
Signed-off-by: Simon Glass <sjg@chromium.org>
---

 arch/sandbox/cpu/Makefile                 |  7 +-
 arch/sandbox/cpu/fuzz.c                   | 81 +++++++++++++++++++++++
 arch/sandbox/cpu/main.c                   | 11 +++
 arch/sandbox/cpu/os.c                     | 74 ---------------------
 arch/sandbox/cpu/start.c                  |  1 +
 arch/sandbox/include/asm/u-boot-sandbox.h |  5 +-
 6 files changed, 102 insertions(+), 77 deletions(-)
 create mode 100644 arch/sandbox/cpu/fuzz.c
 create mode 100644 arch/sandbox/cpu/main.c
  

Patch

diff --git a/arch/sandbox/cpu/Makefile b/arch/sandbox/cpu/Makefile
index 03cdf2ae0f1..35f853776f7 100644
--- a/arch/sandbox/cpu/Makefile
+++ b/arch/sandbox/cpu/Makefile
@@ -6,13 +6,18 @@ 
 # Wolfgang Denk, DENX Software Engineering, wd@denx.de.
 
 obj-y	:= cache.o cpu.o mem.o state.o os.o
+ifdef CONFIG_FUZZ
+obj-y	+= fuzz.o
+else
+obj-y	+= main.o
+endif
 extra-y	:= start.o
 extra-$(CONFIG_SANDBOX_SDL)    += sdl.o
 obj-$(CONFIG_XPL_BUILD)	+= spl.o
 obj-$(CONFIG_ETH_SANDBOX_RAW)	+= eth-raw-os.o
 
 # Compile these files with system headers
-CFLAGS_USE_SYSHDRS := eth-raw-os.o os.o sdl.o
+CFLAGS_USE_SYSHDRS := eth-raw-os.o fuzz.o main.o os.o sdl.o
 
 # sdl.c fails to build with -fshort-wchar using musl
 cmd_cc_sdl.o = $(CC) $(filter-out -nostdinc -fshort-wchar, \
diff --git a/arch/sandbox/cpu/fuzz.c b/arch/sandbox/cpu/fuzz.c
new file mode 100644
index 00000000000..f017c3a33ad
--- /dev/null
+++ b/arch/sandbox/cpu/fuzz.c
@@ -0,0 +1,81 @@ 
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (c) 2022 Google, Inc.
+ * Written by Andrew Scull <ascull@google.com>
+ */
+
+#include <errno.h>
+#include <pthread.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <stdlib.h>
+
+#include <os.h>
+#include <asm/fuzzing_engine.h>
+#include <asm/u-boot-sandbox.h>
+
+static void *fuzzer_thread(void *ptr)
+{
+	char cmd[64];
+	char *argv[5] = {"./u-boot", "-T", "-c", cmd, NULL};
+	const char *fuzz_test;
+
+	/* Find which test to run from an environment variable. */
+	fuzz_test = getenv("UBOOT_SB_FUZZ_TEST");
+	if (!fuzz_test)
+		os_abort();
+
+	snprintf(cmd, sizeof(cmd), "fuzz %s", fuzz_test);
+
+	sandbox_main(4, argv);
+	os_abort();
+	return NULL;
+}
+
+static bool fuzzer_initialized;
+static pthread_mutex_t fuzzer_mutex = PTHREAD_MUTEX_INITIALIZER;
+static pthread_cond_t fuzzer_cond = PTHREAD_COND_INITIALIZER;
+static const uint8_t *fuzzer_data;
+static size_t fuzzer_size;
+
+int sandbox_fuzzing_engine_get_input(const uint8_t **data, size_t *size)
+{
+	if (!fuzzer_initialized)
+		return -ENOSYS;
+
+	/* Tell the main thread we need new inputs then wait for them. */
+	pthread_mutex_lock(&fuzzer_mutex);
+	pthread_cond_signal(&fuzzer_cond);
+	pthread_cond_wait(&fuzzer_cond, &fuzzer_mutex);
+	*data = fuzzer_data;
+	*size = fuzzer_size;
+	pthread_mutex_unlock(&fuzzer_mutex);
+	return 0;
+}
+
+int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
+{
+	static pthread_t tid;
+
+	pthread_mutex_lock(&fuzzer_mutex);
+
+	/* Initialize the sandbox on another thread. */
+	if (!fuzzer_initialized) {
+		fuzzer_initialized = true;
+		if (pthread_create(&tid, NULL, fuzzer_thread, NULL))
+			os_abort();
+		pthread_cond_wait(&fuzzer_cond, &fuzzer_mutex);
+	}
+
+	/* Hand over the input. */
+	fuzzer_data = data;
+	fuzzer_size = size;
+	pthread_cond_signal(&fuzzer_cond);
+
+	/* Wait for the inputs to be finished with. */
+	pthread_cond_wait(&fuzzer_cond, &fuzzer_mutex);
+	pthread_mutex_unlock(&fuzzer_mutex);
+
+	return 0;
+}
diff --git a/arch/sandbox/cpu/main.c b/arch/sandbox/cpu/main.c
new file mode 100644
index 00000000000..617295d142c
--- /dev/null
+++ b/arch/sandbox/cpu/main.c
@@ -0,0 +1,11 @@ 
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (c) 2011 The Chromium OS Authors.
+ */
+
+#include <asm/u-boot-sandbox.h>
+
+int main(int argc, char *argv[])
+{
+	return sandbox_main(argc, argv);
+}
diff --git a/arch/sandbox/cpu/os.c b/arch/sandbox/cpu/os.c
index d1632e6af69..1c4e23cb4eb 100644
--- a/arch/sandbox/cpu/os.c
+++ b/arch/sandbox/cpu/os.c
@@ -10,7 +10,6 @@ 
 #include <fcntl.h>
 #include <pthread.h>
 #include <getopt.h>
-#include <setjmp.h>
 #include <signal.h>
 #include <stdarg.h>
 #include <stdio.h>
@@ -28,7 +27,6 @@ 
 #include <linux/compiler_attributes.h>
 #include <linux/types.h>
 
-#include <asm/fuzzing_engine.h>
 #include <asm/getopt.h>
 #include <asm/sections.h>
 #include <asm/state.h>
@@ -1151,75 +1149,3 @@  void os_relaunch(char *argv[])
 	execv(argv[0], argv);
 	os_exit(1);
 }
-
-#ifdef CONFIG_FUZZ
-static void *fuzzer_thread(void * ptr)
-{
-	char cmd[64];
-	char *argv[5] = {"./u-boot", "-T", "-c", cmd, NULL};
-	const char *fuzz_test;
-
-	/* Find which test to run from an environment variable. */
-	fuzz_test = getenv("UBOOT_SB_FUZZ_TEST");
-	if (!fuzz_test)
-		os_abort();
-
-	snprintf(cmd, sizeof(cmd), "fuzz %s", fuzz_test);
-
-	sandbox_main(4, argv);
-	os_abort();
-	return NULL;
-}
-
-static bool fuzzer_initialized = false;
-static pthread_mutex_t fuzzer_mutex = PTHREAD_MUTEX_INITIALIZER;
-static pthread_cond_t fuzzer_cond = PTHREAD_COND_INITIALIZER;
-static const uint8_t *fuzzer_data;
-static size_t fuzzer_size;
-
-int sandbox_fuzzing_engine_get_input(const uint8_t **data, size_t *size)
-{
-	if (!fuzzer_initialized)
-		return -ENOSYS;
-
-	/* Tell the main thread we need new inputs then wait for them. */
-	pthread_mutex_lock(&fuzzer_mutex);
-	pthread_cond_signal(&fuzzer_cond);
-	pthread_cond_wait(&fuzzer_cond, &fuzzer_mutex);
-	*data = fuzzer_data;
-	*size = fuzzer_size;
-	pthread_mutex_unlock(&fuzzer_mutex);
-	return 0;
-}
-
-int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
-{
-	static pthread_t tid;
-
-	pthread_mutex_lock(&fuzzer_mutex);
-
-	/* Initialize the sandbox on another thread. */
-	if (!fuzzer_initialized) {
-		fuzzer_initialized = true;
-		if (pthread_create(&tid, NULL, fuzzer_thread, NULL))
-			os_abort();
-		pthread_cond_wait(&fuzzer_cond, &fuzzer_mutex);
-	}
-
-	/* Hand over the input. */
-	fuzzer_data = data;
-	fuzzer_size = size;
-	pthread_cond_signal(&fuzzer_cond);
-
-	/* Wait for the inputs to be finished with. */
-	pthread_cond_wait(&fuzzer_cond, &fuzzer_mutex);
-	pthread_mutex_unlock(&fuzzer_mutex);
-
-	return 0;
-}
-#else
-int main(int argc, char *argv[])
-{
-	return sandbox_main(argc, argv);
-}
-#endif
diff --git a/arch/sandbox/cpu/start.c b/arch/sandbox/cpu/start.c
index 8ee12ed1500..40a3559d244 100644
--- a/arch/sandbox/cpu/start.c
+++ b/arch/sandbox/cpu/start.c
@@ -22,6 +22,7 @@ 
 #include <asm/malloc.h>
 #include <asm/sections.h>
 #include <asm/state.h>
+#include <asm/u-boot-sandbox.h>
 #include <dm/root.h>
 #include <linux/ctype.h>
 #include <linux/log2.h>
diff --git a/arch/sandbox/include/asm/u-boot-sandbox.h b/arch/sandbox/include/asm/u-boot-sandbox.h
index 54f0d9832b1..001b00fe41e 100644
--- a/arch/sandbox/include/asm/u-boot-sandbox.h
+++ b/arch/sandbox/include/asm/u-boot-sandbox.h
@@ -46,8 +46,9 @@  void __noreturn sandbox_exit(void);
  *
  * @argc:	the number of arguments passed to the program
  * @argv:	array of argc+1 pointers, of which the last one is null
-
- * This starts sandbox. It does not return unless something goes wrong.
+ *
+ * This calls sandbox_init(), then board_init_f/r(). It does not return unless
+ * something goes wrong.
  *
  * Return: 1 on error
  */