aboutsummaryrefslogtreecommitdiff
path: root/binutils
diff options
context:
space:
mode:
authorNick Clifton <nickc@redhat.com>2013-02-15 14:37:39 +0000
committerNick Clifton <nickc@redhat.com>2013-02-15 14:37:39 +0000
commita043396b72d17ae87267b534aa98457a0702f5c8 (patch)
tree01175912495c045c25625c8048a83ba65c3a5c64 /binutils
parent76d8cf45bb12ae6d8fc41d92579a2e166efb5b2f (diff)
downloadgdb-a043396b72d17ae87267b534aa98457a0702f5c8.zip
gdb-a043396b72d17ae87267b534aa98457a0702f5c8.tar.gz
gdb-a043396b72d17ae87267b534aa98457a0702f5c8.tar.bz2
PR binutils/15140
* ar.c (open_inarch): Fail on attempts to convert a normal archive to a thin archive or vice versa. * elfcomm.c (make_qualified_name): Handle corrupted thin archives. * readelf.c (process_archive): Likewise. * doc/binutils.texi: Clarify documentation describing thin archives. * archive.c (_bfd_get_elt_at_filepos): Prevent an infinite loop accessing a corrupt nested archive.
Diffstat (limited to 'binutils')
-rw-r--r--binutils/ChangeLog11
-rw-r--r--binutils/ar.c23
-rw-r--r--binutils/doc/binutils.texi26
-rw-r--r--binutils/elfcomm.c28
-rw-r--r--binutils/readelf.c9
5 files changed, 77 insertions, 20 deletions
diff --git a/binutils/ChangeLog b/binutils/ChangeLog
index d2e6dd0..06f5dd5 100644
--- a/binutils/ChangeLog
+++ b/binutils/ChangeLog
@@ -4,6 +4,17 @@
2013-02-15 Nick Clifton <nickc@redhat.com>
+ PR binutils/15140
+ * ar.c (open_inarch): Fail on attempts to convert a normal archive
+ to a thin archive or vice versa.
+ * elfcomm.c (make_qualified_name): Handle corrupted thin
+ archives.
+ * readelf.c (process_archive): Likewise.
+ * doc/binutils.texi: Clarify documentation describing thin
+ archives.
+
+2013-02-15 Nick Clifton <nickc@redhat.com>
+
PR binutils/15033
* objcopy.c (enum change_action): Delete.
(struct section_list): Delete remove, copy, change_vma, change_lma
diff --git a/binutils/ar.c b/binutils/ar.c
index 0aa1ba3..c424038 100644
--- a/binutils/ar.c
+++ b/binutils/ar.c
@@ -1,7 +1,5 @@
/* ar.c - Archive modify and extract.
- Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
- 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013
- Free Software Foundation, Inc.
+ Copyright 1991-2013 Free Software Foundation, Inc.
This file is part of GNU Binutils.
@@ -918,6 +916,25 @@ open_inarch (const char *archive_filename, const char *file)
xexit (1);
}
+ if ((operation == replace || operation == quick_append)
+ && bfd_openr_next_archived_file (arch, NULL) != NULL)
+ {
+ /* PR 15140: Catch attempts to convert a normal
+ archive into a thin archive or vice versa. */
+ if (make_thin_archive && ! bfd_is_thin_archive (arch))
+ {
+ fatal (_("Cannot convert existing library %s to thin format"),
+ bfd_get_filename (arch));
+ goto bloser;
+ }
+ else if (! make_thin_archive && bfd_is_thin_archive (arch))
+ {
+ fatal (_("Cannot convert existing thin library %s to normal format"),
+ bfd_get_filename (arch));
+ goto bloser;
+ }
+ }
+
last_one = &(arch->archive_next);
/* Read all the contents right away, regardless. */
for (next_one = bfd_openr_next_archived_file (arch, NULL);
diff --git a/binutils/doc/binutils.texi b/binutils/doc/binutils.texi
index d733fdb..0bb1d92 100644
--- a/binutils/doc/binutils.texi
+++ b/binutils/doc/binutils.texi
@@ -10,10 +10,7 @@
@copying
@c man begin COPYRIGHT
-Copyright @copyright{} 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
-1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009,
-2010, 2011, 2012, 2013
-Free Software Foundation, Inc.
+Copyright @copyright{} 1991-2013 Free Software Foundation, Inc.
Permission is granted to copy, distribute and/or modify this document
under the terms of the GNU Free Documentation License, Version 1.3
@@ -221,12 +218,21 @@ table. If an archive lacks the table, another form of @command{ar} called
@cindex thin archives
@sc{gnu} @command{ar} can optionally create a @emph{thin} archive,
which contains a symbol index and references to the original copies
-of the member files of the archives. Such an archive is useful
-for building libraries for use within a local build, where the
-relocatable objects are expected to remain available, and copying the
-contents of each object would only waste time and space. Thin archives
-are also @emph{flattened}, so that adding one or more archives to a
-thin archive will add the elements of the nested archive individually.
+of the member files of the archive. This is useful for building
+libraries for use within a local build tree, where the relocatable
+objects are expected to remain available, and copying the contents of
+each object would only waste time and space.
+
+An archive can either be @emph{thin} or it can be normal. It cannot
+be both at the same time. Once an archive is created its format
+cannot be changed without first deleting it and then creating a new
+archive in its place.
+
+Thin archives are also @emph{flattened}, so that adding one thin
+archive to another thin archive does not nest it, as would happen with
+a normal archive. Instead the elements of the first archive are added
+individually to the second archive.
+
The paths to the elements of the archive are stored relative to the
archive itself.
diff --git a/binutils/elfcomm.c b/binutils/elfcomm.c
index 64d4b213..1179a1a 100644
--- a/binutils/elfcomm.c
+++ b/binutils/elfcomm.c
@@ -1,6 +1,5 @@
/* elfcomm.c -- common code for ELF format file.
- Copyright 2010
- Free Software Foundation, Inc.
+ Copyright 2010-2013 Free Software Foundation, Inc.
Originally developed by Eric Youngdale <eric@andante.jic.com>
Modifications by Nick Clifton <nickc@redhat.com>
@@ -690,12 +689,20 @@ make_qualified_name (struct archive_info * arch,
struct archive_info * nested_arch,
const char *member_name)
{
+ const char * error_name = _("<corrupt>");
size_t len;
char * name;
len = strlen (arch->file_name) + strlen (member_name) + 3;
- if (arch->is_thin_archive && arch->nested_member_origin != 0)
- len += strlen (nested_arch->file_name) + 2;
+ if (arch->is_thin_archive
+ && arch->nested_member_origin != 0)
+ {
+ /* PR 15140: Allow for corrupt thin archives. */
+ if (nested_arch->file_name)
+ len += strlen (nested_arch->file_name) + 2;
+ else
+ len += strlen (error_name) + 2;
+ }
name = (char *) malloc (len);
if (name == NULL)
@@ -704,9 +711,16 @@ make_qualified_name (struct archive_info * arch,
return NULL;
}
- if (arch->is_thin_archive && arch->nested_member_origin != 0)
- snprintf (name, len, "%s[%s(%s)]", arch->file_name,
- nested_arch->file_name, member_name);
+ if (arch->is_thin_archive
+ && arch->nested_member_origin != 0)
+ {
+ if (nested_arch->file_name)
+ snprintf (name, len, "%s[%s(%s)]", arch->file_name,
+ nested_arch->file_name, member_name);
+ else
+ snprintf (name, len, "%s[%s(%s)]", arch->file_name,
+ error_name, member_name);
+ }
else if (arch->is_thin_archive)
snprintf (name, len, "%s[%s]", arch->file_name, member_name);
else
diff --git a/binutils/readelf.c b/binutils/readelf.c
index 7710079..c7bd05f 100644
--- a/binutils/readelf.c
+++ b/binutils/readelf.c
@@ -13975,6 +13975,15 @@ process_archive (char * file_name, FILE * file, bfd_boolean is_thin_archive)
}
else if (is_thin_archive)
{
+ /* PR 15140: Allow for corrupt thin archives. */
+ if (nested_arch.file == NULL)
+ {
+ error (_("%s: contains corrupt thin archive: %s\n"),
+ file_name, name);
+ ret = 1;
+ break;
+ }
+
/* This is a proxy for a member of a nested archive. */
archive_file_offset = arch.nested_member_origin + sizeof arch.arhdr;