Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(162)

Unified Diff: bfd/archive.c

Issue 124383005: GDB 7.6.50 (Closed) Base URL: http://git.chromium.org/native_client/nacl-gdb.git@upstream
Patch Set: Created 6 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « bfd/aout0.c ('k') | bfd/archive64.c » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: bfd/archive.c
diff --git a/bfd/archive.c b/bfd/archive.c
index fe57755770bbbfc43be705fb5c437dd8619dff7d..32b07a718a2b9825c41885572dbd544d6803c16f 100644
--- a/bfd/archive.c
+++ b/bfd/archive.c
@@ -1,7 +1,5 @@
/* BFD back-end for archive files (libraries).
- Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
- 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011,
- 2012 Free Software Foundation, Inc.
+ Copyright 1990-2013 Free Software Foundation, Inc.
Written by Cygnus Support. Mostly Gumby Henkel-Wallace's fault.
This file is part of BFD, the Binary File Descriptor library.
@@ -42,11 +40,17 @@ DESCRIPTION
have to read the entire archive if you don't want
to! Read it until you find what you want.
+ A BFD returned by <<bfd_openr_next_archived_file>> can be
+ closed manually with <<bfd_close>>. If you do not close it,
+ then a second iteration through the members of an archive may
+ return the same BFD. If you close the archive BFD, then all
+ the member BFDs will automatically be closed as well.
+
Archive contents of output BFDs are chained through the
- <<next>> pointer in a BFD. The first one is findable through
- the <<archive_head>> slot of the archive. Set it with
- <<bfd_set_archive_head>> (q.v.). A given BFD may be in only one
- open output archive at a time.
+ <<archive_next>> pointer in a BFD. The first one is findable
+ through the <<archive_head>> slot of the archive. Set it with
+ <<bfd_set_archive_head>> (q.v.). A given BFD may be in only
+ one open output archive at a time.
As expected, the BFD archive code is more general than the
archive code of any given environment. BFD archives may
@@ -362,6 +366,10 @@ _bfd_add_bfd_to_archive_cache (bfd *arch_bfd, file_ptr filepos, bfd *new_elt)
cache->arbfd = new_elt;
*htab_find_slot (hash_table, (const void *) cache, INSERT) = cache;
+ /* Provide a means of accessing this from child. */
+ arch_eltdata (new_elt)->parent_cache = hash_table;
+ arch_eltdata (new_elt)->key = filepos;
+
return TRUE;
}
@@ -371,6 +379,13 @@ _bfd_find_nested_archive (bfd *arch_bfd, const char *filename)
bfd *abfd;
const char *target;
+ /* PR 15140: Don't allow a nested archive pointing to itself. */
+ if (filename_cmp (filename, arch_bfd->filename) == 0)
+ {
+ bfd_set_error (bfd_error_malformed_archive);
+ return NULL;
+ }
+
for (abfd = arch_bfd->nested_archives;
abfd != NULL;
abfd = abfd->archive_next)
@@ -507,7 +522,7 @@ _bfd_generic_read_ar_hdr_mag (bfd *abfd, const char *mag)
parsed_size -= namelen;
extra_size = namelen;
- allocptr = (char *) bfd_zalloc (abfd, allocsize);
+ allocptr = (char *) bfd_zmalloc (allocsize);
if (allocptr == NULL)
return NULL;
filename = (allocptr
@@ -515,6 +530,7 @@ _bfd_generic_read_ar_hdr_mag (bfd *abfd, const char *mag)
+ sizeof (struct ar_hdr));
if (bfd_bread (filename, namelen, abfd) != namelen)
{
+ free (allocptr);
if (bfd_get_error () != bfd_error_system_call)
bfd_set_error (bfd_error_no_more_archived_files);
return NULL;
@@ -550,7 +566,7 @@ _bfd_generic_read_ar_hdr_mag (bfd *abfd, const char *mag)
if (!allocptr)
{
- allocptr = (char *) bfd_zalloc (abfd, allocsize);
+ allocptr = (char *) bfd_zmalloc (allocsize);
if (allocptr == NULL)
return NULL;
}
@@ -633,7 +649,10 @@ _bfd_get_elt_at_filepos (bfd *archive, file_ptr filepos)
{
filename = _bfd_append_relative_path (archive, filename);
if (filename == NULL)
- return NULL;
+ {
+ free (new_areldata);
+ return NULL;
+ }
}
if (new_areldata->origin > 0)
@@ -645,13 +664,13 @@ _bfd_get_elt_at_filepos (bfd *archive, file_ptr filepos)
if (ext_arch == NULL
|| ! bfd_check_format (ext_arch, bfd_archive))
{
- bfd_release (archive, new_areldata);
+ free (new_areldata);
return NULL;
}
n_nfd = _bfd_get_elt_at_filepos (ext_arch, new_areldata->origin);
if (n_nfd == NULL)
{
- bfd_release (archive, new_areldata);
+ free (new_areldata);
return NULL;
}
n_nfd->proxy_origin = bfd_tell (archive);
@@ -673,7 +692,7 @@ _bfd_get_elt_at_filepos (bfd *archive, file_ptr filepos)
if (n_nfd == NULL)
{
- bfd_release (archive, new_areldata);
+ free (new_areldata);
return NULL;
}
@@ -697,7 +716,8 @@ _bfd_get_elt_at_filepos (bfd *archive, file_ptr filepos)
if (_bfd_add_bfd_to_archive_cache (archive, filepos, n_nfd))
return n_nfd;
- bfd_release (archive, new_areldata);
+ free (new_areldata);
+ n_nfd->arelt_data = NULL;
return NULL;
}
@@ -837,11 +857,7 @@ bfd_generic_archive_p (bfd *abfd)
first->target_defaulted = FALSE;
if (bfd_check_format (first, bfd_object)
&& first->xvec != abfd->xvec)
- {
- bfd_set_error (bfd_error_wrong_object_format);
- bfd_ardata (abfd) = tdata_hold;
- return NULL;
- }
+ bfd_set_error (bfd_error_wrong_object_format);
/* And we ought to close `first' here too. */
}
}
@@ -884,7 +900,7 @@ do_slurp_bsd_armap (bfd *abfd)
if (mapdata == NULL)
return FALSE;
parsed_size = mapdata->parsed_size;
- bfd_release (abfd, mapdata); /* Don't need it any more. */
+ free (mapdata);
raw_armap = (bfd_byte *) bfd_zalloc (abfd, parsed_size);
if (raw_armap == NULL)
@@ -960,7 +976,7 @@ do_slurp_coff_armap (bfd *abfd)
if (mapdata == NULL)
return FALSE;
parsed_size = mapdata->parsed_size;
- bfd_release (abfd, mapdata); /* Don't need it any more. */
+ free (mapdata);
if (bfd_bread (int_buf, 4, abfd) != 4)
{
@@ -1053,7 +1069,7 @@ do_slurp_coff_armap (bfd *abfd)
ardata->first_file_filepos +=
(tmp->parsed_size + sizeof (struct ar_hdr) + 1) & ~(unsigned) 1;
}
- bfd_release (abfd, tmp);
+ free (tmp);
}
}
@@ -1170,15 +1186,17 @@ bfd_slurp_bsd_armap_f2 (bfd *abfd)
if (mapdata->parsed_size < HPUX_SYMDEF_COUNT_SIZE + BSD_STRING_COUNT_SIZE)
{
+ free (mapdata);
wrong_format:
bfd_set_error (bfd_error_wrong_format);
byebye:
- bfd_release (abfd, mapdata);
return FALSE;
}
left = mapdata->parsed_size - HPUX_SYMDEF_COUNT_SIZE - BSD_STRING_COUNT_SIZE;
amt = mapdata->parsed_size;
+ free (mapdata);
+
raw_armap = (bfd_byte *) bfd_zalloc (abfd, amt);
if (raw_armap == NULL)
goto byebye;
@@ -1280,7 +1298,7 @@ _bfd_slurp_extended_name_table (bfd *abfd)
if (bfd_ardata (abfd)->extended_names == NULL)
{
byebye:
- bfd_release (abfd, namedata);
+ free (namedata);
return FALSE;
}
@@ -1317,8 +1335,7 @@ _bfd_slurp_extended_name_table (bfd *abfd)
bfd_ardata (abfd)->first_file_filepos +=
(bfd_ardata (abfd)->first_file_filepos) % 2;
- /* FIXME, we can't release namedata here because it was allocated
- below extended_names on the objalloc... */
+ free (namedata);
}
return TRUE;
}
@@ -1886,7 +1903,7 @@ bfd_ar_hdr_from_filesystem (bfd *abfd, const char *filename, bfd *member)
}
amt = sizeof (struct ar_hdr) + sizeof (struct areltdata);
- ared = (struct areltdata *) bfd_zalloc (abfd, amt);
+ ared = (struct areltdata *) bfd_zmalloc (amt);
if (ared == NULL)
return NULL;
hdr = (struct ar_hdr *) (((char *) ared) + sizeof (struct areltdata));
@@ -2408,9 +2425,6 @@ bsd_write_armap (bfd *arch,
unsigned int count;
struct ar_hdr hdr;
long uid, gid;
- file_ptr max_first_real = 1;
-
- max_first_real <<= 31;
firstreal = mapsize + elength + sizeof (struct ar_hdr) + SARMAG;
@@ -2453,6 +2467,7 @@ bsd_write_armap (bfd *arch,
for (count = 0; count < orl_count; count++)
{
+ unsigned int offset;
bfd_byte buf[BSD_SYMDEF_SIZE];
if (map[count].u.abfd != last_elt)
@@ -2472,12 +2487,13 @@ bsd_write_armap (bfd *arch,
/* The archive file format only has 4 bytes to store the offset
of the member. Check to make sure that firstreal has not grown
too big. */
- if (firstreal >= max_first_real)
+ offset = (unsigned int) firstreal;
+ if (firstreal != (file_ptr) offset)
{
bfd_set_error (bfd_error_file_truncated);
return FALSE;
}
-
+
last_elt = current;
H_PUT_32 (arch, map[count].namidx, buf);
H_PUT_32 (arch, firstreal, buf + BSD_SYMDEF_OFFSET_SIZE);
@@ -2682,3 +2698,58 @@ coff_write_armap (bfd *arch,
return TRUE;
}
+
+static int
+archive_close_worker (void **slot, void *inf ATTRIBUTE_UNUSED)
+{
+ struct ar_cache *ent = (struct ar_cache *) *slot;
+
+ bfd_close_all_done (ent->arbfd);
+ return 1;
+}
+
+bfd_boolean
+_bfd_archive_close_and_cleanup (bfd *abfd)
+{
+ if (bfd_read_p (abfd) && abfd->format == bfd_archive)
+ {
+ bfd *nbfd;
+ bfd *next;
+ htab_t htab;
+
+ /* Close nested archives (if this bfd is a thin archive). */
+ for (nbfd = abfd->nested_archives; nbfd; nbfd = next)
+ {
+ next = nbfd->archive_next;
+ bfd_close (nbfd);
+ }
+
+ htab = bfd_ardata (abfd)->cache;
+ if (htab)
+ {
+ htab_traverse_noresize (htab, archive_close_worker, NULL);
+ htab_delete (htab);
+ bfd_ardata (abfd)->cache = NULL;
+ }
+ }
+ if (arch_eltdata (abfd) != NULL)
+ {
+ struct areltdata *ared = arch_eltdata (abfd);
+ htab_t htab = (htab_t) ared->parent_cache;
+
+ if (htab)
+ {
+ struct ar_cache ent;
+ void **slot;
+
+ ent.ptr = ared->key;
+ slot = htab_find_slot (htab, &ent, NO_INSERT);
+ if (slot != NULL)
+ {
+ BFD_ASSERT (((struct ar_cache *) *slot)->arbfd == abfd);
+ htab_clear_slot (htab, slot);
+ }
+ }
+ }
+ return TRUE;
+}
« no previous file with comments | « bfd/aout0.c ('k') | bfd/archive64.c » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698