From 08e8c9bf57455b8536403db645d10ce20ab60f32 Mon Sep 17 00:00:00 2001 From: Christoffer Lerno Date: Thu, 26 Dec 2024 22:08:02 +0100 Subject: [PATCH] Use `weak` on dyn-symbols on Linux. --- releasenotes.md | 1 + src/compiler/llvm_codegen.c | 2 +- src/compiler/llvm_codegen_function.c | 3 ++- src/compiler/llvm_codegen_internal.h | 1 + test/test_suite/dynamic/inherit_linux.c3t | 4 ++-- test/test_suite/dynamic/overlapping_function_linux.c3t | 6 ++---- 6 files changed, 9 insertions(+), 8 deletions(-) diff --git a/releasenotes.md b/releasenotes.md index 49b4a0fd9..3d07bef2a 100644 --- a/releasenotes.md +++ b/releasenotes.md @@ -26,6 +26,7 @@ - Prevent DString from being initialized with "". - Fix bug in OnStackAllocator when freeing overallocated data. #1720 - Use `weak_odr` rather than `weak` on Windows which seems to prevent issues such as #1704. +- Use `weak` on dyn-symbols on Linux. ### Stdlib changes - Increase BitWriter.write_bits limit up to 32 bits. diff --git a/src/compiler/llvm_codegen.c b/src/compiler/llvm_codegen.c index 21fb27489..848905b19 100644 --- a/src/compiler/llvm_codegen.c +++ b/src/compiler/llvm_codegen.c @@ -468,7 +468,7 @@ void llvm_set_global_tls(Decl *decl) } } -static void llvm_set_weak(GenContext *c, LLVMValueRef global) +void llvm_set_weak(GenContext *c, LLVMValueRef global) { LLVMSetLinkage(global, compiler.platform.os == OS_TYPE_WIN32 ? LLVMWeakODRLinkage : LLVMWeakAnyLinkage); LLVMSetVisibility(global, LLVMDefaultVisibility); diff --git a/src/compiler/llvm_codegen_function.c b/src/compiler/llvm_codegen_function.c index 4294f0806..5f11c16da 100644 --- a/src/compiler/llvm_codegen_function.c +++ b/src/compiler/llvm_codegen_function.c @@ -418,7 +418,7 @@ void llvm_emit_function_body(GenContext *c, Decl *decl) scratch_buffer_append(".__c3_atexit_"); scratch_buffer_set_extern_decl_name(decl, false); LLVMValueRef func = LLVMAddFunction(c->module, scratch_buffer_to_string(), c->xtor_func_type); - + llvm_set_weak(c, func); LLVMBuilderRef builder = llvm_create_function_entry(c, func, NULL); LLVMValueRef args[1] = { decl->backend_ref }; LLVMBuildCall2(builder, c->atexit_type, atexit, args, 1, ""); @@ -598,6 +598,7 @@ void llvm_emit_dynamic_functions(GenContext *c, Decl **funcs) scratch_buffer_append("$ct.dyn."); scratch_buffer_set_extern_decl_name(decl, false); LLVMValueRef global = llvm_add_global_raw(c, scratch_buffer_copy(), c->dtable_type, 0); + llvm_set_weak(c, global); Decl *proto = declptrzero(decl->func_decl.interface_method); LLVMValueRef proto_ref = proto ? llvm_get_ref(c, proto) : llvm_get_selector(c, decl->name); diff --git a/src/compiler/llvm_codegen_internal.h b/src/compiler/llvm_codegen_internal.h index d63ad8c02..751907e9c 100644 --- a/src/compiler/llvm_codegen_internal.h +++ b/src/compiler/llvm_codegen_internal.h @@ -371,6 +371,7 @@ void llvm_set_linkonce(GenContext *c, LLVMValueRef global); void llvm_set_comdat(GenContext *c, LLVMValueRef global); void llvm_set_private_declaration(LLVMValueRef alloc); void llvm_set_decl_linkage(GenContext *c, Decl *decl); +void llvm_set_weak(GenContext *c, LLVMValueRef global); void llvm_set_internal_linkage(LLVMValueRef alloc); void llvm_set_global_tls(Decl *decl); diff --git a/test/test_suite/dynamic/inherit_linux.c3t b/test/test_suite/dynamic/inherit_linux.c3t index 0e61d3fad..3ce011da0 100644 --- a/test/test_suite/dynamic/inherit_linux.c3t +++ b/test/test_suite/dynamic/inherit_linux.c3t @@ -50,8 +50,8 @@ $"$sel.hello" = comdat any @.panic_msg = internal constant [42 x i8] c"No method 'tesT' could be found on target\00", align 1 @.func = internal constant [5 x i8] c"main\00", align 1 @std.core.builtin.panic = extern_weak global ptr, align 8 -@"$ct.dyn.inherit.Test.tesT" = global { ptr, ptr, ptr } { ptr @inherit.Test.tesT, ptr @"$sel.tesT", ptr inttoptr (i64 -1 to ptr) }, align 8 -@"$ct.dyn.inherit.Test.hello" = global { ptr, ptr, ptr } { ptr @inherit.Test.hello, ptr @"$sel.hello", ptr inttoptr (i64 -1 to ptr) }, align 8 +@"$ct.dyn.inherit.Test.tesT" = weak global { ptr, ptr, ptr } { ptr @inherit.Test.tesT, ptr @"$sel.tesT", ptr inttoptr (i64 -1 to ptr) }, comdat, align 8 +@"$ct.dyn.inherit.Test.hello" = weak global { ptr, ptr, ptr } { ptr @inherit.Test.hello, ptr @"$sel.hello", ptr inttoptr (i64 -1 to ptr) }, comdat, align 8 @"$sel.hello" = linkonce_odr constant [6 x i8] c"hello\00", comdat, align 1 @llvm.global_ctors = appending global [1 x { i32, ptr, ptr }] [{ i32, ptr, ptr } { i32 1, ptr @.c3_dynamic_register, ptr null }] define void @inherit.Test.tesT(ptr %0) #0 { diff --git a/test/test_suite/dynamic/overlapping_function_linux.c3t b/test/test_suite/dynamic/overlapping_function_linux.c3t index 78a66a692..05c63b4df 100644 --- a/test/test_suite/dynamic/overlapping_function_linux.c3t +++ b/test/test_suite/dynamic/overlapping_function_linux.c3t @@ -41,8 +41,8 @@ fn void main() @.file = internal constant [30 x i8] c"overlapping_function_linux.c3\00", align 1 @.func = internal constant [5 x i8] c"main\00", align 1 @std.core.builtin.panic = extern_weak global ptr, align 8 -@"$ct.dyn.overlap.Test.tesT" = global { ptr, ptr, ptr } { ptr @overlap.Test.tesT, ptr @"$sel.tesT", ptr inttoptr (i64 -1 to ptr) }, align 8 -@"$ct.dyn.overlap.Test.foo" = global { ptr, ptr, ptr } { ptr @overlap.Test.foo, ptr @"$sel.foo", ptr inttoptr (i64 -1 to ptr) }, align 8 +@"$ct.dyn.overlap.Test.tesT" = weak global { ptr, ptr, ptr } { ptr @overlap.Test.tesT, ptr @"$sel.tesT", ptr inttoptr (i64 -1 to ptr) }, comdat, align 8 +@"$ct.dyn.overlap.Test.foo" = weak global { ptr, ptr, ptr } { ptr @overlap.Test.foo, ptr @"$sel.foo", ptr inttoptr (i64 -1 to ptr) }, comdat, align 8 @"$sel.foo" = linkonce_odr constant [4 x i8] c"foo\00", comdat, align 1 @llvm.global_ctors = appending global [1 x { i32, ptr, ptr }] [{ i32, ptr, ptr } { i32 1, ptr @.c3_dynamic_register, ptr null }] ; Function Attrs: nounwind uwtable @@ -134,8 +134,6 @@ entry: call void @overlap.main() ret i32 0 } - - define weak ptr @.dyn_search(ptr %0, ptr %1) unnamed_addr comdat { entry: br label %check