Skip to content

[BOLT][AArch64] unable to run BOLT on libffi #146541

Open
@geofft

Description

@geofft

We originally ran into this building CPython for python-build-standalone, but here's a minimal reproducer:

ubuntu@ubuntu:~/libffi-3.5.1$ ./configure CFLAGS=-Wl,-emit-relocs
ubuntu@ubuntu:~/libffi-3.5.1$ make -j8
ubuntu@ubuntu:~/libffi-3.5.1$ llvm-bolt-21 aarch64-unknown-linux-gnu/.libs/libffi.so.8.2.0 -o=foo
BOLT-INFO: shared object or position-independent executable detected
BOLT-INFO: Target architecture: aarch64
BOLT-INFO: BOLT version: <unknown>
BOLT-INFO: first alloc address is 0x0
BOLT-INFO: creating new program header table at address 0x200000, offset 0x200000
BOLT-INFO: enabling relocation mode
BOLT-WARNING: function ffi_go_closure_SYSV/1 has an object detected in a padding region at address 0x18048
BOLT-WARNING: function __clear_cache/1 has an object detected in a padding region at address 0x18068
BOLT-WARNING: 1 collisions detected while hashing binary objects. Use -v=1 to see the list.
BOLT-INFO: number of removed linker-inserted veneers: 0
BOLT-INFO: 0 out of 134 functions in the binary (0.0%) have non-empty execution profile
BOLT-INFO: removed 17 empty blocks
BOLT-ERROR: cannot relax ADR in non-simple function trampoline_code_table/1

This is with https://github.com/libffi/libffi/releases/download/v3.5.1/libffi-3.5.1.tar.gz, Ubuntu Plucky, and the the current version from apt.llvm.org (bolt-21=1:21~++20250630095742+59a7185dd9d6-1~exp1~20250630215911.150).

I think this is because trampoline_code_table is defined as hand-written assembly that does an adr and has no nops for BOLT to work with.

A naive attempt at throwing some extra nops into that function gave a worse failure, which I guess makes sense because it's loading some PC-relative addresses and I surely got those addresses wrong. But also it would be cool to be able to run BOLT without requiring changes in third-party code.

FWIW I think I would be happy leaving this un-optimized, if that's an option, but the adr relaxation pass looks unconditional and it seems to error out instead of skipping optimizing this one function. I don't totally understand whether this pass really needs to be mandatory.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions