* NEWS: Mention sparc64-linux-gnu gdbserver support.
[binutils-gdb.git] / bfd / cache.c
index 064cebeb3cb3ec4362bb62b2cc96776f20b8cce7..50674e88b0ece0b58f580dc5d07b179b56e4b75e 100644 (file)
@@ -166,22 +166,6 @@ close_one (void)
 
   kill->where = real_ftell ((FILE *) kill->iostream);
 
-  /* Save the file st_mtime.  This is a hack so that gdb can detect when
-     an executable has been deleted and recreated.  The only thing that
-     makes this reasonable is that st_mtime doesn't change when a file
-     is unlinked, so saving st_mtime makes BFD's file cache operation
-     a little more transparent for this particular usage pattern.  If we
-     hadn't closed the file then we would not have lost the original
-     contents, st_mtime etc.  Of course, if something is writing to an
-     existing file, then this is the wrong thing to do.
-     FIXME: gdb should save these times itself on first opening a file,
-     and this hack be removed.  */
-  if (kill->direction == no_direction || kill->direction == read_direction)
-    {
-      bfd_get_mtime (kill);
-      kill->mtime_set = TRUE;
-    }
-
   return bfd_cache_delete (kill);
 }
 
@@ -266,7 +250,7 @@ cache_bseek (struct bfd *abfd, file_ptr offset, int whence)
    first octet in the file, NOT the beginning of the archive header.  */
 
 static file_ptr
-cache_bread (struct bfd *abfd, void *buf, file_ptr nbytes)
+cache_bread_1 (struct bfd *abfd, void *buf, file_ptr nbytes)
 {
   FILE *f;
   file_ptr nread;
@@ -316,11 +300,49 @@ cache_bread (struct bfd *abfd, void *buf, file_ptr nbytes)
   return nread;
 }
 
+static file_ptr
+cache_bread (struct bfd *abfd, void *buf, file_ptr nbytes)
+{
+  file_ptr nread = 0;
+
+  /* Some filesystems are unable to handle reads that are too large
+     (for instance, NetApp shares with oplocks turned off).  To avoid
+     hitting this limitation, we read the buffer in chunks of 8MB max.  */
+  while (nread < nbytes)
+    {
+      const file_ptr max_chunk_size = 0x800000;
+      file_ptr chunk_size = nbytes - nread;
+      file_ptr chunk_nread;
+
+      if (chunk_size > max_chunk_size)
+        chunk_size = max_chunk_size;
+
+      chunk_nread = cache_bread_1 (abfd, (char *) buf + nread, chunk_size);
+
+      /* Update the nread count.
+
+         We just have to be careful of the case when cache_bread_1 returns
+         a negative count:  If this is our first read, then set nread to
+         that negative count in order to return that negative value to the
+         caller.  Otherwise, don't add it to our total count, or we would
+         end up returning a smaller number of bytes read than we actually
+         did.  */
+      if (nread == 0 || chunk_nread > 0)
+        nread += chunk_nread;
+
+      if (chunk_nread < chunk_size)
+        break;
+    }
+
+  return nread;
+}
+
 static file_ptr
 cache_bwrite (struct bfd *abfd, const void *where, file_ptr nbytes)
 {
   file_ptr nwrite;
   FILE *f = bfd_cache_lookup (abfd, 0);
+
   if (f == NULL)
     return 0;
   nwrite = fwrite (where, 1, nbytes, f);
@@ -343,6 +365,7 @@ cache_bflush (struct bfd *abfd)
 {
   int sts;
   FILE *f = bfd_cache_lookup (abfd, CACHE_NO_OPEN);
+
   if (f == NULL)
     return 0;
   sts = fflush (f);
@@ -356,6 +379,7 @@ cache_bstat (struct bfd *abfd, struct stat *sb)
 {
   int sts;
   FILE *f = bfd_cache_lookup (abfd, CACHE_NO_SEEK_ERROR);
+
   if (f == NULL)
     return -1;
   sts = fstat (fileno (f), sb);
@@ -364,7 +388,8 @@ cache_bstat (struct bfd *abfd, struct stat *sb)
   return sts;
 }
 
-static const struct bfd_iovec cache_iovec = {
+static const struct bfd_iovec cache_iovec =
+{
   &cache_bread, &cache_bwrite, &cache_btell, &cache_bseek,
   &cache_bclose, &cache_bflush, &cache_bstat
 };