From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 9396 invoked by alias); 3 Aug 2012 14:55:03 -0000 Received: (qmail 9382 invoked by uid 22791); 3 Aug 2012 14:55:02 -0000 X-SWARE-Spam-Status: No, hits=-6.5 required=5.0 tests=AWL,BAYES_00,KHOP_RCVD_UNTRUST,RCVD_IN_DNSWL_HI,RCVD_IN_HOSTKARMA_W,SPF_HELO_PASS,T_RP_MATCHES_RCVD X-Spam-Check-By: sourceware.org Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Fri, 03 Aug 2012 14:54:42 +0000 Received: from int-mx09.intmail.prod.int.phx2.redhat.com (int-mx09.intmail.prod.int.phx2.redhat.com [10.5.11.22]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id q73EsfAw015245 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Fri, 3 Aug 2012 10:54:41 -0400 Received: from barimba (ovpn01.gateway.prod.ext.phx2.redhat.com [10.5.9.1]) by int-mx09.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id q73EsesH015951 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES128-SHA bits=128 verify=NO); Fri, 3 Aug 2012 10:54:41 -0400 From: Tom Tromey To: Binutils Development Subject: [PATCH 3/5] remove deleted BFDs from the archive cache Date: Fri, 03 Aug 2012 14:55:00 -0000 Message-ID: <87txwknhzj.fsf@fleche.redhat.com> MIME-Version: 1.0 Content-Type: text/plain Mailing-List: contact binutils-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: binutils-owner@sourceware.org X-SW-Source: 2012-08/txt/msg00057.txt.bz2 Right now if you bfd_close a member BFD, the pointer to the BFD remains in the parent archive's cache. This means that if you try to re-open that member, BFD will return a stale pointer. This patch fixes the problem by deleting the entry from the hash. I could not find a way to look up the member BFD in its parent cache directly, hence the iteration. * archive.c (delete_bfd_from_htab): New function. (_bfd_delete_archive_data): Iterate over the parent archive's hash table. --- bfd/archive.c | 29 +++++++++++++++++++++++++++++ 1 files changed, 29 insertions(+), 0 deletions(-) diff --git a/bfd/archive.c b/bfd/archive.c index 8d02257..f84a8fc 100644 --- a/bfd/archive.c +++ b/bfd/archive.c @@ -293,6 +293,24 @@ bfd_set_archive_head (bfd *output_archive, bfd *new_head) return TRUE; } +/* A callback for htab_traverse that finds and clears an entry + corresponding to a given BFD. */ + +static int +delete_bfd_from_htab (void **slot, void *arg) +{ + struct ar_cache *cache = *slot; + bfd *abfd = arg; + + if (cache->arbfd == abfd) + { + *slot = HTAB_DELETED_ENTRY; + return 0; + } + + return 1; +} + /* Free the archive hash table, if it exists. */ void @@ -302,6 +320,17 @@ _bfd_delete_archive_data (bfd *abfd) if (ardata && ardata->cache) htab_delete (ardata->cache); + + if (abfd->my_archive) + { + ardata = bfd_ardata (abfd->my_archive); + if (ardata && ardata->cache) + { + /* We have to traverse the hash table because there is no + way to find ABFD in it directly. */ + htab_traverse_noresize (ardata->cache, delete_bfd_from_htab, abfd); + } + } } bfd * -- 1.7.7.6