Bug 31106 - strip --strip-debug breaks relocations
Summary: strip --strip-debug breaks relocations
Status: ASSIGNED
Alias: None
Product: binutils
Classification: Unclassified
Component: binutils (show other bugs)
Version: 2.41
: P2 normal
Target Milestone: ---
Assignee: Nick Clifton
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2023-12-01 06:13 UTC by Stas Sergeev
Modified: 2023-12-05 15:19 UTC (History)
2 users (show)

See Also:
Host:
Target:
Build:
Last reconfirmed: 2023-12-04 00:00:00


Attachments
test case (13.02 KB, application/x-executable)
2023-12-01 06:13 UTC, Stas Sergeev
Details
test case (16.52 KB, application/x-executable)
2023-12-04 17:16 UTC, Stas Sergeev
Details
Proposed patch (413 bytes, patch)
2023-12-05 13:48 UTC, Nick Clifton
Details | Diff
Stripped file (13.16 KB, application/x-executable)
2023-12-05 14:11 UTC, Nick Clifton
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Stas Sergeev 2023-12-01 06:13:33 UTC
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.
Comment 1 Nick Clifton 2023-12-04 17:12:07 UTC
(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
Comment 2 Stas Sergeev 2023-12-04 17:16:49 UTC
Created attachment 15235 [details]
test case

Re-attaching.
Comment 3 Stas Sergeev 2023-12-04 17:18:00 UTC
(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)
Comment 4 Nick Clifton 2023-12-04 17:45:45 UTC
(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
Comment 5 Nick Clifton 2023-12-04 17:49:18 UTC
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[...]
  $
Comment 6 Stas Sergeev 2023-12-04 17:56:57 UTC
(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.
Comment 7 Nick Clifton 2023-12-05 13:48:26 UTC
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
Comment 8 Stas Sergeev 2023-12-05 14:02:53 UTC
(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?
Comment 9 Nick Clifton 2023-12-05 14:11:38 UTC
Created attachment 15237 [details]
Stripped file
Comment 10 Nick Clifton 2023-12-05 14:15:32 UTC
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
Comment 11 Stas Sergeev 2023-12-05 14:22:58 UTC
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?
Comment 12 Nick Clifton 2023-12-05 15:16:59 UTC
(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 ?
Comment 13 Sourceware Commits 2023-12-05 15:19:17 UTC
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.