LLVM Bugzilla is read-only and represents the historical archive of all LLVM issues filled before November 26, 2021. Use github to submit LLVM bugs

Bug 45217 - unknown argument '--change-section-address'
Summary: unknown argument '--change-section-address'
Status: NEW
Alias: None
Product: tools
Classification: Unclassified
Component: llvm-objcopy/strip (show other bugs)
Version: trunk
Hardware: PC All
: P enhancement
Assignee: Unassigned LLVM Bugs
URL:
Keywords:
Depends on:
Blocks: 4068
  Show dependency tree
 
Reported: 2020-03-16 13:31 PDT by Nick Desaulniers
Modified: 2020-03-20 01:30 PDT (History)
6 users (show)

See Also:
Fixed By Commit(s):


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Nick Desaulniers 2020-03-16 13:31:45 PDT
The Linux kernel has a custom debug format for eBPF (IIUC) called BTF.  It looks like it's making use of GNU objcopy's `--change-section-address` to set the section address to `0`:

https://github.com/ClangBuiltLinux/linux/commit/df786c9b947639aedbc7bb44b5dae2a7824af360

It doesn't look like there's any non-default linker script being used, so I'm not sure we could avoid this with a linker script.
Comment 1 Nick Desaulniers 2020-03-16 15:32:08 PDT
We'll be able to work around this for now with https://lore.kernel.org/bpf/20200316222518.191601-1-sdf@google.com/T/#u , but leaving this open for now.
Comment 2 James Henderson 2020-03-17 01:46:29 PDT
Yup, we haven't implemented this option (yet) in llvm-objcopy. I've not given it too much thought, but it might not fit particularly well with how llvm-objcopy is currently written, since llvm-objcopy works primarily through its program headers and preserves the section layout within those segments. Changing a section's address would require us to somehow place it elsewhere in the object. It's probably possible, but won't be that simple.

Anyway, somebody should take a look at this at some point. If you want a full workaround using llvm-objcopy, you could do the following sequence:

llvm-objcopy --dump-section .BTF=btf.bin file.o
llvm-objcopy --remove-section .BTF file.o
llvm-objcopy --add-section .BFT=btf.bin file.o
(optionally also use --set-section-flags etc as needed).

That will add the section with a zero address, if I'm not mistaken (not actually verified the invocations, but you should get the gist). It might even be possible to combine those into a single command, though there have been some bugs in ordering of these options, and I'm not sure if they've all been fixed yet.
Comment 3 Fangrui Song 2020-03-19 11:38:58 PDT
https://github.com/torvalds/linux/commit/df786c9b947639aedbc7bb44b5dae2a7824af360 added --change-section-address to work around some dwarves/pahole bug.

https://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf-next.git/commit/?id=90ceddcb495008ac8ba7a3dce297841efcd7d584 is in the bpf-next repository to remove dependency on objcopy --change-section-address (as well as 'file format' and 'architecture' parsing logic of llvm-objdump -f output).

Note that the option can split PT_LOAD and rewrite some fields.
objcopy --change-section-address .plt=0 a b

Before:

  LOAD           0x000000 0x0000000000200000 0x0000000000200000 0x0005dc 0x0005dc R   0x1000                                                          
  LOAD           0x0005e0 0x00000000002015e0 0x00000000002015e0 0x0001d0 0x0001d0 R E 0x1000                                                          
  LOAD           0x0007b0 0x00000000002027b0 0x00000000002027b0 0x0001b0 0x0001b0 RW  0x1000                                                          
  LOAD           0x000960 0x0000000000203960 0x0000000000203960 0x000030 0x000031 RW  0x1000

After:

  LOAD           0x000000 0x0000000000200000 0x0000000000200000 0x0005dc 0x0005dc R   0x1000
  LOAD           0x0005e0 0x00000000002015e0 0x00000000002015e0 0x0001a5 0x0001a5 R E 0x1000
  LOAD           0x001000 0x0000000000000000 0x0000000000000000 0x000020 0x000020 R E 0x1000
  LOAD           0x0017b0 0x00000000002027b0 0x00000000002027b0 0x0001b0 0x0001b0 RW  0x1000
  LOAD           0x001960 0x0000000000203960 0x0000000000203960 0x000030 0x000031 RW  0x1000

I suspect this option won't fit in llvm-objcopy's model (llvm-objcopy/ELF/Object.cpp: layoutSegments/layoutSections). `--change-section-address` stands for updating both VMA and LMA. It is even less clear how LMA can be updated.
Comment 4 James Henderson 2020-03-20 01:30:09 PDT
That program header table in the "After" example looks illegal to me, based on the gABI (loadable segments must be in address order). Does the Linux kernel require this section to be in a program header?

Not tried this yet, but I wouldn't be all that surprised if adding a program header in llvm-objcopy is actually relatively straightforward. If the section would be moved so that you need to split the segment, you could create PT_LOAD, assign the section to it, probably mess about with some offsets, and derive the segment contents from the section. We'd still end up with the old section's contents in the old segment, but this is probably harmless, and could even be changed to blank it out like when a section is explicitly removed. What won't work though is if there are any references to this section (I'm thinking dynamic relocations, or even direct references from code/data etc). As such, I'm not convinced this solution's generality.