ziglang / zig

General-purpose programming language and toolchain for maintaining robust, optimal, and reusable software.
https://ziglang.org
MIT License
34.18k stars 2.5k forks source link

-mcpu cortex_m0 atomics.zig undefined symbols #4959

Open markfirmware opened 4 years ago

markfirmware commented 4 years ago

zig version 0.5.0+701c03d08

lld: error: undefined symbol: __sync_lock_test_and_set_4
>>> referenced by atomics.zig:19 (/root/zig/lib/zig/std/special/compiler_rt/atomics.zig:19)
lld: error: undefined symbol: __sync_lock_test_and_set_1
>>> referenced by atomics.zig:161 (/root/zig/lib/zig/std/special/compiler_rt/atomics.zig:161)
lld: error: undefined symbol: __sync_lock_test_and_set_2
>>> referenced by atomics.zig:161 (/root/zig/lib/zig/std/special/compiler_rt/atomics.zig:161)
lld: error: undefined symbol: __sync_val_compare_and_swap_1
>>> referenced by atomics.zig:188 (/root/zig/lib/zig/std/special/compiler_rt/atomics.zig:188)
lld: error: undefined symbol: __sync_val_compare_and_swap_2
>>> referenced by atomics.zig:188 (/root/zig/lib/zig/std/special/compiler_rt/atomics.zig:188)
lld: error: undefined symbol: __sync_val_compare_and_swap_4
>>> referenced by atomics.zig:188 (/root/zig/lib/zig/std/special/compiler_rt/atomics.zig:188)
lld: error: undefined symbol: __sync_fetch_and_add_1
>>> referenced by atomics.zig:226 (/root/zig/lib/zig/std/special/compiler_rt/atomics.zig:226)
lld: error: undefined symbol: __sync_fetch_and_add_2
>>> referenced by atomics.zig:226 (/root/zig/lib/zig/std/special/compiler_rt/atomics.zig:226)
lld: error: undefined symbol: __sync_fetch_and_add_4
lld: error: undefined symbol: __sync_fetch_and_sub_1
>>> referenced by atomics.zig:226 (/root/zig/lib/zig/std/special/compiler_rt/atomics.zig:226)
lld: error: undefined symbol: __sync_fetch_and_sub_2
>>> referenced by atomics.zig:226 (/root/zig/lib/zig/std/special/compiler_rt/atomics.zig:226)
lld: error: undefined symbol: __sync_fetch_and_sub_4
>>> referenced by atomics.zig:226 (/root/zig/lib/zig/std/special/compiler_rt/atomics.zig:226)
lld: error: undefined symbol: __sync_fetch_and_and_1
>>> referenced by atomics.zig:226 (/root/zig/lib/zig/std/special/compiler_rt/atomics.zig:226)
lld: error: undefined symbol: __sync_fetch_and_and_2
>>> referenced by atomics.zig:226 (/root/zig/lib/zig/std/special/compiler_rt/atomics.zig:226)
lld: error: undefined symbol: __sync_fetch_and_and_4
>>> referenced by atomics.zig:226 (/root/zig/lib/zig/std/special/compiler_rt/atomics.zig:226)
lld: error: undefined symbol: __sync_fetch_and_or_1
>>> referenced by atomics.zig:226 (/root/zig/lib/zig/std/special/compiler_rt/atomics.zig:226)
lld: error: undefined symbol: __sync_fetch_and_or_2
>>> referenced by atomics.zig:226 (/root/zig/lib/zig/std/special/compiler_rt/atomics.zig:226)
lld: error: undefined symbol: __sync_fetch_and_or_4
>>> referenced by atomics.zig:226 (/root/zig/lib/zig/std/special/compiler_rt/atomics.zig:226)
lld: error: undefined symbol: __sync_fetch_and_xor_1
>>> referenced by atomics.zig:226 (/root/zig/lib/zig/std/special/compiler_rt/atomics.zig:226)
lld: error: undefined symbol: __sync_fetch_and_xor_2
>>> referenced by atomics.zig:226 (/root/zig/lib/zig/std/special/compiler_rt/atomics.zig:226)
lld: error: undefined symbol: __sync_fetch_and_xor_4
>>> referenced by atomics.zig:226 (/root/zig/lib/zig/std/special/compiler_rt/atomics.zig:226)
lld: error: undefined symbol: __sync_fetch_and_nand_1
>>> referenced by atomics.zig:226 (/root/zig/lib/zig/std/special/compiler_rt/atomics.zig:226)
lld: error: undefined symbol: __sync_fetch_and_nand_2
>>> referenced by atomics.zig:226 (/root/zig/lib/zig/std/special/compiler_rt/atomics.zig:226)
lld: error: undefined symbol: __sync_fetch_and_nand_4
>>> referenced by atomics.zig:226 (/root/zig/lib/zig/std/special/compiler_rt/atomics.zig:226)
daurnimator commented 4 years ago

