Bug 14475 - strip is broken on archive
Summary: strip is broken on archive
Status: RESOLVED FIXED
Alias: None
Product: binutils
Classification: Unclassified
Component: binutils (show other bugs)
Version: 2.24
: P2 normal
Target Milestone: ---
Assignee: Tom Tromey
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2012-08-15 19:40 UTC by H.J. Lu
Modified: 2012-08-17 16:29 UTC (History)
1 user (show)

See Also:
Host:
Target:
Build:
Last reconfirmed:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description H.J. Lu 2012-08-15 19:40:48 UTC
On Linux/x86-64, I got


[hjl@gnu-6 tmp]$ cp /usr/lib64/libc.a /tmp
...
(gdb) r
Starting program: /export/build/gnu/binutils/build-x86_64-linux/binutils/strip-new /tmp/libc.a

Program received signal SIGSEGV, Segmentation fault.
0x0000000000434a01 in _bfd_archive_close_and_cleanup (abfd=0x13cd6e0)
    at /export/gnu/import/git/binutils/bfd/archive.c:2732
2732	      htab_t htab = (htab_t) ared->parent_cache;
(gdb) bt
#0  0x0000000000434a01 in _bfd_archive_close_and_cleanup (abfd=0x13cd6e0)
    at /export/gnu/import/git/binutils/bfd/archive.c:2732
#1  0x0000000000477dc3 in _bfd_elf_close_and_cleanup (abfd=0x13cd6e0)
    at /export/gnu/import/git/binutils/bfd/elf.c:7842
#2  0x000000000043f469 in bfd_close (abfd=0x13cd6e0)
    at /export/gnu/import/git/binutils/bfd/opncls.c:718
#3  0x000000000040642c in copy_archive (ibfd=0x74dc40, obfd=0x7687a0, 
    output_target=0x506900 "elf64-x86-64", force_output_target=0, 
    input_arch=0x0) at /export/gnu/import/git/binutils/binutils/objcopy.c:2230
#4  0x000000000040669b in copy_file (
    input_filename=0x7fffffffe206 "/tmp/libc.a", 
    output_filename=0x74cf00 "/tmp/stdakjmS", input_target=0x0, 
    output_target=0x506900 "elf64-x86-64", input_arch=0x0)
    at /export/gnu/import/git/binutils/binutils/objcopy.c:2318
#5  0x000000000040809b in strip_main (argc=2, argv=0x7fffffffde88)
    at /export/gnu/import/git/binutils/binutils/objcopy.c:3168
#6  0x0000000000409ffb in main (argc=2, argv=0x7fffffffde88)
    at /export/gnu/import/git/binutils/binutils/objcopy.c:4139
(gdb)
Comment 1 Tom Tromey 2012-08-15 19:45:52 UTC
==27086== Invalid read of size 8
==27086==    at 0x435B6B: _bfd_archive_close_and_cleanup (archive.c:2732)
==27086==    by 0x4797C8: _bfd_elf_close_and_cleanup (elf.c:7842)
==27086==    by 0x4408C1: bfd_close (opncls.c:718)
==27086==    by 0x406144: copy_archive (objcopy.c:2230)
==27086==    by 0x4063B3: copy_file (objcopy.c:2318)
==27086==    by 0x407D27: strip_main (objcopy.c:3168)
==27086==    by 0x409D6A: main (objcopy.c:4139)
==27086==  Address 0x4c48130 is 736 bytes inside a block of size 4,064 free'd
==27086==    at 0x4A0662E: free (vg_replace_malloc.c:366)
==27086==    by 0x91576A: objalloc_free (objalloc.c:180)
==27086==    by 0x43FF61: _bfd_delete_bfd (opncls.c:136)
==27086==    by 0x440902: bfd_close (opncls.c:726)
==27086==    by 0x40608A: copy_archive (objcopy.c:2208)
==27086==    by 0x4063B3: copy_file (objcopy.c:2318)
==27086==    by 0x407D27: strip_main (objcopy.c:3168)
==27086==    by 0x409D6A: main (objcopy.c:4139)
Comment 2 H.J. Lu 2012-08-15 20:01:42 UTC
copy_archive has

  filename = bfd_get_filename (obfd);
  if (!bfd_close (obfd))
    {
      status = 1;
      bfd_nonfatal_message (filename, NULL, NULL, NULL);
      return;
    }

  filename = bfd_get_filename (ibfd);
  if (!bfd_close (ibfd))
    {
      status = 1;
      bfd_nonfatal_message (filename, NULL, NULL, NULL);
      return;
    }

  /* Delete all the files that we opened.  */
  for (l = list; l != NULL; l = l->next)
    {
      if (l->obfd == NULL)
        rmdir (l->name);
      else
        {
          bfd_close (l->obfd);
          unlink (l->name);
        }
    }

