diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 57321afe7e..317133307e 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,15 @@ +2005-03-11 Jakub Jelinek + + * 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 * archive.c (_bfd_look_for_bfd_in_cache): Move declaration of diff --git a/bfd/archive.c b/bfd/archive.c index 79808459b1..937bc7d638 100644 --- a/bfd/archive.c +++ b/bfd/archive.c @@ -121,7 +121,7 @@ DESCRIPTION Regular files with long names (or embedded spaces, for BSD variants): "/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. Implemented for reading, not writing. " 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_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_generic_mkarchive (bfd *abfd) @@ -1283,17 +1298,8 @@ _bfd_construct_extended_name_table (bfd *abfd, strptr[thislen + 1] = '\012'; } hdr->ar_name[0] = ar_padchar (current); - /* We know there will always be enough room (one of the few - cases where you may safely use sprintf). */ - 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 = ' '; - } + _bfd_ar_spacepad (hdr->ar_name + 1, maxname - 1, "%-ld", + strptr - *tabloc); strptr += thislen + 1; if (trailing_slash) ++strptr; @@ -1340,7 +1346,6 @@ bfd_ar_hdr_from_filesystem (bfd *abfd, const char *filename, bfd *member) struct stat status; struct areltdata *ared; struct ar_hdr *hdr; - char *temp, *temp1; bfd_size_type amt; 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! */ memset (hdr, ' ', sizeof (struct ar_hdr)); - strncpy (hdr->ar_fmag, ARFMAG, 2); - - /* Goddamned sprintf doesn't permit MAXIMUM field lengths. */ - sprintf ((hdr->ar_date), "%-12ld", (long) status.st_mtime); + _bfd_ar_spacepad (hdr->ar_date, sizeof (hdr->ar_date), "%-12ld", + status.st_mtime); #ifdef HPUX_LARGE_AR_IDS /* HP has a very "special" way to handle UID/GID's with numeric values > 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 #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 /* HP has a very "special" way to handle UID/GID's with numeric values > 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 #endif - sprintf ((hdr->ar_gid), "%ld", (long) status.st_gid); - sprintf ((hdr->ar_mode), "%-8o", (unsigned int) status.st_mode); - sprintf ((hdr->ar_size), "%-10ld", (long) status.st_size); - /* Correct for a lossage in sprintf whereby it null-terminates. I cannot - understand how these C losers could design such a ramshackle bunch of - IO operations. */ - temp = (char *) hdr; - temp1 = temp + sizeof (struct ar_hdr) - 2; - for (; temp < temp1; temp++) - { - if (*temp == '\0') - *temp = ' '; - } - strncpy (hdr->ar_fmag, ARFMAG, 2); + _bfd_ar_spacepad (hdr->ar_gid, sizeof (hdr->ar_gid), "%ld", + 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); + memcpy (hdr->ar_fmag, ARFMAG, 2); ared->parsed_size = status.st_size; 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. */ bfd_boolean hasobjects = FALSE; bfd_size_type wrote; - unsigned int i; int tries; /* 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; - memset (&hdr, 0, sizeof (struct ar_hdr)); - strcpy (hdr.ar_name, ename); + memset (&hdr, ' ', sizeof (struct ar_hdr)); + memcpy (hdr.ar_name, ename, strlen (ename)); /* Round size up to even number in archive header. */ - sprintf (&(hdr.ar_size[0]), "%-10d", - (int) ((elength + 1) & ~(bfd_size_type) 1)); - strncpy (hdr.ar_fmag, ARFMAG, 2); - for (i = 0; i < sizeof (struct ar_hdr); i++) - if (((char *) (&hdr))[i] == '\0') - (((char *) (&hdr))[i]) = ' '; + _bfd_ar_spacepad (hdr.ar_size, sizeof (hdr.ar_size), "%-10ld", + (elength + 1) & ~(bfd_size_type) 1); + memcpy (hdr.ar_fmag, ARFMAG, 2); if ((bfd_bwrite (&hdr, sizeof (struct ar_hdr), arch) != sizeof (struct ar_hdr)) || bfd_bwrite (etable, elength, arch) != elength) @@ -1920,25 +1913,22 @@ bsd_write_armap (bfd *arch, unsigned int count; struct ar_hdr hdr; struct stat statbuf; - unsigned int i; firstreal = mapsize + elength + sizeof (struct ar_hdr) + SARMAG; stat (arch->filename, &statbuf); - memset (&hdr, 0, sizeof (struct ar_hdr)); - sprintf (hdr.ar_name, RANLIBMAG); + memset (&hdr, ' ', sizeof (struct ar_hdr)); + memcpy (hdr.ar_name, RANLIBMAG, strlen (RANLIBMAG)); /* 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_datepos = (SARMAG + offsetof (struct ar_hdr, ar_date[0])); - sprintf (hdr.ar_date, "%ld", bfd_ardata (arch)->armap_timestamp); - sprintf (hdr.ar_uid, "%ld", (long) getuid ()); - sprintf (hdr.ar_gid, "%ld", (long) getgid ()); - sprintf (hdr.ar_size, "%-10d", (int) mapsize); - strncpy (hdr.ar_fmag, ARFMAG, 2); - for (i = 0; i < sizeof (struct ar_hdr); i++) - if (((char *) (&hdr))[i] == '\0') - (((char *) (&hdr))[i]) = ' '; + _bfd_ar_spacepad (hdr.ar_date, sizeof (hdr.ar_date), "%ld", + bfd_ardata (arch)->armap_timestamp); + _bfd_ar_spacepad (hdr.ar_uid, sizeof (hdr.ar_uid), "%ld", getuid ()); + _bfd_ar_spacepad (hdr.ar_gid, sizeof (hdr.ar_gid), "%ld", getgid ()); + _bfd_ar_spacepad (hdr.ar_size, sizeof (hdr.ar_size), "%-10ld", mapsize); + memcpy (hdr.ar_fmag, ARFMAG, 2); if (bfd_bwrite (&hdr, sizeof (struct ar_hdr), arch) != sizeof (struct ar_hdr)) return FALSE; @@ -2003,7 +1993,6 @@ _bfd_archive_bsd_update_armap_timestamp (bfd *arch) { struct stat archstat; struct ar_hdr hdr; - unsigned int i; /* Flush writes, get last-write timestamp from file, and compare it 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; /* Prepare an ASCII version suitable for writing. */ - memset (hdr.ar_date, 0, sizeof (hdr.ar_date)); - sprintf (hdr.ar_date, "%ld", bfd_ardata (arch)->armap_timestamp); - for (i = 0; i < sizeof (hdr.ar_date); i++) - if (hdr.ar_date[i] == '\0') - (hdr.ar_date)[i] = ' '; + memset (hdr.ar_date, ' ', sizeof (hdr.ar_date)); + _bfd_ar_spacepad (hdr.ar_date, sizeof (hdr.ar_date), "%ld", + bfd_ardata (arch)->armap_timestamp); /* Write it into the file. */ bfd_ardata (arch)->armap_datepos = (SARMAG @@ -2075,7 +2062,6 @@ coff_write_armap (bfd *arch, bfd *current = arch->archive_head; unsigned int count; struct ar_hdr hdr; - unsigned int i; int padit = mapsize & 1; if (padit) @@ -2087,19 +2073,17 @@ coff_write_armap (bfd *arch, + sizeof (struct ar_hdr) + SARMAG); - memset (&hdr, 0, sizeof (struct ar_hdr)); + memset (&hdr, ' ', sizeof (struct ar_hdr)); hdr.ar_name[0] = '/'; - sprintf (hdr.ar_size, "%-10d", (int) mapsize); - sprintf (hdr.ar_date, "%ld", (long) time (NULL)); + _bfd_ar_spacepad (hdr.ar_size, sizeof (hdr.ar_size), "%-10ld", + 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. */ - sprintf ((hdr.ar_uid), "%d", 0); - sprintf ((hdr.ar_gid), "%d", 0); - sprintf ((hdr.ar_mode), "%-7o", (unsigned) 0); - strncpy (hdr.ar_fmag, ARFMAG, 2); - - for (i = 0; i < sizeof (struct ar_hdr); i++) - if (((char *) (&hdr))[i] == '\0') - (((char *) (&hdr))[i]) = ' '; + _bfd_ar_spacepad (hdr.ar_uid, sizeof (hdr.ar_uid), "%ld", 0); + _bfd_ar_spacepad (hdr.ar_gid, sizeof (hdr.ar_gid), "%ld", 0); + _bfd_ar_spacepad (hdr.ar_mode, sizeof (hdr.ar_mode), "%-7lo", 0); + memcpy (hdr.ar_fmag, ARFMAG, 2); /* Write the ar header for this item and the number of symbols. */ if (bfd_bwrite (&hdr, sizeof (struct ar_hdr), arch) diff --git a/bfd/archive64.c b/bfd/archive64.c index 1b9f5f3c0f..6ee0d1aa12 100644 --- a/bfd/archive64.c +++ b/bfd/archive64.c @@ -156,7 +156,6 @@ bfd_elf64_archive_write_armap (bfd *arch, bfd *current = arch->archive_head; unsigned int count; struct ar_hdr hdr; - unsigned int i; int padding; bfd_byte buf[8]; @@ -169,19 +168,17 @@ bfd_elf64_archive_write_armap (bfd *arch, + sizeof (struct ar_hdr) + SARMAG); - memset (&hdr, 0, sizeof (struct ar_hdr)); - strcpy (hdr.ar_name, "/SYM64/"); - sprintf (hdr.ar_size, "%-10d", (int) mapsize); - sprintf (hdr.ar_date, "%ld", (long) time (NULL)); + 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); + _bfd_ar_spacepad (hdr.ar_date, sizeof (hdr.ar_date), "%ld", + time (NULL)); /* This, at least, is what Intel coff sets the values to.: */ - sprintf ((hdr.ar_uid), "%d", 0); - sprintf ((hdr.ar_gid), "%d", 0); - sprintf ((hdr.ar_mode), "%-7o", (unsigned) 0); - strncpy (hdr.ar_fmag, ARFMAG, 2); - - for (i = 0; i < sizeof (struct ar_hdr); i++) - if (((char *) (&hdr))[i] == '\0') - (((char *) (&hdr))[i]) = ' '; + _bfd_ar_spacepad (hdr.ar_uid, sizeof (hdr.ar_uid), "%ld", 0); + _bfd_ar_spacepad (hdr.ar_gid, sizeof (hdr.ar_gid), "%ld", 0); + _bfd_ar_spacepad (hdr.ar_mode, sizeof (hdr.ar_mode), "%-7lo", 0); + memcpy (hdr.ar_fmag, ARFMAG, 2); /* Write the ar header for this item and the number of symbols */ diff --git a/bfd/libbfd-in.h b/bfd/libbfd-in.h index cc65a56301..326d196ea6 100644 --- a/bfd/libbfd-in.h +++ b/bfd/libbfd-in.h @@ -178,6 +178,8 @@ bfd_boolean coff_write_armap extern void *_bfd_generic_read_ar_hdr (bfd *); +extern void _bfd_ar_spacepad + (char *, size_t, const char *, long); extern void *_bfd_generic_read_ar_hdr_mag (bfd *, const char *); diff --git a/bfd/libbfd.h b/bfd/libbfd.h index ee6b42186f..3cfed3a11d 100644 --- a/bfd/libbfd.h +++ b/bfd/libbfd.h @@ -183,6 +183,8 @@ bfd_boolean coff_write_armap extern void *_bfd_generic_read_ar_hdr (bfd *); +extern void _bfd_ar_spacepad + (char *, size_t, const char *, long); extern void *_bfd_generic_read_ar_hdr_mag (bfd *, const char *);