Modifications Made to glibc and crt1.c
1. Changes to glibc
1.1 Changing the System Call Mechanism
The system call mechanism was modified to route system calls through rawposix
instead of directly invoking the kernel. The new format for making system calls is structured as follows:
MAKE_SYSCALL(syscallnum, "syscall|callname", arg1, arg2, arg3, arg4, arg5, arg6)
For each system call file in glibc, a header file named syscall-template.h
was added with the following content:
#include <sys/syscall.h>
#include <stdint.h> // For uint64_t
#include <unistd.h>
#include <lind_syscall.h>
// Define NOTUSED for unused arguments
#define NOTUSED 0xdeadbeefdeadbeefULL
// Macro to create a syscall and redirect it to rawposix
#define MAKE_SYSCALL(syscallnum, callname, arg1, arg2, arg3, arg4, arg5, arg6) \
lind_syscall(syscallnum, \
(unsigned long long)(callname), \
(unsigned long long)(arg1), \
(unsigned long long)(arg2), \
(unsigned long long)(arg3), \
(unsigned long long)(arg4), \
(unsigned long long)(arg5), \
(unsigned long long)(arg6))
The MAKE_SYSCALL
macro redirects system calls to rawposix, providing an interface for syscall handling in this context.
1.2 Eliminating Assembly Code
Since WebAssembly (WASM) does not support assembly, all assembly-related components in glibc were removed:
- Inline assembly code was rewritten in C.
- Files ending in .s
were converted to .c
files, and their functionalities were reimplemented in C.
1.3 Handling Automatically Generated .s
Files
glibc automatically generates .s
files for certain system calls. To address this:
- The script responsible for generating these .s
files was disabled.
- The corresponding system calls were manually implemented in C and placed in appropriate .c
files.
1.4 Additional Modifications
- Disable
_dl_mcount_wrapper_check
: This functionality was disabled as it is not required in the WASI environment. - Change
initial-exec
tolocal-exec
: All instances ofinitial-exec
were replaced withlocal-exec
to align with WebAssembly's threading and memory model. - Implement
BYTE_COPY_FWD
andBYTE_COPY_BWD
: These functions were implemented in C without relying onmemcpy
ormemmove
to ensure compatibility with the WASM environment. - Disable
attribute_relro
: The original C code places the vtable into therelro
section in the binary. Since WebAssembly binaries do not have this section, the attribute was disabled.
2. Modifications and Additions to crt1.c
for WASI
2.1 WASI-Specific Function Wrappers
- Wrappers for WASI Snapshot Preview 1 APIs:
Several wrappers were defined for handling WASI
args
andenviron
APIs, including: __imported_wasi_snapshot_preview1_args_sizes_get
__imported_wasi_snapshot_preview1_args_get
__imported_wasi_snapshot_preview1_environ_get
-
__imported_wasi_snapshot_preview1_environ_sizes_get
-
Implementation: These wrappers use the following attribute for integration:
c __attribute__(( __import_module__("wasi_snapshot_preview1"), __import_name__("function_name") ));
-
Purpose: Enables access to WASI-specific argument and environment APIs.
2.2 Environment Initialization
- Added
__wasi_initialize_environ
: This function initializes the environment variables by: - Using
__wasi_environ_sizes_get
to determine the size of environment data. -
Using
__wasi_environ_get
to populate theenviron
array. -
Fallback Logic: If the environment is empty, the program:
- Falls back to a static empty environment (
empty_environ
). - Exits with an appropriate error code when necessary.
2.3 Thread and TLS Setup
- Added Calls to
__libc_setup_tls
and__wasi_init_tp
: These functions are included in_start
to set up thread-local storage (TLS) and thread pointers, which are essential for multithreading or TLS-dependent code.
2.4 Main Function Handling
- Modified
__main_void
to Handle WASI Arguments: - Initializes command-line arguments by:
- Using
__wasi_args_sizes_get
to determine argument buffer sizes. - Using
__wasi_args_get
to populateargv
andargv_buf
.
- Using
-
Passes the initialized arguments to
__main_argc_argv
. -
Weak Symbol for
__main_argc_argv
: Defined as a weak symbol to allow the dynamic linker to handle cases where nomain
function exists (e.g., in reactor-style applications).
2.5 Error Handling
- Specific Exit Codes:
-
Introduced
_Exit(EX_OSERR)
and_Exit(EX_SOFTWARE)
for different error scenarios, aligning withsysexits.h
standards. -
Purpose: Provides descriptive and standard error handling for memory allocation or initialization failures.
2.6 Placeholder Functions
- Added Stub for
__wasm_call_dtors
: -
An empty placeholder function for future destructor handling.
-
Added Stub for
__wasi_proc_exit
: - A placeholder function for handling process exits in WASI.
2.7 Memory Allocation for argv
and environ
- Allocates memory dynamically for:
- Argument buffers (
argv_buf
) and pointers (argv
). - Environment buffers (
environ_buf
) and pointers (environ_ptrs
). - Uses
malloc
andcalloc
with robust error handling to prevent memory allocation failures.