ClangBuiltLinux / linux

Linux kernel source tree
Other
240 stars 14 forks source link

CONFIG_UBSAN_OBJECT_SIZE leads to Section mismatch warnings #1321

Closed nickdesaulniers closed 2 years ago

nickdesaulniers commented 3 years ago

distinctly separate issue from #1301 and #1302.

@nathanchance reports:

WARNING: modpost: vmlinux.o(.text+0x144328): Section mismatch in reference from the function early_get_smp_config() to the variable .init.data:x86_init
The function early_get_smp_config() references
the variable __initdata x86_init.
This is often because early_get_smp_config lacks a __initdata
annotation or the annotation of x86_init is wrong.

WARNING: modpost: vmlinux.o(.text+0x144334): Section mismatch in reference from the function early_get_smp_config() to the variable .init.data:x86_init
The function early_get_smp_config() references
the variable __initdata x86_init.
This is often because early_get_smp_config lacks a __initdata
annotation or the annotation of x86_init is wrong.

@arndb narrows this down to -fsanitize=object-size/CONFIG_UBSAN_OBJECT_SIZE.

I note that LowerConstantIntrinsicsPass appears to be running after inlining.

arndb commented 3 years ago

The relevant kernel mailing list thread is https://lore.kernel.org/lkml/20210225112247.2240389-1-arnd@kernel.org/

This can be addressed with a kernel change that either marks the inline functions as init (as I suggested), or marks them as always_inline (as Boris suggested), either way would work fine.

The question is whether llvm's decision to not inline the function by default is reasonable. In the retuced test case (https://godbolt.org/z/xW8G9c) I show that even a completely empty function is not inlined here, and that smells like a missed optimization bug in the compiler.

nickdesaulniers commented 3 years ago

These are not completely empty; they are massive because allmodconfig turned on sanitizers and code coverage.

Let me try adding another run of LowerConstantIntrinsicsPass before inlining and see if that helps.

nickdesaulniers commented 3 years ago

Noting in linux-next, I also see:

WARNING: modpost: vmlinux.o(.text+0x73f90a): Section mismatch in reference from the function memblock_bottom_up() to the variable .meminit.data:memblock
The function memblock_bottom_up() references
the variable __meminitdata memblock.
This is often because memblock_bottom_up lacks a __meminitdata 
annotation or the annotation of memblock is wrong.

which goes away if I disable CONFIG_UBSAN_OBJECT_SIZE.

arndb commented 3 years ago

The case that I looked at had the warning for a fairly trivial version of the function, and I used cvise to reduce it from that version to the empty function. I'm not worried about the case in which this happens for a large (because of sanitizers) function that does not get inlined, in that case we should just mark it __init as my original patch does.

The part that needs to be investigated in the compiler is why clang-13 decides to not to inline the function when there is no apparent downside.

arndb commented 3 years ago

See https://lore.kernel.org/lkml/20210225133808.2188581-1-arnd@kernel.org/ for a discussion of the memblock_bottom_up() function, this one did result in a fairly large function for me.

emojifreak commented 2 years ago

CONFIG_UBSAN_OBJECT_SIZE also produces the same warnings for mips64el build as below:

  LD      vmlinux.o
  MODPOST vmlinux.symvers
WARNING: modpost: vmlinux.o(.text+0x10a569c): Section mismatch in reference from the function find_first_bit() to the variable .init.data:pcpu_build_alloc_info.mask
The function find_first_bit() references
the variable __initdata pcpu_build_alloc_info.mask.
This is often because find_first_bit lacks a __initdata 
annotation or the annotation of pcpu_build_alloc_info.mask is wrong.

WARNING: modpost: vmlinux.o(.text+0x10a56a0): Section mismatch in reference from the function find_first_bit() to the variable .init.data:pcpu_build_alloc_info.mask
The function find_first_bit() references
the variable __initdata pcpu_build_alloc_info.mask.
This is often because find_first_bit lacks a __initdata 
annotation or the annotation of pcpu_build_alloc_info.mask is wrong.

WARNING: modpost: vmlinux.o(.text+0x10a56a8): Section mismatch in reference from the function find_first_bit() to the variable .init.data:pcpu_build_alloc_info.mask
The function find_first_bit() references
the variable __initdata pcpu_build_alloc_info.mask.
This is often because find_first_bit lacks a __initdata 
annotation or the annotation of pcpu_build_alloc_info.mask is wrong.

WARNING: modpost: vmlinux.o(.text+0x10a56b0): Section mismatch in reference from the function find_first_bit() to the variable .init.data:pcpu_build_alloc_info.mask
The function find_first_bit() references
the variable __initdata pcpu_build_alloc_info.mask.
This is often because find_first_bit lacks a __initdata 
annotation or the annotation of pcpu_build_alloc_info.mask is wrong.

  MODINFO modules.builtin.modinfo
llvm-objcopy: error: invalid symbol index: 67108864
make: *** [Makefile:1161: vmlinux] Error 1
make: Target 'all' not remade because of errors.

The llvm-objecopy error is #1534 and is probably independent of this. The above warning can be reproduced by the following script. Please add the tag mips.

#!/bin/sh

KVER=5.16-rc4
LANG=C.UTF-8
export LANG
cd /var/tmp/tmp11mips64el_3

  cat >/tmp/config$$.txt <<EOF
CONFIG_FTRACE_MCOUNT_USE_RECORDMCOUNT=n
CONFIG_KASAN=n
CONFIG_GCOV_KERNEL=n
CONFIG_COMPILE_TEST=n
CONFIG_TRIM_UNUSED_KSYMS=n
CONFIG_SHADOW_CALL_STACK=y
CONFIG_LD_DEAD_CODE_DATA_ELIMINATION=n
CONFIG_INIT_STACK_ALL_ZERO=y
CONFIG_KVM=y
CONFIG_PREEMPT=y
CONFIG_PREEMPT_DYNAMIC=y

CONFIG_WERROR=n
CONFIG_RUNTIME_TESTING_MENU=n
CONFIG_XFS_FS=n
CONFIG_OVERLAY_FS=n
CONFIG_EMBEDDED=n

CONFIG_DEBUG_INFO=y
CONFIG_DEBUG_INFO_DWARF5=y

CONFIG_ACPI=y
CONFIG_EFI_STUB=y
CONFIG_EFI=y
CONFIG_DMI=y
CONFIG_NUMA=y
CONFIG_MEMORY_HOTPLUG=y
CONFIG_HOTPLUG_PCI=y
CONFIG_HOTPLUG_PCI_PCIE=y
CONFIG_HOTPLUG_CPU=y

CONFIG_XILINX_SDFEC=n
CONFIG_CPU_MIPS64_R6=y
CONFIG_HIBERNATION=y
CONFIG_MIPS_CPS=y
CONFIG_CPU_HAS_MSA=y
CONFIG_RELOCATABLE=y
CONFIG_KEXEC=n
CONFIG_CPU_LITTLE_ENDIAN=y
CONFIG_CPU_BIG_ENDIAN=n
CONFIG_32BIT=n
CONFIG_64BIT=y
EOF

for a in mips; do
  rm -rf /var/tmp/tmp11mips64el_3/$a
  mkdir /var/tmp/tmp11mips64el_3/$a
  cd /var/tmp/tmp11mips64el_3/$a
  exec </dev/null >build-log-${KVER}-${a}.txt 2>&1
  set -xe
  tar zxf /var/tmp/linux-${KVER}.tar.gz
  cd linux-${KVER}

#  sed -i 's/-O2/-O3/g' Makefile
#  sed -i 's/-Os/-Oz/g' Makefile
  cp /tmp/config$$.txt .config
  make LLVM=1 LLVM_IAS=1 CROSS_COMPILE=mips64el-linux-gnuabi64- allmodconfig
  cat /tmp/config$$.txt >>.config

  yes '' |
    chrt --idle 0 nice -19 make --keep-going ARCH=$a LLVM=1 LLVM_IAS=1 CROSS_COMPILE=mips64el-linux-gnuabi64- KCFLAGS="-mllvm -polly-ast-use-context -mllvm -polly-invariant-load-hoisting -mllvm -polly-opt-fusion=max -mllvm -polly-run-inliner -mllvm -polly-vectorizer=stripmine -mllvm -polly-run-dce"  all &
  exec </dev/null >/dev/null 2>&1
done 
wait
nathanchance commented 2 years ago

There are plans to remove CONFIG_UBSAN_OBJECT_SIZE from the kernel so these warnings should disappear by nature of that change: https://lore.kernel.org/r/20211203235346.110809-1-keescook@chromium.org/

I believe Nick's change resolves this on the LLVM side as well: https://reviews.llvm.org/D111456

nathanchance commented 2 years ago

As CONFIG_UBSAN_OBJECT_SIZE has been removed from the kernel, I am going to close this up, as there are no more warnings as a result of it.