ziglang / zig

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

Link script "incompatible section flags" issue #636

Closed skyfex closed 4 years ago

skyfex commented 6 years ago

When trying to build a zig file for the NRF51 microcontroller, Zig seems to have a problem with the linker script used.

Here is the example: https://github.com/skyfex/zig-nrf-demo

And this is the output when running build-zig.bat:

lld: error: incompatible section flags for .text
>>> .\zig-cache\test.o:(.text): 0x6 
>>> output section .text: 0x0 

I've tried to modify the link script. The issue seems to appear as soon as the .text section is defined in the link script. I haven't found a way to set the mentioned flags of the .text section to match the object file

Linking with GCC works (build-gcc.bat)

Tested with version 0.1.1.afbbdb2c on Windows

skyfex commented 6 years ago

I tried downloading LLVM 6 and use the standalone version of LLD, and it has the same issue. It's probably an issue with LLD

skyfex commented 6 years ago

After some more investigation, it seems that the issue only appears if the ".isr_vector" section (defined in gcc_startup_nrf51.S) is included in .text. If I change the assembly file to:

.section .isr_vector, "ax"

Then it works when linking with LLD version 6 standalone. If I use Zig to link, it crashes:

0x00007FF68FD974E4 (0x00007FF68FD9CF90 0x0000000000000000 0x0000000000000000 0x000001AC0CB14CE8)
0x00007FF68FD7F428 (0x0000000000000000 0x0000000000000000 0x0000000000000000 0x0000007B1D7FEE10)
0x00007FF68FD846B0 (0x0000000000000002 0x0000000000000000 0x0000007B1D7FF010 0x00007FFDAC05C97B)
0x00007FF68FD6EDEC (0x000001AC0CC14060 0x0000000000000030 0x000001AC0C49EF40 0x000001AC0CC14060)
0x00007FF68FCC36C1 (0x0000000000000000 0x0000000000000000 0x000001AC0BDF59F0 0x0000000000000000)
0x00007FF68FCCC675 (0x0000007B1D7FF4A0 0x0000000000000008 0x000001AC0BDF9B88 0x0000000000000000)
0x00007FF68FCCBF63 (0x0000000000000008 0x0000007B1D7FF5B9 0x0000007B1D7FF570 0x000000000000003B)
0x00007FF68F35B331 (0x00007FF6912E4194 0x00007FF6912E4194 0x0000007B1D7FEDB8 0x0000007B1D7FEEB0)
0x00007FF68F33AFAF (0x000001AC0A3E7544 0x000001AC0A410040 0x000001AC0A40EA20 0x000001AC0A410040)
0x00007FF68F341AB0 (0x0000000000000000 0x0000000000000000 0x00007FFDAC1369D8 0x0000000000000000)
0x00007FF6912C0B25 (0x0000000000000000 0x0000000000000000 0x0000000000000000 0x0000000000000000)
0x00007FFDAF7B2774 (0x0000000000000000 0x0000000000000000 0x0000000000000000 0x0000000000000000), BaseThreadInitThunk() + 0x14 bytes(s)
0x00007FFDAFA10D61 (0x0000000000000000 0x0000000000000000 0x0000000000000000 0x0000000000000000), RtlUserThreadStart() + 0x21 bytes(s) 

Edit: But there's some issue using the binary/hex generated by lld Edit 2: Nevermind, just some confusion. It runs on the microcontroller just fine with lld

andrewrk commented 6 years ago

The good news is if it works with LLD master branch (which will become LLD 6), then it's going to work in the next release of zig that depends on LLVM 6. Unfortunately we'll need a workaround in the meantime, such as manually linking with GCC or linking with LLD 6 standalone as you have done.

I tried using the llvm6 branch of zig like this:

