$ 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.
Seen with 18.1.3. Simplest example:
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.