Rust: Support Windows ARM

Created on 24 Jul 2018  路  8Comments  路  Source: rust-lang/rust

Windows does exist on ARM devices, so it makes sense for Rust to try to support it.

C-feature-request O-ARM O-windows

Most helpful comment

Got rust binaries running on Windows/ARM by changing LLVM target from armv7 to thumbv7a.

All 8 comments

We want this too. Is anyone else working on this? I've been working on it for about a week and am stuck on the following error.

    LLVM ERROR: Cannot select: t10: ch = cleanupret t9
    In function: _ZN4core3str21_$LT$impl$u20$str$GT$4trim17h079b395f396c992aE
    error: Could not compile `core`.

    Caused by:
      process didn't exit successfully: `D:\workspace\rust\build\bootstrap/debug/rustc --crate-name core libcore\lib.rs --error-format json --crate-type lib --emit=dep-info,link -C opt-level=2 -C metadata=ee59c66784deb9b7 -C extra-filename=-ee59c66784deb9b7 --out-dir D:\workspace\rust\build\x86_64-pc-windows-msvc\stage2-std\armv7-pc-windows-msvc\release\deps --target armv7-pc-windows-msvc -L dependency=D:\workspace\rust\build\x86_64-pc-windows-msvc\stage2-std\armv7-pc-windows-msvc\release\deps -L dependency=D:\workspace\rust\build\x86_64-pc-windows-msvc\stage2-std\release\deps` (exit code: 1)
    command did not execute successfully: "D:\\workspace\\rust\\build\\x86_64-pc-windows-msvc\\stage0/bin\\cargo.exe" "build" "--target" "armv7-pc-windows-msvc" "-j" "12" "-v" "--release" "--features" "panic-unwind backtrace" "--manifest-path" "D:\\workspace\\rust\\src/libstd/Cargo.toml" "--message-format" "json"
    expected success, got: exit code: 101
    thread 'main' panicked at 'cargo must succeed', bootstrap\compile.rs:1091:9

I have not been able to find much information on cleanupret, but I think this error may have to do something with exception handling. Any suggestions on how to debug this issue further would be appreciated.

After enabling debugging options in config.toml, I'm seeing a different error:

LLVM ERROR: target does not implement codeview register mapping
error: Could not compile `core`.

I captured a dump of the failing call stack. Surprisingly, the rust code has source line information, and windbg can pull up the source code. But the LLVM code, which is C++, does not have source information. It looks like the llvm code is compiled directly into the rustc_codegen_llvm_llvm module, which already has private PDB symbols loaded.

Any ideas why there's no debug information for the llvm code? Also, any information on the actual LLVM error would be appreciated!

0:004> k
  *** Stack trace for last set context - .thread/.cxr resets it
 # Child-SP          RetAddr           Call Site
