Commit 5cbae7b671

Andrew Kelley <superjoe30@gmail.com>
2017-10-02 06:10:42
better compiler-rt linkage logic
now the compiler-rt tests are passing on windows. See #302
1 parent 8156e4f
src/link.cpp
@@ -52,6 +52,12 @@ static Buf *build_o_raw(CodeGen *parent_gen, const char *oname, Buf *full_path)
     codegen_set_mmacosx_version_min(child_gen, parent_gen->mmacosx_version_min);
     codegen_set_mios_version_min(child_gen, parent_gen->mios_version_min);
 
+    for (size_t i = 0; i < parent_gen->link_libs_list.length; i += 1) {
+        LinkLib *link_lib = parent_gen->link_libs_list.at(i);
+        LinkLib *new_link_lib = codegen_add_link_lib(child_gen, link_lib->name);
+        new_link_lib->provided_explicitly = link_lib->provided_explicitly;
+    }
+
     codegen_build(child_gen);
     const char *o_ext = target_o_file_ext(&child_gen->zig_target);
     Buf *o_out_name = buf_sprintf("%s%s", oname, o_ext);
std/special/compiler_rt/comparetf2.zig
@@ -20,10 +20,11 @@ const infRep = exponentMask;
 
 const builtin = @import("builtin");
 const is_test = builtin.is_test;
