PR binutils/13534

* archive.c (_bfd_ar_sizepad): New function. Correctly install and
	pad the size field in an archive header.
	(_bfd_generic_read_ar_hdr_mag): Use the correct type and scan
	function for the archive size field.
	(bfd_generic_openr_next_archived_file): Likewise.
	(do_slurp_coff_armap): Likewise.
	(_bfd_write_archive_contents): Likewise.
	(_bfd_bsd44_write_ar_hdr): Use the new function.
	(bfd_ar_hdr_from_filesystem): Likewise.
	(_bfd_write_archive_contents): Likewise.
	(bsd_write_armap): Likewise.
	(coff_write_armap): Likewise.
	* archive64.c (bfd_elf64_archive_write_armap): Likewise.
	* bfdio.c (bfd_bread): Use correct type for archive element
	sizes.
	* ar.c (open_inarch): Likewise.
	(extract_file): Likewise.
	* libbfd-in.h (struct areltdata): Use correct types for
	parsed_size and extra_size fields.
	Prototype _bfd_ar_sizepad function.
	* libbfd.h: Regenerate.
This commit is contained in:
Nick Clifton 2012-01-20 14:42:57 +00:00
parent 2128eb399e
commit f1bb16f888
6 changed files with 112 additions and 49 deletions

View File

@ -1,3 +1,28 @@
2012-01-20 Francois Gouget <fgouget@codeweavers.com>
PR binutils/13534
* archive.c (_bfd_ar_sizepad): New function. Correctly install and
pad the size field in an archive header.
(_bfd_generic_read_ar_hdr_mag): Use the correct type and scan
function for the archive size field.
(bfd_generic_openr_next_archived_file): Likewise.
(do_slurp_coff_armap): Likewise.
(_bfd_write_archive_contents): Likewise.
(_bfd_bsd44_write_ar_hdr): Use the new function.
(bfd_ar_hdr_from_filesystem): Likewise.
(_bfd_write_archive_contents): Likewise.
(bsd_write_armap): Likewise.
(coff_write_armap): Likewise.
* archive64.c (bfd_elf64_archive_write_armap): Likewise.
* bfdio.c (bfd_bread): Use correct type for archive element
sizes.
* ar.c (open_inarch): Likewise.
(extract_file): Likewise.
* libbfd-in.h (struct areltdata): Use correct types for
parsed_size and extra_size fields.
Prototype _bfd_ar_sizepad function.
* libbfd.h: Regenerate.
2012-01-20 Ulrich Weigand <ulrich.weigand@linaro.org>
* elf.c (elfcore_write_prpsinfo): Provide unconditionally.

View File

