Are the symbols starting with __aarch64_ generated by rust?

When I compile the following code into an obj file,

use std::{sync::{Arc, atomic::{AtomicI64, Ordering}}, thread};

pub fn rust_atomic_base001() -> i64 {
    let count = Arc::new(AtomicI64::new(0));
    let mut thread_list = Vec::with_capacity(100);
    for _ in 0..100 {
        let count_clone = count.clone();
        let handle = thread::spawn(move || {
            count_clone.fetch_add(1, Ordering::Relaxed);
        });
        thread_list.push(handle);
    }

    for thread in thread_list {
        thread.join().unwrap();
    }

    let res = count.load(Ordering::Relaxed);
    res
}

I find that there are some symbols in the obj that start with _aarch64.

readelf -sW ../build/patch_obj/patchfunc.o | grep __aarch64_
   170: 0000000000000000     0 NOTYPE  GLOBAL DEFAULT  UND __aarch64_ldadd8_rel
   178: 0000000000000000     0 NOTYPE  GLOBAL DEFAULT  UND __aarch64_ldadd8_relax
   197: 0000000000000000     0 NOTYPE  GLOBAL DEFAULT  UND __aarch64_cas8_acq

I have a few questions:
1、These symbols don't use the rust-specific mangle names(legacy or V0). Are these symbols generated by rust?
2、What do these symbols do? ,
3、Where does the linker finding the definitions of these symbols?

They look like atomic operations. I would expect that these are something that LLVM is generating. Ultimately, when you make a Rust atomic operation, this turns into an LLVM intrinsic and LLVM takes care of generating the appropriate machine code.

These symbols are found in the libcompiler_builtins-76fca0633b54e12b.rlib file in the rust installation path. Is this where the linker finds the symbols?

/.rustup/toolchains/nightly-aarch64-unknown-linux-gnu/lib/rustlib/aarch64-unknown-linux-gnu/lib $  readelf -sW libcompiler_builtins-76fca0633b54e12b.rlib | grep __aarch64_
   .........

    14: 0000000000000000    44 FUNC    GLOBAL HIDDEN     1 __aarch64_ldset4_acq_rel
    13: 0000000000000000     0 NOTYPE  GLOBAL HIDDEN   UND __aarch64_have_lse_atomics
    14: 0000000000000000    44 FUNC    GLOBAL HIDDEN     1 __aarch64_ldset8_relax
    13: 0000000000000000     0 NOTYPE  GLOBAL HIDDEN   UND __aarch64_have_lse_atomics
    14: 0000000000000000    44 FUNC    GLOBAL HIDDEN     1 __aarch64_ldset8_acq
    13: 0000000000000000     0 NOTYPE  GLOBAL HIDDEN   UND __aarch64_have_lse_atomics
    14: 0000000000000000    44 FUNC    GLOBAL HIDDEN     1 __aarch64_ldset8_rel
    13: 0000000000000000     0 NOTYPE  GLOBAL HIDDEN   UND __aarch64_have_lse_atomics
    14: 0000000000000000    44 FUNC    GLOBAL HIDDEN     1 __aarch64_ldset8_acq_rel
    35: 0000000000000000     8 OBJECT  GLOBAL HIDDEN    14 __aarch64_cpu_features
    36: 0000000000000000     1 OBJECT  GLOBAL HIDDEN    15 __aarch64_have_lse_atomics
.......

That is one of the possible places they can be found. libgcc and compiler-rt from the GCC and LLVM projects respectively implement them too. They are all equivalent in behavior though, so it normally doesn't matter which one actually defines them.

Thanks for the reply, but I searched for libgcc_s.so.1 on my arm64 machine and found that it doesn't have these symbols.
image

It is possible that your libgcc version is too old. In that case the version in compiler-builtins will be used.

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.