Line 1... |
Line 1... |
/* BFD back-end for archive files (libraries).
|
/* BFD back-end for archive files (libraries).
|
Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
|
Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
|
2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011
|
2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011,
|
Free Software Foundation, Inc.
|
2012 Free Software Foundation, Inc.
|
Written by Cygnus Support. Mostly Gumby Henkel-Wallace's fault.
|
Written by Cygnus Support. Mostly Gumby Henkel-Wallace's fault.
|
|
|
This file is part of BFD, the Binary File Descriptor library.
|
This file is part of BFD, the Binary File Descriptor library.
|
|
|
This program is free software; you can redistribute it and/or modify
|
This program is free software; you can redistribute it and/or modify
|
Line 176... |
Line 176... |
memset (p + len, ' ', n - len);
|
memset (p + len, ' ', n - len);
|
}
|
}
|
else
|
else
|
memcpy (p, buf, n);
|
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_boolean
|
_bfd_generic_mkarchive (bfd *abfd)
|
_bfd_generic_mkarchive (bfd *abfd)
|
{
|
{
|
bfd_size_type amt = sizeof (struct artdata);
|
bfd_size_type amt = sizeof (struct artdata);
|
Line 422... |
Line 445... |
void *
|
void *
|
_bfd_generic_read_ar_hdr_mag (bfd *abfd, const char *mag)
|
_bfd_generic_read_ar_hdr_mag (bfd *abfd, const char *mag)
|
{
|
{
|
struct ar_hdr hdr;
|
struct ar_hdr hdr;
|
char *hdrp = (char *) &hdr;
|
char *hdrp = (char *) &hdr;
|
size_t parsed_size;
|
bfd_size_type parsed_size;
|
struct areltdata *ared;
|
struct areltdata *ared;
|
char *filename = NULL;
|
char *filename = NULL;
|
bfd_size_type namelen = 0;
|
bfd_size_type namelen = 0;
|
bfd_size_type allocsize = sizeof (struct areltdata) + sizeof (struct ar_hdr);
|
bfd_size_type allocsize = sizeof (struct areltdata) + sizeof (struct ar_hdr);
|
char *allocptr = 0;
|
char *allocptr = 0;
|
Line 446... |
Line 469... |
bfd_set_error (bfd_error_malformed_archive);
|
bfd_set_error (bfd_error_malformed_archive);
|
return NULL;
|
return NULL;
|
}
|
}
|
|
|
errno = 0;
|
errno = 0;
|
parsed_size = strtol (hdr.ar_size, NULL, 10);
|
if (sscanf (hdr.ar_size, "%" BFD_VMA_FMT "u", &parsed_size) != 1)
|
if (errno != 0)
|
|
{
|
{
|
bfd_set_error (bfd_error_malformed_archive);
|
bfd_set_error (bfd_error_malformed_archive);
|
return NULL;
|
return NULL;
|
}
|
}
|
|
|
Line 579... |
Line 601... |
{
|
{
|
struct areltdata *new_areldata;
|
struct areltdata *new_areldata;
|
bfd *n_nfd;
|
bfd *n_nfd;
|
char *filename;
|
char *filename;
|
|
|
if (archive->my_archive)
|
|
{
|
|
filepos += archive->origin;
|
|
archive = archive->my_archive;
|
|
}
|
|
|
|
n_nfd = _bfd_look_for_bfd_in_cache (archive, filepos);
|
n_nfd = _bfd_look_for_bfd_in_cache (archive, filepos);
|
if (n_nfd)
|
if (n_nfd)
|
return n_nfd;
|
return n_nfd;
|
|
|
if (0 > bfd_seek (archive, filepos, SEEK_SET))
|
if (0 > bfd_seek (archive, filepos, SEEK_SET))
|
Line 725... |
Line 741... |
|
|
if (!last_file)
|
if (!last_file)
|
filestart = bfd_ardata (archive)->first_file_filepos;
|
filestart = bfd_ardata (archive)->first_file_filepos;
|
else
|
else
|
{
|
{
|
unsigned int size = arelt_size (last_file);
|
bfd_size_type size = arelt_size (last_file);
|
|
|
filestart = last_file->proxy_origin;
|
filestart = last_file->proxy_origin;
|
if (! bfd_is_thin_archive (archive))
|
if (! bfd_is_thin_archive (archive))
|
filestart += size;
|
filestart += size;
|
if (archive->my_archive)
|
|
filestart -= archive->origin;
|
|
/* Pad to an even boundary...
|
/* Pad to an even boundary...
|
Note that last_file->origin can be odd in the case of
|
Note that last_file->origin can be odd in the case of
|
BSD-4.4-style element with a long odd size. */
|
BSD-4.4-style element with a long odd size. */
|
filestart += filestart % 2;
|
filestart += filestart % 2;
|
}
|
}
|
Line 923... |
Line 937... |
struct areltdata *mapdata;
|
struct areltdata *mapdata;
|
int *raw_armap, *rawptr;
|
int *raw_armap, *rawptr;
|
struct artdata *ardata = bfd_ardata (abfd);
|
struct artdata *ardata = bfd_ardata (abfd);
|
char *stringbase;
|
char *stringbase;
|
bfd_size_type stringsize;
|
bfd_size_type stringsize;
|
unsigned int parsed_size;
|
bfd_size_type parsed_size;
|
carsym *carsyms;
|
carsym *carsyms;
|
bfd_size_type nsymz; /* Number of symbols in armap. */
|
bfd_size_type nsymz; /* Number of symbols in armap. */
|
bfd_vma (*swap) (const void *);
|
bfd_vma (*swap) (const void *);
|
char int_buf[sizeof (long)];
|
char int_buf[sizeof (long)];
|
bfd_size_type carsym_size, ptrsize;
|
bfd_size_type carsym_size, ptrsize;
|
Line 1087... |
Line 1101... |
if (bfd_bread (&hdr, sizeof (hdr), abfd) != sizeof (hdr))
|
if (bfd_bread (&hdr, sizeof (hdr), abfd) != sizeof (hdr))
|
return FALSE;
|
return FALSE;
|
/* Read the extended name. We know its length. */
|
/* Read the extended name. We know its length. */
|
if (bfd_bread (extname, 20, abfd) != 20)
|
if (bfd_bread (extname, 20, abfd) != 20)
|
return FALSE;
|
return FALSE;
|
if (bfd_seek (abfd, (file_ptr) -(sizeof (hdr) + 20), SEEK_CUR) != 0)
|
if (bfd_seek (abfd, -(file_ptr) (sizeof (hdr) + 20), SEEK_CUR) != 0)
|
return FALSE;
|
return FALSE;
|
if (CONST_STRNEQ (extname, "__.SYMDEF SORTED")
|
if (CONST_STRNEQ (extname, "__.SYMDEF SORTED")
|
|| CONST_STRNEQ (extname, "__.SYMDEF"))
|
|| CONST_STRNEQ (extname, "__.SYMDEF"))
|
return do_slurp_bsd_armap (abfd);
|
return do_slurp_bsd_armap (abfd);
|
}
|
}
|
Line 1768... |
Line 1782... |
unsigned int len = strlen (fullname);
|
unsigned int len = strlen (fullname);
|
unsigned int padded_len = (len + 3) & ~3;
|
unsigned int padded_len = (len + 3) & ~3;
|
|
|
BFD_ASSERT (padded_len == arch_eltdata (abfd)->extra_size);
|
BFD_ASSERT (padded_len == arch_eltdata (abfd)->extra_size);
|
|
|
_bfd_ar_spacepad (hdr->ar_size, sizeof (hdr->ar_size), "%-10ld",
|
if (!_bfd_ar_sizepad (hdr->ar_size, sizeof (hdr->ar_size),
|
arch_eltdata (abfd)->parsed_size + padded_len);
|
arch_eltdata (abfd)->parsed_size + padded_len))
|
|
return FALSE;
|
|
|
if (bfd_bwrite (hdr, sizeof (*hdr), archive) != sizeof (*hdr))
|
if (bfd_bwrite (hdr, sizeof (*hdr), archive) != sizeof (*hdr))
|
return FALSE;
|
return FALSE;
|
|
|
if (bfd_bwrite (fullname, len, archive) != len)
|
if (bfd_bwrite (fullname, len, archive) != len)
|
return FALSE;
|
return FALSE;
|
|
|
if (len & 3)
|
if (len & 3)
|
{
|
{
|
static const char pad[3] = { 0, 0, 0 };
|
static const char pad[3] = { 0, 0, 0 };
|
|
|
len = 4 - (len & 3);
|
len = 4 - (len & 3);
|
Line 1889... |
Line 1905... |
#endif
|
#endif
|
_bfd_ar_spacepad (hdr->ar_gid, sizeof (hdr->ar_gid), "%ld",
|
_bfd_ar_spacepad (hdr->ar_gid, sizeof (hdr->ar_gid), "%ld",
|
status.st_gid);
|
status.st_gid);
|
_bfd_ar_spacepad (hdr->ar_mode, sizeof (hdr->ar_mode), "%-8lo",
|
_bfd_ar_spacepad (hdr->ar_mode, sizeof (hdr->ar_mode), "%-8lo",
|
status.st_mode);
|
status.st_mode);
|
_bfd_ar_spacepad (hdr->ar_size, sizeof (hdr->ar_size), "%-10ld",
|
if (!_bfd_ar_sizepad (hdr->ar_size, sizeof (hdr->ar_size), status.st_size))
|
status.st_size);
|
{
|
|
free (ared);
|
|
return NULL;
|
|
}
|
memcpy (hdr->ar_fmag, ARFMAG, 2);
|
memcpy (hdr->ar_fmag, ARFMAG, 2);
|
ared->parsed_size = status.st_size;
|
ared->parsed_size = status.st_size;
|
ared->arch_header = (char *) hdr;
|
ared->arch_header = (char *) hdr;
|
|
|
return ared;
|
return ared;
|
Line 2130... |
Line 2149... |
struct ar_hdr hdr;
|
struct ar_hdr hdr;
|
|
|
memset (&hdr, ' ', sizeof (struct ar_hdr));
|
memset (&hdr, ' ', sizeof (struct ar_hdr));
|
memcpy (hdr.ar_name, ename, strlen (ename));
|
memcpy (hdr.ar_name, ename, strlen (ename));
|
/* Round size up to even number in archive header. */
|
/* Round size up to even number in archive header. */
|
_bfd_ar_spacepad (hdr.ar_size, sizeof (hdr.ar_size), "%-10ld",
|
if (!_bfd_ar_sizepad (hdr.ar_size, sizeof (hdr.ar_size),
|
(elength + 1) & ~(bfd_size_type) 1);
|
(elength + 1) & ~(bfd_size_type) 1))
|
|
return FALSE;
|
memcpy (hdr.ar_fmag, ARFMAG, 2);
|
memcpy (hdr.ar_fmag, ARFMAG, 2);
|
if ((bfd_bwrite (&hdr, sizeof (struct ar_hdr), arch)
|
if ((bfd_bwrite (&hdr, sizeof (struct ar_hdr), arch)
|
!= sizeof (struct ar_hdr))
|
!= sizeof (struct ar_hdr))
|
|| bfd_bwrite (etable, elength, arch) != elength)
|
|| bfd_bwrite (etable, elength, arch) != elength)
|
return FALSE;
|
return FALSE;
|
Line 2149... |
Line 2169... |
for (current = arch->archive_head;
|
for (current = arch->archive_head;
|
current != NULL;
|
current != NULL;
|
current = current->archive_next)
|
current = current->archive_next)
|
{
|
{
|
char buffer[DEFAULT_BUFFERSIZE];
|
char buffer[DEFAULT_BUFFERSIZE];
|
unsigned int remaining = arelt_size (current);
|
bfd_size_type remaining = arelt_size (current);
|
|
|
/* Write ar header. */
|
/* Write ar header. */
|
if (!_bfd_write_ar_hdr (arch, current))
|
if (!_bfd_write_ar_hdr (arch, current))
|
return FALSE;
|
return FALSE;
|
if (bfd_is_thin_archive (arch))
|
if (bfd_is_thin_archive (arch))
|
Line 2407... |
Line 2427... |
+ offsetof (struct ar_hdr, ar_date[0]));
|
+ offsetof (struct ar_hdr, ar_date[0]));
|
_bfd_ar_spacepad (hdr.ar_date, sizeof (hdr.ar_date), "%ld",
|
_bfd_ar_spacepad (hdr.ar_date, sizeof (hdr.ar_date), "%ld",
|
bfd_ardata (arch)->armap_timestamp);
|
bfd_ardata (arch)->armap_timestamp);
|
_bfd_ar_spacepad (hdr.ar_uid, sizeof (hdr.ar_uid), "%ld", uid);
|
_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_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);
|
memcpy (hdr.ar_fmag, ARFMAG, 2);
|
if (bfd_bwrite (&hdr, sizeof (struct ar_hdr), arch)
|
if (bfd_bwrite (&hdr, sizeof (struct ar_hdr), arch)
|
!= sizeof (struct ar_hdr))
|
!= sizeof (struct ar_hdr))
|
return FALSE;
|
return FALSE;
|
H_PUT_32 (arch, ranlibsize, temp);
|
H_PUT_32 (arch, ranlibsize, temp);
|
Line 2562... |
Line 2583... |
+ sizeof (struct ar_hdr)
|
+ sizeof (struct ar_hdr)
|
+ SARMAG);
|
+ SARMAG);
|
|
|
memset (&hdr, ' ', sizeof (struct ar_hdr));
|
memset (&hdr, ' ', sizeof (struct ar_hdr));
|
hdr.ar_name[0] = '/';
|
hdr.ar_name[0] = '/';
|
_bfd_ar_spacepad (hdr.ar_size, sizeof (hdr.ar_size), "%-10ld",
|
if (!_bfd_ar_sizepad (hdr.ar_size, sizeof (hdr.ar_size), mapsize))
|
mapsize);
|
return FALSE;
|
_bfd_ar_spacepad (hdr.ar_date, sizeof (hdr.ar_date), "%ld",
|
_bfd_ar_spacepad (hdr.ar_date, sizeof (hdr.ar_date), "%ld",
|
((arch->flags & BFD_DETERMINISTIC_OUTPUT) == 0
|
((arch->flags & BFD_DETERMINISTIC_OUTPUT) == 0
|
? time (NULL) : 0));
|
? time (NULL) : 0));
|
/* This, at least, is what Intel coff sets the values to. */
|
/* This, at least, is what Intel coff sets the values to. */
|
_bfd_ar_spacepad (hdr.ar_uid, sizeof (hdr.ar_uid), "%ld", 0);
|
_bfd_ar_spacepad (hdr.ar_uid, sizeof (hdr.ar_uid), "%ld", 0);
|