@ -1,7 +1,7 @@
/* 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
Free Software Foundation, Inc.
2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011,
2012 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.
@ -178,6 +178,29 @@ _bfd_ar_spacepad (char *p, size_t n, const char *fmt, long val)
else
memcpy (p, buf, n);
}
bfd_boolean
_bfd_ar_sizepad (char *p, size_t n, bfd_size_type size)
{
static char buf[21];
size_t len;
snprintf (buf, sizeof (buf), "%-10" BFD_VMA_FMT "u", size);
len = strlen (buf);
if (len > n)
{
bfd_set_error (bfd_error_file_too_big);
return FALSE;
}
if (len < n)
{
memcpy (p, buf, len);
memset (p + len, ' ', n - len);
}
else
memcpy (p, buf, n);
return TRUE;
}
bfd_boolean
_bfd_generic_mkarchive (bfd *abfd)
@ -424,7 +447,7 @@ _bfd_generic_read_ar_hdr_mag (bfd *abfd, const char *mag)
{
struct ar_hdr hdr;
char *hdrp = (char *) &hdr;
size_t parsed_size;
bfd_size_type parsed_size;
struct areltdata *ared;
char *filename = NULL;
bfd_size_type namelen = 0;
@ -448,8 +471,7 @@ _bfd_generic_read_ar_hdr_mag (bfd *abfd, const char *mag)
}
errno = 0;
parsed_size = strtol (hdr.ar_size, NULL, 10);
if (errno != 0)
if (sscanf (hdr.ar_size, "%" BFD_VMA_FMT "u", &parsed_size) != 1)
{
bfd_set_error (bfd_error_malformed_archive);
return NULL;
@ -721,7 +743,7 @@ bfd_generic_openr_next_archived_file (bfd *archive, bfd *last_file)
filestart = bfd_ardata (archive)->first_file_filepos;
else
{
unsigned int size = arelt_size (last_file);
bfd_size_type size = arelt_size (last_file);
filestart = last_file->proxy_origin;
if (! bfd_is_thin_archive (archive))
@ -917,7 +939,7 @@ do_slurp_coff_armap (bfd *abfd)
struct artdata *ardata = bfd_ardata (abfd);
char *stringbase;
bfd_size_type stringsize;
unsigned int parsed_size;
bfd_size_type parsed_size;
carsym *carsyms;
bfd_size_type nsymz; /* Number of symbols in armap. */
bfd_vma (*swap) (const void *);
@ -1762,14 +1784,16 @@ _bfd_bsd44_write_ar_hdr (bfd *archive, bfd *abfd)
BFD_ASSERT (padded_len == arch_eltdata (abfd)->extra_size);
_bfd_ar_spacepad (hdr->ar_size, sizeof (hdr->ar_size), "%-10ld",
arch_eltdata (abfd)->parsed_size + padded_len);
if (!_bfd_ar_sizepad (hdr->ar_size, sizeof (hdr->ar_size),
arch_eltdata (abfd)->parsed_size + padded_len))
return FALSE;
if (bfd_bwrite (hdr, sizeof (*hdr), archive) != sizeof (*hdr))
return FALSE;
if (bfd_bwrite (fullname, len, archive) != len)
return FALSE;
if (len & 3)
{
static const char pad[3] = { 0, 0, 0 };
@ -1883,8 +1907,11 @@ bfd_ar_hdr_from_filesystem (bfd *abfd, const char *filename, bfd *member)
status.st_gid);
_bfd_ar_spacepad (hdr->ar_mode, sizeof (hdr->ar_mode), "%-8lo",
status.st_mode);
_bfd_ar_spacepad (hdr->ar_size, sizeof (hdr->ar_size), "%-10ld",
status.st_size);
if (!_bfd_ar_sizepad (hdr->ar_size, sizeof (hdr->ar_size), status.st_size))
{
free (ared);
return NULL;
}
memcpy (hdr->ar_fmag, ARFMAG, 2);
ared->parsed_size = status.st_size;
ared->arch_header = (char *) hdr;
@ -2124,8 +2151,9 @@ _bfd_write_archive_contents (bfd *arch)
memset (&hdr, ' ', sizeof (struct ar_hdr));
memcpy (hdr.ar_name, ename, strlen (ename));
/* Round size up to even number in archive header. */
_bfd_ar_spacepad (hdr.ar_size, sizeof (hdr.ar_size), "%-10ld",
(elength + 1) & ~(bfd_size_type) 1);
if (!_bfd_ar_sizepad (hdr.ar_size, sizeof (hdr.ar_size),
(elength + 1) & ~(bfd_size_type) 1))
return FALSE;
memcpy (hdr.ar_fmag, ARFMAG, 2);
if ((bfd_bwrite (&hdr, sizeof (struct ar_hdr), arch)
!= sizeof (struct ar_hdr))
@ -2143,7 +2171,7 @@ _bfd_write_archive_contents (bfd *arch)
current = current->archive_next)
{
char buffer[DEFAULT_BUFFERSIZE];
unsigned int remaining = arelt_size (current);
bfd_size_type remaining = arelt_size (current);
/* Write ar header. */
if (!_bfd_write_ar_hdr (arch, current))
@ -2401,7 +2429,8 @@ bsd_write_armap (bfd *arch,
bfd_ardata (arch)->armap_timestamp);
_bfd_ar_spacepad (hdr.ar_uid, sizeof (hdr.ar_uid), "%ld", uid);
_bfd_ar_spacepad (hdr.ar_gid, sizeof (hdr.ar_gid), "%ld", gid);
_bfd_ar_spacepad (hdr.ar_size, sizeof (hdr.ar_size), "%-10ld", mapsize);
if (!_bfd_ar_sizepad (hdr.ar_size, sizeof (hdr.ar_size), mapsize))
return FALSE;
memcpy (hdr.ar_fmag, ARFMAG, 2);
if (bfd_bwrite (&hdr, sizeof (struct ar_hdr), arch)
!= sizeof (struct ar_hdr))
@ -2556,8 +2585,8 @@ coff_write_armap (bfd *arch,
memset (&hdr, ' ', sizeof (struct ar_hdr));
hdr.ar_name[0] = '/';
_bfd_ar_spacepad (hdr.ar_size, sizeof (hdr.ar_size), "%-10ld",
mapsize);
if (!_bfd_ar_sizepad (hdr.ar_size, sizeof (hdr.ar_size), mapsize))
return FALSE;
_bfd_ar_spacepad (hdr.ar_date, sizeof (hdr.ar_date), "%ld",
((arch->flags & BFD_DETERMINISTIC_OUTPUT) == 0
? time (NULL) : 0));

View File

@ -1,6 +1,6 @@
/* MIPS-specific support for 64-bit ELF
Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2005, 2006, 2007,
2010 Free Software Foundation, Inc.
2010, 2012 Free Software Foundation, Inc.
Ian Lance Taylor, Cygnus Support
Linker support added by Mark Mitchell, CodeSourcery, LLC.
<mark@codesourcery.com>
@ -169,8 +169,8 @@ bfd_elf64_archive_write_armap (bfd *arch,
memset (&hdr, ' ', sizeof (struct ar_hdr));
memcpy (hdr.ar_name, "/SYM64/", strlen ("/SYM64/"));
_bfd_ar_spacepad (hdr.ar_size, sizeof (hdr.ar_size), "%-10ld",
mapsize);
if (!_bfd_ar_sizepad (hdr.ar_size, sizeof (hdr.ar_size), mapsize))
return FALSE;
_bfd_ar_spacepad (hdr.ar_date, sizeof (hdr.ar_date), "%ld",
time (NULL));
/* This, at least, is what Intel coff sets the values to.: */

View File

@ -185,7 +185,8 @@ bfd_bread (void *ptr, bfd_size_type size, bfd *abfd)
this element. */
if (abfd->arelt_data != NULL)
{
size_t maxbytes = arelt_size (abfd);
bfd_size_type maxbytes = arelt_size (abfd);
if (abfd->where + size > maxbytes)
{
if (abfd->where >= maxbytes)

View File

@ -3,7 +3,7 @@
Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009,
2010, 2011
2010, 2011, 2012
Free Software Foundation, Inc.
Written by Cygnus Support.
@ -64,16 +64,17 @@ struct section_hash_entry
/* tdata for an archive. For an input archive, cache
needs to be free()'d. For an output archive, symdefs do. */
struct artdata {
struct artdata
{
file_ptr first_file_filepos;
/* Speed up searching the armap */
htab_t cache;
bfd *archive_head; /* Only interesting in output routines */
carsym *symdefs; /* the symdef entries */
symindex symdef_count; /* how many there are */
char *extended_names; /* clever intel extension */
bfd_size_type extended_names_size; /* Size of extended names */
/* when more compilers are standard C, this can be a time_t */
bfd *archive_head; /* Only interesting in output routines. */
carsym *symdefs; /* The symdef entries. */
symindex symdef_count; /* How many there are. */
char *extended_names; /* Clever intel extension. */
bfd_size_type extended_names_size; /* Size of extended names. */
/* When more compilers are standard C, this can be a time_t. */
long armap_timestamp; /* Timestamp value written into armap.
This is used for BSD archives to check
that the timestamp is recent enough
@ -88,12 +89,13 @@ struct artdata {
#define bfd_ardata(bfd) ((bfd)->tdata.aout_ar_data)
/* Goes in bfd's arelt_data slot */
struct areltdata {
char * arch_header; /* it's actually a string */
unsigned int parsed_size; /* octets of filesize not including ar_hdr */
unsigned int extra_size; /* BSD4.4: extra bytes after the header. */
char *filename; /* null-terminated */
file_ptr origin; /* for element of a thin archive */
struct areltdata
{
char * arch_header; /* It's actually a string. */
bfd_size_type parsed_size; /* Octets of filesize not including ar_hdr. */
bfd_size_type extra_size; /* BSD4.4: extra bytes after the header. */
char *filename; /* Null-terminated. */
file_ptr origin; /* For element of a thin archive. */
};
#define arelt_size(bfd) (((struct areltdata *)((bfd)->arelt_data))->parsed_size)
@ -203,6 +205,8 @@ extern void *_bfd_generic_read_ar_hdr
(bfd *);
extern void _bfd_ar_spacepad
(char *, size_t, const char *, long);
extern bfd_boolean _bfd_ar_sizepad
(char *, size_t, bfd_size_type);
extern void *_bfd_generic_read_ar_hdr_mag
(bfd *, const char *);

View File

@ -8,7 +8,7 @@
Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009,
2010, 2011
2010, 2011, 2012
Free Software Foundation, Inc.
Written by Cygnus Support.
@ -69,16 +69,17 @@ struct section_hash_entry
/* tdata for an archive. For an input archive, cache
needs to be free()'d. For an output archive, symdefs do. */
struct artdata {
struct artdata
{
file_ptr first_file_filepos;
/* Speed up searching the armap */
htab_t cache;
bfd *archive_head; /* Only interesting in output routines */
carsym *symdefs; /* the symdef entries */
symindex symdef_count; /* how many there are */
char *extended_names; /* clever intel extension */
bfd_size_type extended_names_size; /* Size of extended names */
/* when more compilers are standard C, this can be a time_t */
bfd *archive_head; /* Only interesting in output routines. */
carsym *symdefs; /* The symdef entries. */
symindex symdef_count; /* How many there are. */
char *extended_names; /* Clever intel extension. */
bfd_size_type extended_names_size; /* Size of extended names. */
/* When more compilers are standard C, this can be a time_t. */
long armap_timestamp; /* Timestamp value written into armap.
This is used for BSD archives to check
that the timestamp is recent enough
@ -93,12 +94,13 @@ struct artdata {
#define bfd_ardata(bfd) ((bfd)->tdata.aout_ar_data)
/* Goes in bfd's arelt_data slot */
struct areltdata {
char * arch_header; /* it's actually a string */
unsigned int parsed_size; /* octets of filesize not including ar_hdr */
unsigned int extra_size; /* BSD4.4: extra bytes after the header. */
char *filename; /* null-terminated */
file_ptr origin; /* for element of a thin archive */
struct areltdata
{
char * arch_header; /* It's actually a string. */
bfd_size_type parsed_size; /* Octets of filesize not including ar_hdr. */
bfd_size_type extra_size; /* BSD4.4: extra bytes after the header. */
char *filename; /* Null-terminated. */
file_ptr origin; /* For element of a thin archive. */
};
#define arelt_size(bfd) (((struct areltdata *)((bfd)->arelt_data))->parsed_size)
@ -208,6 +210,8 @@ extern void *_bfd_generic_read_ar_hdr
(bfd *);
extern void _bfd_ar_spacepad
(char *, size_t, const char *, long);
extern bfd_boolean _bfd_ar_sizepad
(char *, size_t, bfd_size_type);
extern void *_bfd_generic_read_ar_hdr_mag
(bfd *, const char *);