Line 1... |
Line 1... |
/* Low-level I/O routines for BFDs.
|
/* Low-level I/O routines for BFDs.
|
|
|
Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
|
Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
|
1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
|
1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
|
Free Software Foundation, Inc.
|
Free Software Foundation, Inc.
|
|
|
Written by Cygnus Support.
|
Written by Cygnus Support.
|
|
|
This file is part of BFD, the Binary File Descriptor library.
|
This file is part of BFD, the Binary File Descriptor library.
|
Line 36... |
Line 36... |
#endif
|
#endif
|
#ifndef S_IXOTH
|
#ifndef S_IXOTH
|
#define S_IXOTH 0001 /* Execute by others. */
|
#define S_IXOTH 0001 /* Execute by others. */
|
#endif
|
#endif
|
|
|
|
#ifndef FD_CLOEXEC
|
|
#define FD_CLOEXEC 1
|
|
#endif
|
|
|
file_ptr
|
file_ptr
|
real_ftell (FILE *file)
|
real_ftell (FILE *file)
|
{
|
{
|
#if defined (HAVE_FTELLO64)
|
#if defined (HAVE_FTELLO64)
|
return ftello64 (file);
|
return ftello64 (file);
|
Line 60... |
Line 64... |
#else
|
#else
|
return fseek (file, offset, whence);
|
return fseek (file, offset, whence);
|
#endif
|
#endif
|
}
|
}
|
|
|
|
/* Mark FILE as close-on-exec. Return FILE. FILE may be NULL, in
|
|
which case nothing is done. */
|
|
static FILE *
|
|
close_on_exec (FILE *file)
|
|
{
|
|
#if defined (HAVE_FILENO) && defined (F_GETFD)
|
|
if (file)
|
|
{
|
|
int fd = fileno (file);
|
|
int old = fcntl (fd, F_GETFD, 0);
|
|
if (old >= 0)
|
|
fcntl (fd, F_SETFD, old | FD_CLOEXEC);
|
|
}
|
|
#endif
|
|
return file;
|
|
}
|
|
|
FILE *
|
FILE *
|
real_fopen (const char *filename, const char *modes)
|
real_fopen (const char *filename, const char *modes)
|
{
|
{
|
|
#ifdef VMS
|
|
char vms_modes[4];
|
|
char *vms_attr;
|
|
|
|
/* On VMS, fopen allows file attributes as optionnal arguments.
|
|
We need to use them but we'd better to use the common prototype.
|
|
In fopen-vms.h, they are separated from the mode with a comma.
|
|
Split here. */
|
|
vms_attr = strchr (modes, ',');
|
|
if (vms_attr == NULL)
|
|
{
|
|
/* No attributes. */
|
|
return close_on_exec (fopen (filename, modes));
|
|
}
|
|
else
|
|
{
|
|
/* Attributes found. Split. */
|
|
size_t modes_len = strlen (modes) + 1;
|
|
char attrs[modes_len + 1];
|
|
char *at[3];
|
|
int i;
|
|
|
|
memcpy (attrs, modes, modes_len);
|
|
at[0] = attrs;
|
|
for (i = 0; i < 2; i++)
|
|
{
|
|
at[i + 1] = strchr (at[i], ',');
|
|
BFD_ASSERT (at[i + 1] != NULL);
|
|
*(at[i + 1]++) = 0; /* Replace ',' with a nul, and skip it. */
|
|
}
|
|
return close_on_exec (fopen (filename, at[0], at[1], at[2]));
|
|
}
|
|
#else /* !VMS */
|
#if defined (HAVE_FOPEN64)
|
#if defined (HAVE_FOPEN64)
|
return fopen64 (filename, modes);
|
return close_on_exec (fopen64 (filename, modes));
|
#else
|
#else
|
return fopen (filename, modes);
|
return close_on_exec (fopen (filename, modes));
|
#endif
|
#endif
|
|
#endif /* !VMS */
|
}
|
}
|
|
|
/*
|
/*
|
INTERNAL_DEFINITION
|
INTERNAL_DEFINITION
|
struct bfd_iovec
|
struct bfd_iovec
|
Line 101... |
Line 156... |
. Otherwise, a value of -1 is returned (and <<bfd_error>> is set). *}
|
. Otherwise, a value of -1 is returned (and <<bfd_error>> is set). *}
|
. int (*bseek) (struct bfd *abfd, file_ptr offset, int whence);
|
. int (*bseek) (struct bfd *abfd, file_ptr offset, int whence);
|
. int (*bclose) (struct bfd *abfd);
|
. int (*bclose) (struct bfd *abfd);
|
. int (*bflush) (struct bfd *abfd);
|
. int (*bflush) (struct bfd *abfd);
|
. int (*bstat) (struct bfd *abfd, struct stat *sb);
|
. int (*bstat) (struct bfd *abfd, struct stat *sb);
|
|
. {* Just like mmap: (void*)-1 on failure, mmapped address on success. *}
|
|
. void *(*bmmap) (struct bfd *abfd, void *addr, bfd_size_type len,
|
|
. int prot, int flags, file_ptr offset);
|
.};
|
.};
|
|
|
*/
|
*/
|
|
|
|
|
Line 127... |
Line 185... |
if ((abfd->flags & BFD_IN_MEMORY) != 0)
|
if ((abfd->flags & BFD_IN_MEMORY) != 0)
|
{
|
{
|
struct bfd_in_memory *bim;
|
struct bfd_in_memory *bim;
|
bfd_size_type get;
|
bfd_size_type get;
|
|
|
bim = abfd->iostream;
|
bim = (struct bfd_in_memory *) abfd->iostream;
|
get = size;
|
get = size;
|
if (abfd->where + get > bim->size)
|
if (abfd->where + get > bim->size)
|
{
|
{
|
if (bim->size < (bfd_size_type) abfd->where)
|
if (bim->size < (bfd_size_type) abfd->where)
|
get = 0;
|
get = 0;
|
Line 159... |
Line 217... |
{
|
{
|
size_t nwrote;
|
size_t nwrote;
|
|
|
if ((abfd->flags & BFD_IN_MEMORY) != 0)
|
if ((abfd->flags & BFD_IN_MEMORY) != 0)
|
{
|
{
|
struct bfd_in_memory *bim = abfd->iostream;
|
struct bfd_in_memory *bim = (struct bfd_in_memory *) abfd->iostream;
|
|
|
size = (size_t) size;
|
size = (size_t) size;
|
if (abfd->where + size > bim->size)
|
if (abfd->where + size > bim->size)
|
{
|
{
|
bfd_size_type newsize, oldsize;
|
bfd_size_type newsize, oldsize;
|
Line 172... |
Line 230... |
bim->size = abfd->where + size;
|
bim->size = abfd->where + size;
|
/* Round up to cut down on memory fragmentation */
|
/* Round up to cut down on memory fragmentation */
|
newsize = (bim->size + 127) & ~(bfd_size_type) 127;
|
newsize = (bim->size + 127) & ~(bfd_size_type) 127;
|
if (newsize > oldsize)
|
if (newsize > oldsize)
|
{
|
{
|
bim->buffer = bfd_realloc_or_free (bim->buffer, newsize);
|
bim->buffer = (bfd_byte *) bfd_realloc_or_free (bim->buffer,
|
|
newsize);
|
if (bim->buffer == NULL)
|
if (bim->buffer == NULL)
|
{
|
{
|
bim->size = 0;
|
bim->size = 0;
|
return 0;
|
return 0;
|
}
|
}
|
|
if (newsize > bim->size)
|
|
memset (bim->buffer + bim->size, 0, newsize - bim->size);
|
}
|
}
|
}
|
}
|
memcpy (bim->buffer + abfd->where, ptr, (size_t) size);
|
memcpy (bim->buffer + abfd->where, ptr, (size_t) size);
|
abfd->where += size;
|
abfd->where += size;
|
return size;
|
return size;
|
Line 276... |
Line 337... |
|
|
if ((abfd->flags & BFD_IN_MEMORY) != 0)
|
if ((abfd->flags & BFD_IN_MEMORY) != 0)
|
{
|
{
|
struct bfd_in_memory *bim;
|
struct bfd_in_memory *bim;
|
|
|
bim = abfd->iostream;
|
bim = (struct bfd_in_memory *) abfd->iostream;
|
|
|
if (direction == SEEK_SET)
|
if (direction == SEEK_SET)
|
abfd->where = position;
|
abfd->where = position;
|
else
|
else
|
abfd->where += position;
|
abfd->where += position;
|
|
|
if (abfd->where > bim->size)
|
if (abfd->where > bim->size)
|
{
|
{
|
if ((abfd->direction == write_direction) ||
|
if (abfd->direction == write_direction
|
(abfd->direction == both_direction))
|
|| abfd->direction == both_direction)
|
{
|
{
|
bfd_size_type newsize, oldsize;
|
bfd_size_type newsize, oldsize;
|
|
|
oldsize = (bim->size + 127) & ~(bfd_size_type) 127;
|
oldsize = (bim->size + 127) & ~(bfd_size_type) 127;
|
bim->size = abfd->where;
|
bim->size = abfd->where;
|
/* Round up to cut down on memory fragmentation */
|
/* Round up to cut down on memory fragmentation */
|
newsize = (bim->size + 127) & ~(bfd_size_type) 127;
|
newsize = (bim->size + 127) & ~(bfd_size_type) 127;
|
if (newsize > oldsize)
|
if (newsize > oldsize)
|
{
|
{
|
bim->buffer = bfd_realloc_or_free (bim->buffer, newsize);
|
bim->buffer = (bfd_byte *) bfd_realloc_or_free (bim->buffer,
|
|
newsize);
|
if (bim->buffer == NULL)
|
if (bim->buffer == NULL)
|
{
|
{
|
bim->size = 0;
|
bim->size = 0;
|
return -1;
|
return -1;
|
}
|
}
|
|
memset (bim->buffer + oldsize, 0, newsize - oldsize);
|
}
|
}
|
}
|
}
|
else
|
else
|
{
|
{
|
abfd->where = bim->size;
|
abfd->where = bim->size;
|
Line 452... |
Line 515... |
return 0;
|
return 0;
|
|
|
return buf.st_size;
|
return buf.st_size;
|
}
|
}
|
|
|
No newline at end of file
|
No newline at end of file
|
|
|
|
/*
|
|
FUNCTION
|
|
bfd_mmap
|
|
|
|
SYNOPSIS
|
|
void *bfd_mmap (bfd *abfd, void *addr, bfd_size_type len,
|
|
int prot, int flags, file_ptr offset);
|
|
|
|
DESCRIPTION
|
|
Return mmap()ed region of the file, if possible and implemented.
|
|
|
|
*/
|
|
|
|
void *
|
|
bfd_mmap (bfd *abfd, void *addr, bfd_size_type len,
|
|
int prot, int flags, file_ptr offset)
|
|
{
|
|
void *ret = (void *)-1;
|
|
if ((abfd->flags & BFD_IN_MEMORY) != 0)
|
|
return ret;
|
|
|
|
if (abfd->iovec == NULL)
|
|
return ret;
|
|
|
|
return abfd->iovec->bmmap (abfd, addr, len, prot, flags, offset);
|
|
}
|
|
|
No newline at end of file
|
No newline at end of file
|