Since if (!bfd_close (obfd)) closed all output bfds now,
bfd_close (l->obfd) closes a closed bfd.
Comment 3 Tom Tromey 2012-08-15 20:57:30 UTC
I think the bug is that bfd_ar_hdr_from_filesystem
allocates the areltdata on the wrong BFD.
I'm testing a patch.
Comment 4 Tom Tromey 2012-08-15 21:00:51 UTC
(In reply to comment #2)

> Since if (!bfd_close (obfd)) closed all output bfds now,
> bfd_close (l->obfd) closes a closed bfd.

No, that isn't it.  The member BFDs are only closed for
an archive opened for reading.

I'll send my patch in a minute.
Comment 5 Sourceware Commits 2012-08-16 14:24:55 UTC
CVSROOT:	/cvs/src
Module name:	src
Changes by:	tromey@sourceware.org	2012-08-16 14:24:44

Modified files:
	bfd            : ChangeLog archive.c 

Log message:
	PR binutils/14475:
	* archive.c (bfd_ar_hdr_from_filesystem): Allocate areltdata on
	'member' BFD.  Don't try to free 'ared'.

Patches:
http://sourceware.org/cgi-bin/cvsweb.cgi/src/bfd/ChangeLog.diff?cvsroot=src&r1=1.5781&r2=1.5782
http://sourceware.org/cgi-bin/cvsweb.cgi/src/bfd/archive.c.diff?cvsroot=src&r1=1.89&r2=1.90
Comment 6 Tom Tromey 2012-08-16 14:26:33 UTC
Fixed.
Comment 7 H.J. Lu 2012-08-16 15:57:31 UTC
The checkin totally breaks binutils and "make check"
reports:


FAIL: ar symbol table
FAIL: ar thin archive
FAIL: ar thin archive with nested archive
FAIL: ar argument parsing
FAIL: ar deterministic archive
FAIL: ar deleting an element
FAIL: ar moving an element
FAIL: ar unique symbol in archive
FAIL: compressed debug sections
FAIL: strip
FAIL: Build symbol3.a
FAIL: Build symbol3w.a
FAIL: Build pr14170a.o
FAIL: ld-elf/warn3
FAIL: Build library1.a
FAIL: Build library2.a
FAIL: Build secondary3a.o
FAIL: Build libpr9676-1.a
FAIL: Build libpr9676-2.a
FAIL: Build libpr9676-4a.so
FAIL: Could not create a static library containing an IFUNC symbol
FAIL: Build libentry.a
FAIL: --entry foo archive
FAIL: --entry foo -u foo archive
FAIL: -shared --entry foo archive
FAIL: -shared --entry foo -u foo archive
FAIL: Helper X32 DSO from x86-64 object

on Linux/x86-64.
Comment 8 Sourceware Commits 2012-08-17 01:06:34 UTC
CVSROOT:	/cvs/src
Module name:	src
Changes by:	amodra@sourceware.org	2012-08-17 01:06:28

Modified files:
	bfd            : ChangeLog archive.c 

Log message:
	PR binutils/14475:
	* archive.c (bfd_ar_hdr_from_filesystem): Revert last change.
	Instead malloc areltdata.

Patches:
http://sourceware.org/cgi-bin/cvsweb.cgi/src/bfd/ChangeLog.diff?cvsroot=src&r1=1.5782&r2=1.5783
http://sourceware.org/cgi-bin/cvsweb.cgi/src/bfd/archive.c.diff?cvsroot=src&r1=1.90&r2=1.91
Comment 9 H.J. Lu 2012-08-17 16:29:41 UTC
Fixed.