4

I'm writing for education purposes an embedded Rust program for ARM. Since it is a bare metal system, I use the core library only. The library's manual page claims that corelib depends on nothing, but memcpy, memcmp, and memset, and the unwind functions (see https://doc.rust-lang.org/core/index.html). However, especially if I use atomic types, I continue to get linker errors because of missing symbols, such as __sync_val_compare_and_swap_4 or __sync_lock_test_and_set_4 that indicates a missing compiler-rt library. I understand, that compiler-rt should on top of corelib. That looks like a circular dependency, what shouldn't be. In addition, I understand that compiler-rt in turn depends on an OS.

  1. What part of my understanding is not correct?
  2. How can I get a real independent corelib, or what parts of it are really independent? I know that I could re-implement the missing functions, but they seem to be quite a lot. Also, I'm aware of the compiler-builtins crate, but it still leaves me with unresolved symbols.
Matthias
  • 8,018
  • 2
  • 27
  • 53
  • `__sync_val_compare_and_swap_4` is *not* provided by compiler-rt. Does linking to `libgcc_s` work? (ref http://stackoverflow.com/a/9329139/224671) – kennytm May 18 '17 at 02:51
  • @kennytm: Not yet, I'm not sure whether I even have it for the target platform, but I'll give it a try. However, it is kind of strange that llvm should need libgcc_s. – Matthias May 18 '17 at 05:48
  • The linked question uses GCC 4, I don't know what is the LLVM equivalent :) – kennytm May 18 '17 at 06:00

1 Answers1

3

In the meantime, I've found a solution. I share it in the hope it will be useful for somebody else.

As kennytm correctly mentioned, the symbols do not belong to compiler_rt. In addition, the symbols are only by chance the same as in the functions of the libgcc, c.f. here. The calls will be emitted by llvm in case the CPU does not support atomic commands such as cmpxchg.

My processor is an ARMv6 and does support atomic commands. However, I failed to tell Rust/llvm about: the JSON file with the target description looked like that:

{  "llvm-target": "arm-none-eabihf",  
   "target-endian": "little",
   "target-pointer-width": "32", 
   "os": "none",
   "env": "eabihf", 
   "vendor": "unknown",
   "arch": "arm", 
   "linker": "arm-none-eabi-gcc",
   "linker-flavor": "gnu",
   "data-layout": "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64",
   "executables": true,
   "relocation-model": "static",
   "no-compiler-rt": true
}

In this way, my CPU could also have been an ARMv5 what do not support atomic commands. By adding a field "cpu": "arm1176jzf-s" I could solve the linker error.

Matthias
  • 8,018
  • 2
  • 27
  • 53