首页 > 解决方案 > clang ASAN 交叉编译忽略 --whole-archive 的 sysroot

问题描述

--sysroot我使用 debian x86_64 进行交叉编译,并通过使用指向目标架构的完整文件系统(IE/cache/arm64/cache/armel)来定位 aarch64 和 armv6l 。我qemu-debootstrap用来创建/cache/arm64/cache/armeldebian 系统,在这些系统上包含必要的 *-dev 包,然后通过简单地将整个缓存系统声明为 sysroot ( --sysroot=/cache/arm64) 来为编译器包含这些库。这适用于gcc-8,但我在clang-7使用 address-sanitizer 进行交叉编译时遇到问题。

例如,对于 aarch64,链接器会抱怨:

/usr/bin/aarch64-linux-gnu-ld: cannot find /usr/lib/llvm-7/lib/clang/7.0.1/lib/linux/libclang_rt.asan-aarch64.a: No such file or directory

libclang_rt.asan-aarch64.a来自 libclang-common-7-dev:

dpkg -S /usr/lib/llvm-7/lib/clang/7.0.1/lib/linux/libclang_rt.asan-aarch64.a
libclang-common-7-dev: /usr/lib/llvm-7/lib/clang/7.0.1/lib/linux/libclang_rt.asan-aarch64.a

这个包和文件安装在 arm64 系统上。使用clang -v我可以看到链接器正在尝试使用--whole-archive /usr/lib/llvm-7/lib/clang/7.0.1/lib/linux/libclang_rt.asan-aarch64.a,但我需要它来使用--whole-archive /cache/arm64/usr/lib/llvm-7/lib/clang/7.0.1/lib/linux/libclang_rt.asan-aarch64.a. 该--sysroot选项正在更改-L链接器中的所有选项,但不是此--whole-archive选项。

我可以手动更改链接器命令以完成编译。但是,我还有其他问题。

它似乎不使用/cache/arm64/lib/aarch64-linux-gnu/,而是/lib/aarch64-linux-gnu/在主机系统上使用。如果我rsync将所有/cache/arm64/lib/aarch64-linux-gnu/文件都放在主机上,并且还手动更改链接器命令,那么它“成功”,除了当我进入目标系统/lib/aarch64-linux-gnu/时二进制文件仍然无法运行:chroot

# chroot /cache/arm64 /bin/bash
# ./binary
==13339==Sanitizer CHECK failed: /build/llvm-toolchain-7-whi4O5/llvm-toolchain-7-7.0.1/projects/compiler-rt/lib/sanitizer_common/sanitizer_procmaps_common.cc:83 ((data_.proc_self_maps.mmaped_size)) > ((0)) (0, 0)

我采用这种方法的动机--sysroot仅仅是因为它很简单。它避免了dpkg --add-architecture arm64将库加载到主机上。此外,libclang_rt.asan-aarch64.a在 libclang-common-7-dev 中,如果我愿意,我无法加载libclang-common-7-dev:arm64;它与clang包冲突:

apt install libclang-common-7-dev:arm64
Reading package lists... Done
Building dependency tree... Done
The following additional packages will be installed:
  gcc-8-base:arm64 libbsd0:arm64 libbsd0 libc6:arm64 libedit2:arm64 libffi6:arm64 libgcc1:arm64
  libidn2-0:arm64 libllvm7:arm64 libstdc++6:arm64 libtinfo6:arm64 libunistring2:arm64 zlib1g:arm64
Suggested packages:
  glibc-doc:arm64 locales:arm64
The following packages will be REMOVED:
  clang-7 libclang-common-7-dev
The following NEW packages will be installed:
  gcc-8-base:arm64 libbsd0:arm64 libc6:arm64 libclang-common-7-dev:arm64 libedit2:arm64 libffi6:arm64
  libgcc1:arm64 libidn2-0:arm64 libllvm7:arm64 libstdc++6:arm64 libtinfo6:arm64 libunistring2:arm64
  zlib1g:arm64

我的clang-7选择:-v -fPIC -O1 -target aarch64-linux-gnu --sysroot=/cache/arm64 -fsanitize=address -fno-omit-frame-pointer -fno-optimize-sibling-calls' 还要注意:我将源代码编译为程序集,将程序集编译为对象,然后将对象编译为二进制文件。我执行这些步骤来保留中间文件主要是出于好奇。当我这样做不是作为交叉编译时,我没有任何问题。所以,我不应该认为这很重要,但我会提到它以防万一。

标签: clangllvmcross-compilingaddress-sanitizer

解决方案


推荐阅读