aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--base/runtime/core_builtin.odin7
-rw-r--r--base/runtime/entry_windows.odin14
-rw-r--r--core/testing/signal_handler_libc.odin16
-rw-r--r--src/linker.cpp6
-rw-r--r--src/llvm_backend.cpp10
-rw-r--r--src/main.cpp5
6 files changed, 50 insertions, 8 deletions
diff --git a/base/runtime/core_builtin.odin b/base/runtime/core_builtin.odin
index 3a51d71fb..33b600c3e 100644
--- a/base/runtime/core_builtin.odin
+++ b/base/runtime/core_builtin.odin
@@ -54,7 +54,12 @@ container_of :: #force_inline proc "contextless" (ptr: $P/^$Field_Type, $T: type
when !NO_DEFAULT_TEMP_ALLOCATOR {
- @thread_local global_default_temp_allocator_data: Default_Temp_Allocator
+ when ODIN_ARCH == .i386 && ODIN_OS == .Windows {
+ // Thread-local storage is problematic on Windows i386
+ global_default_temp_allocator_data: Default_Temp_Allocator
+ } else {
+ @thread_local global_default_temp_allocator_data: Default_Temp_Allocator
+ }
}
@(builtin, disabled=NO_DEFAULT_TEMP_ALLOCATOR)
diff --git a/base/runtime/entry_windows.odin b/base/runtime/entry_windows.odin
index 8eb4cc7d1..dc8e9b82c 100644
--- a/base/runtime/entry_windows.odin
+++ b/base/runtime/entry_windows.odin
@@ -28,7 +28,19 @@ when ODIN_BUILD_MODE == .Dynamic {
return true
}
} else when !ODIN_TEST && !ODIN_NO_ENTRY_POINT {
- when ODIN_ARCH == .i386 || ODIN_NO_CRT {
+ when ODIN_ARCH == .i386 && !ODIN_NO_CRT {
+ // Windows i386 with CRT: libcmt provides mainCRTStartup which calls _main
+ // Note: "c" calling convention adds underscore prefix automatically on i386
+ @(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
+ }
+ } else when ODIN_NO_CRT {
@(link_name="mainCRTStartup", linkage="strong", require)
mainCRTStartup :: proc "system" () -> i32 {
context = default_context()
diff --git a/core/testing/signal_handler_libc.odin b/core/testing/signal_handler_libc.odin
index 4fc9552ae..961f5c7ce 100644
--- a/core/testing/signal_handler_libc.odin
+++ b/core/testing/signal_handler_libc.odin
@@ -24,10 +24,18 @@ import "core:terminal/ansi"
@(private="file") stop_test_passed: libc.sig_atomic_t
@(private="file") stop_test_alert: libc.sig_atomic_t
-@(private="file", thread_local)
-local_test_index: libc.sig_atomic_t
-@(private="file", thread_local)
-local_test_index_set: bool
+when ODIN_ARCH == .i386 && ODIN_OS == .Windows {
+ // Thread-local storage is problematic on Windows i386
+ @(private="file")
+ local_test_index: libc.sig_atomic_t
+ @(private="file")
+ local_test_index_set: bool
+} else {
+ @(private="file", thread_local)
+ local_test_index: libc.sig_atomic_t
+ @(private="file", thread_local)
+ local_test_index_set: bool
+}
// Windows does not appear to have a SIGTRAP, so this is defined here, instead
// of in the libc package, just so there's no confusion about it being
diff --git a/src/linker.cpp b/src/linker.cpp
index 41333a3c9..333cb792e 100644
--- a/src/linker.cpp
+++ b/src/linker.cpp
@@ -281,7 +281,11 @@ try_cross_linking:;
link_settings = gb_string_append_fmt(link_settings, " /NOENTRY");
}
} else {
- link_settings = gb_string_append_fmt(link_settings, " /ENTRY:mainCRTStartup");
+ // For i386 with CRT, libcmt provides the entry point
+ // For other cases or no_crt, we need to specify the entry point
+ if (!(build_context.metrics.arch == TargetArch_i386 && !build_context.no_crt)) {
+ link_settings = gb_string_append_fmt(link_settings, " /ENTRY:mainCRTStartup");
+ }
}
if (build_context.build_paths[BuildPath_Symbols].name != "") {
diff --git a/src/llvm_backend.cpp b/src/llvm_backend.cpp
index ff17e9c10..f2d09f400 100644
--- a/src/llvm_backend.cpp
+++ b/src/llvm_backend.cpp
@@ -2686,8 +2686,15 @@ gb_internal lbProcedure *lb_create_main_procedure(lbModule *m, lbProcedure *star
params->Tuple.variables[1] = alloc_entity_param(nullptr, make_token_ident("fdwReason"), t_u32, false, true);
params->Tuple.variables[2] = alloc_entity_param(nullptr, make_token_ident("lpReserved"), t_rawptr, false, true);
call_cleanup = false;
- } else if (build_context.metrics.os == TargetOs_windows && (build_context.metrics.arch == TargetArch_i386 || build_context.no_crt)) {
+ } else if (build_context.metrics.os == TargetOs_windows && build_context.no_crt) {
name = str_lit("mainCRTStartup");
+ } else if (build_context.metrics.os == TargetOs_windows && build_context.metrics.arch == TargetArch_i386 && !build_context.no_crt) {
+ // Windows i386 with CRT: libcmt expects _main (main with underscore prefix)
+ name = str_lit("main");
+ has_args = true;
+ slice_init(&params->Tuple.variables, permanent_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"), t_ptr_cstring, false, true);
} else if (is_arch_wasm()) {
name = str_lit("_start");
call_cleanup = false;
@@ -3162,6 +3169,7 @@ gb_internal bool lb_generate_code(lbGenerator *gen) {
String link_name = e->Procedure.link_name;
if (e->pkg->kind == Package_Runtime) {
if (link_name == "main" ||
+ link_name == "_main" ||
link_name == "DllMain" ||
link_name == "WinMain" ||
link_name == "wWinMain" ||
diff --git a/src/main.cpp b/src/main.cpp
index db4dee080..c4646bc9f 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -3617,6 +3617,11 @@ int main(int arg_count, char const **arg_ptr) {
// print_usage_line(0, "%.*s 32-bit is not yet supported for this platform", LIT(args[0]));
// return 1;
// }
+
+ // Warn about Windows i386 thread-local storage limitations
+ if (build_context.metrics.arch == TargetArch_i386 && build_context.metrics.os == TargetOs_windows) {
+ gb_printf_err("Warning: Thread-local storage is disabled on Windows i386.\n");
+ }
// Check chosen microarchitecture. If not found or ?, print list.
bool print_microarch_list = true;