andy@xps ~/D/zig-nrf-demo> ~/dev/zig/build-llvm-master-debug/zig build-exe --static --target-os freestanding --target-arch thumb --target-environ eabihf --assembly gcc_startup_nrf51.S --linker-script nrf51_xxaa.ld --verbose-link test.zig
zig: /home/andy/Downloads/llvm-project/llvm/lib/Target/ARM/Thumb1FrameLowering.cpp:645: bool llvm::Thumb1FrameLowering::emitPopSpecialFixUp(llvm::MachineBasicBlock&, bool) const: Assertion `PopReg && "Do not know how to get LR"' failed.
fish: “~/dev/zig/build-llvm-master-deb…” terminated by signal SIGABRT (Abort)

I got this assertion error. This is compiled with llvm/lld master branch as of Nov 29 2017 (sha1 ff1009fa3858374e7ca5035faa9c85217e957ebb). Since this comes from LLVMTargetMachineEmitToFile, I believe it's a bug in LLVM. I'll make a report.

zig: /home/andy/Downloads/llvm-project/llvm/lib/Target/ARM/Thumb1FrameLowering.cpp:645: bool llvm::Thumb1FrameLowering::emitPopSpecialFixUp(llvm::MachineBasicBlock&, bool) const: Assertion `PopReg && "Do not know how to get LR"' failed.

Program received signal SIGABRT, Aborted.
0x00007ffff6938274 in raise () from /nix/store/mjx71lmnlf4psm9942djjcd8b56hyk8b-glibc-2.26-75/lib/libc.so.6
(gdb) bt
#0  0x00007ffff6938274 in raise () from /nix/store/mjx71lmnlf4psm9942djjcd8b56hyk8b-glibc-2.26-75/lib/libc.so.6
#1  0x00007ffff6939675 in abort () from /nix/store/mjx71lmnlf4psm9942djjcd8b56hyk8b-glibc-2.26-75/lib/libc.so.6
#2  0x00007ffff6930cf7 in __assert_fail_base () from /nix/store/mjx71lmnlf4psm9942djjcd8b56hyk8b-glibc-2.26-75/lib/libc.so.6
#3  0x00007ffff6930da2 in __assert_fail () from /nix/store/mjx71lmnlf4psm9942djjcd8b56hyk8b-glibc-2.26-75/lib/libc.so.6
#4  0x0000000003fe7516 in llvm::Thumb1FrameLowering::emitPopSpecialFixUp (this=0xb5cf500, MBB=..., DoIt=true)
    at /home/andy/Downloads/llvm-project/llvm/lib/Target/ARM/Thumb1FrameLowering.cpp:645
#5  0x0000000003fe695a in llvm::Thumb1FrameLowering::emitEpilogue (this=0xb5cf500, MF=..., MBB=...)
    at /home/andy/Downloads/llvm-project/llvm/lib/Target/ARM/Thumb1FrameLowering.cpp:487
#6  0x0000000004ec01b0 in (anonymous namespace)::PEI::insertPrologEpilogCode (this=0xad821e0, Fn=...)
    at /home/andy/Downloads/llvm-project/llvm/lib/CodeGen/PrologEpilogInserter.cpp:973
#7  0x0000000004ebcfbe in (anonymous namespace)::PEI::runOnMachineFunction (this=0xad821e0, Fn=...)
    at /home/andy/Downloads/llvm-project/llvm/lib/CodeGen/PrologEpilogInserter.cpp:210
#8  0x0000000004dd5f84 in llvm::MachineFunctionPass::runOnFunction (this=0xad821e0, F=...)
    at /home/andy/Downloads/llvm-project/llvm/lib/CodeGen/MachineFunctionPass.cpp:62
#9  0x0000000005e7ce9d in llvm::FPPassManager::runOnFunction (this=0xad99bf0, F=...)
    at /home/andy/Downloads/llvm-project/llvm/lib/IR/LegacyPassManager.cpp:1514
#10 0x0000000005e7d014 in llvm::FPPassManager::runOnModule (this=0xad99bf0, M=...)
    at /home/andy/Downloads/llvm-project/llvm/lib/IR/LegacyPassManager.cpp:1535
