This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
More fixes for files bigger than 2GB
- From: Francois Gouget <fgouget at codeweavers dot com>
- To: binutils at sourceware dot org
- Date: Fri, 18 May 2012 16:15:35 +0200 (CEST)
- Subject: More fixes for files bigger than 2GB
This is related to PR 13534 but most of it was fixed already.
http://sourceware.org/bugzilla/show_bug.cgi?id=13534
So the best was to test for this now is to archive / unarchive a 4GB
file on a 32bit system:
$ dd if=/dev/zero of=file4G bs=1M count=4096
4096+0 enregistrements lus
4096+0 enregistrements écrits
4294967296 bytes (4,3 GB) copied, 44,7366 s, 96,0 MB/s
$ ./binutils/ar q ar4G.ar file4G
$ ./binutils/ar tv ar4G.ar
rw-r--r-- 1001/2000 0 May 18 08:29 2012 file4G
$ ./binutils/ar x ar4G.ar
$ ls -l file4G
-rw-r--r-- 1 gouget cw 0 mai 18 14:06 file4G
$ ./binutils/ar p ar4G.ar >file4G
$ ls -l file4G
-rw-r--r-- 1 gouget cw 0 mai 18 14:07 file4G
This issue happens because of the conversion of the st_size values which
are typically of the off64_t type to size_t variables that can only hold
unsigned 32bit values. Archive element sizes should only ever be held in
bfd_size_type variables.
The bucomm.c (print_arelt_descr) chunks fix 'ar tv', the ar.c
(print_contents) chunks fix 'ar p' and the ar.c (extract_file) chunks
fix 'ar x'.
I believe the ar.c part was supposed to be included in the previous
commit for PR 13534 but somehow got left out (the changelog mentions
ar.c but the commit does not touch it).
I've tried to provide a suitable changelog below but feel free to fix it
as you see fit.
2012-05-17 Francois Gouget <fgouget@codeweavers.com>
PR binutils/13534
* bucomm.c (print_arelt_descr): Correctly report the archive size field.
* ar.c (print_contents): Use correct types for archive element sizes.
(extract_file): Likewise.
diff --git a/binutils/ar.c b/binutils/ar.c
index 13637f4..6ee1dd0 100644
--- a/binutils/ar.c
+++ b/binutils/ar.c
@@ -937,10 +937,10 @@ open_inarch (const char *archive_filename, const char *file)
static void
print_contents (bfd *abfd)
{
- size_t ncopied = 0;
+ bfd_size_type ncopied = 0;
char *cbuf = (char *) xmalloc (BUFSIZE);
struct stat buf;
- size_t size;
+ bfd_size_type size;
if (bfd_stat_arch_elt (abfd, &buf) != 0)
/* xgettext:c-format */
fatal (_("internal stat error on %s"), bfd_get_filename (abfd));
@@ -954,12 +954,12 @@ print_contents (bfd *abfd)
while (ncopied < size)
{
- size_t nread;
- size_t tocopy = size - ncopied;
+ bfd_size_type nread;
+ bfd_size_type tocopy = size - ncopied;
if (tocopy > BUFSIZE)
tocopy = BUFSIZE;
- nread = bfd_bread (cbuf, (bfd_size_type) tocopy, abfd);
+ nread = bfd_bread (cbuf, tocopy, abfd);
if (nread != tocopy)
/* xgettext:c-format */
fatal (_("%s is not a valid archive"),
@@ -990,9 +990,9 @@ extract_file (bfd *abfd)
{
FILE *ostream;
char *cbuf = (char *) xmalloc (BUFSIZE);
- size_t nread, tocopy;
- size_t ncopied = 0;
- size_t size;
+ bfd_size_type nread, tocopy;
+ bfd_size_type ncopied = 0;
+ bfd_size_type size;
struct stat buf;
if (bfd_stat_arch_elt (abfd, &buf) != 0)
@@ -1027,7 +1027,7 @@ extract_file (bfd *abfd)
if (tocopy > BUFSIZE)
tocopy = BUFSIZE;
- nread = bfd_bread (cbuf, (bfd_size_type) tocopy, abfd);
+ nread = bfd_bread (cbuf, tocopy, abfd);
if (nread != tocopy)
/* xgettext:c-format */
fatal (_("%s is not a valid archive"),
diff --git a/binutils/bucomm.c b/binutils/bucomm.c
index 86cb6e4..bb3fb3f 100644
--- a/binutils/bucomm.c
+++ b/binutils/bucomm.c
@@ -427,16 +427,18 @@ print_arelt_descr (FILE *file, bfd *abfd, bfd_boolean verbose)
char timebuf[40];
time_t when = buf.st_mtime;
const char *ctime_result = (const char *) ctime (&when);
+ bfd_size_type size;
/* POSIX format: skip weekday and seconds from ctime output. */
sprintf (timebuf, "%.12s %.4s", ctime_result + 4, ctime_result + 20);
mode_string (buf.st_mode, modebuf);
modebuf[10] = '\0';
+ size = buf.st_size;
/* POSIX 1003.2/D11 says to skip first character (entry type). */
- fprintf (file, "%s %ld/%ld %6ld %s ", modebuf + 1,
+ fprintf (file, "%s %ld/%ld %6" BFD_VMA_FMT "u %s ", modebuf + 1,
(long) buf.st_uid, (long) buf.st_gid,
- (long) buf.st_size, timebuf);
+ size, timebuf);
}
}
--
Francois Gouget <fgouget@codeweavers.com>