* libbfd-in.h (_bfd_ar_spacepad): New prototype.

* libbfd.h: Rebuilt.
	* archive.c (_bfd_ar_spacepad): New function.
	(_bfd_construct_extended_name_table, _bfd_write_archive_contents,
	bsd_write_armap, _bfd_archive_bsd_update_armap_timestamp,
	coff_write_armap): Use it.
	(bfd_ar_hdr_from_filesystem): Likewise.  Fix HP-UX large
	uid/gid support.
	* archive64.c (bfd_elf64_archive_write_armap): Use _bfd_ar_spacepad.
This commit is contained in:
Jakub Jelinek 2005-03-11 16:37:17 +00:00
parent e8d4604887
commit 390c0e4288
5 changed files with 83 additions and 86 deletions

View file

@ -1,3 +1,15 @@
2005-03-11 Jakub Jelinek <jakub@redhat.com>
* libbfd-in.h (_bfd_ar_spacepad): New prototype.
* libbfd.h: Rebuilt.
* archive.c (_bfd_ar_spacepad): New function.
(_bfd_construct_extended_name_table, _bfd_write_archive_contents,
bsd_write_armap, _bfd_archive_bsd_update_armap_timestamp,
coff_write_armap): Use it.
(bfd_ar_hdr_from_filesystem): Likewise. Fix HP-UX large
uid/gid support.
* archive64.c (bfd_elf64_archive_write_armap): Use _bfd_ar_spacepad.
2005-03-10 Mark Kettenis <kettenis@gnu.org> 2005-03-10 Mark Kettenis <kettenis@gnu.org>
* archive.c (_bfd_look_for_bfd_in_cache): Move declaration of * archive.c (_bfd_look_for_bfd_in_cache): Move declaration of

View file

