llvm / llvm-project

The LLVM Project is a collection of modular and reusable compiler and toolchain technologies.
http://llvm.org
Other
29.3k stars 12.11k forks source link

stripping a binary modified by bolt causes it to crash on startup #89336

Open berolinux opened 7 months ago

berolinux commented 7 months ago

Seen with 18.1.3. Simplest example:

$ cat test.c
#include <stdio.h>
int main(int argc, char **argv) {
  puts("Test");
}
$ clang -o test test.c
$ ./test
Test
$ llvm-bolt -o test.bolt test
BOLT-INFO: shared object or position-independent executable detected
BOLT-INFO: Target architecture: x86_64
BOLT-INFO: BOLT version: 1b71387311a807d4d600915d1157bf1f9e291e27
BOLT-INFO: first alloc address is 0x0
BOLT-INFO: creating new program header table at address 0x200000, offset 0x200000
BOLT-INFO: disabling -align-macro-fusion in non-relocation mode
BOLT-INFO: enabling lite mode
BOLT-INFO: 0 out of 9 functions in the binary (0.0%) have non-empty execution profile
BOLT-INFO: removed 2 empty blocks
BOLT-INFO: UCE removed 1 blocks and 7 bytes of code
BOLT: 6 out of 11 functions were overwritten.
BOLT-INFO: patched build-id (flipped last bit)
$ ./test.bolt
Test
$ llvm-strip test.bolt
$ ./test.bolt
Segmentation fault

Same happens when using gcc and BFD strip instead of clang and llvm-strip.

For obvious reasons, stripping a binary before throwing it at bolt is a bad idea -- but there's no equally obvious reason why stripping a binary after running bolt should break it badly.

Also, a bolt-then-strip binary is much bigger than a stripped binary.

Zentrik commented 7 months ago

Striping bolted binaries doesn't work, e.g. https://github.com/llvm/llvm-project/issues/56738

yota9 commented 7 months ago

https://github.com/llvm/llvm-project/issues/85796#issuecomment-2015622214