OpenCores
URL https://opencores.org/ocsvn/openrisc_me/openrisc_me/trunk

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [gnu-src/] [gdb-6.8/] [bfd/] [cache.c] - Diff between revs 157 and 225

Go to most recent revision | Show entire file | Details | Blame | View Log

Rev 157 Rev 225
Line 1... Line 1...
/* BFD library -- caching of file descriptors.
/* BFD library -- caching of file descriptors.
 
 
   Copyright 1990, 1991, 1992, 1993, 1994, 1996, 2000, 2001, 2002,
   Copyright 1990, 1991, 1992, 1993, 1994, 1996, 2000, 2001, 2002,
   2003, 2004, 2005, 2007 Free Software Foundation, Inc.
   2003, 2004, 2005, 2007, 2008, 2009 Free Software Foundation, Inc.
 
 
   Hacked by Steve Chamberlain of Cygnus Support (steve@cygnus.com).
   Hacked by Steve Chamberlain of Cygnus Support (steve@cygnus.com).
 
 
   This file is part of BFD, the Binary File Descriptor library.
   This file is part of BFD, the Binary File Descriptor library.
 
 
Line 44... Line 44...
#include "sysdep.h"
#include "sysdep.h"
#include "bfd.h"
#include "bfd.h"
#include "libbfd.h"
#include "libbfd.h"
#include "libiberty.h"
#include "libiberty.h"
 
 
 
#ifdef HAVE_MMAP
 
#include <sys/mman.h>
 
#endif
 
 
/* In some cases we can optimize cache operation when reopening files.
/* In some cases we can optimize cache operation when reopening files.
   For instance, a flush is entirely unnecessary if the file is already
   For instance, a flush is entirely unnecessary if the file is already
   closed, so a flush would use CACHE_NO_OPEN.  Similarly, a seek using
   closed, so a flush would use CACHE_NO_OPEN.  Similarly, a seek using
   SEEK_SET or SEEK_END need not first seek to the current position.
   SEEK_SET or SEEK_END need not first seek to the current position.
   For stat we ignore seek errors, just in case the file has changed
   For stat we ignore seek errors, just in case the file has changed
Line 164... Line 168...
      return TRUE;
      return TRUE;
    }
    }
 
 
  kill->where = real_ftell ((FILE *) kill->iostream);
  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);
  return bfd_cache_delete (kill);
}
}
 
 
/* Check to see if the required BFD is the same as the last one
/* Check to see if the required BFD is the same as the last one
   looked up. If so, then it can use the stream in the BFD with
   looked up. If so, then it can use the stream in the BFD with
Line 250... Line 238...
}
}
 
 
static int
static int
cache_bseek (struct bfd *abfd, file_ptr offset, int whence)
cache_bseek (struct bfd *abfd, file_ptr offset, int whence)
{
{
  FILE *f = bfd_cache_lookup (abfd, whence != SEEK_CUR ? CACHE_NO_SEEK : 0);
  FILE *f = bfd_cache_lookup (abfd, whence != SEEK_CUR ? CACHE_NO_SEEK : CACHE_NORMAL);
  if (f == NULL)
  if (f == NULL)
    return -1;
    return -1;
  return real_fseek (f, offset, whence);
  return real_fseek (f, offset, whence);
}
}
 
 
Line 264... Line 252...
   Also, note that the origin pointer points to the beginning of a file's
   Also, note that the origin pointer points to the beginning of a file's
   contents (0 for non-archive elements).  For archive entries this is the
   contents (0 for non-archive elements).  For archive entries this is the
   first octet in the file, NOT the beginning of the archive header.  */
   first octet in the file, NOT the beginning of the archive header.  */
 
 
static file_ptr
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 *f;
  file_ptr nread;
  file_ptr nread;
  /* FIXME - this looks like an optimization, but it's really to cover
  /* FIXME - this looks like an optimization, but it's really to cover
     up for a feature of some OSs (not solaris - sigh) that
     up for a feature of some OSs (not solaris - sigh) that
Line 280... Line 268...
     dump, but on other platforms it just returns zero bytes read.
     dump, but on other platforms it just returns zero bytes read.
     This makes it to something reasonable. - DJ */
     This makes it to something reasonable. - DJ */
  if (nbytes == 0)
  if (nbytes == 0)
    return 0;
    return 0;
 
 
  f = bfd_cache_lookup (abfd, 0);
  f = bfd_cache_lookup (abfd, CACHE_NORMAL);
  if (f == NULL)
  if (f == NULL)
    return 0;
    return 0;
 
 
