Description
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
.