ClangBuiltLinux / linux

Linux kernel source tree
Other
241 stars 14 forks source link

ld.lld: error: undefined symbol: __aeabi_unwind_cpp_pr0 #1191

Open nathanchance opened 3 years ago

nathanchance commented 3 years ago

Reported-by: kernel test robot <lkp@intel.com>

Initial report: https://lore.kernel.org/lkml/202011032340.LRdUzWHN-lkp@intel.com/

With this config, on v5.10-rc1:

$ curl -LSs https://lore.kernel.org/lkml/202011032340.LRdUzWHN-lkp@intel.com/2-a.bin | gzip -d > .config

$ make -skj"$(nproc)" ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- LLVM=1 olddefconfig all
...
ld.lld: error: undefined symbol: __aeabi_unwind_cpp_pr0
>>> referenced by trace_clock.c
>>>               trace/trace_clock.o:(.ARM.exidx+0x28) in archive kernel/built-in.a
>>> referenced by ring_buffer.c
>>>               trace/ring_buffer.o:(.ARM.exidx+0x2D0) in archive kernel/built-in.a
>>> referenced by trace.c
>>>               trace/trace.o:(.ARM.exidx+0x730) in archive kernel/built-in.a
>>> referenced 20 more times
...
nickdesaulniers commented 3 years ago

".handlerdata directive (without .personality directive)" ? https://github.com/llvm/llvm-project/blob/df952cb914eae5264603bd9fadffcc7626355c51/llvm/test/MC/ARM/eh-directive-handlerdata.s#L45

https://github.com/llvm/llvm-project/blob/df952cb914eae5264603bd9fadffcc7626355c51/llvm/test/MC/ARM/eh-directive-text-section.s#L75-L77

https://github.com/llvm/llvm-project/blob/a55daa146166353236aa528546397226bee9363b/llvm/lib/Target/ARM/MCTargetDesc/ARMUnwindOpAsm.cpp#L171

https://github.com/llvm/llvm-project/blob/c031378ce01b8485ba0ef486654bc9393c4ac024/llvm/lib/Target/ARM/MCTargetDesc/ARMELFStreamer.cpp#L1292

https://github.com/llvm/llvm-project/blob/2946cd701067404b99c39fb29dc9c74bd7193eb3/llvm/include/llvm/Support/ARMEHABI.h#L123

https://github.com/llvm/llvm-project/blob/fdceec7aeac6ae0fba4db9703bf4e4e69a126d0d/llvm/tools/llvm-readobj/ARMEHABIPrinter.h#L487

nickdesaulniers commented 3 years ago

It looks like __aeabi_unwind_cpp_pr0 is defined as an empty function in arch/arm/kernel/unwind.c.

nathanchance commented 3 years ago
$ curl -LSs https://lore.kernel.org/lkml/202011032340.LRdUzWHN-lkp@intel.com/2-a.bin | gzip -d | rg "CONFIG_UNWINDER_"
CONFIG_UNWINDER_FRAME_POINTER=y
# CONFIG_UNWINDER_ARM is not set

Presumably, __aeabi_unwind_cpp_pr0 should not even be a factor if CONFIG_UNWINDER_ARM is not set.

nickdesaulniers commented 3 years ago

I wonder if CONFIG_FUNCTION_TRACER is set and ccflags-remove-$(CONFIG_FUNCTION_TRACER) += $(CC_FLAGS_FTRACE) in kernel/trace/Makefile is messing this up? From the error posted, it looks like someone must be messing with the flags used to build trace_clock.o, ring_buffer.o, and trace.o, or at least they seem to differ for CONFIG_UNWINDER_FRAME_POINTER which probably changes some flags for 32b ARM. (Like add -fno-omit-frame-pointer and probably something related to -fno-asynchronous-unwind-tables).

nathanchance commented 3 years ago
$ curl -LSs https://lore.kernel.org/lkml/202011032340.LRdUzWHN-lkp@intel.com/2-a.bin | gzip -d | rg FUNCTION_TRACER
CONFIG_HAVE_FUNCTION_TRACER=y
# CONFIG_FUNCTION_TRACER is not set
arndb commented 3 years ago

I see it in multiple randconfig builds as well now, interestingly always on ARMv4/ARMv4T/ARMv5 builds later ones. All these configurations enable frame pointer, KASAN and modules, and enabling these three on a tinyconfig build runs into it as well.

As far as I can tell, the source of the issue is that clang unconditionally inserts '.fnstart' and '.fnend' directives into the assembly regardless of -fomit-frame-pointer and -funwind-tables, while gcc leaves those out, see https://godbolt.org/z/vWPxon

nickdesaulniers commented 3 years ago

FWIW: https://sourceware.org/binutils/docs/as/ARM-Directives.html

.fnstart Marks the start of a function with an unwind table entry.

.fnend Marks the end of a function with an unwind table entry. The unwind index table entry is created when this directive is processed. If no personality routine has been specified then standard personality routine 0 or 1 will be used, depending on the number of unwind opcodes required.

There's also no .handlerdata in @arndb 's example.

There is .cantunwind emitted:

.cantunwind Prevents unwinding through the current function. No personality routine or exception table data is required or permitted.

nathanchance commented 3 years ago
$ make -skj"$(nproc)" ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- LLVM=1 LLVM_IAS=1 defconfig

$ scripts/config -d UNWINDER_ARM -e KASAN -e UNWINDER_FRAME_POINTER

$ make -skj"$(nproc)" ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- LLVM=1 LLVM_IAS=1 olddefconfig all

is enough to reproduce this. This should probably reported to upstream LLVM.

nickdesaulniers commented 1 year ago

This should probably reported to upstream LLVM.

https://github.com/llvm/llvm-project/issues/69020