Back to index

cell-binutils  2.17cvs20070401
Defines | Enumerations | Functions | Variables
cache.c File Reference
#include "bfd.h"
#include "sysdep.h"
#include "libbfd.h"
#include "libiberty.h"

Go to the source code of this file.

Defines

#define BFD_CACHE_MAX_OPEN   10
#define bfd_cache_lookup(x, flag)

Enumerations

enum  cache_flag { CACHE_NORMAL = 0, CACHE_NO_OPEN = 1, CACHE_NO_SEEK = 2, CACHE_NO_SEEK_ERROR = 4 }

Functions

static void insert (bfd *abfd)
static void snip (bfd *abfd)
static bfd_boolean bfd_cache_delete (bfd *abfd)
static bfd_boolean close_one (void)
static FILE * bfd_cache_lookup_worker (bfd *abfd, enum cache_flag flag)
static file_ptr cache_btell (struct bfd *abfd)
static int cache_bseek (struct bfd *abfd, file_ptr offset, int whence)
static file_ptr cache_bread (struct bfd *abfd, void *buf, file_ptr nbytes)
static file_ptr cache_bwrite (struct bfd *abfd, const void *where, file_ptr nbytes)
static int cache_bclose (struct bfd *abfd)
static int cache_bflush (struct bfd *abfd)
static int cache_bstat (struct bfd *abfd, struct stat *sb)
bfd_boolean bfd_cache_init (bfd *abfd)
bfd_boolean bfd_cache_close (bfd *abfd)
bfd_boolean bfd_cache_close_all ()
FILE * bfd_open_file (bfd *abfd)

Variables

static int open_files
static bfdbfd_last_cache = NULL
static struct bfd_iovec

Define Documentation

#define bfd_cache_lookup (   x,
  flag 
)
Value:
((x) == bfd_last_cache                    \
   ? (FILE *) (bfd_last_cache->iostream)  \
   : bfd_cache_lookup_worker (x, flag))

Definition at line 192 of file cache.c.

#define BFD_CACHE_MAX_OPEN   10

Definition at line 66 of file cache.c.


Enumeration Type Documentation

enum cache_flag
Enumerator:
CACHE_NORMAL 
CACHE_NO_OPEN 
CACHE_NO_SEEK 
CACHE_NO_SEEK_ERROR 

Definition at line 56 of file cache.c.


Function Documentation

Definition at line 410 of file cache.c.