@ -121,7 +121,7 @@ DESCRIPTION
Regular files with long names (or embedded spaces, for BSD variants): Regular files with long names (or embedded spaces, for BSD variants):
"/18 " - SVR4 style, name at offset 18 in name table. "/18 " - SVR4 style, name at offset 18 in name table.
"#1/23 " - Long name (or embedded paces) 23 characters long, "#1/23 " - Long name (or embedded spaces) 23 characters long,
BSD 4.4 style, full name follows header. BSD 4.4 style, full name follows header.
Implemented for reading, not writing. Implemented for reading, not writing.
" 18 " - Long name 18 characters long, extended pseudo-BSD. " 18 " - Long name 18 characters long, extended pseudo-BSD.
@ -155,7 +155,22 @@ struct ar_cache {
#define arch_eltdata(bfd) ((struct areltdata *) ((bfd)->arelt_data)) #define arch_eltdata(bfd) ((struct areltdata *) ((bfd)->arelt_data))
#define arch_hdr(bfd) ((struct ar_hdr *) arch_eltdata(bfd)->arch_header) #define arch_hdr(bfd) ((struct ar_hdr *) arch_eltdata(bfd)->arch_header)
void
_bfd_ar_spacepad (char *p, size_t n, const char *fmt, long val)
{
static char buf[20];
size_t len;
snprintf (buf, sizeof (buf), fmt, val);
len = strlen (buf);
if (len < n)
{
memcpy (p, buf, len);
memset (p + len, ' ', n - len);
}
else
memcpy (p, buf, n);
}
bfd_boolean bfd_boolean
_bfd_generic_mkarchive (bfd *abfd) _bfd_generic_mkarchive (bfd *abfd)
@ -1283,17 +1298,8 @@ _bfd_construct_extended_name_table (bfd *abfd,
strptr[thislen + 1] = '\012'; strptr[thislen + 1] = '\012';
} }
hdr->ar_name[0] = ar_padchar (current); hdr->ar_name[0] = ar_padchar (current);
/* We know there will always be enough room (one of the few _bfd_ar_spacepad (hdr->ar_name + 1, maxname - 1, "%-ld",
cases where you may safely use sprintf). */ strptr - *tabloc);
sprintf ((hdr->ar_name) + 1, "%-d", (unsigned) (strptr - *tabloc));
/* Kinda Kludgy. We should just use the returned value of
sprintf but not all implementations get this right. */
{
char *temp = hdr->ar_name + 2;
for (; temp < hdr->ar_name + maxname; temp++)
if (*temp == '\0')
*temp = ' ';
}
strptr += thislen + 1; strptr += thislen + 1;
if (trailing_slash) if (trailing_slash)
++strptr; ++strptr;
@ -1340,7 +1346,6 @@ bfd_ar_hdr_from_filesystem (bfd *abfd, const char *filename, bfd *member)
struct stat status; struct stat status;
struct areltdata *ared; struct areltdata *ared;
struct ar_hdr *hdr; struct ar_hdr *hdr;
char *temp, *temp1;
bfd_size_type amt; bfd_size_type amt;
if (member && (member->flags & BFD_IN_MEMORY) != 0) if (member && (member->flags & BFD_IN_MEMORY) != 0)
@ -1368,39 +1373,31 @@ bfd_ar_hdr_from_filesystem (bfd *abfd, const char *filename, bfd *member)
/* ar headers are space padded, not null padded! */ /* ar headers are space padded, not null padded! */
memset (hdr, ' ', sizeof (struct ar_hdr)); memset (hdr, ' ', sizeof (struct ar_hdr));
strncpy (hdr->ar_fmag, ARFMAG, 2); _bfd_ar_spacepad (hdr->ar_date, sizeof (hdr->ar_date), "%-12ld",
status.st_mtime);
/* Goddamned sprintf doesn't permit MAXIMUM field lengths. */
sprintf ((hdr->ar_date), "%-12ld", (long) status.st_mtime);
#ifdef HPUX_LARGE_AR_IDS #ifdef HPUX_LARGE_AR_IDS
/* HP has a very "special" way to handle UID/GID's with numeric values /* HP has a very "special" way to handle UID/GID's with numeric values
> 99999. */ > 99999. */
if (status.st_uid > 99999) if (status.st_uid > 99999)
hpux_uid_gid_encode (hdr->ar_gid, (long) status.st_uid); hpux_uid_gid_encode (hdr->ar_uid, (long) status.st_uid);
else else
#endif #endif
sprintf ((hdr->ar_uid), "%ld", (long) status.st_uid); _bfd_ar_spacepad (hdr->ar_uid, sizeof (hdr->ar_uid), "%ld",
status.st_uid);
#ifdef HPUX_LARGE_AR_IDS #ifdef HPUX_LARGE_AR_IDS
/* HP has a very "special" way to handle UID/GID's with numeric values /* HP has a very "special" way to handle UID/GID's with numeric values
> 99999. */ > 99999. */
if (status.st_gid > 99999) if (status.st_gid > 99999)
hpux_uid_gid_encode (hdr->ar_uid, (long) status.st_gid); hpux_uid_gid_encode (hdr->ar_gid, (long) status.st_gid);
else else
#endif #endif
sprintf ((hdr->ar_gid), "%ld", (long) status.st_gid); _bfd_ar_spacepad (hdr->ar_gid, sizeof (hdr->ar_gid), "%ld",
sprintf ((hdr->ar_mode), "%-8o", (unsigned int) status.st_mode); status.st_gid);
sprintf ((hdr->ar_size), "%-10ld", (long) status.st_size); _bfd_ar_spacepad (hdr->ar_mode, sizeof (hdr->ar_mode), "%-8lo",
/* Correct for a lossage in sprintf whereby it null-terminates. I cannot status.st_mode);
understand how these C losers could design such a ramshackle bunch of _bfd_ar_spacepad (hdr->ar_size, sizeof (hdr->ar_size), "%-10ld",
IO operations. */ status.st_size);
temp = (char *) hdr; memcpy (hdr->ar_fmag, ARFMAG, 2);
temp1 = temp + sizeof (struct ar_hdr) - 2;
for (; temp < temp1; temp++)
{
if (*temp == '\0')
*temp = ' ';
}
strncpy (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;
@ -1621,7 +1618,6 @@ _bfd_write_archive_contents (bfd *arch)
/* If no .o's, don't bother to make a map. */ /* If no .o's, don't bother to make a map. */
bfd_boolean hasobjects = FALSE; bfd_boolean hasobjects = FALSE;
bfd_size_type wrote; bfd_size_type wrote;
unsigned int i;
int tries; int tries;
/* Verify the viability of all entries; if any of them live in the /* Verify the viability of all entries; if any of them live in the
@ -1678,15 +1674,12 @@ _bfd_write_archive_contents (bfd *arch)
{ {
struct ar_hdr hdr; struct ar_hdr hdr;
memset (&hdr, 0, sizeof (struct ar_hdr)); memset (&hdr, ' ', sizeof (struct ar_hdr));
strcpy (hdr.ar_name, 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. */
sprintf (&(hdr.ar_size[0]), "%-10d", _bfd_ar_spacepad (hdr.ar_size, sizeof (hdr.ar_size), "%-10ld",
(int) ((elength + 1) & ~(bfd_size_type) 1)); (elength + 1) & ~(bfd_size_type) 1);
strncpy (hdr.ar_fmag, ARFMAG, 2); memcpy (hdr.ar_fmag, ARFMAG, 2);
for (i = 0; i < sizeof (struct ar_hdr); i++)
if (((char *) (&hdr))[i] == '\0')
(((char *) (&hdr))[i]) = ' ';
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)
@ -1920,25 +1913,22 @@ bsd_write_armap (bfd *arch,
unsigned int count; unsigned int count;
struct ar_hdr hdr; struct ar_hdr hdr;
struct stat statbuf; struct stat statbuf;
unsigned int i;
firstreal = mapsize + elength + sizeof (struct ar_hdr) + SARMAG; firstreal = mapsize + elength + sizeof (struct ar_hdr) + SARMAG;
stat (arch->filename, &statbuf); stat (arch->filename, &statbuf);
memset (&hdr, 0, sizeof (struct ar_hdr)); memset (&hdr, ' ', sizeof (struct ar_hdr));
sprintf (hdr.ar_name, RANLIBMAG); memcpy (hdr.ar_name, RANLIBMAG, strlen (RANLIBMAG));
/* Remember the timestamp, to keep it holy. But fudge it a little. */ /* Remember the timestamp, to keep it holy. But fudge it a little. */
bfd_ardata (arch)->armap_timestamp = statbuf.st_mtime + ARMAP_TIME_OFFSET; bfd_ardata (arch)->armap_timestamp = statbuf.st_mtime + ARMAP_TIME_OFFSET;
bfd_ardata (arch)->armap_datepos = (SARMAG bfd_ardata (arch)->armap_datepos = (SARMAG
+ offsetof (struct ar_hdr, ar_date[0])); + offsetof (struct ar_hdr, ar_date[0]));
sprintf (hdr.ar_date, "%ld", bfd_ardata (arch)->armap_timestamp); _bfd_ar_spacepad (hdr.ar_date, sizeof (hdr.ar_date), "%ld",
sprintf (hdr.ar_uid, "%ld", (long) getuid ()); bfd_ardata (arch)->armap_timestamp);
sprintf (hdr.ar_gid, "%ld", (long) getgid ()); _bfd_ar_spacepad (hdr.ar_uid, sizeof (hdr.ar_uid), "%ld", getuid ());
sprintf (hdr.ar_size, "%-10d", (int) mapsize); _bfd_ar_spacepad (hdr.ar_gid, sizeof (hdr.ar_gid), "%ld", getgid ());
strncpy (hdr.ar_fmag, ARFMAG, 2); _bfd_ar_spacepad (hdr.ar_size, sizeof (hdr.ar_size), "%-10ld", mapsize);
for (i = 0; i < sizeof (struct ar_hdr); i++) memcpy (hdr.ar_fmag, ARFMAG, 2);
if (((char *) (&hdr))[i] == '\0')
(((char *) (&hdr))[i]) = ' ';
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;
@ -2003,7 +1993,6 @@ _bfd_archive_bsd_update_armap_timestamp (bfd *arch)
{ {
struct stat archstat; struct stat archstat;
struct ar_hdr hdr; struct ar_hdr hdr;
unsigned int i;
/* Flush writes, get last-write timestamp from file, and compare it /* Flush writes, get last-write timestamp from file, and compare it
to the timestamp IN the file. */ to the timestamp IN the file. */
@ -2023,11 +2012,9 @@ _bfd_archive_bsd_update_armap_timestamp (bfd *arch)
bfd_ardata (arch)->armap_timestamp = archstat.st_mtime + ARMAP_TIME_OFFSET; bfd_ardata (arch)->armap_timestamp = archstat.st_mtime + ARMAP_TIME_OFFSET;
/* Prepare an ASCII version suitable for writing. */ /* Prepare an ASCII version suitable for writing. */
memset (hdr.ar_date, 0, sizeof (hdr.ar_date)); memset (hdr.ar_date, ' ', sizeof (hdr.ar_date));
sprintf (hdr.ar_date, "%ld", bfd_ardata (arch)->armap_timestamp); _bfd_ar_spacepad (hdr.ar_date, sizeof (hdr.ar_date), "%ld",
for (i = 0; i < sizeof (hdr.ar_date); i++) bfd_ardata (arch)->armap_timestamp);
if (hdr.ar_date[i] == '\0')
(hdr.ar_date)[i] = ' ';
/* Write it into the file. */ /* Write it into the file. */
bfd_ardata (arch)->armap_datepos = (SARMAG bfd_ardata (arch)->armap_datepos = (SARMAG
@ -2075,7 +2062,6 @@ coff_write_armap (bfd *arch,
bfd *current = arch->archive_head; bfd *current = arch->archive_head;
unsigned int count; unsigned int count;
struct ar_hdr hdr; struct ar_hdr hdr;
unsigned int i;
int padit = mapsize & 1; int padit = mapsize & 1;
if (padit) if (padit)
@ -2087,19 +2073,17 @@ coff_write_armap (bfd *arch,
+ sizeof (struct ar_hdr) + sizeof (struct ar_hdr)
+ SARMAG); + SARMAG);
memset (&hdr, 0, sizeof (struct ar_hdr)); memset (&hdr, ' ', sizeof (struct ar_hdr));
hdr.ar_name[0] = '/'; hdr.ar_name[0] = '/';
sprintf (hdr.ar_size, "%-10d", (int) mapsize); _bfd_ar_spacepad (hdr.ar_size, sizeof (hdr.ar_size), "%-10ld",
sprintf (hdr.ar_date, "%ld", (long) time (NULL)); mapsize);
_bfd_ar_spacepad (hdr.ar_date, sizeof (hdr.ar_date), "%ld",
time (NULL));
/* This, at least, is what Intel coff sets the values to. */ /* This, at least, is what Intel coff sets the values to. */
sprintf ((hdr.ar_uid), "%d", 0); _bfd_ar_spacepad (hdr.ar_uid, sizeof (hdr.ar_uid), "%ld", 0);
sprintf ((hdr.ar_gid), "%d", 0); _bfd_ar_spacepad (hdr.ar_gid, sizeof (hdr.ar_gid), "%ld", 0);
sprintf ((hdr.ar_mode), "%-7o", (unsigned) 0); _bfd_ar_spacepad (hdr.ar_mode, sizeof (hdr.ar_mode), "%-7lo", 0);
strncpy (hdr.ar_fmag, ARFMAG, 2); memcpy (hdr.ar_fmag, ARFMAG, 2);
for (i = 0; i < sizeof (struct ar_hdr); i++)
if (((char *) (&hdr))[i] == '\0')
(((char *) (&hdr))[i]) = ' ';
/* Write the ar header for this item and the number of symbols. */ /* Write the ar header for this item and the number of symbols. */
if (bfd_bwrite (&hdr, sizeof (struct ar_hdr), arch) if (bfd_bwrite (&hdr, sizeof (struct ar_hdr), arch)

View file

@ -156,7 +156,6 @@ bfd_elf64_archive_write_armap (bfd *arch,
bfd *current = arch->archive_head; bfd *current = arch->archive_head;
unsigned int count; unsigned int count;
struct ar_hdr hdr; struct ar_hdr hdr;
unsigned int i;
int padding; int padding;
bfd_byte buf[8]; bfd_byte buf[8];
@ -169,19 +168,17 @@ bfd_elf64_archive_write_armap (bfd *arch,
+ sizeof (struct ar_hdr) + sizeof (struct ar_hdr)
+ SARMAG); + SARMAG);
memset (&hdr, 0, sizeof (struct ar_hdr)); memset (&hdr, ' ', sizeof (struct ar_hdr));
strcpy (hdr.ar_name, "/SYM64/"); memcpy (hdr.ar_name, "/SYM64/", strlen ("/SYM64/"));
sprintf (hdr.ar_size, "%-10d", (int) mapsize); _bfd_ar_spacepad (hdr.ar_size, sizeof (hdr.ar_size), "%-10ld",
sprintf (hdr.ar_date, "%ld", (long) time (NULL)); mapsize);
_bfd_ar_spacepad (hdr.ar_date, sizeof (hdr.ar_date), "%ld",
time (NULL));
/* This, at least, is what Intel coff sets the values to.: */ /* This, at least, is what Intel coff sets the values to.: */
sprintf ((hdr.ar_uid), "%d", 0); _bfd_ar_spacepad (hdr.ar_uid, sizeof (hdr.ar_uid), "%ld", 0);
sprintf ((hdr.ar_gid), "%d", 0); _bfd_ar_spacepad (hdr.ar_gid, sizeof (hdr.ar_gid), "%ld", 0);
sprintf ((hdr.ar_mode), "%-7o", (unsigned) 0); _bfd_ar_spacepad (hdr.ar_mode, sizeof (hdr.ar_mode), "%-7lo", 0);
strncpy (hdr.ar_fmag, ARFMAG, 2); memcpy (hdr.ar_fmag, ARFMAG, 2);
for (i = 0; i < sizeof (struct ar_hdr); i++)
if (((char *) (&hdr))[i] == '\0')
(((char *) (&hdr))[i]) = ' ';
/* Write the ar header for this item and the number of symbols */ /* Write the ar header for this item and the number of symbols */

View file

@ -178,6 +178,8 @@ bfd_boolean coff_write_armap
extern void *_bfd_generic_read_ar_hdr extern void *_bfd_generic_read_ar_hdr
(bfd *); (bfd *);
extern void _bfd_ar_spacepad
(char *, size_t, const char *, long);
extern void *_bfd_generic_read_ar_hdr_mag extern void *_bfd_generic_read_ar_hdr_mag
(bfd *, const char *); (bfd *, const char *);

View file

@ -183,6 +183,8 @@ bfd_boolean coff_write_armap
extern void *_bfd_generic_read_ar_hdr extern void *_bfd_generic_read_ar_hdr
(bfd *); (bfd *);
extern void _bfd_ar_spacepad
(char *, size_t, const char *, long);
extern void *_bfd_generic_read_ar_hdr_mag extern void *_bfd_generic_read_ar_hdr_mag
(bfd *, const char *); (bfd *, const char *);