BFD 2.14 crashes when program is opening and operating on archives containing other archives (with bfd_openr_next_archived_file). The problems arise usually when there are too many open files and open file caching takes effect. At many places in code, there are constructs like if (bfd->my_archive) offset += bfd->origin; and similar. The problem with these is that if bfd->my_archive is contained in some archive too, you add only offset of inner archive, not offset of outer archive. Similarly, in bfd_cache_lookup_worker you do if (abfd->my_archive) abfd = abfd->my_archive; --- now if archives are nested, you need to get to the topmost archive. The crash becomes because of this and other bug --- bfd cache doesn't check if files was reopened succesfully --- see my next bug report. The attached patch fixes the problems with nested archives --- it modifies archive creating so that bfd->my_archive always points to the topmost archive, not to the immediate descendant. With the patch, i can link large programs with nested archives flawlessly. --- bfd/archive.c_ Wed Apr 21 19:28:07 2004 +++ bfd/archive.c Wed Apr 21 20:54:25 2004 @@ -498,6 +498,11 @@ struct areltdata *new_areldata; bfd *n_nfd; + if (archive->my_archive) { + filepos += archive->origin; + archive = archive->my_archive; + } + n_nfd = _bfd_look_for_bfd_in_cache (archive, filepos); if (n_nfd) return n_nfd; @@ -593,6 +598,7 @@ BSD-4.4-style element with a long odd size. */ filestart = last_file->origin + size; filestart += filestart % 2; + if (archive->my_archive) filestart -= archive->origin; } return _bfd_get_elt_at_filepos (archive, filestart);
Can you supply a simple test case (in the dejagnu harness) to demonstrate that this patch works? Thanks, Ben
Probably not --- it was triggered with custom linker using bfd (not gnu-ld ... gnu ld walks all archives only once, so maybe this bug is not triggerable with it at all) and several megabyte application. It can't be triggered with simple nested archives, because bfd caching doesn't take effect. Or do you want that big application and linker?
Adding here for the audit trail: From: Nick Clifton <nickc@redhat.com> Subject: Re: crashes with nested archives Cc: bug-binutils@gnu.org Date: Wed, 05 May 2004 15:59:12 +0100 Hi Mikulas, >Binutils-2.14 have serious problems when processing archives containing > other archives. Thanks for bringing this to our attention. I hope that you do not mind, but there are a couple of problems with your proposed patch: * It is not clear to me how nested archives can be successfully used. I tried a simplest test like this: gcc hello-world.c -c -o file1.o cp file1.o file2.o cp file1.o file3.o cp file1.o file4.o ar cr lib1.a file1.o file2.o ar cr lib2.a file3.o file4.o ar cr lib3.a lib1.a lib2.s objdump -p lib3.a In archive lib3.a: objdump: lib1.a: File format not recognized objdump: lib2.a: File format not recognized So in order to proceed with fixing this bug we definitely need a test case that can reproduce the problem. * The patch assumes that there will only be one level of nested archives. Instead it should recurse until there are no more nested archive levels to process. * The patch to bfd_generic_openr_next_archived_file() puts the new code *after* filestart has been aligned to an even byte boundary. It ought to be *before* the alignment. * It would be helpful if you could include a ChangeLog entry for the patch as well. I hope that you will consider resubmitting your patch with these points addressed. Cheers Nick
The PR is not host or target specific.
Nick committed the patch.