{
  if (abfd->iovec != &cache_iovec)
    return TRUE;

  if (abfd->iostream == NULL)
    /* Previously closed.  */
    return TRUE;

  return bfd_cache_delete (abfd);
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 439 of file cache.c.

{
  bfd_boolean ret = TRUE;

  while (bfd_last_cache != NULL)
    ret &= bfd_cache_close (bfd_last_cache);

  return ret;
}

Here is the call graph for this function:

static bfd_boolean bfd_cache_delete ( bfd abfd) [static]

Definition at line 116 of file cache.c.

{
  bfd_boolean ret;

  if (fclose ((FILE *) abfd->iostream) == 0)
    ret = TRUE;
  else
    {
      ret = FALSE;
      bfd_set_error (bfd_error_system_call);
    }

  snip (abfd);

  abfd->iostream = NULL;
  --open_files;

  return ret;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 379 of file cache.c.

{
  BFD_ASSERT (abfd->iostream != NULL);
  if (open_files >= BFD_CACHE_MAX_OPEN)
    {
      if (! close_one ())
       return FALSE;
    }
  abfd->iovec = &cache_iovec;
  insert (abfd);
  ++open_files;
  return TRUE;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static FILE* bfd_cache_lookup_worker ( bfd abfd,
enum cache_flag  flag 
) [static]

Definition at line 205 of file cache.c.

{
  bfd *orig_bfd = abfd;
  if ((abfd->flags & BFD_IN_MEMORY) != 0)
    abort ();

  if (abfd->my_archive)
    abfd = abfd->my_archive;

  if (abfd->iostream != NULL)
    {
      /* Move the file to the start of the cache.  */
      if (abfd != bfd_last_cache)
       {
         snip (abfd);
         insert (abfd);
       }
      return (FILE *) abfd->iostream;
    }

  if (flag & CACHE_NO_OPEN)
    return NULL;

  if (bfd_open_file (abfd) == NULL)
    ;
  else if (!(flag & CACHE_NO_SEEK)
          && real_fseek ((FILE *) abfd->iostream, abfd->where, SEEK_SET) != 0
          && !(flag & CACHE_NO_SEEK_ERROR))
    bfd_set_error (bfd_error_system_call);
  else
    return (FILE *) abfd->iostream;

  (*_bfd_error_handler) (_("reopening %B: %s\n"),
                      orig_bfd, bfd_errmsg (bfd_get_error ()));
  return NULL;
}

Here is the call graph for this function:

FILE* bfd_open_file ( bfd abfd)

Definition at line 465 of file cache.c.

{
  abfd->cacheable = TRUE;   /* Allow it to be closed later.  */

  if (open_files >= BFD_CACHE_MAX_OPEN)
    {
      if (! close_one ())
       return NULL;
    }

  switch (abfd->direction)
    {
    case read_direction:
    case no_direction:
      abfd->iostream = (PTR) real_fopen (abfd->filename, FOPEN_RB);
      break;
    case both_direction:
    case write_direction:
      if (abfd->opened_once)
       {
         abfd->iostream = (PTR) real_fopen (abfd->filename, FOPEN_RUB);
         if (abfd->iostream == NULL)
           abfd->iostream = (PTR) real_fopen (abfd->filename, FOPEN_WUB);
       }
      else
       {
         /* Create the file.

            Some operating systems won't let us overwrite a running
            binary.  For them, we want to unlink the file first.

            However, gcc 2.95 will create temporary files using
            O_EXCL and tight permissions to prevent other users from
            substituting other .o files during the compilation.  gcc
            will then tell the assembler to use the newly created
            file as an output file.  If we unlink the file here, we
            open a brief window when another user could still
            substitute a file.

            So we unlink the output file if and only if it has
            non-zero size.  */
#ifndef __MSDOS__
         /* Don't do this for MSDOS: it doesn't care about overwriting
            a running binary, but if this file is already open by
            another BFD, we will be in deep trouble if we delete an
            open file.  In fact, objdump does just that if invoked with
            the --info option.  */
         struct stat s;

         if (stat (abfd->filename, &s) == 0 && s.st_size != 0)
           unlink_if_ordinary (abfd->filename);
#endif
         abfd->iostream = (PTR) real_fopen (abfd->filename, FOPEN_WUB);
         abfd->opened_once = TRUE;
       }
      break;
    }

  if (abfd->iostream == NULL)
    bfd_set_error (bfd_error_system_call);
  else
    {
      if (! bfd_cache_init (abfd))
       return NULL;
    }

  return (FILE *) abfd->iostream;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int cache_bclose ( struct bfd abfd) [static]

Definition at line 331 of file cache.c.

{
  return bfd_cache_close (abfd);
}

Here is the call graph for this function:

static int cache_bflush ( struct bfd abfd) [static]

Definition at line 337 of file cache.c.

{
  int sts;
  FILE *f = bfd_cache_lookup (abfd, CACHE_NO_OPEN);
  if (f == NULL)
    return 0;
  sts = fflush (f);
  if (sts < 0)
    bfd_set_error (bfd_error_system_call);
  return sts;
}

Here is the call graph for this function:

static file_ptr cache_bread ( struct bfd abfd,
void *  buf,
file_ptr  nbytes 
) [static]

Definition at line 268 of file cache.c.

{
  FILE *f;
  file_ptr nread;
  /* FIXME - this looks like an optimization, but it's really to cover
     up for a feature of some OSs (not solaris - sigh) that
     ld/pe-dll.c takes advantage of (apparently) when it creates BFDs
     internally and tries to link against them.  BFD seems to be smart
     enough to realize there are no symbol records in the "file" that
     doesn't exist but attempts to read them anyway.  On Solaris,
     attempting to read zero bytes from a NULL file results in a core
     dump, but on other platforms it just returns zero bytes read.
     This makes it to something reasonable. - DJ */
  if (nbytes == 0)
    return 0;

  f = bfd_cache_lookup (abfd, 0);
  if (f == NULL)
    return 0;

#if defined (__VAX) && defined (VMS)
  /* Apparently fread on Vax VMS does not keep the record length
     information.  */
  nread = read (fileno (f), buf, nbytes);
  /* Set bfd_error if we did not read as much data as we expected.  If
     the read failed due to an error set the bfd_error_system_call,
     else set bfd_error_file_truncated.  */
  if (nread == (file_ptr)-1)
    {
      bfd_set_error (bfd_error_system_call);
      return -1;
    }
#else
  nread = fread (buf, 1, nbytes, f);
  /* Set bfd_error if we did not read as much data as we expected.  If
     the read failed due to an error set the bfd_error_system_call,
     else set bfd_error_file_truncated.  */
  if (nread < nbytes && ferror (f))
    {
      bfd_set_error (bfd_error_system_call);
      return -1;
    }
#endif
  return nread;
}

Here is the call graph for this function:

static int cache_bseek ( struct bfd abfd,
file_ptr  offset,
int  whence 
) [static]

Definition at line 252 of file cache.c.

{
  FILE *f = bfd_cache_lookup (abfd, whence != SEEK_CUR ? CACHE_NO_SEEK : 0);
  if (f == NULL)
    return -1;
  return real_fseek (f, offset, whence);
}

Here is the call graph for this function:

static int cache_bstat ( struct bfd abfd,
struct stat sb 
) [static]

Definition at line 350 of file cache.c.

{
  int sts;
  FILE *f = bfd_cache_lookup (abfd, CACHE_NO_SEEK_ERROR);
  if (f == NULL)
    return -1;
  sts = fstat (fileno (f), sb);
  if (sts < 0)
    bfd_set_error (bfd_error_system_call);
  return sts;
}

Here is the call graph for this function:

static file_ptr cache_btell ( struct bfd abfd) [static]

Definition at line 243 of file cache.c.

{
  FILE *f = bfd_cache_lookup (abfd, CACHE_NO_OPEN);
  if (f == NULL)
    return abfd->where;
  return real_ftell (f);
}

Here is the call graph for this function:

static file_ptr cache_bwrite ( struct bfd abfd,
const void *  where,
file_ptr  nbytes 
) [static]

Definition at line 315 of file cache.c.

{
  file_ptr nwrite;
  FILE *f = bfd_cache_lookup (abfd, 0);
  if (f == NULL)
    return 0;
  nwrite = fwrite (where, 1, nbytes, f);
  if (nwrite < nbytes && ferror (f))
    {
      bfd_set_error (bfd_error_system_call);
      return -1;
    }
  return nwrite;
}

Here is the call graph for this function:

static bfd_boolean close_one ( void  ) [static]

Definition at line 140 of file cache.c.

{
  register bfd *kill;

  if (bfd_last_cache == NULL)
    kill = NULL;
  else
    {
      for (kill = bfd_last_cache->lru_prev;
          ! kill->cacheable;
          kill = kill->lru_prev)
       {
         if (kill == bfd_last_cache)
           {
             kill = NULL;
             break;
           }
       }
    }

  if (kill == NULL)
    {
      /* There are no open cacheable BFD's.  */
      return TRUE;
    }

  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);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void insert ( bfd abfd) [static]

Definition at line 81 of file cache.c.

{
  if (bfd_last_cache == NULL)
    {
      abfd->lru_next = abfd;
      abfd->lru_prev = abfd;
    }
  else
    {
      abfd->lru_next = bfd_last_cache;
      abfd->lru_prev = bfd_last_cache->lru_prev;
      abfd->lru_prev->lru_next = abfd;
      abfd->lru_next->lru_prev = abfd;
    }
  bfd_last_cache = abfd;
}

Here is the caller graph for this function:

static void snip ( bfd abfd) [static]

Definition at line 101 of file cache.c.

{
  abfd->lru_prev->lru_next = abfd->lru_next;
  abfd->lru_next->lru_prev = abfd->lru_prev;
  if (abfd == bfd_last_cache)
    {
      bfd_last_cache = abfd->lru_next;
      if (abfd == bfd_last_cache)
       bfd_last_cache = NULL;
    }
}

Here is the caller graph for this function:


Variable Documentation

struct bfd_iovec [static]
Initial value:

Definition at line 362 of file cache.c.

bfd* bfd_last_cache = NULL [static]

Definition at line 76 of file cache.c.

int open_files [static]

Definition at line 70 of file cache.c.