Created attachment 15232 [details] test case Attached is a test-case. It is an elf file fdppkrnl.35.10.elf with debug info. Please do: ``` $ readelf -r fdppkrnl.35.10.elf | grep ':s8:' | wc -l 65 $ strip --strip-debug fdppkrnl.35.10.elf $ readelf -r fdppkrnl.35.10.elf | grep ':s8:' | wc -l 1 ``` As we can see, strip removed relocations to a particular symbol (1 reloc left from 65). This renders the object disfunctional. llvm-strip works properly and doesn't break anything.
(In reply to Stas Sergeev from comment #0) Hi Stas, > Created attachment 15232 [details] > $ readelf -r fdppkrnl.35.10.elf | grep ':s8:' | wc -l > 65 Err, are you sure about this first count ? For me I only see one reloc against s8 in the original file: $ readelf -r fdppkrnl.35.10.elf | grep ':s8:' | wc -l 1 Is it possible that you uploaded the stripped file ? Cheers Nick
Created attachment 15235 [details] test case Re-attaching.
(In reply to Nick Clifton from comment #1) > Is it possible that you uploaded the stripped file ? Thank you. I have re-uploaded the file now (haven't checked if the first one was alredy stripped, but likely so)
(In reply to Stas Sergeev from comment #3) > I have re-uploaded the file now > (haven't checked if the first one > was alredy stripped, but likely so) Thank you. This second version contains all the relocs, and strip does indeed behave as you described. Interestingly strip is not actually removing the relocations, but instead it is changing them, removing the references to the symbols. (Incidentally the symbols have very strange looking names. Is this deliberate ?) Anyway I am investigating to see if I can find out what strip thinks it is doing. Cheers Nick
Addendum: It may not be the effect of stripping that causes this behaviour. Just copying the file using objcopy also shows the same effect: $ objcopy fdppkrnl.35.10.elf test.elf $ readelf -r test.elf | grep s8 00002344 00026714 R_386_16 00000010 >>:s8:_PGROUP~:#0[...] $
(In reply to Nick Clifton from comment #4) > (Incidentally the symbols have very strange > looking names. Is this deliberate ?) This is a so-called "RELC encoding". I've looked into binutils source to find that it even exists. :) Now my modified nasm generates such symbols.
Created attachment 15236 [details] Proposed patch Hi Stas, Please can you try out this patch ? The issue is that the relocation processing code is noticing that the symbols involved in the problematic relocations are absolute and have a value of zero. So in theory they can just be discarded. For normal relocations this is OK, but for complex relocations it is not safe, since the symbol itself might be significant. So the patch tweaks the reloc processing code so that it will not drop the symbol in complex relocs. Cheers Nick
(In reply to Nick Clifton from comment #7) > Created attachment 15236 [details] > Proposed patch > > Hi Stas, > > Please can you try out this patch ? Hi, it would be easier if you just provide the newly stripped binary. I'll see if it works. But I can as well try the path. However: > So the patch tweaks the reloc processing code so that it will not > drop the symbol in complex relocs. Have you considered to spare the '--strip-debug' case from any possible heuristic, so that it only strips debug sections? I think your check should only apply to the normal strip process, but '--strip-debug' remains broken. It needs to keep any relocs, regardless of how safe is that. What do you think?
Created attachment 15237 [details] Stripped file
Hi Stas, (In reply to Stas Sergeev from comment #8) > Hi, it would be easier if you just > provide the newly stripped binary. OK, I have uploaded a copy. > Have you considered to spare the > '--strip-debug' case from any possible > heuristic, so that it only strips debug > sections? That would mean creating a separate path in the BFD library for reloc processing when stripping debug sections which would add to the complexity. If we can fix the bug you found then the current code can still be used because it does not remove any relocations, it just tries to simplify one special case. And if we do not simplify complex relocs then everything should work. Cheers Nick
OK, I checked that the new binary works as expected. Thank you! But I am really a bit disappointed if you leave the current objcopy behavior that can still remove relocations at will... Yes, I understand that your patch fixes my problem. But IMHO having such side effects from mere objcopy, is plain wrong. > That would mean creating a separate path in the BFD If that's the problem, then I'd suggest no not touch relocations at all. It will fix both objcopy and '--strip-debug', and will actually regress nothing that I can think of?
(In reply to Stas Sergeev from comment #11) > OK, I checked that the new binary > works as expected. Ok, I will check in the patch. > If that's the problem, then I'd suggest > no not touch relocations at all. It will > fix both objcopy and '--strip-debug', and > will actually regress nothing that I can > think of? Consider this, rather contrived, example: $ cat demo.s .data .long debug_sym .section .debug_aranges .global debug_sym debug_sym: .word 1 $ as demo.s -o demo.o % strip --strip-debug demo.o -o demo.stripped strip: demo.stripped: symbol `debug_sym' required but not present If strip just deleted the debug sections and did not process the relocations then it would not detect the fact that the output was broken and so it would not be able to generate those error messages. In general removing sections from a binary is not just as simple as deleting their presence. There are lots of potential dependencies between sections and the code has to make sure that they are all checked. Cheers Nick PS. Yes, in theory a straight "objcopy foo foo.copy" should not need any checks, but why would that ever be done, and is it really worth coding a special case just to optimize it ?
The master branch has been updated by Nick Clifton <nickc@sourceware.org>: https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=e60675a228a8ecd2cfdc7e45cb315a1838b91f74 commit e60675a228a8ecd2cfdc7e45cb315a1838b91f74 Author: Nick Clifton <nickc@redhat.com> Date: Tue Dec 5 15:18:40 2023 +0000 Fix: strip --strip-debug breaks relocations PR 31106 * elfcode.h (elf_write_relocs): Do not convert a relocation against a zero-value absolute symbol into a relocation without a symbol if the symbol is being used for a complex relocation.