Quellcode durchsuchen

-no-crt and assembly compilation on darwin

Laytan Laats vor 1 Jahr
Ursprung
Commit
6b9202dfbf

+ 6 - 5
core/runtime/entry_unix.odin

@@ -26,8 +26,13 @@ when ODIN_BUILD_MODE == .Dynamic {
 		// to retrieve argc and argv from the stack
 		when ODIN_ARCH == .amd64 {
 			@require foreign import entry "entry_unix_no_crt_amd64.asm"
+			SYS_exit :: 60
 		} else when ODIN_ARCH == .i386 {
 			@require foreign import entry "entry_unix_no_crt_i386.asm"
+			SYS_exit :: 1
+		} else when ODIN_OS == .Darwin && ODIN_ARCH == .arm64 {
+			@require foreign import entry "entry_unix_no_crt_darwin_arm64.asm"
+			SYS_exit :: 1
 		}
 		@(link_name="_start_odin", linkage="strong", require)
 		_start_odin :: proc "c" (argc: i32, argv: [^]cstring) -> ! {
@@ -36,11 +41,7 @@ when ODIN_BUILD_MODE == .Dynamic {
 			#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)
-			}
+			intrinsics.syscall(SYS_exit, 0)
 			unreachable()
 		}
 	} else {

+ 20 - 0
core/runtime/entry_unix_no_crt_darwin_arm64.asm

@@ -0,0 +1,20 @@
+	.section __TEXT,__text
+
+	; NOTE(laytan): this should ideally be the -minimum-os-version flag but there is no nice way of preprocessing assembly in Odin.
+	; 10 seems to be the lowest it goes and I don't see it mess with any targeted os version so this seems fine.
+	.build_version macos, 10, 0
+
+	.extern __start_odin
+
+	.global _main
+	.align 2
+_main:
+	mov x5, sp       ; use x5 as the stack pointer
+
+	str x0, [x5]     ; get argc into x0 (kernel passes 32-bit int argc as 64-bits on stack to keep alignment)
+	str x1, [x5, #8] ; get argv into x1
+
+	and sp, x5, #~15 ; force 16-byte alignment of the stack
+	
+	bl __start_odin  ; call into Odin entry point
+	ret              ; should never get here

+ 1 - 1
core/runtime/os_specific_any.odin

@@ -1,4 +1,4 @@
-//+build !freestanding !wasi !windows !js
+//+build !freestanding !wasi !windows !js !darwin
 package runtime
 
 import "core:os"

+ 12 - 0
core/runtime/os_specific_darwin.odin

@@ -0,0 +1,12 @@
+//+build darwin
+package runtime
+
+import "core:intrinsics"
+
+_os_write :: proc "contextless" (data: []byte) -> (int, _OS_Errno) {
+	ret := intrinsics.syscall(4, 1, uintptr(raw_data(data)), uintptr(len(data)))
+	if ret < 0 {
+		return 0, _OS_Errno(-ret)
+	}
+	return int(ret), 0
+}

+ 1 - 1
src/checker.cpp

@@ -4733,7 +4733,7 @@ gb_internal void check_add_foreign_import_decl(CheckerContext *ctx, Ast *decl) {
 	}
 
 	if (has_asm_extension(fullpath)) {
-		if (build_context.metrics.arch != TargetArch_amd64) {
+		if (build_context.metrics.arch != TargetArch_amd64 && build_context.metrics.os != TargetOs_darwin) {
 			error(decl, "Assembly files are not yet supported on this platform: %.*s_%.*s",
 			      LIT(target_os_names[build_context.metrics.os]), LIT(target_arch_names[build_context.metrics.arch]));
 		}

+ 28 - 14
src/linker.cpp

@@ -337,20 +337,34 @@ gb_internal i32 linker_stage(LinkerData *gen) {
 							obj_format = str_lit("elf32");
 						}
 #endif // GB_ARCH_*_BIT
-						// Note(bumbread): I'm assuming nasm is installed on the host machine.
-						// Shipping binaries on unix-likes gets into the weird territorry of
-						// "which version of glibc" is it linked with.
-						result = system_exec_command_line_app("nasm",
-							"nasm \"%.*s\" "
-							"-f \"%.*s\" "
-							"-o \"%.*s\" "
-							"%.*s "
-							"",
-							LIT(asm_file),
-							LIT(obj_format),
-							LIT(obj_file),
-							LIT(build_context.extra_assembler_flags)
-						);						
+
+						if (is_osx) {
+							// `as` comes with MacOS.
+							result = system_exec_command_line_app("as",
+								"as \"%.*s\" "
+								"-o \"%.*s\" "
+								"%.*s "
+								"",
+								LIT(asm_file),
+								LIT(obj_file),
+								LIT(build_context.extra_assembler_flags)
+							);
+						} else {
+							// Note(bumbread): I'm assuming nasm is installed on the host machine.
+							// Shipping binaries on unix-likes gets into the weird territorry of
+							// "which version of glibc" is it linked with.
+							result = system_exec_command_line_app("nasm",
+								"nasm \"%.*s\" "
+								"-f \"%.*s\" "
+								"-o \"%.*s\" "
+								"%.*s "
+								"",
+								LIT(asm_file),
+								LIT(obj_format),
+								LIT(obj_file),
+								LIT(build_context.extra_assembler_flags)
+							);						
+						}
 						array_add(&gen->output_object_paths, obj_file);
 					} else {
 						if (string_set_update(&libs, lib)) {