+const linkage = if (builtin.is_test) builtin.GlobalLinkage.Internal else builtin.GlobalLinkage.LinkOnce;
 
 export fn __letf2(a: f128, b: f128) -> c_int {
     @setDebugSafety(this, is_test);
-    @setGlobalLinkage(__letf2, builtin.GlobalLinkage.LinkOnce);
+    @setGlobalLinkage(__letf2, linkage);
 
     const aInt = @bitCast(rep_t, a);
     const bInt = @bitCast(rep_t, b);
@@ -65,7 +66,7 @@ export fn __letf2(a: f128, b: f128) -> c_int {
 // Alias for libgcc compatibility
 // TODO https://github.com/zig-lang/zig/issues/420
 export fn __cmptf2(a: f128, b: f128) -> c_int {
-    @setGlobalLinkage(__cmptf2, builtin.GlobalLinkage.LinkOnce);
+    @setGlobalLinkage(__cmptf2, linkage);
     @setDebugSafety(this, is_test);
     return __letf2(a, b);
 }
@@ -78,7 +79,7 @@ const GE_GREATER = c_int(1);
 const GE_UNORDERED = c_int(-1); // Note: different from LE_UNORDERED
 
 export fn __getf2(a: f128, b: f128) -> c_int {
-    @setGlobalLinkage(__getf2, builtin.GlobalLinkage.LinkOnce);
+    @setGlobalLinkage(__getf2, linkage);
     @setDebugSafety(this, is_test);
 
     const aInt = @bitCast(srep_t, a);
@@ -108,7 +109,7 @@ export fn __getf2(a: f128, b: f128) -> c_int {
 }
 
 export fn __unordtf2(a: f128, b: f128) -> c_int {
-    @setGlobalLinkage(__unordtf2, builtin.GlobalLinkage.LinkOnce);
+    @setGlobalLinkage(__unordtf2, linkage);
     @setDebugSafety(this, is_test);
 
     const aAbs = @bitCast(rep_t, a) & absMask;
@@ -120,25 +121,25 @@ export fn __unordtf2(a: f128, b: f128) -> c_int {
 // TODO use aliases https://github.com/zig-lang/zig/issues/462
 
 export fn __eqtf2(a: f128, b: f128) -> c_int {
-    @setGlobalLinkage(__eqtf2, builtin.GlobalLinkage.LinkOnce);
+    @setGlobalLinkage(__eqtf2, linkage);
     @setDebugSafety(this, is_test);
     return __letf2(a, b);
 }
 
 export fn __lttf2(a: f128, b: f128) -> c_int {
-    @setGlobalLinkage(__lttf2, builtin.GlobalLinkage.LinkOnce);
+    @setGlobalLinkage(__lttf2, linkage);
     @setDebugSafety(this, is_test);
     return __letf2(a, b);
 }
 
 export fn __netf2(a: f128, b: f128) -> c_int {
-    @setGlobalLinkage(__netf2, builtin.GlobalLinkage.LinkOnce);
+    @setGlobalLinkage(__netf2, linkage);
     @setDebugSafety(this, is_test);
     return __letf2(a, b);
 }
 
 export fn __gttf2(a: f128, b: f128) -> c_int {
-    @setGlobalLinkage(__gttf2, builtin.GlobalLinkage.LinkOnce);
+    @setGlobalLinkage(__gttf2, linkage);
     @setDebugSafety(this, is_test);
     return __getf2(a, b);
 }
std/special/compiler_rt/fixunsdfdi.zig
@@ -1,7 +1,10 @@
 const fixuint = @import("fixuint.zig").fixuint;
+const builtin = @import("builtin");
+const linkage = if (builtin.is_test) builtin.GlobalLinkage.Internal else builtin.GlobalLinkage.LinkOnce;
 
 export fn __fixunsdfdi(a: f64) -> u64 {
-    @setGlobalLinkage(__fixunsdfdi, @import("builtin").GlobalLinkage.LinkOnce);
+    @setDebugSafety(this, builtin.is_test);
+    @setGlobalLinkage(__fixunsdfdi, linkage);
     return fixuint(f64, u64, a);
 }
 
std/special/compiler_rt/fixunsdfsi.zig
@@ -1,7 +1,10 @@
 const fixuint = @import("fixuint.zig").fixuint;
+const builtin = @import("builtin");
+const linkage = if (builtin.is_test) builtin.GlobalLinkage.Internal else builtin.GlobalLinkage.LinkOnce;
 
 export fn __fixunsdfsi(a: f64) -> u32 {
-    @setGlobalLinkage(__fixunsdfsi, @import("builtin").GlobalLinkage.LinkOnce);
+    @setDebugSafety(this, builtin.is_test);
+    @setGlobalLinkage(__fixunsdfsi, linkage);
     return fixuint(f64, u32, a);
 }
 
std/special/compiler_rt/fixunsdfti.zig
@@ -1,7 +1,10 @@
 const fixuint = @import("fixuint.zig").fixuint;
+const builtin = @import("builtin");
+const linkage = if (builtin.is_test) builtin.GlobalLinkage.Internal else builtin.GlobalLinkage.LinkOnce;
 
 export fn __fixunsdfti(a: f64) -> u128 {
-    @setGlobalLinkage(__fixunsdfti, @import("builtin").GlobalLinkage.LinkOnce);
+    @setDebugSafety(this, builtin.is_test);
+    @setGlobalLinkage(__fixunsdfti, linkage);
     return fixuint(f64, u128, a);
 }
 
std/special/compiler_rt/fixunssfdi.zig
@@ -1,7 +1,10 @@
 const fixuint = @import("fixuint.zig").fixuint;
+const builtin = @import("builtin");
+const linkage = if (builtin.is_test) builtin.GlobalLinkage.Internal else builtin.GlobalLinkage.LinkOnce;
 
 export fn __fixunssfdi(a: f32) -> u64 {
-    @setGlobalLinkage(__fixunssfdi, @import("builtin").GlobalLinkage.LinkOnce);
+    @setDebugSafety(this, builtin.is_test);
+    @setGlobalLinkage(__fixunssfdi, linkage);
     return fixuint(f32, u64, a);
 }
 
std/special/compiler_rt/fixunssfsi.zig
@@ -1,7 +1,10 @@
 const fixuint = @import("fixuint.zig").fixuint;
+const builtin = @import("builtin");
+const linkage = if (builtin.is_test) builtin.GlobalLinkage.Internal else builtin.GlobalLinkage.LinkOnce;
 
 export fn __fixunssfsi(a: f32) -> u32 {
-    @setGlobalLinkage(__fixunssfsi, @import("builtin").GlobalLinkage.LinkOnce);
+    @setDebugSafety(this, builtin.is_test);
+    @setGlobalLinkage(__fixunssfsi, linkage);
     return fixuint(f32, u32, a);
 }
 
std/special/compiler_rt/fixunssfti.zig
@@ -1,7 +1,10 @@
 const fixuint = @import("fixuint.zig").fixuint;
+const builtin = @import("builtin");
+const linkage = if (builtin.is_test) builtin.GlobalLinkage.Internal else builtin.GlobalLinkage.LinkOnce;
 
 export fn __fixunssfti(a: f32) -> u128 {
-    @setGlobalLinkage(__fixunssfti, @import("builtin").GlobalLinkage.LinkOnce);
+    @setDebugSafety(this, builtin.is_test);
+    @setGlobalLinkage(__fixunssfti, linkage);
     return fixuint(f32, u128, a);
 }
 
std/special/compiler_rt/fixunstfdi.zig
@@ -1,7 +1,10 @@
 const fixuint = @import("fixuint.zig").fixuint;
+const builtin = @import("builtin");
+const linkage = if (builtin.is_test) builtin.GlobalLinkage.Internal else builtin.GlobalLinkage.LinkOnce;
 
 export fn __fixunstfdi(a: f128) -> u64 {
-    @setGlobalLinkage(__fixunstfdi, @import("builtin").GlobalLinkage.LinkOnce);
+    @setDebugSafety(this, builtin.is_test);
+    @setGlobalLinkage(__fixunstfdi, linkage);
     return fixuint(f128, u64, a);
 }
 
std/special/compiler_rt/fixunstfsi.zig
@@ -1,7 +1,10 @@
 const fixuint = @import("fixuint.zig").fixuint;
+const builtin = @import("builtin");
+const linkage = if (builtin.is_test) builtin.GlobalLinkage.Internal else builtin.GlobalLinkage.LinkOnce;
 
 export fn __fixunstfsi(a: f128) -> u32 {
-    @setGlobalLinkage(__fixunstfsi, @import("builtin").GlobalLinkage.LinkOnce);
+    @setDebugSafety(this, builtin.is_test);
+    @setGlobalLinkage(__fixunstfsi, linkage);
     return fixuint(f128, u32, a);
 }
 
std/special/compiler_rt/fixunstfti.zig
@@ -1,7 +1,10 @@
 const fixuint = @import("fixuint.zig").fixuint;
+const builtin = @import("builtin");
+const linkage = if (builtin.is_test) builtin.GlobalLinkage.Internal else builtin.GlobalLinkage.LinkOnce;
 
 export fn __fixunstfti(a: f128) -> u128 {
-    @setGlobalLinkage(__fixunstfti, @import("builtin").GlobalLinkage.LinkOnce);
+    @setDebugSafety(this, builtin.is_test);
+    @setGlobalLinkage(__fixunstfti, linkage);
     return fixuint(f128, u128, a);
 }
 
std/special/compiler_rt/index.zig
@@ -21,6 +21,13 @@ const builtin = @import("builtin");
 const is_test = builtin.is_test;
 const assert = @import("../../debug.zig").assert;
 
+
+const win32 = builtin.os == builtin.Os.windows and builtin.arch == builtin.Arch.i386;
+const win64 = builtin.os == builtin.Os.windows and builtin.arch == builtin.Arch.x86_64;
+const win32_nocrt = win32 and !builtin.link_libc;
+const win64_nocrt = win64 and !builtin.link_libc;
+const linkage = if (builtin.is_test) builtin.GlobalLinkage.Internal else builtin.GlobalLinkage.LinkOnce;
+
 const __udivmoddi4 = @import("udivmoddi4.zig").__udivmoddi4;
 
 // Avoid dragging in the debug safety mechanisms into this .o file,
@@ -35,13 +42,13 @@ pub coldcc fn panic(msg: []const u8) -> noreturn {
 
 export fn __udivdi3(a: u64, b: u64) -> u64 {
     @setDebugSafety(this, is_test);
-    @setGlobalLinkage(__udivdi3, builtin.GlobalLinkage.LinkOnce);
+    @setGlobalLinkage(__udivdi3, linkage);
     return __udivmoddi4(a, b, null);
 }
 
 export fn __umoddi3(a: u64, b: u64) -> u64 {
     @setDebugSafety(this, is_test);
-    @setGlobalLinkage(__umoddi3, builtin.GlobalLinkage.LinkOnce);
+    @setGlobalLinkage(__umoddi3, linkage);
 
     var r: u64 = undefined;
     _ = __udivmoddi4(a, b, &r);
@@ -55,7 +62,7 @@ const AeabiUlDivModResult = extern struct {
 export fn __aeabi_uldivmod(numerator: u64, denominator: u64) -> AeabiUlDivModResult {
     @setDebugSafety(this, is_test);
     if (comptime isArmArch()) {
-        @setGlobalLinkage(__aeabi_uldivmod, builtin.GlobalLinkage.LinkOnce);
+        @setGlobalLinkage(__aeabi_uldivmod, linkage);
         var result: AeabiUlDivModResult = undefined;
         result.quot = __udivmoddi4(numerator, denominator, &result.rem);
         return result;
@@ -94,7 +101,7 @@ export nakedcc fn __aeabi_uidivmod() {
     @setDebugSafety(this, false);
 
     if (comptime isArmArch()) {
-        @setGlobalLinkage(__aeabi_uidivmod, builtin.GlobalLinkage.LinkOnce);
+        @setGlobalLinkage(__aeabi_uidivmod, linkage);
         asm volatile (
             \\ push    { lr }
             \\ sub     sp, sp, #4
@@ -117,32 +124,31 @@ export nakedcc fn __aeabi_uidivmod() {
 export nakedcc fn _chkstk() align(4) {
     @setDebugSafety(this, false);
 
-    if (comptime builtin.os == builtin.Os.windows) {
-        if (comptime builtin.arch == builtin.Arch.i386) {
-            asm volatile (
-                \\         push   %%ecx
-                \\         cmp    $0x1000,%%eax
-                \\         lea    8(%%esp),%%ecx     // esp before calling this routine -> ecx
-                \\         jb     1f
-                \\ 2:
-                \\         sub    $0x1000,%%ecx
-                \\         test   %%ecx,(%%ecx)
-                \\         sub    $0x1000,%%eax
-                \\         cmp    $0x1000,%%eax
-                \\         ja     2b
-                \\ 1:
-                \\         sub    %%eax,%%ecx
-                \\         test   %%ecx,(%%ecx)
-                \\ 
-                \\         lea    4(%%esp),%%eax     // load pointer to the return address into eax
-                \\         mov    %%ecx,%%esp        // install the new top of stack pointer into esp
-                \\         mov    -4(%%eax),%%ecx    // restore ecx
-                \\         push   (%%eax)           // push return address onto the stack
-                \\         sub    %%esp,%%eax        // restore the original value in eax
-                \\         ret
-            );
-            unreachable;
-        }
+    if (win32_nocrt) {
+        @setGlobalLinkage(_chkstk, linkage);
+        asm volatile (
+            \\         push   %%ecx
+            \\         cmp    $0x1000,%%eax
+            \\         lea    8(%%esp),%%ecx     // esp before calling this routine -> ecx
+            \\         jb     1f
+            \\ 2:
+            \\         sub    $0x1000,%%ecx
+            \\         test   %%ecx,(%%ecx)
+            \\         sub    $0x1000,%%eax
+            \\         cmp    $0x1000,%%eax
+            \\         ja     2b
+            \\ 1:
+            \\         sub    %%eax,%%ecx
+            \\         test   %%ecx,(%%ecx)
+            \\ 
+            \\         lea    4(%%esp),%%eax     // load pointer to the return address into eax
+            \\         mov    %%ecx,%%esp        // install the new top of stack pointer into esp
+            \\         mov    -4(%%eax),%%ecx    // restore ecx
+            \\         push   (%%eax)           // push return address onto the stack
+            \\         sub    %%esp,%%eax        // restore the original value in eax
+            \\         ret
+        );
+        unreachable;
     }
 
     @setGlobalLinkage(_chkstk, builtin.GlobalLinkage.Internal);
@@ -151,32 +157,31 @@ export nakedcc fn _chkstk() align(4) {
 export nakedcc fn __chkstk() align(4) {
     @setDebugSafety(this, false);
 
-    if (comptime builtin.os == builtin.Os.windows) {
-        if (comptime builtin.arch == builtin.Arch.x86_64) {
-            asm volatile (
-                \\         push   %%rcx
-                \\         cmp    $0x1000,%%rax
-                \\         lea    16(%%rsp),%%rcx     // rsp before calling this routine -> rcx
-                \\         jb     1f
-                \\ 2:
-                \\         sub    $0x1000,%%rcx
-                \\         test   %%rcx,(%%rcx)
-                \\         sub    $0x1000,%%rax
-                \\         cmp    $0x1000,%%rax
-                \\         ja     2b
-                \\ 1:
-                \\         sub    %%rax,%%rcx
-                \\         test   %%rcx,(%%rcx)
-                \\ 
-                \\         lea    8(%%rsp),%%rax     // load pointer to the return address into rax
-                \\         mov    %%rcx,%%rsp        // install the new top of stack pointer into rsp
-                \\         mov    -8(%%rax),%%rcx    // restore rcx
-                \\         push   (%%rax)           // push return address onto the stack
-                \\         sub    %%rsp,%%rax        // restore the original value in rax
-                \\         ret
-            );
-            unreachable;
-        }
+    if (win64_nocrt) {
+        @setGlobalLinkage(__chkstk, linkage);
+        asm volatile (
+            \\         push   %%rcx
+            \\         cmp    $0x1000,%%rax
+            \\         lea    16(%%rsp),%%rcx     // rsp before calling this routine -> rcx
+            \\         jb     1f
+            \\ 2:
+            \\         sub    $0x1000,%%rcx
+            \\         test   %%rcx,(%%rcx)
+            \\         sub    $0x1000,%%rax
+            \\         cmp    $0x1000,%%rax
+            \\         ja     2b
+            \\ 1:
+            \\         sub    %%rax,%%rcx
+            \\         test   %%rcx,(%%rcx)
+            \\ 
+            \\         lea    8(%%rsp),%%rax     // load pointer to the return address into rax
+            \\         mov    %%rcx,%%rsp        // install the new top of stack pointer into rsp
+            \\         mov    -8(%%rax),%%rcx    // restore rcx
+            \\         push   (%%rax)           // push return address onto the stack
+            \\         sub    %%rsp,%%rax        // restore the original value in rax
+            \\         ret
+        );
+        unreachable;
     }
 
     @setGlobalLinkage(__chkstk, builtin.GlobalLinkage.Internal);
@@ -188,29 +193,28 @@ export nakedcc fn __chkstk() align(4) {
 export nakedcc fn __chkstk_ms() align(4) {
     @setDebugSafety(this, false);
 
-    if (comptime builtin.os == builtin.Os.windows) {
-        if (comptime builtin.arch == builtin.Arch.i386) {
-            asm volatile (
-                \\         push   %%ecx
-                \\         push   %%eax
-                \\         cmp    $0x1000,%%eax
-                \\         lea    12(%%esp),%%ecx
-                \\         jb     1f
-                \\ 2:
-                \\         sub    $0x1000,%%ecx
-                \\         test   %%ecx,(%%ecx)
-                \\         sub    $0x1000,%%eax
-                \\         cmp    $0x1000,%%eax
-                \\         ja     2b
-                \\ 1:
-                \\         sub    %%eax,%%ecx
-                \\         test   %%ecx,(%%ecx)
-                \\         pop    %%eax
-                \\         pop    %%ecx
-                \\         ret
-            );
-            unreachable;
-        }
+    if (win32_nocrt) {
+        @setGlobalLinkage(__chkstk, linkage);
+        asm volatile (
+            \\         push   %%ecx
+            \\         push   %%eax
+            \\         cmp    $0x1000,%%eax
+            \\         lea    12(%%esp),%%ecx
+            \\         jb     1f
+            \\ 2:
+            \\         sub    $0x1000,%%ecx
+            \\         test   %%ecx,(%%ecx)
+            \\         sub    $0x1000,%%eax
+            \\         cmp    $0x1000,%%eax
+            \\         ja     2b
+            \\ 1:
+            \\         sub    %%eax,%%ecx
+            \\         test   %%ecx,(%%ecx)
+            \\         pop    %%eax
+            \\         pop    %%ecx
+            \\         ret
+        );
+        unreachable;
     }
 
     @setGlobalLinkage(__chkstk_ms, builtin.GlobalLinkage.Internal);
@@ -219,29 +223,28 @@ export nakedcc fn __chkstk_ms() align(4) {
 export nakedcc fn ___chkstk_ms() align(4) {
     @setDebugSafety(this, false);
 
-    if (comptime builtin.os == builtin.Os.windows) {
-        if (comptime builtin.arch == builtin.Arch.x86_64) {
-            asm volatile (
-                \\        push   %%rcx
-                \\        push   %%rax
-                \\        cmp    $0x1000,%%rax
-                \\        lea    24(%%rsp),%%rcx
-                \\        jb     1f
-                \\2:
-                \\        sub    $0x1000,%%rcx
-                \\        test   %%rcx,(%%rcx)
-                \\        sub    $0x1000,%%rax
-                \\        cmp    $0x1000,%%rax
-                \\        ja     2b
-                \\1:
-                \\        sub    %%rax,%%rcx
-                \\        test   %%rcx,(%%rcx)
-                \\        pop    %%rax
-                \\        pop    %%rcx
-                \\        ret
-            );
-            unreachable;
-        }
+    if (win64_nocrt) {
+        @setGlobalLinkage(___chkstk_ms, linkage);
+        asm volatile (
+            \\        push   %%rcx
+            \\        push   %%rax
+            \\        cmp    $0x1000,%%rax
+            \\        lea    24(%%rsp),%%rcx
+            \\        jb     1f
+            \\2:
+            \\        sub    $0x1000,%%rcx
+            \\        test   %%rcx,(%%rcx)
+            \\        sub    $0x1000,%%rax
+            \\        cmp    $0x1000,%%rax
+            \\        ja     2b
+            \\1:
+            \\        sub    %%rax,%%rcx
+            \\        test   %%rcx,(%%rcx)
+            \\        pop    %%rax
+            \\        pop    %%rcx
+            \\        ret
+        );
+        unreachable;
     }
 
     @setGlobalLinkage(___chkstk_ms, builtin.GlobalLinkage.Internal);
@@ -249,7 +252,7 @@ export nakedcc fn ___chkstk_ms() align(4) {
 
 export fn __udivmodsi4(a: u32, b: u32, rem: &u32) -> u32 {
     @setDebugSafety(this, is_test);
-    @setGlobalLinkage(__udivmodsi4, builtin.GlobalLinkage.LinkOnce);
+    @setGlobalLinkage(__udivmodsi4, linkage);
 
     const d = __udivsi3(a, b);
     *rem = u32(i32(a) -% (i32(d) * i32(b)));
@@ -262,14 +265,14 @@ export fn __udivmodsi4(a: u32, b: u32, rem: &u32) -> u32 {
 
 export fn __aeabi_uidiv(n: u32, d: u32) -> u32 {
     @setDebugSafety(this, is_test);
-    @setGlobalLinkage(__aeabi_uidiv, builtin.GlobalLinkage.LinkOnce);
+    @setGlobalLinkage(__aeabi_uidiv, linkage);
 
     return __udivsi3(n, d);
 }
 
 export fn __udivsi3(n: u32, d: u32) -> u32 {
     @setDebugSafety(this, is_test);
-    @setGlobalLinkage(__udivsi3, builtin.GlobalLinkage.LinkOnce);
+    @setGlobalLinkage(__udivsi3, linkage);
 
     const n_uword_bits: c_uint = u32.bit_count;
     // special cases
std/special/compiler_rt/udivmoddi4.zig
@@ -1,9 +1,10 @@
 const udivmod = @import("udivmod.zig").udivmod;
 const builtin = @import("builtin");
+const linkage = if (builtin.is_test) builtin.GlobalLinkage.Internal else builtin.GlobalLinkage.LinkOnce;
 
 export fn __udivmoddi4(a: u64, b: u64, maybe_rem: ?&u64) -> u64 {
     @setDebugSafety(this, builtin.is_test);
-    @setGlobalLinkage(__udivmoddi4, builtin.GlobalLinkage.LinkOnce);
+    @setGlobalLinkage(__udivmoddi4, linkage);
     return udivmod(u64, a, b, maybe_rem);
 }
 
std/special/compiler_rt/udivmodti4.zig
@@ -1,9 +1,10 @@
 const udivmod = @import("udivmod.zig").udivmod;
 const builtin = @import("builtin");
+const linkage = if (builtin.is_test) builtin.GlobalLinkage.Internal else builtin.GlobalLinkage.LinkOnce;
 
 export fn __udivmodti4(a: u128, b: u128, maybe_rem: ?&u128) -> u128 {
     @setDebugSafety(this, builtin.is_test);
-    @setGlobalLinkage(__udivmodti4, builtin.GlobalLinkage.LinkOnce);
+    @setGlobalLinkage(__udivmodti4, linkage);
     return udivmod(u128, a, b, maybe_rem);
 }
 
std/special/compiler_rt/udivti3.zig
@@ -1,8 +1,9 @@
 const __udivmodti4 = @import("udivmodti4.zig").__udivmodti4;
 const builtin = @import("builtin");
+const linkage = if (builtin.is_test) builtin.GlobalLinkage.Internal else builtin.GlobalLinkage.LinkOnce;
 
 export fn __udivti3(a: u128, b: u128) -> u128 {
     @setDebugSafety(this, builtin.is_test);
-    @setGlobalLinkage(__udivti3, builtin.GlobalLinkage.LinkOnce);
+    @setGlobalLinkage(__udivti3, linkage);
     return __udivmodti4(a, b, null);
 }
std/special/compiler_rt/umodti3.zig
@@ -1,9 +1,10 @@
 const __udivmodti4 = @import("udivmodti4.zig").__udivmodti4;
 const builtin = @import("builtin");
+const linkage = if (builtin.is_test) builtin.GlobalLinkage.Internal else builtin.GlobalLinkage.LinkOnce;
 
 export fn __umodti3(a: u128, b: u128) -> u128 {
     @setDebugSafety(this, builtin.is_test);
-    @setGlobalLinkage(__umodti3, builtin.GlobalLinkage.LinkOnce);
+    @setGlobalLinkage(__umodti3, linkage);
     var r: u128 = undefined;
     _ = __udivmodti4(a, b, &r);
     return r;