2005-03-07 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. --- bfd/libbfd-in.h.jj 2005-02-25 13:06:22.000000000 +0100 +++ bfd/libbfd-in.h 2005-03-07 11:10:58.745366987 +0100 @@ -176,6 +176,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 *); --- bfd/libbfd.h.jj 2005-02-25 13:06:22.000000000 +0100 +++ bfd/libbfd.h 2005-03-07 11:11:28.099135905 +0100 @@ -181,6 +181,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 *); --- bfd/archive.c.jj 2005-02-25 13:06:00.000000000 +0100 +++ bfd/archive.c 2005-03-07 11:09:22.003607377 +0100 @@ -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) @@ -1262,17 +1277,8 @@ _bfd_construct_extended_name_table (bfd 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", + (unsigned) (strptr - *tabloc)); strptr += thislen + 1; if (trailing_slash) ++strptr; @@ -1319,7 +1325,6 @@ bfd_ar_hdr_from_filesystem (bfd *abfd, c 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) @@ -1347,39 +1352,31 @@ bfd_ar_hdr_from_filesystem (bfd *abfd, c /* 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", + (long) 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", + (long) 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", + (long) status.st_gid); + _bfd_ar_spacepad (hdr->ar_mode, sizeof (hdr->ar_mode), "%-8lo", + (unsigned int) status.st_mode); + _bfd_ar_spacepad (hdr->ar_size, sizeof (hdr->ar_size), "%-10ld", + (long) status.st_size); + memcpy (hdr->ar_fmag, ARFMAG, 2); ared->parsed_size = status.st_size; ared->arch_header = (char *) hdr; @@ -1600,7 +1597,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 @@ -1657,15 +1653,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", + (int) ((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) @@ -1899,25 +1892,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", (long) getuid ()); + _bfd_ar_spacepad (hdr.ar_gid, sizeof (hdr.ar_gid), "%ld", (long) getgid ()); + _bfd_ar_spacepad (hdr.ar_size, sizeof (hdr.ar_size), "%-10ld", (int) mapsize); + memcpy (hdr.ar_fmag, ARFMAG, 2); if (bfd_bwrite (&hdr, sizeof (struct ar_hdr), arch) != sizeof (struct ar_hdr)) return FALSE; @@ -1982,7 +1972,6 @@ _bfd_archive_bsd_update_armap_timestamp { 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. */ @@ -2002,11 +1991,9 @@ _bfd_archive_bsd_update_armap_timestamp 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 @@ -2054,7 +2041,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) @@ -2066,19 +2052,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", + (int) mapsize); + _bfd_ar_spacepad (hdr.ar_date, sizeof (hdr.ar_date), "%ld", + (long) 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) --- bfd/archive64.c.jj 2003-07-02 17:01:47.000000000 +0200 +++ bfd/archive64.c 2005-03-07 11:11:36.334668270 +0100 @@ -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", + (int) mapsize); + _bfd_ar_spacepad (hdr.ar_date, sizeof (hdr.ar_date), "%ld", + (long) 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 */