#if defined (__VAX) && defined (VMS)
#if defined (__VAX) && defined (VMS)
  /* Apparently fread on Vax VMS does not keep the record length
  /* Apparently fread on Vax VMS does not keep the record length
Line 315... Line 303...
    bfd_set_error (bfd_error_file_truncated);
    bfd_set_error (bfd_error_file_truncated);
  return nread;
  return nread;
}
}
 
 
static file_ptr
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)
cache_bwrite (struct bfd *abfd, const void *where, file_ptr nbytes)
{
{
  file_ptr nwrite;
  file_ptr nwrite;
  FILE *f = bfd_cache_lookup (abfd, 0);
  FILE *f = bfd_cache_lookup (abfd, CACHE_NORMAL);
 
 
  if (f == NULL)
  if (f == NULL)
    return 0;
    return 0;
  nwrite = fwrite (where, 1, nbytes, f);
  nwrite = fwrite (where, 1, nbytes, f);
  if (nwrite < nbytes && ferror (f))
  if (nwrite < nbytes && ferror (f))
    {
    {
Line 341... Line 367...
static int
static int
cache_bflush (struct bfd *abfd)
cache_bflush (struct bfd *abfd)
{
{
  int sts;
  int sts;
  FILE *f = bfd_cache_lookup (abfd, CACHE_NO_OPEN);
  FILE *f = bfd_cache_lookup (abfd, CACHE_NO_OPEN);
 
 
  if (f == NULL)
  if (f == NULL)
    return 0;
    return 0;
  sts = fflush (f);
  sts = fflush (f);
  if (sts < 0)
  if (sts < 0)
    bfd_set_error (bfd_error_system_call);
    bfd_set_error (bfd_error_system_call);
Line 354... Line 381...
static int
static int
cache_bstat (struct bfd *abfd, struct stat *sb)
cache_bstat (struct bfd *abfd, struct stat *sb)
{
{
  int sts;
  int sts;
  FILE *f = bfd_cache_lookup (abfd, CACHE_NO_SEEK_ERROR);
  FILE *f = bfd_cache_lookup (abfd, CACHE_NO_SEEK_ERROR);
 
 
  if (f == NULL)
  if (f == NULL)
    return -1;
    return -1;
  sts = fstat (fileno (f), sb);
  sts = fstat (fileno (f), sb);
  if (sts < 0)
  if (sts < 0)
    bfd_set_error (bfd_error_system_call);
    bfd_set_error (bfd_error_system_call);
  return sts;
  return sts;
}
}
 
 
static const struct bfd_iovec cache_iovec = {
static void *
 
cache_bmmap (struct bfd *abfd ATTRIBUTE_UNUSED,
 
             void *addr ATTRIBUTE_UNUSED,
 
             bfd_size_type len ATTRIBUTE_UNUSED,
 
             int prot ATTRIBUTE_UNUSED,
 
             int flags ATTRIBUTE_UNUSED,
 
             file_ptr offset ATTRIBUTE_UNUSED)
 
{
 
  void *ret = (void *) -1;
 
 
 
  if ((abfd->flags & BFD_IN_MEMORY) != 0)
 
    abort ();
 
#ifdef HAVE_MMAP
 
  else
 
    {
 
      FILE *f = bfd_cache_lookup (abfd, CACHE_NO_SEEK_ERROR);
 
      if (f == NULL)
 
        return ret;
 
 
 
      ret = mmap (addr, len, prot, flags, fileno (f), offset);
 
      if (ret == (void *) -1)
 
        bfd_set_error (bfd_error_system_call);
 
    }
 
#endif
 
 
 
  return ret;
 
}
 
 
 
static const struct bfd_iovec cache_iovec =
 
{
  &cache_bread, &cache_bwrite, &cache_btell, &cache_bseek,
  &cache_bread, &cache_bwrite, &cache_btell, &cache_bseek,
  &cache_bclose, &cache_bflush, &cache_bstat
  &cache_bclose, &cache_bflush, &cache_bstat, &cache_bmmap
};
};
 
 
/*
/*
INTERNAL_FUNCTION
INTERNAL_FUNCTION
        bfd_cache_init
        bfd_cache_init

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.