Skip to content

Stripping BOLTed binaries may result in misaligned PT_LOADs #56738

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
amharc opened this issue Jul 26, 2022 · 8 comments
Closed

Stripping BOLTed binaries may result in misaligned PT_LOADs #56738

amharc opened this issue Jul 26, 2022 · 8 comments
Labels
BOLT question A question, not bug report. Check out https://llvm.org/docs/GettingInvolved.html instead! tools:llvm-objcopy/strip

Comments

@amharc
Copy link
Contributor

amharc commented Jul 26, 2022

Consider the following simple main.cc file:

int main() {}

Running:

$ clang++ main.cc -o main -Wl,-q
$ llvm-bolt main -o main.bolted
$ llvm-strip -S main.bolted -o main.bolted.stripped

Results in a misaligned PT_LOAD:

  Type           Offset   VirtAddr           PhysAddr           FileSiz  MemSiz   Flg Align
...
  LOAD           0x003028 0x0000000000200000 0x0000000000200000 0x200384 0x200384 R E 0x200000

which leads to program crashes at startup:

$ ./main.bolted.stripped
[1]    153575 segmentation fault  ./main.bolted.stripped
$ /lib64/ld-linux-x86-64.so.2 ./main.bolted.stripped
./main.bolted.stripped: error while loading shared libraries: ./main.bolted.stripped: ELF load command address/offset not properly aligned

This is because the new PT_PHDR header was placed at the same offset as the new PT_LOAD containing the modified .text section:

$ llvm-readelf -l -h main.bolted
...
  Type           Offset   VirtAddr           PhysAddr           FileSiz  MemSiz   Flg Align
  PHDR           0x200000 0x0000000000200000 0x0000000000200000 0x000310 0x000310 R   0x8
...
  LOAD           0x200000 0x0000000000200000 0x0000000000200000 0x200384 0x200384 R E 0x200000

Which confuses llvm-strip, as it thinks that the PT_LOAD is a child of the PT_PHDR and thus it will disregard the alignment requirements of the (alleged) child.

@llvmbot
Copy link
Member

llvmbot commented Jul 26, 2022

@llvm/issue-subscribers-bolt

@maksfb
Copy link
Contributor

maksfb commented Jul 27, 2022

@amharc, do you consider it to be an llvm-bolt issue or llvm-strip issue?

@amharc
Copy link
Contributor Author

amharc commented Jul 27, 2022

I'm not actually sure: on one hand, my system's version of GNU binutils strip fails to strip a BOLTed binary altogether with error messages like:

strip: main.bolted.stripped.gnu: section `.text' can't be allocated in segment 4
LOAD: .text .eh_frame .eh_frame_hdr
strip: main.bolted.stripped.gnu: section `.eh_frame' can't be allocated in segment 4
LOAD: .text .eh_frame .eh_frame_hdr
strip: main.bolted.stripped.gnu: section `.eh_frame_hdr' can't be allocated in segment 4
LOAD: .text .eh_frame .eh_frame_hdr

and I wasn't able to find a conclusive reference documenting what a strip tool should do in such a case, and making llvm-bolt update the alignment requirements for the new PT_PHDR header would solve the problem.

But on the other hand a reasonable solution would indeed be to teach llvm-strip to propagate child segments' alignment requirements back to the parents before assigning offsets to segments.

berkley4 added a commit to berkley4/ungoogled-chromium-debian that referenced this issue Sep 20, 2023
Although this appears to work fine, this might not be a good
idea until upstream llvm fixes bug [56738](llvm/llvm-project#56738).

The llvm/clang build instructions have been updated to use
'ninja -j4 install' instead of 'ninja -j4 install/strip'.
@llvmbot
Copy link
Member

llvmbot commented Oct 31, 2024

@llvm/issue-subscribers-tools-llvm-objcopy-strip

Author: Krzysztof Pszeniczny (amharc)

Consider the following simple `main.cc` file: ```c++ int main() {} ```

Running:

$ clang++ main.cc -o main -Wl,-q
$ llvm-bolt main -o main.bolted
$ llvm-strip -S main.bolted -o main.bolted.stripped

Results in a misaligned PT_LOAD:

  Type           Offset   VirtAddr           PhysAddr           FileSiz  MemSiz   Flg Align
...
  LOAD           0x003028 0x0000000000200000 0x0000000000200000 0x200384 0x200384 R E 0x200000

which leads to program crashes at startup:

$ ./main.bolted.stripped
[1]    153575 segmentation fault  ./main.bolted.stripped
$ /lib64/ld-linux-x86-64.so.2 ./main.bolted.stripped
./main.bolted.stripped: error while loading shared libraries: ./main.bolted.stripped: ELF load command address/offset not properly aligned

This is because the new PT_PHDR header was placed at the same offset as the new PT_LOAD containing the modified .text section:

$ llvm-readelf -l -h main.bolted
...
  Type           Offset   VirtAddr           PhysAddr           FileSiz  MemSiz   Flg Align
  PHDR           0x200000 0x0000000000200000 0x0000000000200000 0x000310 0x000310 R   0x8
...
  LOAD           0x200000 0x0000000000200000 0x0000000000200000 0x200384 0x200384 R E 0x200000

Which confuses llvm-strip, as it thinks that the PT_LOAD is a child of the PT_PHDR and thus it will disregard the alignment requirements of the (alleged) child.

@jh7370
Copy link
Collaborator

jh7370 commented Oct 31, 2024

What version of llvm-strip are you using? There was a commit about 8 months ago to the LLVM main branch (so should be in the most recent release, I believe) that should address this issue, if I understand it correctly.

@glyh
Copy link
Contributor

glyh commented Dec 12, 2024

I've tested the reproduction on 9f1e9f6 and this seems to be fixed, just as @jh7370 suggested.

@paschalis-mpeis
Copy link
Member

Is this issue (and duplicate #89336) still relevant, after this gnu strip patch?

https://sourceware.org/git/?p=binutils-gdb.git;a=commitdiff;h=bbc969306f8d5fb6c7b636e25f6f8e278946ef23

@jh7370
Copy link
Collaborator

jh7370 commented Jan 23, 2025

Is this issue (and duplicate #89336) still relevant, after this gnu strip patch?

https://sourceware.org/git/?p=binutils-gdb.git;a=commitdiff;h=bbc969306f8d5fb6c7b636e25f6f8e278946ef23

GNU strip is a different tool to llvm-strip (although they parallel each other), so patches to GNU strip have no bearing on issues against llvm-strip.

That being said, given my investigation and @glyh's comment later on, I think this ticket should be closed, since the issue has already been fixed, it seems.

@jh7370 jh7370 closed this as completed Jan 23, 2025
@EugeneZelenko EugeneZelenko added question A question, not bug report. Check out https://llvm.org/docs/GettingInvolved.html instead! and removed waiting-for-response labels Jan 23, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
BOLT question A question, not bug report. Check out https://llvm.org/docs/GettingInvolved.html instead! tools:llvm-objcopy/strip
Projects
None yet
Development

No branches or pull requests

9 participants