I was looking at this yesterday! Docs are at https://llvm.org/docs/Atomics.html#libcalls-sync

Given that you're on an m0 (single core) then I suspect we can just lower them into normal operations?

LemonBoy commented 4 years ago

You have to provide those functions yourself, to guarantee the atomicity on such a platform you'd have to turn off the interrupts, perform the load/store and then turn them back on.

markfirmware commented 4 years ago

What might need atomicity? I think I’m only using the formatting functions from the standard library.

LemonBoy commented 4 years ago

What might need atomicity?

Well the compiler-rt has to export the __atomic* functions in case a program needs them.

In your case (and in general for every other v6m user) the correct solution is to modify largest_atomic_size so that it returns 0 if the v6m flag is set.

markfirmware commented 4 years ago

Isn’t an aligned word naturally atomic?

LemonBoy commented 4 years ago

Isn’t an aligned word naturally atomic?

Yes, but we have to take care of unaligned words too and non-word-sized objects too and operations other than a simple load/store...

Do you have some sample code that triggers this problem? I have a patch ready for this but I cannot trigger the error you're having.

markfirmware commented 4 years ago

The linker script is incomplete and will probably produce unrelated errors after this is resolved.

zig build-exe -target thumb-freestanding-none -mcpu cortex_m0 --linker-script linker.ld main.zig

export fn main() void {
    var buf: [1]u8 = undefined;
    _ = @import("std").fmt.bufPrint(&buf, "", .{}) catch unreachable;
}

SECTIONS {
    .flash : {
        KEEP(*(.text.*))
    }
}
LemonBoy commented 4 years ago

I couldn't reproduce that error but I've put #4962 up for review, that should reduce the linker errors to just one item __sync_lock_test_and_set_4 that you should provide.

The code should do something like this:

export fn __sync_lock_test_and_set_4(ptr: *u32, val: u32) callconv(.C) u32 {
    // disable the IRQ
    const old_val = ptr.*;
    ptr.* = val;
    // enable the IRQ
    return old_val;
}

This is needed because the v6m arch doesn't support any atomic RMW operation nor CMPXCHG and we need at least this one to provide a basic spinlock implementation to implement the other missing builtins.

markfirmware commented 4 years ago

Thanks. I will try that.

markfirmware commented 4 years ago

Ok, the error is resolved. Let me ponder this before I close the issue.

frmdstryr commented 2 years ago

Also hit this with the cm0plus because it was using atomics when updating the system time.

Would it be possible/make sense for the compiler to emit a note/warning when the cpu doesn't support using the @atomic builtins?

matu3ba commented 2 years ago

Would it be possible/make sense for the compiler to emit a note/warning when the cpu doesn't support using the @atomic builtins?

Zig policy is to not emit warnings, if not necessary ie for things like missing linker flags.

If you want to fix this, you can start with https://github.com/ziglang/zig/pull/10756