This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
Re: [PATCH] objcopy --only-keep-debug vs SHT_NOTE
On Mon, May 21, 2007 at 08:45:07PM +0930, Alan Modra wrote:
> On Sat, May 19, 2007 at 04:24:41PM -0700, Roland McGrath wrote:
> > This patch changes objcopy --only-keep-debug in two ways. First, it
> > preserves the sh_type of saved sections not being otherwise molested.
> > This, for example, makes unallocated note sections preserved in .debug
> > files keep their SHT_NOTE type instead of being reset to SHT_PROGBITS.
>
> Yes, that's a bug. I don't think your fix is the best possible
> though; We probably should be calling copy_private_section_data for
> any sections we copy.
This patch puts back the ELF program headers for debug info files,
tidying the way objcopy handles --only-keep-debug. We no longer need
to avoid copying section and bfd private data for ELF, and my change
to assign_file_positions_for_load_sections means that we can leave
bfd section flags unchanged. The latter is important, considering
that elf.c:_bfd_elf_copy_private_header_data completely rewrites the
program headers if it sees any section flag changes.
> > Second, it does not discard allocated SHT_NOTE sections.
I haven't done anything about this part of Roland's patch. ie. we
still discard them. Roland, please resubmit (it should just be a
one line change to the condition where we set SHT_NOBITS, I think).
bfd/
* elf.c (elf_fake_sections): Adjust test for SHT_NOBITS sections
created by objcopy --only-keep-debug.
(_bfd_elf_init_private_section_data): Only change elf_section_type
if it is SHT_NULL.
binutils/
* objcopy.c (copy_object): Revert 2007-05-11 change. Don't
avoid calling bfd_copy_private_bfd_data for ELF STRIP_NONDEBUG.
(setup_section): Don't modify flags, and don't avoid calling
bfd_copy_private_section_data for ELF STRIP_NONDEBUG.
* readelf.c (process_program_headers): Ignore .dynamic of type
SHT_NOBITS.
Index: bfd/elf.c
===================================================================
RCS file: /cvs/src/src/bfd/elf.c,v
retrieving revision 1.390
diff -u -p -r1.390 elf.c
--- bfd/elf.c 30 May 2007 13:38:50 -0000 1.390
+++ bfd/elf.c 30 May 2007 13:58:23 -0000
@@ -2907,11 +2907,10 @@ elf_fake_sections (bfd *abfd, asection *
&& !(*bed->elf_backend_fake_sections) (abfd, this_hdr, asect))
*failedptr = TRUE;
- if (sh_type == SHT_NOBITS
- && elf_elfheader (abfd)->e_phnum == 0)
+ if (sh_type == SHT_NOBITS && asect->size != 0)
{
/* Don't change the header type from NOBITS if we are being
- called for strip/objcopy --only-keep-debug. */
+ called for objcopy --only-keep-debug. */
this_hdr->sh_type = sh_type;
}
@@ -6039,13 +6038,9 @@ _bfd_elf_init_private_section_data (bfd
output BFD section flags have been set to something different.
elf_fake_sections will set ELF section type based on BFD
section flags. */
- if (osec->flags == isec->flags || !osec->flags)
- {
- BFD_ASSERT (osec->flags == isec->flags
- || (!osec->flags
- && elf_section_type (osec) == SHT_NULL));
- elf_section_type (osec) = elf_section_type (isec);
- }
+ if (elf_section_type (osec) == SHT_NULL
+ && (osec->flags == isec->flags || !osec->flags))
+ elf_section_type (osec) = elf_section_type (isec);
/* FIXME: Is this correct for all OS/PROC specific flags? */
elf_section_flags (osec) |= (elf_section_flags (isec)
Index: binutils/objcopy.c
===================================================================
RCS file: /cvs/src/src/binutils/objcopy.c,v
retrieving revision 1.112
diff -u -p -r1.112 objcopy.c
--- binutils/objcopy.c 18 May 2007 06:36:14 -0000 1.112
+++ binutils/objcopy.c 30 May 2007 13:58:27 -0000
@@ -1423,12 +1423,7 @@ copy_object (bfd *ibfd, bfd *obfd)
any output is done. Thus, we traverse all sections multiple times. */
bfd_map_over_sections (ibfd, setup_section, obfd);
- /* Don't copy headers when creating an ELF format debug info file. */
- if (bfd_get_flavour (ibfd) == bfd_target_elf_flavour
- && strip_symbols == STRIP_NONDEBUG)
- ;
- else
- setup_bfd_headers (ibfd, obfd);
+ setup_bfd_headers (ibfd, obfd);
if (add_sections != NULL)
{
@@ -1771,12 +1766,7 @@ copy_object (bfd *ibfd, bfd *obfd)
from the input BFD to the output BFD. This is done last to
permit the routine to look at the filtered symbol table, which is
important for the ECOFF code at least. */
- if (bfd_get_flavour (ibfd) == bfd_target_elf_flavour
- && strip_symbols == STRIP_NONDEBUG)
- /* Do not copy the private data when creating an ELF format
- debug info file. We do not want the program headers. */
- ;
- else if (! bfd_copy_private_bfd_data (ibfd, obfd))
+ if (! bfd_copy_private_bfd_data (ibfd, obfd))
{
non_fatal (_("%s: error copying private BFD data: %s"),
bfd_get_filename (obfd),
@@ -2206,7 +2196,9 @@ setup_section (bfd *ibfd, sec_ptr isecti
if (p != NULL && p->set_flags)
flags = p->flags | (flags & (SEC_HAS_CONTENTS | SEC_RELOC));
- else if (strip_symbols == STRIP_NONDEBUG && (flags & SEC_ALLOC) != 0)
+ else if (strip_symbols == STRIP_NONDEBUG
+ && obfd->xvec->flavour != bfd_target_elf_flavour
+ && (flags & SEC_ALLOC) != 0)
flags &= ~(SEC_HAS_CONTENTS | SEC_LOAD);
osection = bfd_make_section_anyway_with_flags (obfd, name, flags);
@@ -2289,12 +2281,7 @@ setup_section (bfd *ibfd, sec_ptr isecti
/* Allow the BFD backend to copy any private data it understands
from the input section to the output section. */
- if (bfd_get_flavour (ibfd) == bfd_target_elf_flavour
- && strip_symbols == STRIP_NONDEBUG)
- /* Do not copy the private data when creating an ELF format
- debug info file. We do not want the program headers. */
- ;
- else if (!bfd_copy_private_section_data (ibfd, isection, obfd, osection))
+ if (!bfd_copy_private_section_data (ibfd, isection, obfd, osection))
{
err = _("private data");
goto loser;
Index: binutils/readelf.c
===================================================================
RCS file: /cvs/src/src/binutils/readelf.c,v
retrieving revision 1.364
diff -u -p -r1.364 readelf.c
--- binutils/readelf.c 26 Apr 2007 14:46:59 -0000 1.364
+++ binutils/readelf.c 30 May 2007 13:58:28 -0000
@@ -3516,6 +3516,9 @@ process_program_headers (FILE *file)
break;
}
+ if (sec->sh_type == SHT_NOBITS)
+ break;
+
dynamic_addr = sec->sh_offset;
dynamic_size = sec->sh_size;
--
Alan Modra
IBM OzLabs - Linux Technology Centre