00 00000045`b73fd210 00007ffc`91dc7f61 rustc_codegen_llvm_llvm!llvm::report_fatal_error+0xfb
01 00000045`b73fd300 00007ffc`928e3019 rustc_codegen_llvm_llvm!llvm::report_fatal_error+0x21
02 00000045`b73fd350 00007ffc`930a33ec rustc_codegen_llvm_llvm!llvm::MCRegisterInfo::getCodeViewRegNum+0x149
03 00000045`b73fd390 00007ffc`930a46ea rustc_codegen_llvm_llvm!llvm::CodeViewDebug::calculateRanges+0x1dc
04 00000045`b73fd4a0 00007ffc`930a9ade rustc_codegen_llvm_llvm!llvm::CodeViewDebug::collectVariableInfo+0x2da
05 00000045`b73fd5b0 00007ffc`934f0344 rustc_codegen_llvm_llvm!llvm::CodeViewDebug::endFunctionImpl+0xbe
06 00000045`b73fd630 00007ffc`928f6aeb rustc_codegen_llvm_llvm!llvm::DebugHandlerBase::endFunction+0x34
07 00000045`b73fd660 00007ffc`91f8e186 rustc_codegen_llvm_llvm!llvm::AsmPrinter::EmitFunctionBody+0x103b
08 00000045`b73fdd10 00007ffc`9289f075 rustc_codegen_llvm_llvm!llvm::ARMAsmPrinter::runOnMachineFunction+0x3d6
09 00000045`b73fde90 00007ffc`91ec941d rustc_codegen_llvm_llvm!llvm::MachineFunctionPass::runOnFunction+0x1e5
0a 00000045`b73fdf30 00007ffc`91ec959f rustc_codegen_llvm_llvm!llvm::FPPassManager::runOnFunction+0x1bd
0b 00000045`b73fe000 00007ffc`91ec985e rustc_codegen_llvm_llvm!llvm::FPPassManager::runOnModule+0x5f
0c 00000045`b73fe030 00007ffc`91ec8d11 rustc_codegen_llvm_llvm!llvm::FPPassManager::runOnModule+0x31e
0d 00000045`b73fe100 00007ffc`91db9410 rustc_codegen_llvm_llvm!llvm::legacy::PassManagerImpl::run+0x181
0e 00000045`b73fe150 00007ffc`91c41071 rustc_codegen_llvm_llvm!LLVMRustWriteOutputFile+0x140
0f 00000045`b73fe280 00007ffc`91c462cb rustc_codegen_llvm_llvm!rustc_codegen_llvm::back::write::write_output_file+0x71 [d:\workspace\rust\src\librustc_codegen_llvm\back\write.rs @ 106] 
10 (Inline Function) --------`-------- rustc_codegen_llvm_llvm!rustc_codegen_llvm::back::write::codegen::{{closure}}::{{closure}}+0x40 [d:\workspace\rust\src\librustc_codegen_llvm\back\write.rs @ 776] 
11 (Inline Function) --------`-------- rustc_codegen_llvm_llvm!rustc_codegen_llvm::back::write::codegen::with_codegen+0x70 [d:\workspace\rust\src\librustc_codegen_llvm\back\write.rs @ 653] 
12 00000045`b73fe380 00007ffc`91c44397 rustc_codegen_llvm_llvm!rustc_codegen_llvm::back::write::codegen::{{closure}}+0x33b [d:\workspace\rust\src\librustc_codegen_llvm\back\write.rs @ 775] 
13 00000045`b73fe6a0 00007ffc`91c4d051 rustc_codegen_llvm_llvm!rustc_codegen_llvm::back::write::codegen+0x1227 [d:\workspace\rust\src\librustc_codegen_llvm\back\write.rs @ 709] 
14 00000045`b73fe9f0 00007ffc`91ba8ee0 rustc_codegen_llvm_llvm!rustc_codegen_llvm::back::write::execute_work_item+0x2381 [d:\workspace\rust\src\librustc_codegen_llvm\back\write.rs @ 1373] 
15 (Inline Function) --------`-------- rustc_codegen_llvm_llvm!rustc_codegen_llvm::back::write::spawn_work::{{closure}}+0x34d [d:\workspace\rust\src\librustc_codegen_llvm\back\write.rs @ 2018] 
16 00000045`b73ff180 00007ffc`91baa449 rustc_codegen_llvm_llvm!std::sys_common::backtrace::__rust_begin_short_backtrace<closure,()>+0x380 [d:\workspace\rust\src\libstd\sys_common\backtrace.rs @ 136] 
*** WARNING: Unable to verify checksum for std-6a3ca8e43d641166.dll
17 (Inline Function) --------`-------- rustc_codegen_llvm_llvm!std::thread::{{impl}}::spawn::{{closure}}::{{closure}}+0x19 [d:\workspace\rust\src\libstd\thread\mod.rs @ 409] 
18 (Inline Function) --------`-------- rustc_codegen_llvm_llvm!std::panic::{{impl}}::call_once+0x19 [d:\workspace\rust\src\libstd\panic.rs @ 308] 
19 00000045`b73ff5d0 00007ffc`b576d2c2 rustc_codegen_llvm_llvm!std::panicking::try::do_call<std::panic::AssertUnwindSafe<closure>,()>+0x29 [d:\workspace\rust\src\libstd\panicking.rs @ 312] 
1a 00000045`b73ff7c0 00007ffc`91bd99fa std_6a3ca8e43d641166!panic_unwind::__rust_maybe_catch_panic+0x22 [d:\workspace\rust\src\libpanic_unwind\lib.rs @ 105] 
1b (Inline Function) --------`-------- rustc_codegen_llvm_llvm!std::panic::catch_unwind+0x45 [d:\workspace\rust\src\libstd\panic.rs @ 392] 
1c (Inline Function) --------`-------- rustc_codegen_llvm_llvm!std::thread::{{impl}}::spawn::{{closure}}+0x9c [d:\workspace\rust\src\libstd\thread\mod.rs @ 408] 
1d 00000045`b73ff820 00007ffc`b576a9a5 rustc_codegen_llvm_llvm!alloc::boxed::{{impl}}::call_box<(),closure>+0xea [d:\workspace\rust\src\liballoc\boxed.rs @ 640] 
1e (Inline Function) --------`-------- std_6a3ca8e43d641166!alloc::boxed::{{impl}}::call_once+0x7 [d:\workspace\rust\src\liballoc\boxed.rs @ 650] 
1f (Inline Function) --------`-------- std_6a3ca8e43d641166!std::sys_common::thread::start_thread+0x5f [d:\workspace\rust\src\libstd\sys_common\thread.rs @ 24] 
20 00000045`b73ffc30 00007ffc`e797fea4 std_6a3ca8e43d641166!std::sys::windows::thread::{{impl}}::new::thread_start+0x75 [d:\workspace\rust\src\libstd\sys\windows\thread.rs @ 55] 
21 00000045`b73ffc80 00007ffc`e9dd54f1 kernel32!BaseThreadInitThunk+0x14 [base\win32\client\thread.c @ 64] 
22 00000045`b73ffcb0 00000000`00000000 ntdll!RtlUserThreadStart+0x21 [minkernel\ntdll\rtlstrt.c @ 1163] 

I think it has to do with lack of Clang/LLVM support for EH exceptions on ARM. I wrote a simple test that throws an exception and tried to compile it with clang++ for arm-pc-windows-msvc. It fails with the following message.

#include <stdio.h>
#include <stdexcept>

int main()
{
        printf("Hello ...\n");
        try {
                throw std::runtime_error("this is an exception message");
        } catch (const std::exception& ex) {
                fprintf(stderr, "Error: %s\n", ex.what());
        }

        printf("World\n");
        return 0;
}

Output:

clang++ --target=arm-pc-windows-msvc -D_ARM_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE -v -o test.exe clang_except_test.cpp
clang version 6.0.0 (tags/RELEASE_600/final)
Target: arm-pc-windows-msvc
Thread model: posix
InstalledDir: C:\Program Files\LLVM\bin
 "C:\\Program Files\\LLVM\\bin\\clang++.exe" -cc1 -triple thumbv7-pc-windows-msvc19.11.25547 -emit-obj -mrelax-all -mincremental-linker-compatible -disable-free -disable-llvm-verifier -discard-value-names -main-file-name clang_except_test.cpp -mrelocation-model static -mthread-model posix -mdisable-fp-elim -fmath-errno -masm-verbose -mconstructor-aliases -target-cpu cortex-a9 -target-feature +strict-align -target-abi aapcs -mfloat-abi hard -fallow-half-arguments-and-returns -dwarf-column-info -debugger-tuning=gdb -v -resource-dir "C:\\Program Files\\LLVM\\lib\\clang\\6.0.0" -D _ARM_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE -internal-isystem "C:\\Program Files\\LLVM\\lib\\clang\\6.0.0\\include" -internal-isystem "C:\\Program Files (x86)\\Microsoft Visual Studio\\2017\\Enterprise\\VC\\Tools\\MSVC\\14.11.25503\\include" -internal-isystem "C:\\Program Files (x86)\\Windows Kits\\10\\Include\\10.0.17134.0\\ucrt" -internal-isystem "C:\\Program Files (x86)\\Windows Kits\\10\\include\\10.0.17134.0\\shared" -internal-isystem "C:\\Program Files (x86)\\Windows Kits\\10\\include\\10.0.17134.0\\um" -internal-isystem "C:\\Program Files (x86)\\Windows Kits\\10\\include\\10.0.17134.0\\winrt" -fdeprecated-macro -fdebug-compilation-dir "d:\\work\\rust" -ferror-limit 19 -fmessage-length 80 -backend-option -arm-restrict-it -fno-use-cxa-atexit -fms-extensions -fms-compatibility -fms-compatibility-version=19.11.25547 -std=c++14 -fdelayed-template-parsing -fobjc-runtime=gcc -fcxx-exceptions -fexceptions -fseh-exceptions -fdiagnostics-show-option -fcolor-diagnostics -o "C:\\Users\\jordanrh\\AppData\\Local\\Temp\\clang_except_test-8cb11c.o" -x c++ clang_except_test.cpp
clang -cc1 version 6.0.0 based upon LLVM 6.0.0 default target x86_64-pc-windows-msvc
#include "..." search starts here:
#include <...> search starts here:
 C:\Program Files\LLVM\lib\clang\6.0.0\include
 C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\VC\Tools\MSVC\14.11.25503\include
 C:\Program Files (x86)\Windows Kits\10\Include\10.0.17134.0\ucrt
 C:\Program Files (x86)\Windows Kits\10\include\10.0.17134.0\shared
 C:\Program Files (x86)\Windows Kits\10\include\10.0.17134.0\um
 C:\Program Files (x86)\Windows Kits\10\include\10.0.17134.0\winrt
End of search list.
fatal error: error in backend: Funclet EH is not implemented for this target
clang++.exe: error: clang frontend command failed with exit code 70 (use -v to see invocation)
clang version 6.0.0 (tags/RELEASE_600/final)
Target: arm-pc-windows-msvc
Thread model: posix
InstalledDir: C:\Program Files\LLVM\bin
clang++.exe: note: diagnostic msg: PLEASE submit a bug report to http://llvm.org/bugs/ and include the crash backtrace, preprocessed source, and associated run script.
clang++.exe: note: diagnostic msg:
********************

PLEASE ATTACH THE FOLLOWING FILES TO THE BUG REPORT:
Preprocessed source(s) and associated run script(s) are located at:
clang++.exe: note: diagnostic msg: C:\Users\jordanrh\AppData\Local\Temp\clang_except_test-c25954.cpp
clang++.exe: note: diagnostic msg: C:\Users\jordanrh\AppData\Local\Temp\clang_except_test-c25954.sh
clang++.exe: note: diagnostic msg:

********************
make: *** [Makefile:4: test.exe] Error 70

Can we try with panic=abort?

Yep, I got past it by setting panic_strategy=PanicStrategy::Abort in the target spec. After working through a number of other issues I'm now able to generate executables. Current issue is that callback entries in the TLS Directory do not have the thumb bit set, which causes an illegal instruction exception when the loader tries to run the TLS callbacks at load time.

Got rust binaries running on Windows/ARM by changing LLVM target from armv7 to thumbv7a.

thumbv7a-pc-windows-msvc target is in tree. Open more specific issues for problems. Thanks!

FYI the LLVM ERROR: target does not implement codeview register mapping error was because LLVM didn't completely implement the Windows debug format (codeview) for the 32-bit arm targets. So building without debuginfo would sidestep that error.

But I also submitted the fix for proper 32-bit ARM CodeView support upstream: https://reviews.llvm.org/D89622

Sadly the exception handling needed for panic=unwind is still unimplemented.

Was this page helpful?
0 / 5 - 0 ratings