mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2025-01-18 12:24:38 +08:00
Change the behaviour of the --only-keep-debug option to objcopy and strip so that the sh_link and sh_info fields in stripped section headers are preserved.
bfd * elf.c (_bfd_elf_copy_private_bfd_data): Copy the sh_link and sh_info fields of sections whose type has been changed to SHT_NOBITS. bin * doc/binutils.texi: Document that the --only-keep-debug option to strip and objcopy preserves the section headers of stripped sections. tests * binutils-all/objcopy.exp (keep_debug_symbols_and_check_links): New proc. Checks that debug-info-only binaries retain the sh_link field in stripped sections.
This commit is contained in:
parent
260439cb8e
commit
63b9bbb7d7
@ -1,3 +1,9 @@
|
||||
2015-08-05 Nick Clifton <nickc@redhat.com>
|
||||
|
||||
* elf.c (_bfd_elf_copy_private_bfd_data): Copy the sh_link and
|
||||
sh_info fields of sections whose type has been changed to
|
||||
SHT_NOBITS.
|
||||
|
||||
2015-08-04 Yuriy M. Kaminskiy" <yumkam@gmail.com>
|
||||
Tyler Hicks <tyhicks@canonical.com>
|
||||
|
||||
|
57
bfd/elf.c
57
bfd/elf.c
@ -1203,6 +1203,63 @@ _bfd_elf_copy_private_bfd_data (bfd *ibfd, bfd *obfd)
|
||||
|
||||
/* Copy object attributes. */
|
||||
_bfd_elf_copy_obj_attributes (ibfd, obfd);
|
||||
|
||||
/* This is an feature for objcopy --only-keep-debug: When a section's type
|
||||
is changed to NOBITS, we preserve the sh_link and sh_info fields so that
|
||||
they can be matched up with the original. */
|
||||
Elf_Internal_Shdr ** iheaders = elf_elfsections (ibfd);
|
||||
Elf_Internal_Shdr ** oheaders = elf_elfsections (obfd);
|
||||
|
||||
if (iheaders != NULL && oheaders != NULL)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < elf_numsections (obfd); i++)
|
||||
{
|
||||
unsigned int j;
|
||||
Elf_Internal_Shdr * oheader = oheaders[i];
|
||||
|
||||
if (oheader == NULL
|
||||
|| oheader->sh_type != SHT_NOBITS
|
||||
|| oheader->sh_size == 0
|
||||
|| (oheader->sh_info != 0 && oheader->sh_link != 0))
|
||||
continue;
|
||||
|
||||
/* Scan for the matching section in the input bfd.
|
||||
FIXME: We could use something better than a linear scan here.
|
||||
Unfortunately we cannot compare names as the output string table
|
||||
is empty, so instead we check size, address and type. */
|
||||
for (j = 0; j < elf_numsections (ibfd); j++)
|
||||
{
|
||||
Elf_Internal_Shdr * iheader = iheaders[j];
|
||||
|
||||
if (iheader->sh_type != SHT_NOBITS
|
||||
&& iheader->sh_size == oheader->sh_size
|
||||
&& iheader->sh_addr == oheader->sh_addr
|
||||
&& (iheader->sh_info != oheader->sh_info
|
||||
|| iheader->sh_link != oheader->sh_link))
|
||||
{
|
||||
/* Note: Strictly speaking these assignments are wrong.
|
||||
The sh_link and sh_info fields should point to the
|
||||
relevent sections in the output BFD, which may not be in
|
||||
the same location as they were in the input BFD. But the
|
||||
whole point of this action is to preserve the original
|
||||
values of the sh_link and sh_info fields, so that they
|
||||
can be matched up with the section headers in the
|
||||
original file. So strictly speaking we may be creating
|
||||
an invalid ELF file, but it is only for a file that just
|
||||
contains debug info and only for sections without any
|
||||
contents. */
|
||||
if (oheader->sh_link == 0)
|
||||
oheader->sh_link = iheader->sh_link;
|
||||
if (oheader->sh_info == 0)
|
||||
oheader->sh_info = iheader->sh_info;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
@ -1,3 +1,9 @@
|
||||
2015-08-05 Nick Clifton <nickc@redhat.com>
|
||||
|
||||
* doc/binutils.texi: Document that the --only-keep-debug option
|
||||
to strip and objcopy preserves the section headers of stripped
|
||||
sections.
|
||||
|
||||
2015-08-04 Yuriy M. Kaminskiy" <yumkam@gmail.com>
|
||||
Tyler Hicks <tyhicks@canonical.com>
|
||||
|
||||
|
@ -1731,6 +1731,12 @@ Strip a file, removing contents of any sections that would not be
|
||||
stripped by @option{--strip-debug} and leaving the debugging sections
|
||||
intact. In ELF files, this preserves all note sections in the output.
|
||||
|
||||
Note - the section headers of the stripped sections are preserved,
|
||||
including their sizes, but the contents of the section are discarded.
|
||||
The section headers are preserved so that other tools can match up the
|
||||
debuginfo file with the real executable, even if that executable has
|
||||
been relocated to a different address space.
|
||||
|
||||
The intention is that this option will be used in conjunction with
|
||||
@option{--add-gnu-debuglink} to create a two part executable. One a
|
||||
stripped binary which will occupy less space in RAM and in a
|
||||
@ -3074,9 +3080,16 @@ When stripping a file, perhaps with @option{--strip-debug} or
|
||||
which would otherwise get stripped.
|
||||
|
||||
@item --only-keep-debug
|
||||
Strip a file, removing contents of any sections that would not be
|
||||
Strip a file, emptying the contents of any sections that would not be
|
||||
stripped by @option{--strip-debug} and leaving the debugging sections
|
||||
intact. In ELF files, this preserves all note sections in the output.
|
||||
intact. In ELF files, this preserves all the note sections in the
|
||||
output as well.
|
||||
|
||||
Note - the section headers of the stripped sections are preserved,
|
||||
including their sizes, but the contents of the section are discarded.
|
||||
The section headers are preserved so that other tools can match up the
|
||||
debuginfo file with the real executable, even if that executable has
|
||||
been relocated to a different address space.
|
||||
|
||||
The intention is that this option will be used in conjunction with
|
||||
@option{--add-gnu-debuglink} to create a two part executable. One a
|
||||
|
@ -1,3 +1,9 @@
|
||||
2015-08-05 Nick Clifton <nickc@redhat.com>
|
||||
|
||||
* binutils-all/objcopy.exp (keep_debug_symbols_and_check_links):
|
||||
New proc. Checks that debug-info-only binaries retain the
|
||||
sh_link field in stripped sections.
|
||||
|
||||
2015-08-04 Nick Clifton <nickc@redhat.com>
|
||||
|
||||
* lib/utils-lib.exp (run_dump_test): Document DUMPPROG, readelf
|
||||
|
@ -829,12 +829,70 @@ proc keep_debug_symbols_and_test_copy { prog1 flags1 test1 prog2 flags2 test2 }
|
||||
pass $test2
|
||||
}
|
||||
|
||||
# Tests that in a debug only copy of a file the sections
|
||||
# headers whoes types have been changed to NOBITS still
|
||||
# retain their sh_link fields.
|
||||
|
||||
proc keep_debug_symbols_and_check_links { prog flags test } {
|
||||
global READELF
|
||||
|
||||
remote_file build delete tmpdir/striprog
|
||||
remote_download build tmpdir/copyprog tmpdir/striprog
|
||||
if [is_remote host] {
|
||||
set copyfile [remote_download host tmpdir/striprog]
|
||||
} else {
|
||||
set copyfile tmpdir/striprog
|
||||
}
|
||||
|
||||
set exec_output [binutils_run $prog "$flags ${copyfile}"]
|
||||
if ![string match "" $exec_output] {
|
||||
fail $test
|
||||
return
|
||||
}
|
||||
|
||||
set got [binutils_run $READELF "-S --wide ${copyfile}"]
|
||||
|
||||
set fails 0
|
||||
# Regexp to match a section with NOBITS type and extract its name and sh_link fields
|
||||
while {[regexp \
|
||||
{[^a-zA-Z]+([a-zA-Z0-9_\.]+)[ ]+NOBITS[ ]+[0-9a-fA-F]+ [0-9a-fA-F]+ [0-9a-fA-F]+ [0-9]+[ A]+([0-9]+)(.*)} \
|
||||
$got all name link rest]} {
|
||||
set sh_link 0x$link
|
||||
if {$sh_link == 0} {
|
||||
# Only some NOBITS sections should have a non-zero sh_link field.
|
||||
# Look for them by name.
|
||||
verbose "NOBITS section .$name has a 0 sh_link field\n"
|
||||
switch $name {
|
||||
"rela.*" { set fails 1 ; send_log "Expected non-zero sh_link for .$name\n" }
|
||||
"rel.*" { set fails 1 ; send_log "Expected non-zero sh_link for .$name\n" }
|
||||
"hash" { set fails 1 ; send_log "Expected non-zero sh_link for .$name\n" }
|
||||
"gnu_version" { set fails 1 ; send_log "Expected non-zero sh_link for .$name\n" }
|
||||
"dynsym" { set fails 1 ; send_log "Expected non-zero sh_link for .$name\n" }
|
||||
"gnu.version_r" { set fails 1 ; send_log "Expected non-zero sh_link for .$name\n" }
|
||||
"dynamic" { set fails 1 ; send_log "Expected non-zero sh_link for .$name\n" }
|
||||
"symtab" { set fails 1 ; send_log "Expected non-zero sh_link for .$name\n" }
|
||||
}
|
||||
}
|
||||
set got $rest
|
||||
}
|
||||
|
||||
if {$fails == 0} {
|
||||
pass $test
|
||||
} else {
|
||||
fail $test
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
set test1 "simple objcopy of executable"
|
||||
set test2 "run objcopy of executable"
|
||||
set test3 "run stripped executable"
|
||||
set test4 "run stripped executable with saving a symbol"
|
||||
set test5 "keep only debug data"
|
||||
set test6 "simple objcopy of debug data"
|
||||
if [is_elf_format] {
|
||||
set test7 "NOBITS sections retain sh_link field"
|
||||
}
|
||||
|
||||
switch [copy_setup] {
|
||||
"1" {
|
||||
@ -847,6 +905,9 @@ switch [copy_setup] {
|
||||
untested $test4
|
||||
untested $test5
|
||||
untested $test6
|
||||
if [is_elf_format] {
|
||||
untested $test7
|
||||
}
|
||||
}
|
||||
"3" {
|
||||
copy_executable "$OBJCOPY" "$OBJCOPYFLAGS" "$test1" ""
|
||||
@ -855,6 +916,9 @@ switch [copy_setup] {
|
||||
unsupported $test4
|
||||
unsupported $test5
|
||||
unsupported $test6
|
||||
if [is_elf_format] {
|
||||
unsupported $test7
|
||||
}
|
||||
}
|
||||
"0" {
|
||||
copy_executable "$OBJCOPY" "$OBJCOPYFLAGS" "$test1" "$test2"
|
||||
@ -862,6 +926,9 @@ switch [copy_setup] {
|
||||
strip_executable_with_saving_a_symbol "$STRIP" "-K main -K _main $STRIPFLAGS" "$test4"
|
||||
keep_debug_symbols_and_test_copy "$STRIP" "--only-keep-debug $STRIPFLAGS" "$test5" \
|
||||
"$OBJCOPY" "$OBJCOPYFLAGS" "$test6"
|
||||
if [is_elf_format] {
|
||||
keep_debug_symbols_and_check_links "$STRIP" "--only-keep-debug $STRIPFLAGS" "$test7"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user