diff options
| author | flysand7 <yyakut.ac@gmail.com> | 2023-10-22 01:58:35 +1100 |
|---|---|---|
| committer | flysand7 <yyakut.ac@gmail.com> | 2023-10-22 01:58:35 +1100 |
| commit | 2e66d621b50965624f244a77661bcd0225cfdfd5 (patch) | |
| tree | a6aced122e708a9cf7f21f80ebe2df470f9912a0 /core/runtime | |
| parent | 566a11a585f1d6f8f55b0888ef8cdd084a76fc49 (diff) | |
Implement -no-crt entry point on linux
Diffstat (limited to 'core/runtime')
| -rw-r--r-- | core/runtime/entry_unix.odin | 40 | ||||
| -rw-r--r-- | core/runtime/entry_unix_no_crt_amd64.asm | 43 | ||||
| -rw-r--r-- | core/runtime/entry_unix_no_crt_i386.asm | 18 |
3 files changed, 93 insertions, 8 deletions
diff --git a/core/runtime/entry_unix.odin b/core/runtime/entry_unix.odin index 9f7d219c3..0c718445a 100644 --- a/core/runtime/entry_unix.odin +++ b/core/runtime/entry_unix.odin @@ -21,13 +21,37 @@ when ODIN_BUILD_MODE == .Dynamic { return 0 } } else when !ODIN_TEST && !ODIN_NO_ENTRY_POINT { - @(link_name="main", linkage="strong", require) - main :: proc "c" (argc: i32, argv: [^]cstring) -> i32 { - args__ = argv[:argc] - context = default_context() - #force_no_inline _startup_runtime() - intrinsics.__entry_point() - #force_no_inline _cleanup_runtime() - return 0 + when ODIN_NO_CRT { + // NOTE(flysand): We need to start from assembly because we need + // to retrieve argc and argv from the stack + when ODIN_ARCH == .amd64 { + @require foreign import entry "entry_unix_no_crt_amd64.asm" + } else when ODIN_ARCH == .i386 { + @require foreign import entry "entry_unix_no_crt_i386.asm" + } + @(link_name="_start_odin", linkage="strong", require) + _start_odin :: proc "c" (argc: i32, argv: [^]cstring) -> ! { + args__ = argv[:argc] + context = default_context() + #force_no_inline _startup_runtime() + intrinsics.__entry_point() + #force_no_inline _cleanup_runtime() + when ODIN_ARCH == .amd64 { + intrinsics.syscall(/*SYS_exit = */60) + } else when ODIN_ARCH == .i386 { + intrinsics.syscall(/*SYS_exit = */1) + } + unreachable() + } + } else { + @(link_name="main", linkage="strong", require) + main :: proc "c" (argc: i32, argv: [^]cstring) -> i32 { + args__ = argv[:argc] + context = default_context() + #force_no_inline _startup_runtime() + intrinsics.__entry_point() + #force_no_inline _cleanup_runtime() + return 0 + } } } diff --git a/core/runtime/entry_unix_no_crt_amd64.asm b/core/runtime/entry_unix_no_crt_amd64.asm new file mode 100644 index 000000000..f0bdce8d7 --- /dev/null +++ b/core/runtime/entry_unix_no_crt_amd64.asm @@ -0,0 +1,43 @@ +bits 64 + +extern _start_odin +global _start + +section .text + +;; Entry point for programs that specify -no-crt option +;; This entry point should be compatible with dynamic loaders on linux +;; The parameters the dynamic loader passes to the _start function: +;; RDX = pointer to atexit function +;; The stack layout is as follows: +;; +-------------------+ +;; NULL +;; +-------------------+ +;; envp[m] +;; +-------------------+ +;; ... +;; +-------------------+ +;; envp[0] +;; +-------------------+ +;; NULL +;; +-------------------+ +;; argv[n] +;; +-------------------+ +;; ... +;; +-------------------+ +;; argv[0] +;; +-------------------+ +;; argc +;; +-------------------+ <------ RSP +;; +_start: + ;; Mark stack frame as the top of the stack + xor rbp, rbp + ;; Load argc into 1st param reg, argv into 2nd param reg + pop rdi + mov rdx, rsi + ;; Align stack pointer down to 16-bytes (sysv calling convention) + and rsp, -16 + ;; Call into odin entry point + call _start_odin + jmp $$
\ No newline at end of file diff --git a/core/runtime/entry_unix_no_crt_i386.asm b/core/runtime/entry_unix_no_crt_i386.asm new file mode 100644 index 000000000..a61d56a16 --- /dev/null +++ b/core/runtime/entry_unix_no_crt_i386.asm @@ -0,0 +1,18 @@ +bits 32 + +extern _start_odin +global _start + +section .text + +;; NOTE(flysand): For description see the corresponding *_amd64.asm file +;; also I didn't test this on x86-32 +_start: + xor ebp, rbp + pop ecx + mov eax, esp + and esp, -16 + push eax + push ecx + call _start_odin + jmp $$
\ No newline at end of file |