Skip to content

[BOLT][AArch64] 0-bit relocation offset expected #138264

Open
@paschalis-mpeis

Description

@paschalis-mpeis

Update:

In short: we'll need to add support for conditional tail calls, which appear to be coming from hand-written assembly.
A minimal assembly reproducer is available in: #139565.


Assertion Crash:

When compiling chromium with the options below using BOLT trunk, the following assertion is triggered:

AArch64MCPlusBuilder::createRelocation(const MCFixup &, const MCAsmBackend &) const: Assertion `FKI.TargetOffset == 0 && "0-bit relocation offset expected"' failed.

Details:

The crash occurs in scanExternalRefs, when it attempts to createRelocation for a fixup_aarch64_pcrel_branch19, which has a non-zero TargetOffset.

This fixup sets the high 19 bits of a 21-bit PC-relative immediate.

Reproducer:

To compile the original reproducer see last section.
Note: debug symbols were kept in the binary as without those bolt hits different errors.

Skip functions via skipfuncs.txt:

.*tap.*
Builtins_.*

Optimize with BOLT:

  • BOLT revision e046f2050578b8cda394143fafbfb476767b836a
  • Optimized build with assertions enabled
llvm-bolt --skip-funcs-file=skipfuncs.txt chrome -o chrome.bolt

Error log:

BOLT-INFO: shared object or position-independent executable detected
BOLT-INFO: Target architecture: aarch64
BOLT-INFO: BOLT version: e046f2050578b8cda394143fafbfb476767b836a
BOLT-INFO: first alloc address is 0x0
BOLT-INFO: creating new program header table at address 0xee00000, offset 0xee00000
BOLT-WARNING: debug info will be stripped from the binary. Use -update-debug-sections to keep it.
BOLT-INFO: enabling relocation mode
BOLT-WARNING: ignoring symbol __ehdr_start at 0x0, which lies outside .interp
llvm-bolt: /home/user/llvm-project/bolt/lib/Target/AArch64/AArch64MCPlusBuilder.cpp:2341: virtual std::optional<Relocation> (anonymous namespace)::AArch64MCPlusBuilder::createRelocation(const MCFixup &, const MCAsmBackend &) const: Assertion `FKI.TargetOffset == 0 && "0-bit relocation offset expected"' failed.
 #0 0x0000ecb0cce31578 llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) /home/user/llvm-project/llvm/lib/Support/Unix/Signals.inc:804:13
 #1 0x0000ecb0cce2f3c4 store /usr/bin/../lib/gcc/aarch64-linux-gnu/13/../../../../include/c++/13/atomic:279:2
 #2 0x0000ecb0cce2f3c4 llvm::sys::RunSignalHandlers() /home/user/llvm-project/llvm/lib/Support/Signals.cpp:107:16
 #3 0x0000ecb0cce31ca0 SignalHandler(int, siginfo_t*, void*) /home/user/llvm-project/llvm/lib/Support/Unix/Signals.inc:418:13
 #4 0x0000ecb0cf0ae8f8 (linux-vdso.so.1+0x8f8)
 #5 0x0000ecb0cc747608 __pthread_kill_implementation ./nptl/pthread_kill.c:44:76
 #6 0x0000ecb0cc6fcb3c raise ./signal/../sysdeps/posix/raise.c:27:6
 #7 0x0000ecb0cc6e7e00 abort ./stdlib/abort.c:81:7
 #8 0x0000ecb0cc6f5cc0 __assert_fail_base ./assert/assert.c:93:7
 #9 0x0000ecb0cc6f5d30 __assert_perror_fail ./assert/assert-perr.c:31:1