#11 0x0000000005e7d361 in (anonymous namespace)::MPPassManager::runOnModule (this=0xa944e80, M=...)
    at /home/andy/Downloads/llvm-project/llvm/lib/IR/LegacyPassManager.cpp:1591
#12 0x0000000005e7da15 in llvm::legacy::PassManagerImpl::run (this=0xb5a7640, M=...)
    at /home/andy/Downloads/llvm-project/llvm/lib/IR/LegacyPassManager.cpp:1694
#13 0x0000000005e7dc0d in llvm::legacy::PassManager::run (this=0x7fffffffcc00, M=...)
    at /home/andy/Downloads/llvm-project/llvm/lib/IR/LegacyPassManager.cpp:1725
#14 0x0000000001bb841d in ZigLLVMTargetMachineEmitToFile (targ_machine_ref=0xa98e5c0, module_ref=0xa98d4f0, 
    filename=0xb503cd0 "./zig-cache/compiler_rt.o", output_type=ZigLLVM_EmitBinary, error_message=0x7fffffffcef8, is_debug=true)
    at /home/andy/dev/zig/src/zig_llvm.cpp:165
#15 0x0000000001b3fa01 in do_code_gen (g=0xace38b0) at /home/andy/dev/zig/src/codegen.cpp:4684
#16 0x0000000001b43f63 in codegen_build (g=0xace38b0) at /home/andy/dev/zig/src/codegen.cpp:5841
#17 0x0000000001b89ce3 in build_o_raw (parent_gen=0xa8c1010, oname=0x606a7a4 "compiler_rt", full_path=0xad35590) at /home/andy/dev/zig/src/link.cpp:65
#18 0x0000000001b89e52 in build_compiler_rt (parent_gen=0xa8c1010) at /home/andy/dev/zig/src/link.cpp:91
#19 0x0000000001b8a824 in construct_linker_job_elf (lj=0x7fffffffd2b0) at /home/andy/dev/zig/src/link.cpp:284
#20 0x0000000001b8c41b in construct_linker_job (lj=0x7fffffffd2b0) at /home/andy/dev/zig/src/link.cpp:854
---Type <return> to continue, or q <return> to quit---
#21 0x0000000001b8c780 in codegen_link (g=0xa8c1010, out_file=0x0) at /home/andy/dev/zig/src/link.cpp:919
#22 0x0000000001b90309 in main (argc=15, argv=0x7fffffffd8d8) at /home/andy/dev/zig/src/main.cpp:840
andrewrk commented 6 years ago

I reported the LLVM bug here: https://bugs.llvm.org/show_bug.cgi?id=35481

Unfortunately I was unable to reproduce the issue with clang -c on the IR directly.

andrewrk commented 6 years ago

I think this has something to do with armv6kz ("warning: overriding the module target triple with armv6kz-unknown-unknown-eabihf [-Woverride-module]") which strangely is not in include/llvm/ADT/Triple.h (which is why it's not in zig targets) but it is in lib/Target/ARM/ARMGenSubtargetInfo.inc. Maybe if we were able to specify armv6kz target, this would work.

andrewrk commented 6 years ago

I asked about this on the LLVM-dev mailing list: http://lists.llvm.org/pipermail/llvm-dev/2017-November/119405.html

skyfex commented 6 years ago

Where does armv6kz come into this? That's an armv6 architecture with trustzone, which is not the intended target. Weird

andrewrk commented 6 years ago

when I try to compile the llvm IR that is causing the assertion error, manually, with clang, it gives the warning that it has decided to compile for armv6kz instead of thumb. Maybe that's another bug.

andrewrk commented 6 years ago

As a workaround we can compile with -fno-frame-pointer for thumb. We'll probably want to implement #398 to keep stack traces meaningful when we do this.

andrewrk commented 5 years ago

I pinged upstream

daurnimator commented 5 years ago

This appears to have been fixed with https://reviews.llvm.org/rGd17dabca31dc744ddeaf14610c948d5c8f4e0326 ?

andrewrk commented 4 years ago

Looks like this was actually solved way back with LLVM 7.