diff --git a/core/os/os_windows.odin b/core/os/os_windows.odin index 9b1be3493..4efa1d8ee 100644 --- a/core/os/os_windows.odin +++ b/core/os/os_windows.odin @@ -196,12 +196,12 @@ file_size :: proc(fd: Handle) -> (i64, Errno) { // NOTE(bill): Uses startup to initialize it -stdin := get_std_handle(int(win32.STD_INPUT_HANDLE)); -stdout := get_std_handle(int(win32.STD_OUTPUT_HANDLE)); -stderr := get_std_handle(int(win32.STD_ERROR_HANDLE)); +stdin := get_std_handle(uint(win32.STD_INPUT_HANDLE)); +stdout := get_std_handle(uint(win32.STD_OUTPUT_HANDLE)); +stderr := get_std_handle(uint(win32.STD_ERROR_HANDLE)); -get_std_handle :: proc "contextless" (h: int) -> Handle { +get_std_handle :: proc "contextless" (h: uint) -> Handle { fd := win32.GetStdHandle(win32.DWORD(h)); win32.SetHandleInformation(fd, win32.HANDLE_FLAG_INHERIT, 0); return Handle(fd); diff --git a/core/runtime/core.odin b/core/runtime/core.odin index dcee6f4c7..db08995c4 100644 --- a/core/runtime/core.odin +++ b/core/runtime/core.odin @@ -1126,21 +1126,21 @@ card :: proc(s: $S/bit_set[$E; $U]) -> int { @builtin -raw_array_data :: proc(a: $P/^($T/[$N]$E)) -> ^E { +raw_array_data :: proc "contextless" (a: $P/^($T/[$N]$E)) -> ^E { return (^E)(a); } @builtin -raw_slice_data :: proc(s: $S/[]$E) -> ^E { +raw_slice_data :: proc "contextless" (s: $S/[]$E) -> ^E { ptr := (transmute(Raw_Slice)s).data; return (^E)(ptr); } @builtin -raw_dynamic_array_data :: proc(s: $S/[dynamic]$E) -> ^E { +raw_dynamic_array_data :: proc "contextless" (s: $S/[dynamic]$E) -> ^E { ptr := (transmute(Raw_Dynamic_Array)s).data; return (^E)(ptr); } @builtin -raw_string_data :: proc(s: $S/string) -> ^u8 { +raw_string_data :: proc "contextless" (s: $S/string) -> ^u8 { return (transmute(Raw_String)s).data; } diff --git a/core/runtime/procs_windows_386.odin b/core/runtime/procs_windows_386.odin index d484addb8..fc7bbcf98 100644 --- a/core/runtime/procs_windows_386.odin +++ b/core/runtime/procs_windows_386.odin @@ -2,35 +2,68 @@ package runtime foreign import kernel32 "system:Kernel32.lib" -@private -@(link_name="_tls_index") -_tls_index: u32; +windows_trap_array_bounds :: proc "contextless" () -> ! { + DWORD :: u32; + ULONG_PTR :: uint; + + EXCEPTION_ARRAY_BOUNDS_EXCEEDED :: 0xC000008C; + + foreign kernel32 { + RaiseException :: proc "stdcall" (dwExceptionCode, dwExceptionFlags, nNumberOfArguments: DWORD, lpArguments: ^ULONG_PTR) -> ! --- + } + + RaiseException(EXCEPTION_ARRAY_BOUNDS_EXCEEDED, 0, 0, nil); +} + +windows_trap_type_assertion :: proc "contextless" () -> ! { + windows_trap_array_bounds(); +} + +@(private, require, link_name="_fltused") _fltused: i32 = 0x9875; + +@(private, require, link_name="_tls_index") _tls_index: u32; +@(private, require, link_name="_tls_array") _tls_array: u32; + -@private -@(link_name="_fltused") -_fltused: i32 = 0x9875; @(link_name="memcpy") memcpy :: proc "c" (dst, src: rawptr, len: int) -> rawptr { - foreign kernel32 { - RtlCopyMemory :: proc "c" (dst, src: rawptr, len: int) --- - } - if dst == nil || src == nil || len == 0 { + if dst == nil || src == nil || len == 0 || dst == src { return dst; } - RtlCopyMemory(dst, src, len); + d := uintptr(dst); + s := uintptr(src); + n := uintptr(len); + + for i in 0.. rawptr { - foreign kernel32 { - RtlMoveMemory :: proc "c" (dst, src: rawptr, len: int) --- - } - if dst == nil || src == nil || len == 0 { + if dst == nil || src == nil || len == 0 || dst == src { return dst; } - RtlMoveMemory(dst, src, len); + + d := uintptr(dst); + s := uintptr(src); + n := uintptr(len); + + if s < d && d < s+n { + // Overlap + for i := n-1; n >= 0; i -= 1 { + (^byte)(d+i)^ = (^byte)(s+i)^; + } + + } else { + for i in 0.. ! { EXCEPTION_ARRAY_BOUNDS_EXCEEDED :: 0xC000008C; foreign kernel32 { - RaiseException :: proc(dwExceptionCode, dwExceptionFlags, nNumberOfArguments: DWORD, lpArguments: ^ULONG_PTR) -> ! --- + RaiseException :: proc "stdcall" (dwExceptionCode, dwExceptionFlags, nNumberOfArguments: DWORD, lpArguments: ^ULONG_PTR) -> ! --- } RaiseException(EXCEPTION_ARRAY_BOUNDS_EXCEEDED, 0, 0, nil); diff --git a/src/build_settings.cpp b/src/build_settings.cpp index 1e9d82b0a..171fca756 100644 --- a/src/build_settings.cpp +++ b/src/build_settings.cpp @@ -138,6 +138,7 @@ struct BuildContext { bool use_lld; bool vet; bool cross_compiling; + bool different_os; bool keep_object_files; bool use_llvm_api; @@ -624,8 +625,9 @@ void init_build_context(TargetMetrics *cross_target) { #endif if (cross_target != nullptr && metrics != cross_target) { - metrics = cross_target; + bc->different_os = cross_target->os != metrics->os; bc->cross_compiling = true; + metrics = cross_target; } GB_ASSERT(metrics->os != TargetOs_Invalid); diff --git a/src/llvm_backend.cpp b/src/llvm_backend.cpp index 1ee517dcd..1d5cf83f7 100644 --- a/src/llvm_backend.cpp +++ b/src/llvm_backend.cpp @@ -12272,19 +12272,29 @@ void lb_generate_code(lbGenerator *gen) { } if (!(build_context.build_mode == BuildMode_DynamicLibrary && !has_dll_main)) { + + Type *params = alloc_type_tuple(); Type *results = alloc_type_tuple(); - array_init(¶ms->Tuple.variables, heap_allocator(), 2); - params->Tuple.variables[0] = alloc_entity_param(nullptr, make_token_ident("argc"), t_i32, false, true); - params->Tuple.variables[1] = alloc_entity_param(nullptr, make_token_ident("argv"), alloc_type_pointer(t_cstring), false, true); + String name = str_lit("main"); + if (build_context.metrics.os == TargetOs_windows && build_context.metrics.arch == TargetArch_386) { + name = str_lit("mainCRTStartup"); + } else { + array_init(¶ms->Tuple.variables, heap_allocator(), 2); + params->Tuple.variables[0] = alloc_entity_param(nullptr, make_token_ident("argc"), t_i32, false, true); + params->Tuple.variables[1] = alloc_entity_param(nullptr, make_token_ident("argv"), alloc_type_pointer(t_cstring), false, true); + } array_init(&results->Tuple.variables, heap_allocator(), 1); results->Tuple.variables[0] = alloc_entity_param(nullptr, make_token_ident("_"), t_i32, false, true); - Type *proc_type = alloc_type_proc(nullptr, params, 2, results, 1, false, ProcCC_CDecl); + Type *proc_type = alloc_type_proc(nullptr, + params, params->Tuple.variables.count, + results, results->Tuple.variables.count, false, ProcCC_CDecl); - lbProcedure *p = lb_create_dummy_procedure(m, str_lit("main"), proc_type); + + lbProcedure *p = lb_create_dummy_procedure(m, name, proc_type); p->is_startup = true; lb_begin_procedure_body(p); diff --git a/src/main.cpp b/src/main.cpp index 4cfcdf7c9..450dcdf48 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -162,7 +162,7 @@ i32 linker_stage(lbGenerator *gen) { LIT(target_arch_names[build_context.metrics.arch]) ); #endif - } else if (build_context.cross_compiling) { + } else if (build_context.cross_compiling && build_context.different_os) { gb_printf_err("Linking for cross compilation for this platform is not yet supported (%.*s %.*s)\n", LIT(target_os_names[build_context.metrics.os]), LIT(target_arch_names[build_context.metrics.arch]) @@ -1689,10 +1689,10 @@ int main(int arg_count, char const **arg_ptr) { init_build_context(selected_target_metrics ? selected_target_metrics->metrics : nullptr); - if (build_context.word_size == 4 && build_context.metrics.os != TargetOs_js) { - print_usage_line(0, "%.*s 32-bit is not yet supported for this platform", LIT(args[0])); - return 1; - } + // if (build_context.word_size == 4 && build_context.metrics.os != TargetOs_js) { + // print_usage_line(0, "%.*s 32-bit is not yet supported for this platform", LIT(args[0])); + // return 1; + // } if (build_context.metrics.os == TargetOs_js) { if (!build_context.use_llvm_api) { print_usage_line(0, "%.*s - js platform only supported with the -llvm-api backend", LIT(args[0])); @@ -1880,7 +1880,7 @@ int main(int arg_count, char const **arg_ptr) { LIT(target_arch_names[build_context.metrics.arch]) ); #endif - } else if (build_context.cross_compiling) { + } else if (build_context.cross_compiling && build_context.different_os) { gb_printf_err("Linking for cross compilation for this platform is not yet supported (%.*s %.*s)\n", LIT(target_os_names[build_context.metrics.os]), LIT(target_arch_names[build_context.metrics.arch])