#10 0x0000ecb0c9562928 getOpcode /home/user/llvm-project/llvm/include/llvm/MC/MCInst.h:199:39
#11 0x0000ecb0c9562928 llvm::bolt::MCPlusBuilder::isCFI(llvm::MCInst const&) const /home/user/llvm-project/bolt/include/bolt/Core/MCPlusBuilder.h:1815:17
#12 0x0000ecb0c9089314 _M_is_engaged /usr/bin/../lib/gcc/aarch64-linux-gnu/13/../../../../include/c++/13/optional:473:58
#13 0x0000ecb0c9089314 _M_get /usr/bin/../lib/gcc/aarch64-linux-gnu/13/../../../../include/c++/13/optional:479:2
#14 0x0000ecb0c9089314 operator-> /usr/bin/../lib/gcc/aarch64-linux-gnu/13/../../../../include/c++/13/optional:968:39
#15 0x0000ecb0c9089314 llvm::bolt::BinaryFunction::scanExternalRefs() /home/user/llvm-project/bolt/lib/Core/BinaryFunction.cpp:1799:7
#16 0x0000ecb0cdda6400 ~TimeRegion /home/user/llvm-project/llvm/include/llvm/Support/Timer.h:160:9
#17 0x0000ecb0cdda6400 llvm::bolt::RewriteInstance::disassembleFunctions() /home/user/llvm-project/bolt/lib/Rewrite/RewriteInstance.cpp:3415:5
#18 0x0000ecb0cdd9efe0 processMetadataPreCFG /home/user/llvm-project/bolt/lib/Rewrite/RewriteInstance.cpp:3319:20
#19 0x0000ecb0cdd9efe0 llvm::bolt::RewriteInstance::run() /home/user/llvm-project/bolt/lib/Rewrite/RewriteInstance.cpp:730:3
#20 0x0000c97e55096014 getPtr /home/user/llvm-project/llvm/include/llvm/Support/Error.h:278:42
#21 0x0000c97e55096014 operator bool /home/user/llvm-project/llvm/include/llvm/Support/Error.h:241:16
#22 0x0000c97e55096014 main /home/user/llvm-project/bolt/tools/driver/llvm-bolt.cpp:260:17
#23 0x0000ecb0cc6e84c4 __libc_start_call_main ./csu/../sysdeps/nptl/libc_start_call_main.h:74:3
#24 0x0000ecb0cc6e8598 call_init ./csu/../csu/libc-start.c:128:20
#25 0x0000ecb0cc6e8598 __libc_start_main ./csu/../csu/libc-start.c:347:5
#26 0x0000c97e55094030 _start (/home/user/llvm-project/build/bin/llvm-bolt+0x14030)
PLEASE submit a bug report to https://github.com/llvm/llvm-project/issues/ and include the crash backtrace.
Stack dump:
0.      Program arguments: llvm-bolt -o chrome.bolt --skip-funcs-file=skipfuncs.txt chrome
[1]    1905728 abort (core dumped)  llvm-bolt -o chrome.bolt --skip-funcs-file=skipfuncs.txt chrome

Build Chromium from Source:

Based on the official Chromium Guide.

Tested on:

  • Host Machine: Ubuntu 22.04.4 LTS (6.8.0-1015-aws, c7i, x86)
  • Chromium version: a3e414899de9028990fbd7022e4184469932e890
cd $HOME
git clone https://chromium.googlesource.com/chromium/tools/depot_tools.git
export PATH="$PATH:$HOME/depot_tools"

mkdir chromium && cd chromium
fetch --nohooks chromium

Edit .gclient to set target and pull PGO profiles:

vim .gclient # and adjust like below:
solutions = [
  {
    "name": "src",
    "url": "https://chromium.googlesource.com/chromium/src.git",
    "managed": False,
    "custom_deps": {},
    "custom_vars": {
      "checkout_pgo_profiles": True,
    },
  },
]
target_cpu = ["arm64"]

Then pull components and install dependencies:

gclient sync
gclient runhooks

# verify that pgo profile was downloaded:
ls -l chrome/build/pgo_profiles/

cd src
./build/install-build-deps.sh # assumes Ubuntu

Set GN arguments:

gn args out/Default # Your EDITOR will open. Paste the below args:
is_debug=false
target_cpu="arm64"
symbol_level=1
target_os="linux"
chrome_pgo_phase=2
dcheck_always_on=false
is_official_build=true
disable_fieldtrial_testing_config=true
arm_control_flow_integrity="none"

Build chromium (you'll need bolt-chromium-0bitreloc.patch):

gn gen out/Default
git am ~/bolt-chromium-0bitreloc.patch

autoninja -C out/Default chrome

The binary will be at out/Default/chrome.

Metadata

Metadata

Labels

BOLTcrashPrefer [crash-on-valid] or [crash-on-invalid]

Type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions