aboutsummaryrefslogtreecommitdiff
path: root/bfd/elf.c
diff options
context:
space:
mode:
authorNick Clifton <nickc@redhat.com>2015-08-05 16:16:39 +0100
committerNick Clifton <nickc@redhat.com>2015-08-05 16:16:39 +0100
commit63b9bbb7d7bcdcb6e0f59dd8da9615d80c537b8d (patch)
tree63a87d567a4c30e48ed3ae9784fe5b03e3621a31 /bfd/elf.c
parent260439cb8ec21ffd75b240aadc55fd341c8c8dd4 (diff)
downloadgdb-63b9bbb7d7bcdcb6e0f59dd8da9615d80c537b8d.zip
gdb-63b9bbb7d7bcdcb6e0f59dd8da9615d80c537b8d.tar.gz
gdb-63b9bbb7d7bcdcb6e0f59dd8da9615d80c537b8d.tar.bz2
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.
Diffstat (limited to 'bfd/elf.c')
-rw-r--r--bfd/elf.c57
1 files changed, 57 insertions, 0 deletions
diff --git a/bfd/elf.c b/bfd/elf.c
index 05ee025..67e4240 100644
--- a/bfd/elf.c
+++ b/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;
}