Skip to content

Commit 66d28ff

Browse files
committed
Add crt2-command.o to provide __main_void
cf. #485
1 parent 230d4be commit 66d28ff

File tree

1 file changed

+54
-0
lines changed

1 file changed

+54
-0
lines changed

libc-bottom-half/crt/crt2-command.c

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
#include <wasi/api.h>
2+
#include <stdlib.h>
3+
#include <sysexits.h>
4+
5+
// The user's `main` function, expecting arguments.
6+
int __main_argc_argv(int argc, char *argv[]);
7+
8+
// If the user's `main` function expects arguments, the compiler will rename
9+
// it to `__main_argc_argv`, and this version will get linked in, which
10+
// initializes the argument data and calls `__main_argc_argv`.
11+
__attribute__((__weak__, nodebug))
12+
int __main_void(void) {
13+
__wasi_errno_t err;
14+
15+
// Get the sizes of the arrays we'll have to create to copy in the args.
16+
size_t argv_buf_size;
17+
size_t argc;
18+
err = __wasi_args_sizes_get(&argc, &argv_buf_size);
19+
if (err != __WASI_ERRNO_SUCCESS) {
20+
_Exit(EX_OSERR);
21+
}
22+
23+
// Add 1 for the NULL pointer to mark the end, and check for overflow.
24+
size_t num_ptrs = argc + 1;
25+
if (num_ptrs == 0) {
26+
_Exit(EX_SOFTWARE);
27+
}
28+
29+
// Allocate memory for storing the argument chars.
30+
char *argv_buf = malloc(argv_buf_size);
31+
if (argv_buf == NULL) {
32+
_Exit(EX_SOFTWARE);
33+
}
34+
35+
// Allocate memory for the array of pointers. This uses `calloc` both to
36+
// handle overflow and to initialize the NULL pointer at the end.
37+
char **argv = calloc(num_ptrs, sizeof(char *));
38+
if (argv == NULL) {
39+
free(argv_buf);
40+
_Exit(EX_SOFTWARE);
41+
}
42+
43+
// Fill the argument chars, and the argv array with pointers into those chars.
44+
// TODO: Remove the casts on `argv_ptrs` and `argv_buf` once the witx is updated with char8 support.
45+
err = __wasi_args_get((uint8_t **)argv, (uint8_t *)argv_buf);
46+
if (err != __WASI_ERRNO_SUCCESS) {
47+
free(argv_buf);
48+
free(argv);
49+
_Exit(EX_OSERR);
50+
}
51+
52+
// Call `__main_argc_argv` with the arguments!
53+
return __main_argc_argv(argc, argv);
54+
}

0 commit comments

Comments
 (0)