[PATCH] D74755: [llvm-objcopy] Attribute an empty section to a segment ending at its address
James Henderson via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Thu Apr 2 03:45:46 PDT 2020
jhenderson added a comment.
I've played around with the llvm-objcopy's with and without this patch to see the impact of the change. One situation I noticed is where using the `--remove-section` option, combined with the `--only-keep-debug` option. In the example I'm using, there is a PT_LOAD which contains a PT_GNU_RELRO, which contains, at its end, a PT_TLS, with another relro section before the TLS segment. (Note: the segment types, apart from the PT_LOAD are irrelevant here - a custom linker script could have all sorts of different segment types where this layout could happen). If the relro section is removed by objcopy, the output from only-keep-debug differs before and after this patch. I haven't experimented yet due to time constraints, but I wouldn't be entirely surprised if the same behaviour difference would be observed if --remove-section was performed in a prior run of llvm-objcopy, or if the section was replaced with segment padding of some variety.
Here is the input source I used:
// test.cpp
thread_local int tdata = 42;
extern void (* const ptr)();
extern "C" void _start (){}
void (* const ptr)() = &_start;
// test.script - derived from LLD's output without a linker script but with the relro and tls segments and sections swapped.
PHDRS
{
ph_phdr PT_PHDR PHDRS FLAGS (0x4);
ph_ro PT_LOAD FILEHDR PHDRS FLAGS (0x4);
ph_text PT_LOAD FLAGS (0x1 | 0x4);
ph_data PT_LOAD FLAGS (0x2 | 0x4);
ph_relro PT_GNU_RELRO FLAGS (0x4);
ph_tls PT_TLS FLAGS (0x4);
}
SECTIONS
{
. = 0x200000 + SIZEOF_HEADERS;
.eh_frame : { *(.eh_frame) } : ph_ro
.text : { *(.text .text.*) } : ph_text
.data.rel.ro : { *(.data.rel.ro .data.rel.ro*) } : ph_data : ph_relro
.tdata : { *(.tdata .tdata.*) } : ph_data : ph_relro : ph_tls
}
// Compile and link this using clang+LLD. I then ran the following commands:
C:\Work\D74755> .\patched-objcopy.exe test.elf test.okd-patched.elf --only-keep-debug --remove-section=.data.rel.ro
C:\Work\D74755> .\base-objcopy.exe test.elf test.okd-base.elf --only-keep-debug --remove-section=.data.rel.ro
C:\Work\D74755> C:\llvm\build\Debug\bin\llvm-readelf --sections -l .\test.okd-base.elf > 1.txt
C:\Work\D74755> C:\llvm\build\Debug\bin\llvm-readelf --sections -l .\test.okd-patched.elf > 2.txt
1.txt and 2.txt illustrate that the section header offsets have been modified, such that they do not match those of the equivalent ELF file (i.e. one only created with just --remove-section=.data.rel.ro applied). I do not know how debuggers use the only-keep-debug information, but if they use section offsets, the patched version of objcopy will break them, as they will no longer match up. I will look at the remaining differences another time.
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D74755/new/
https://reviews.llvm.org/D74755
More information about the llvm-commits
mailing list