This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
Re: [PATCH 3/5] remove deleted BFDs from the archive cache
On Thu, Aug 16, 2012 at 5:48 PM, Alan Modra <amodra@gmail.com> wrote:
> On Thu, Aug 16, 2012 at 11:02:18AM -0600, Tom Tromey wrote:
>> Another possible fix for this bug would be to allocate the areltdata
>> using malloc. That way it would be immune to the objalloc_free call.
>> This would require a few more tweaks, like properly freeing it in
>> _bfd_delete_bfd, etc.
>>
>> I'm happy to make and test this change if you think it would be better.
>
> Yes, I do think that would be better. bfd_free_cached_info is called
> only in one place, and the whole point of the call is as the comment
> says
> /* Now ask the BFD to free up any cached information, so we
> don't fill all of memory with symbol tables. */
>
> If you don't free the bfd memory there isn't much point in having
> bfd_free_cached_info!
>
We run into this problem only when we allocate areltdata from
archive member from filesystem. When we use xcalloc,
we only support bfd_close archive before bfd_close archive member
if we want to free the memory in bfd_close archive member.
Here is a patch to only use xcalloc in bfd_ar_hdr_from_filesystem.
We can check if parent_cache is NULL before calling free.
--
H.J.
--
2012-08-16 H.J. Lu <hongjiu.lu@intel.com>
PR binutils/14475
* archive.c (bfd_ar_hdr_from_filesystem): Allocate areltdata
with xcalloc.
(_bfd_archive_close_and_cleanup): Free areltdata if allocated
with xcalloc.
diff --git a/bfd/archive.c b/bfd/archive.c
index e0cb370..608a7e9 100644
--- a/bfd/archive.c
+++ b/bfd/archive.c
@@ -1896,7 +1896,9 @@ bfd_ar_hdr_from_filesystem (bfd *abfd, const char *filena
me, bfd *member)
}
amt = sizeof (struct ar_hdr) + sizeof (struct areltdata);
- ared = (struct areltdata *) bfd_zalloc (member, amt);
+ /* Use xcalloc instead of bfd_zalloc so that areltdata is available
+ to archive after objalloc_free is called on member memory. */
+ ared = (struct areltdata *) xcalloc (1, amt);
if (ared == NULL)
return NULL;
hdr = (struct ar_hdr *) (((char *) ared) + sizeof (struct areltdata));
@@ -2741,6 +2743,11 @@ _bfd_archive_close_and_cleanup (bfd *abfd)
htab_clear_slot (htab, slot);
}
}
+ else
+ {
+ /* If HTAB is NULL, free ARED allocated with xcalloc. */
+ free (ared);
+ }
}
return TRUE;
}