mirror of
https://github.com/darlinghq/darling-gdb.git
synced 2024-11-23 20:19:49 +00:00
2002-11-16 Klee Dienes <kdienes@apple.com>
* Makefile.am (BFD32_LIBS): Add bfdwin.lo, bfdio.lo. (BFD32_LIBS_CFILES): Add bfdwin.c, bfdio.c. (BFD_H_FILES): Add bfdwin.c, bfdio.c. (LIBBFD_H_FILES): Add bfdwin.c, bfdio.c. Add dependencies for bfdwin.c, bfdio.c. * bfd.c: Remove bfd_get_mtime, bfd_get_size. * libbfd.c: Remove real_read, bfd_bread, _bfd_window_internal, bfd_init_window, bfd_free_window, bfd_get_file_window, bfd_bwrite, bfd_tell, bfd_flush, bfd_stat, bfd_seek. * bfdio.c: New file. Contains real_read, bfd_bread, bfd_write, bfd_tell, bfd_flush, bfd_stat, bfd_seek, bfd_ge_mtime, bfd_get_size (moved from libbfd.c and bfd.c). * bfdwin.c New file. Contains _bfd_window_internal, bfd_init_window, bfd_free_window, bfd_get_file_window (moved from libbfd.c and bfd.c). * po/SRC-POTFILES.in: Regenerate. * po/bfd.pot: Regenerate. * libbfd.h: Regenerate. * bfd-in2.h: Regenerate. * aclocal.m4: Regenerate. * Makefile.in: Regenerate. * configure: Regenerate. 2002-11-16 Klee Dienes <kdienes@apple.com> * Makefile.am (DOCFILES): Add bfdwin.texi, bfdio.texi. (PROTOS): Add bfdio.p, bfdwin.p. (SRCDOC): Add bfdio.c, bfdwin.c. (SRCPROT): Add bfdio.c, bfdwin.c. (SRCIPROT): Add bfdio.c, bfdwin.c. (LIBBFD_H_DEP): Add bfdio.c, bfdwin.c. (BFD_H_DEP): Add bfdio.c, bfdwin.c. Add rules for bfdio.texi, bfdwin.text. * bfd.texinfo: Include bfdio.texi.
This commit is contained in:
parent
eb1284494b
commit
93509525ce
@ -1,3 +1,28 @@
|
||||
2002-11-18 Klee Dienes <kdienes@apple.com>
|
||||
|
||||
* Makefile.am (BFD32_LIBS): Add bfdwin.lo, bfdio.lo.
|
||||
(BFD32_LIBS_CFILES): Add bfdwin.c, bfdio.c.
|
||||
(BFD_H_FILES): Add bfdwin.c, bfdio.c.
|
||||
(LIBBFD_H_FILES): Add bfdwin.c, bfdio.c.
|
||||
Add dependencies for bfdwin.c, bfdio.c.
|
||||
* bfd.c: Remove bfd_get_mtime, bfd_get_size.
|
||||
* libbfd.c: Remove real_read, bfd_bread, _bfd_window_internal,
|
||||
bfd_init_window, bfd_free_window, bfd_get_file_window, bfd_bwrite,
|
||||
bfd_tell, bfd_flush, bfd_stat, bfd_seek.
|
||||
* bfdio.c: New file. Contains real_read, bfd_bread, bfd_write,
|
||||
bfd_tell, bfd_flush, bfd_stat, bfd_seek, bfd_ge_mtime,
|
||||
bfd_get_size (moved from libbfd.c and bfd.c).
|
||||
* bfdwin.c New file. Contains _bfd_window_internal,
|
||||
bfd_init_window, bfd_free_window, bfd_get_file_window (moved from
|
||||
libbfd.c and bfd.c).
|
||||
* po/SRC-POTFILES.in: Regenerate.
|
||||
* po/bfd.pot: Regenerate.
|
||||
* libbfd.h: Regenerate.
|
||||
* bfd-in2.h: Regenerate.
|
||||
* aclocal.m4: Regenerate.
|
||||
* Makefile.in: Regenerate.
|
||||
* configure: Regenerate.
|
||||
|
||||
2002-11-18 Klee Dienes <kdienes@apple.com>
|
||||
|
||||
* bfd.c (bfd_preserve_save): Don't zero BFD_IN_MEMORY.
|
||||
|
@ -28,7 +28,8 @@ BFD_H = bfd.h
|
||||
# need two copies of the executable, one to download and one for the
|
||||
# debugger).
|
||||
BFD32_LIBS = \
|
||||
archive.lo archures.lo bfd.lo cache.lo coffgen.lo corefile.lo \
|
||||
archive.lo archures.lo bfd.lo bfdio.lo bfdwin.lo \
|
||||
cache.lo coffgen.lo corefile.lo \
|
||||
format.lo init.lo libbfd.lo opncls.lo reloc.lo \
|
||||
section.lo syms.lo targets.lo hash.lo linker.lo \
|
||||
srec.lo binary.lo tekhex.lo ihex.lo stabs.lo stab-syms.lo \
|
||||
@ -37,7 +38,8 @@ BFD32_LIBS = \
|
||||
BFD64_LIBS = archive64.lo
|
||||
|
||||
BFD32_LIBS_CFILES = \
|
||||
archive.c archures.c bfd.c cache.c coffgen.c corefile.c \
|
||||
archive.c archures.c bfd.c bfdio.c bfdwin.c \
|
||||
cache.c coffgen.c corefile.c \
|
||||
format.c init.c libbfd.c opncls.c reloc.c \
|
||||
section.c syms.c targets.c hash.c linker.c \
|
||||
srec.c binary.c tekhex.c ihex.c stabs.c stab-syms.c \
|
||||
@ -794,9 +796,11 @@ stmp-bfd-h: bfd-in3.h
|
||||
touch stmp-bfd-h
|
||||
|
||||
BFD_H_FILES = bfd-in.h init.c opncls.c libbfd.c section.c archures.c \
|
||||
reloc.c syms.c bfd.c archive.c corefile.c targets.c format.c
|
||||
reloc.c syms.c bfd.c bfdio.c bfdwin.c \
|
||||
archive.c corefile.c targets.c format.c
|
||||
BFD64_H_FILES = archive64.c
|
||||
LIBBFD_H_FILES = libbfd-in.h init.c libbfd.c cache.c reloc.c archures.c elf.c
|
||||
LIBBFD_H_FILES = libbfd-in.h init.c libbfd.c bfdio.c bfdwin.c \
|
||||
cache.c reloc.c archures.c elf.c
|
||||
LIBCOFF_H_FILES = libcoff-in.h coffcode.h
|
||||
|
||||
# Could really use a "copy-if-change"...
|
||||
@ -856,6 +860,8 @@ bfd.lo: bfd.c bfdver.h $(INCDIR)/filenames.h $(INCDIR)/libiberty.h \
|
||||
$(INCDIR)/coff/sym.h libcoff.h libecoff.h $(INCDIR)/coff/ecoff.h \
|
||||
elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
|
||||
$(INCDIR)/elf/external.h
|
||||
bfdio.lo: bfdio.c $(INCDIR)/filenames.h
|
||||
bfdwin.lo: bfdwin.c $(INCDIR)/filenames.h
|
||||
cache.lo: cache.c $(INCDIR)/filenames.h
|
||||
coffgen.lo: coffgen.c $(INCDIR)/filenames.h $(INCDIR)/coff/internal.h \
|
||||
libcoff.h $(INCDIR)/bfdlink.h
|
||||
|
@ -151,7 +151,8 @@ BFD_H = bfd.h
|
||||
# need two copies of the executable, one to download and one for the
|
||||
# debugger).
|
||||
BFD32_LIBS = \
|
||||
archive.lo archures.lo bfd.lo cache.lo coffgen.lo corefile.lo \
|
||||
archive.lo archures.lo bfd.lo bfdio.lo bfdwin.lo \
|
||||
cache.lo coffgen.lo corefile.lo \
|
||||
format.lo init.lo libbfd.lo opncls.lo reloc.lo \
|
||||
section.lo syms.lo targets.lo hash.lo linker.lo \
|
||||
srec.lo binary.lo tekhex.lo ihex.lo stabs.lo stab-syms.lo \
|
||||
@ -161,7 +162,8 @@ BFD32_LIBS = \
|
||||
BFD64_LIBS = archive64.lo
|
||||
|
||||
BFD32_LIBS_CFILES = \
|
||||
archive.c archures.c bfd.c cache.c coffgen.c corefile.c \
|
||||
archive.c archures.c bfd.c bfdio.c bfdwin.c \
|
||||
cache.c coffgen.c corefile.c \
|
||||
format.c init.c libbfd.c opncls.c reloc.c \
|
||||
section.c syms.c targets.c hash.c linker.c \
|
||||
srec.c binary.c tekhex.c ihex.c stabs.c stab-syms.c \
|
||||
@ -741,10 +743,13 @@ BFD_H_DEPS = $(INCDIR)/ansidecl.h $(INCDIR)/symcat.h
|
||||
LOCAL_H_DEPS = libbfd.h sysdep.h config.h
|
||||
|
||||
BFD_H_FILES = bfd-in.h init.c opncls.c libbfd.c section.c archures.c \
|
||||
reloc.c syms.c bfd.c archive.c corefile.c targets.c format.c
|
||||
reloc.c syms.c bfd.c bfdio.c bfdwin.c \
|
||||
archive.c corefile.c targets.c format.c
|
||||
|
||||
BFD64_H_FILES = archive64.c
|
||||
LIBBFD_H_FILES = libbfd-in.h init.c libbfd.c cache.c reloc.c archures.c elf.c
|
||||
LIBBFD_H_FILES = libbfd-in.h init.c libbfd.c bfdio.c bfdwin.c \
|
||||
cache.c reloc.c archures.c elf.c
|
||||
|
||||
LIBCOFF_H_FILES = libcoff-in.h coffcode.h
|
||||
|
||||
MOSTLYCLEANFILES = ofiles stamp-ofiles
|
||||
@ -769,10 +774,11 @@ libbfd_a_LIBADD =
|
||||
libbfd_a_OBJECTS =
|
||||
LTLIBRARIES = $(bfdlib_LTLIBRARIES)
|
||||
|
||||
libbfd_la_OBJECTS = archive.lo archures.lo bfd.lo cache.lo coffgen.lo \
|
||||
corefile.lo format.lo init.lo libbfd.lo opncls.lo reloc.lo section.lo \
|
||||
syms.lo targets.lo hash.lo linker.lo srec.lo binary.lo tekhex.lo \
|
||||
ihex.lo stabs.lo stab-syms.lo merge.lo dwarf2.lo simple.lo archive64.lo
|
||||
libbfd_la_OBJECTS = archive.lo archures.lo bfd.lo bfdio.lo bfdwin.lo \
|
||||
cache.lo coffgen.lo corefile.lo format.lo init.lo libbfd.lo opncls.lo \
|
||||
reloc.lo section.lo syms.lo targets.lo hash.lo linker.lo srec.lo \
|
||||
binary.lo tekhex.lo ihex.lo stabs.lo stab-syms.lo merge.lo dwarf2.lo \
|
||||
simple.lo archive64.lo
|
||||
CFLAGS = @CFLAGS@
|
||||
COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
|
||||
LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
|
||||
@ -1387,6 +1393,8 @@ bfd.lo: bfd.c bfdver.h $(INCDIR)/filenames.h $(INCDIR)/libiberty.h \
|
||||
$(INCDIR)/coff/sym.h libcoff.h libecoff.h $(INCDIR)/coff/ecoff.h \
|
||||
elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
|
||||
$(INCDIR)/elf/external.h
|
||||
bfdio.lo: bfdio.c $(INCDIR)/filenames.h
|
||||
bfdwin.lo: bfdwin.c $(INCDIR)/filenames.h
|
||||
cache.lo: cache.c $(INCDIR)/filenames.h
|
||||
coffgen.lo: coffgen.c $(INCDIR)/filenames.h $(INCDIR)/coff/internal.h \
|
||||
libcoff.h $(INCDIR)/bfdlink.h
|
||||
|
18
bfd/aclocal.m4
vendored
18
bfd/aclocal.m4
vendored
@ -173,6 +173,24 @@ else
|
||||
$1_FALSE=
|
||||
fi])
|
||||
|
||||
#serial 1
|
||||
# This test replaces the one in autoconf.
|
||||
# Currently this macro should have the same name as the autoconf macro
|
||||
# because gettext's gettext.m4 (distributed in the automake package)
|
||||
# still uses it. Otherwise, the use in gettext.m4 makes autoheader
|
||||
# give these diagnostics:
|
||||
# configure.in:556: AC_TRY_COMPILE was called before AC_ISC_POSIX
|
||||
# configure.in:556: AC_TRY_RUN was called before AC_ISC_POSIX
|
||||
|
||||
undefine([AC_ISC_POSIX])
|
||||
|
||||
AC_DEFUN([AC_ISC_POSIX],
|
||||
[
|
||||
dnl This test replaces the obsolescent AC_ISC_POSIX kludge.
|
||||
AC_CHECK_LIB(cposix, strerror, [LIBS="$LIBS -lcposix"])
|
||||
]
|
||||
)
|
||||
|
||||
# Do all the work for Automake. This macro actually does too much --
|
||||
# some checks are only needed if your package does certain things.
|
||||
# But this isn't really a big deal.
|
||||
|
@ -1,7 +1,8 @@
|
||||
/* DO NOT EDIT! -*- buffer-read-only: t -*- This file is automatically
|
||||
generated from "bfd-in.h", "init.c", "opncls.c", "libbfd.c",
|
||||
"section.c", "archures.c", "reloc.c", "syms.c", "bfd.c", "archive.c",
|
||||
"corefile.c", "targets.c", "format.c", "linker.c" and "simple.c".
|
||||
"bfdio.c", "bfdwin.c", "section.c", "archures.c", "reloc.c",
|
||||
"syms.c", "bfd.c", "archive.c", "corefile.c", "targets.c", "format.c",
|
||||
"linker.c" and "simple.c".
|
||||
Run "make headers" in your build bfd/ to regenerate. */
|
||||
|
||||
/* Main header file for the bfd library -- portable access to object files.
|
||||
@ -993,6 +994,14 @@ bfd_make_readable PARAMS ((bfd *abfd));
|
||||
#define H_GET_S8 bfd_h_get_signed_8
|
||||
|
||||
|
||||
/* Extracted from bfdio.c. */
|
||||
long
|
||||
bfd_get_mtime PARAMS ((bfd *abfd));
|
||||
|
||||
long
|
||||
bfd_get_size PARAMS ((bfd *abfd));
|
||||
|
||||
/* Extracted from bfdwin.c. */
|
||||
/* Extracted from section.c. */
|
||||
/* This structure is used for a comdat section, as in PE. A comdat
|
||||
section is associated with a particular symbol. When the linker
|
||||
@ -3627,12 +3636,6 @@ bfd_get_sign_extend_vma PARAMS ((bfd *abfd));
|
||||
boolean
|
||||
bfd_set_start_address PARAMS ((bfd *abfd, bfd_vma vma));
|
||||
|
||||
long
|
||||
bfd_get_mtime PARAMS ((bfd *abfd));
|
||||
|
||||
long
|
||||
bfd_get_size PARAMS ((bfd *abfd));
|
||||
|
||||
unsigned int
|
||||
bfd_get_gp_size PARAMS ((bfd *abfd));
|
||||
|
||||
|
81
bfd/bfd.c
81
bfd/bfd.c
@ -828,87 +828,6 @@ bfd_set_start_address (abfd, vma)
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
FUNCTION
|
||||
bfd_get_mtime
|
||||
|
||||
SYNOPSIS
|
||||
long bfd_get_mtime(bfd *abfd);
|
||||
|
||||
DESCRIPTION
|
||||
Return the file modification time (as read from the file system, or
|
||||
from the archive header for archive members).
|
||||
|
||||
*/
|
||||
|
||||
long
|
||||
bfd_get_mtime (abfd)
|
||||
bfd *abfd;
|
||||
{
|
||||
FILE *fp;
|
||||
struct stat buf;
|
||||
|
||||
if (abfd->mtime_set)
|
||||
return abfd->mtime;
|
||||
|
||||
fp = bfd_cache_lookup (abfd);
|
||||
if (0 != fstat (fileno (fp), &buf))
|
||||
return 0;
|
||||
|
||||
abfd->mtime = buf.st_mtime; /* Save value in case anyone wants it */
|
||||
return buf.st_mtime;
|
||||
}
|
||||
|
||||
/*
|
||||
FUNCTION
|
||||
bfd_get_size
|
||||
|
||||
SYNOPSIS
|
||||
long bfd_get_size(bfd *abfd);
|
||||
|
||||
DESCRIPTION
|
||||
Return the file size (as read from file system) for the file
|
||||
associated with BFD @var{abfd}.
|
||||
|
||||
The initial motivation for, and use of, this routine is not
|
||||
so we can get the exact size of the object the BFD applies to, since
|
||||
that might not be generally possible (archive members for example).
|
||||
It would be ideal if someone could eventually modify
|
||||
it so that such results were guaranteed.
|
||||
|
||||
Instead, we want to ask questions like "is this NNN byte sized
|
||||
object I'm about to try read from file offset YYY reasonable?"
|
||||
As as example of where we might do this, some object formats
|
||||
use string tables for which the first <<sizeof (long)>> bytes of the
|
||||
table contain the size of the table itself, including the size bytes.
|
||||
If an application tries to read what it thinks is one of these
|
||||
string tables, without some way to validate the size, and for
|
||||
some reason the size is wrong (byte swapping error, wrong location
|
||||
for the string table, etc.), the only clue is likely to be a read
|
||||
error when it tries to read the table, or a "virtual memory
|
||||
exhausted" error when it tries to allocate 15 bazillon bytes
|
||||
of space for the 15 bazillon byte table it is about to read.
|
||||
This function at least allows us to answer the quesion, "is the
|
||||
size reasonable?".
|
||||
*/
|
||||
|
||||
long
|
||||
bfd_get_size (abfd)
|
||||
bfd *abfd;
|
||||
{
|
||||
FILE *fp;
|
||||
struct stat buf;
|
||||
|
||||
if ((abfd->flags & BFD_IN_MEMORY) != 0)
|
||||
return ((struct bfd_in_memory *) abfd->iostream)->size;
|
||||
|
||||
fp = bfd_cache_lookup (abfd);
|
||||
if (0 != fstat (fileno (fp), & buf))
|
||||
return 0;
|
||||
|
||||
return buf.st_size;
|
||||
}
|
||||
|
||||
/*
|
||||
FUNCTION
|
||||
bfd_get_gp_size
|
||||
|
436
bfd/bfdio.c
Normal file
436
bfd/bfdio.c
Normal file
@ -0,0 +1,436 @@
|
||||
/* Low-level I/O routines for BFDs.
|
||||
Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
|
||||
2000, 2001, 2002 Free Software Foundation, Inc.
|
||||
Written by Cygnus Support.
|
||||
|
||||
This file is part of BFD, the Binary File Descriptor library.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||
|
||||
#include "sysdep.h"
|
||||
|
||||
#include "bfd.h"
|
||||
#include "libbfd.h"
|
||||
|
||||
#include <limits.h>
|
||||
|
||||
#ifndef S_IXUSR
|
||||
#define S_IXUSR 0100 /* Execute by owner. */
|
||||
#endif
|
||||
#ifndef S_IXGRP
|
||||
#define S_IXGRP 0010 /* Execute by group. */
|
||||
#endif
|
||||
#ifndef S_IXOTH
|
||||
#define S_IXOTH 0001 /* Execute by others. */
|
||||
#endif
|
||||
|
||||
/* Note that archive entries don't have streams; they share their parent's.
|
||||
This allows someone to play with the iostream behind BFD's back.
|
||||
|
||||
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
|
||||
first octet in the file, NOT the beginning of the archive header. */
|
||||
|
||||
static size_t real_read PARAMS ((PTR where, size_t a, size_t b, FILE *file));
|
||||
static size_t
|
||||
real_read (where, a, b, file)
|
||||
PTR where;
|
||||
size_t a;
|
||||
size_t b;
|
||||
FILE *file;
|
||||
{
|
||||
/* 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 (a == 0 || b == 0)
|
||||
return 0;
|
||||
|
||||
|
||||
#if defined (__VAX) && defined (VMS)
|
||||
/* Apparently fread on Vax VMS does not keep the record length
|
||||
information. */
|
||||
return read (fileno (file), where, a * b);
|
||||
#else
|
||||
return fread (where, a, b, file);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Return value is amount read. */
|
||||
|
||||
bfd_size_type
|
||||
bfd_bread (ptr, size, abfd)
|
||||
PTR ptr;
|
||||
bfd_size_type size;
|
||||
bfd *abfd;
|
||||
{
|
||||
size_t nread;
|
||||
|
||||
if ((abfd->flags & BFD_IN_MEMORY) != 0)
|
||||
{
|
||||
struct bfd_in_memory *bim;
|
||||
bfd_size_type get;
|
||||
|
||||
bim = (struct bfd_in_memory *) abfd->iostream;
|
||||
get = size;
|
||||
if (abfd->where + get > bim->size)
|
||||
{
|
||||
if (bim->size < (bfd_size_type) abfd->where)
|
||||
get = 0;
|
||||
else
|
||||
get = bim->size - abfd->where;
|
||||
bfd_set_error (bfd_error_file_truncated);
|
||||
}
|
||||
memcpy (ptr, bim->buffer + abfd->where, (size_t) get);
|
||||
abfd->where += get;
|
||||
return get;
|
||||
}
|
||||
|
||||
nread = real_read (ptr, 1, (size_t) size, bfd_cache_lookup (abfd));
|
||||
if (nread != (size_t) -1)
|
||||
abfd->where += nread;
|
||||
|
||||
/* 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.
|
||||
|
||||
A BFD backend may wish to override bfd_error_file_truncated to
|
||||
provide something more useful (eg. no_symbols or wrong_format). */
|
||||
if (nread != size)
|
||||
{
|
||||
if (ferror (bfd_cache_lookup (abfd)))
|
||||
bfd_set_error (bfd_error_system_call);
|
||||
else
|
||||
bfd_set_error (bfd_error_file_truncated);
|
||||
}
|
||||
|
||||
return nread;
|
||||
}
|
||||
|
||||
bfd_size_type
|
||||
bfd_bwrite (ptr, size, abfd)
|
||||
const PTR ptr;
|
||||
bfd_size_type size;
|
||||
bfd *abfd;
|
||||
{
|
||||
size_t nwrote;
|
||||
|
||||
if ((abfd->flags & BFD_IN_MEMORY) != 0)
|
||||
{
|
||||
struct bfd_in_memory *bim = (struct bfd_in_memory *) (abfd->iostream);
|
||||
size = (size_t) size;
|
||||
if (abfd->where + size > bim->size)
|
||||
{
|
||||
bfd_size_type newsize, oldsize;
|
||||
|
||||
oldsize = (bim->size + 127) & ~(bfd_size_type) 127;
|
||||
bim->size = abfd->where + size;
|
||||
/* Round up to cut down on memory fragmentation */
|
||||
newsize = (bim->size + 127) & ~(bfd_size_type) 127;
|
||||
if (newsize > oldsize)
|
||||
{
|
||||
bim->buffer = (bfd_byte *) bfd_realloc (bim->buffer, newsize);
|
||||
if (bim->buffer == 0)
|
||||
{
|
||||
bim->size = 0;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
memcpy (bim->buffer + abfd->where, ptr, (size_t) size);
|
||||
abfd->where += size;
|
||||
return size;
|
||||
}
|
||||
|
||||
nwrote = fwrite (ptr, 1, (size_t) size, bfd_cache_lookup (abfd));
|
||||
if (nwrote != (size_t) -1)
|
||||
abfd->where += nwrote;
|
||||
if (nwrote != size)
|
||||
{
|
||||
#ifdef ENOSPC
|
||||
errno = ENOSPC;
|
||||
#endif
|
||||
bfd_set_error (bfd_error_system_call);
|
||||
}
|
||||
return nwrote;
|
||||
}
|
||||
|
||||
bfd_vma
|
||||
bfd_tell (abfd)
|
||||
bfd *abfd;
|
||||
{
|
||||
file_ptr ptr;
|
||||
|
||||
if ((abfd->flags & BFD_IN_MEMORY) != 0)
|
||||
return abfd->where;
|
||||
|
||||
ptr = ftell (bfd_cache_lookup (abfd));
|
||||
|
||||
if (abfd->my_archive)
|
||||
ptr -= abfd->origin;
|
||||
abfd->where = ptr;
|
||||
return ptr;
|
||||
}
|
||||
|
||||
int
|
||||
bfd_flush (abfd)
|
||||
bfd *abfd;
|
||||
{
|
||||
if ((abfd->flags & BFD_IN_MEMORY) != 0)
|
||||
return 0;
|
||||
return fflush (bfd_cache_lookup(abfd));
|
||||
}
|
||||
|
||||
/* Returns 0 for success, negative value for failure (in which case
|
||||
bfd_get_error can retrieve the error code). */
|
||||
int
|
||||
bfd_stat (abfd, statbuf)
|
||||
bfd *abfd;
|
||||
struct stat *statbuf;
|
||||
{
|
||||
FILE *f;
|
||||
int result;
|
||||
|
||||
if ((abfd->flags & BFD_IN_MEMORY) != 0)
|
||||
abort ();
|
||||
|
||||
f = bfd_cache_lookup (abfd);
|
||||
if (f == NULL)
|
||||
{
|
||||
bfd_set_error (bfd_error_system_call);
|
||||
return -1;
|
||||
}
|
||||
result = fstat (fileno (f), statbuf);
|
||||
if (result < 0)
|
||||
bfd_set_error (bfd_error_system_call);
|
||||
return result;
|
||||
}
|
||||
|
||||
/* Returns 0 for success, nonzero for failure (in which case bfd_get_error
|
||||
can retrieve the error code). */
|
||||
|
||||
int
|
||||
bfd_seek (abfd, position, direction)
|
||||
bfd *abfd;
|
||||
file_ptr position;
|
||||
int direction;
|
||||
{
|
||||
int result;
|
||||
FILE *f;
|
||||
long file_position;
|
||||
/* For the time being, a BFD may not seek to it's end. The problem
|
||||
is that we don't easily have a way to recognize the end of an
|
||||
element in an archive. */
|
||||
|
||||
BFD_ASSERT (direction == SEEK_SET || direction == SEEK_CUR);
|
||||
|
||||
if (direction == SEEK_CUR && position == 0)
|
||||
return 0;
|
||||
|
||||
if ((abfd->flags & BFD_IN_MEMORY) != 0)
|
||||
{
|
||||
struct bfd_in_memory *bim;
|
||||
|
||||
bim = (struct bfd_in_memory *) abfd->iostream;
|
||||
|
||||
if (direction == SEEK_SET)
|
||||
abfd->where = position;
|
||||
else
|
||||
abfd->where += position;
|
||||
|
||||
if (abfd->where > bim->size)
|
||||
{
|
||||
if ((abfd->direction == write_direction) ||
|
||||
(abfd->direction == both_direction))
|
||||
{
|
||||
bfd_size_type newsize, oldsize;
|
||||
oldsize = (bim->size + 127) & ~(bfd_size_type) 127;
|
||||
bim->size = abfd->where;
|
||||
/* Round up to cut down on memory fragmentation */
|
||||
newsize = (bim->size + 127) & ~(bfd_size_type) 127;
|
||||
if (newsize > oldsize)
|
||||
{
|
||||
bim->buffer = (bfd_byte *) bfd_realloc (bim->buffer, newsize);
|
||||
if (bim->buffer == 0)
|
||||
{
|
||||
bim->size = 0;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
abfd->where = bim->size;
|
||||
bfd_set_error (bfd_error_file_truncated);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (abfd->format != bfd_archive && abfd->my_archive == 0)
|
||||
{
|
||||
#if 0
|
||||
/* Explanation for this code: I'm only about 95+% sure that the above
|
||||
conditions are sufficient and that all i/o calls are properly
|
||||
adjusting the `where' field. So this is sort of an `assert'
|
||||
that the `where' field is correct. If we can go a while without
|
||||
tripping the abort, we can probably safely disable this code,
|
||||
so that the real optimizations happen. */
|
||||
file_ptr where_am_i_now;
|
||||
where_am_i_now = ftell (bfd_cache_lookup (abfd));
|
||||
if (abfd->my_archive)
|
||||
where_am_i_now -= abfd->origin;
|
||||
if (where_am_i_now != abfd->where)
|
||||
abort ();
|
||||
#endif
|
||||
if (direction == SEEK_SET && (bfd_vma) position == abfd->where)
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* We need something smarter to optimize access to archives.
|
||||
Currently, anything inside an archive is read via the file
|
||||
handle for the archive. Which means that a bfd_seek on one
|
||||
component affects the `current position' in the archive, as
|
||||
well as in any other component.
|
||||
|
||||
It might be sufficient to put a spike through the cache
|
||||
abstraction, and look to the archive for the file position,
|
||||
but I think we should try for something cleaner.
|
||||
|
||||
In the meantime, no optimization for archives. */
|
||||
}
|
||||
|
||||
f = bfd_cache_lookup (abfd);
|
||||
file_position = position;
|
||||
if (direction == SEEK_SET && abfd->my_archive != NULL)
|
||||
file_position += abfd->origin;
|
||||
|
||||
result = fseek (f, file_position, direction);
|
||||
if (result != 0)
|
||||
{
|
||||
int hold_errno = errno;
|
||||
|
||||
/* Force redetermination of `where' field. */
|
||||
bfd_tell (abfd);
|
||||
|
||||
/* An EINVAL error probably means that the file offset was
|
||||
absurd. */
|
||||
if (hold_errno == EINVAL)
|
||||
bfd_set_error (bfd_error_file_truncated);
|
||||
else
|
||||
{
|
||||
bfd_set_error (bfd_error_system_call);
|
||||
errno = hold_errno;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Adjust `where' field. */
|
||||
if (direction == SEEK_SET)
|
||||
abfd->where = position;
|
||||
else
|
||||
abfd->where += position;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
FUNCTION
|
||||
bfd_get_mtime
|
||||
|
||||
SYNOPSIS
|
||||
long bfd_get_mtime(bfd *abfd);
|
||||
|
||||
DESCRIPTION
|
||||
Return the file modification time (as read from the file system, or
|
||||
from the archive header for archive members).
|
||||
|
||||
*/
|
||||
|
||||
long
|
||||
bfd_get_mtime (abfd)
|
||||
bfd *abfd;
|
||||
{
|
||||
FILE *fp;
|
||||
struct stat buf;
|
||||
|
||||
if (abfd->mtime_set)
|
||||
return abfd->mtime;
|
||||
|
||||
fp = bfd_cache_lookup (abfd);
|
||||
if (0 != fstat (fileno (fp), &buf))
|
||||
return 0;
|
||||
|
||||
abfd->mtime = buf.st_mtime; /* Save value in case anyone wants it */
|
||||
return buf.st_mtime;
|
||||
}
|
||||
|
||||
/*
|
||||
FUNCTION
|
||||
bfd_get_size
|
||||
|
||||
SYNOPSIS
|
||||
long bfd_get_size(bfd *abfd);
|
||||
|
||||
DESCRIPTION
|
||||
Return the file size (as read from file system) for the file
|
||||
associated with BFD @var{abfd}.
|
||||
|
||||
The initial motivation for, and use of, this routine is not
|
||||
so we can get the exact size of the object the BFD applies to, since
|
||||
that might not be generally possible (archive members for example).
|
||||
It would be ideal if someone could eventually modify
|
||||
it so that such results were guaranteed.
|
||||
|
||||
Instead, we want to ask questions like "is this NNN byte sized
|
||||
object I'm about to try read from file offset YYY reasonable?"
|
||||
As as example of where we might do this, some object formats
|
||||
use string tables for which the first <<sizeof (long)>> bytes of the
|
||||
table contain the size of the table itself, including the size bytes.
|
||||
If an application tries to read what it thinks is one of these
|
||||
string tables, without some way to validate the size, and for
|
||||
some reason the size is wrong (byte swapping error, wrong location
|
||||
for the string table, etc.), the only clue is likely to be a read
|
||||
error when it tries to read the table, or a "virtual memory
|
||||
exhausted" error when it tries to allocate 15 bazillon bytes
|
||||
of space for the 15 bazillon byte table it is about to read.
|
||||
This function at least allows us to answer the quesion, "is the
|
||||
size reasonable?".
|
||||
*/
|
||||
|
||||
long
|
||||
bfd_get_size (abfd)
|
||||
bfd *abfd;
|
||||
{
|
||||
FILE *fp;
|
||||
struct stat buf;
|
||||
|
||||
if ((abfd->flags & BFD_IN_MEMORY) != 0)
|
||||
return ((struct bfd_in_memory *) abfd->iostream)->size;
|
||||
|
||||
fp = bfd_cache_lookup (abfd);
|
||||
if (0 != fstat (fileno (fp), & buf))
|
||||
return 0;
|
||||
|
||||
return buf.st_size;
|
||||
}
|
255
bfd/bfdwin.c
Normal file
255
bfd/bfdwin.c
Normal file
@ -0,0 +1,255 @@
|
||||
/* Support for memory-mapped windows into a BFD.
|
||||
Copyright 1995, 1996, 2001, 2002 Free Software Foundation, Inc.
|
||||
Written by Cygnus Support.
|
||||
|
||||
This file is part of BFD, the Binary File Descriptor library.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||
|
||||
#include "sysdep.h"
|
||||
|
||||
#include "bfd.h"
|
||||
#include "libbfd.h"
|
||||
|
||||
/* Currently, if USE_MMAP is undefined, none if the window stuff is
|
||||
used. Okay, so it's mis-named. At least the command-line option
|
||||
"--without-mmap" is more obvious than "--without-windows" or some
|
||||
such. */
|
||||
|
||||
#ifdef USE_MMAP
|
||||
|
||||
#undef HAVE_MPROTECT /* code's not tested yet */
|
||||
|
||||
#if HAVE_MMAP || HAVE_MPROTECT || HAVE_MADVISE
|
||||
#include <sys/mman.h>
|
||||
#endif
|
||||
|
||||
#ifndef MAP_FILE
|
||||
#define MAP_FILE 0
|
||||
#endif
|
||||
|
||||
static int debug_windows;
|
||||
|
||||
/* The idea behind the next and refcount fields is that one mapped
|
||||
region can suffice for multiple read-only windows or multiple
|
||||
non-overlapping read-write windows. It's not implemented yet
|
||||
though. */
|
||||
|
||||
/*
|
||||
INTERNAL_DEFINITION
|
||||
|
||||
.struct _bfd_window_internal {
|
||||
. struct _bfd_window_internal *next;
|
||||
. PTR data;
|
||||
. bfd_size_type size;
|
||||
. int refcount : 31; {* should be enough... *}
|
||||
. unsigned mapped : 1; {* 1 = mmap, 0 = malloc *}
|
||||
.};
|
||||
*/
|
||||
|
||||
void
|
||||
bfd_init_window (windowp)
|
||||
bfd_window *windowp;
|
||||
{
|
||||
windowp->data = 0;
|
||||
windowp->i = 0;
|
||||
windowp->size = 0;
|
||||
}
|
||||
|
||||
void
|
||||
bfd_free_window (windowp)
|
||||
bfd_window *windowp;
|
||||
{
|
||||
bfd_window_internal *i = windowp->i;
|
||||
windowp->i = 0;
|
||||
windowp->data = 0;
|
||||
if (i == 0)
|
||||
return;
|
||||
i->refcount--;
|
||||
if (debug_windows)
|
||||
fprintf (stderr, "freeing window @%p<%p,%lx,%p>\n",
|
||||
windowp, windowp->data, windowp->size, windowp->i);
|
||||
if (i->refcount != 0)
|
||||
return;
|
||||
|
||||
if (i->mapped)
|
||||
{
|
||||
#ifdef HAVE_MMAP
|
||||
munmap (i->data, i->size);
|
||||
goto no_free;
|
||||
#else
|
||||
abort ();
|
||||
#endif
|
||||
}
|
||||
#ifdef HAVE_MPROTECT
|
||||
mprotect (i->data, i->size, PROT_READ | PROT_WRITE);
|
||||
#endif
|
||||
free (i->data);
|
||||
#ifdef HAVE_MMAP
|
||||
no_free:
|
||||
#endif
|
||||
i->data = 0;
|
||||
/* There should be no more references to i at this point. */
|
||||
free (i);
|
||||
}
|
||||
|
||||
static int ok_to_map = 1;
|
||||
|
||||
boolean
|
||||
bfd_get_file_window (abfd, offset, size, windowp, writable)
|
||||
bfd *abfd;
|
||||
file_ptr offset;
|
||||
bfd_size_type size;
|
||||
bfd_window *windowp;
|
||||
boolean writable;
|
||||
{
|
||||
static size_t pagesize;
|
||||
bfd_window_internal *i = windowp->i;
|
||||
bfd_size_type size_to_alloc = size;
|
||||
|
||||
if (debug_windows)
|
||||
fprintf (stderr, "bfd_get_file_window (%p, %6ld, %6ld, %p<%p,%lx,%p>, %d)",
|
||||
abfd, (long) offset, (long) size,
|
||||
windowp, windowp->data, (unsigned long) windowp->size,
|
||||
windowp->i, writable);
|
||||
|
||||
/* Make sure we know the page size, so we can be friendly to mmap. */
|
||||
if (pagesize == 0)
|
||||
pagesize = getpagesize ();
|
||||
if (pagesize == 0)
|
||||
abort ();
|
||||
|
||||
if (i == 0)
|
||||
{
|
||||
i = ((bfd_window_internal *)
|
||||
bfd_zmalloc ((bfd_size_type) sizeof (bfd_window_internal)));
|
||||
windowp->i = i;
|
||||
if (i == 0)
|
||||
return false;
|
||||
i->data = 0;
|
||||
}
|
||||
#ifdef HAVE_MMAP
|
||||
if (ok_to_map
|
||||
&& (i->data == 0 || i->mapped == 1)
|
||||
&& (abfd->flags & BFD_IN_MEMORY) == 0)
|
||||
{
|
||||
file_ptr file_offset, offset2;
|
||||
size_t real_size;
|
||||
int fd;
|
||||
FILE *f;
|
||||
|
||||
/* Find the real file and the real offset into it. */
|
||||
while (abfd->my_archive != NULL)
|
||||
{
|
||||
offset += abfd->origin;
|
||||
abfd = abfd->my_archive;
|
||||
}
|
||||
f = bfd_cache_lookup (abfd);
|
||||
fd = fileno (f);
|
||||
|
||||
/* Compute offsets and size for mmap and for the user's data. */
|
||||
offset2 = offset % pagesize;
|
||||
if (offset2 < 0)
|
||||
abort ();
|
||||
file_offset = offset - offset2;
|
||||
real_size = offset + size - file_offset;
|
||||
real_size = real_size + pagesize - 1;
|
||||
real_size -= real_size % pagesize;
|
||||
|
||||
/* If we're re-using a memory region, make sure it's big enough. */
|
||||
if (i->data && i->size < size)
|
||||
{
|
||||
munmap (i->data, i->size);
|
||||
i->data = 0;
|
||||
}
|
||||
i->data = mmap (i->data, real_size,
|
||||
writable ? PROT_WRITE | PROT_READ : PROT_READ,
|
||||
(writable
|
||||
? MAP_FILE | MAP_PRIVATE
|
||||
: MAP_FILE | MAP_SHARED),
|
||||
fd, file_offset);
|
||||
if (i->data == (PTR) -1)
|
||||
{
|
||||
/* An error happened. Report it, or try using malloc, or
|
||||
something. */
|
||||
bfd_set_error (bfd_error_system_call);
|
||||
i->data = 0;
|
||||
windowp->data = 0;
|
||||
if (debug_windows)
|
||||
fprintf (stderr, "\t\tmmap failed!\n");
|
||||
return false;
|
||||
}
|
||||
if (debug_windows)
|
||||
fprintf (stderr, "\n\tmapped %ld at %p, offset is %ld\n",
|
||||
(long) real_size, i->data, (long) offset2);
|
||||
i->size = real_size;
|
||||
windowp->data = (PTR) ((bfd_byte *) i->data + offset2);
|
||||
windowp->size = size;
|
||||
i->mapped = 1;
|
||||
return true;
|
||||
}
|
||||
else if (debug_windows)
|
||||
{
|
||||
if (ok_to_map)
|
||||
fprintf (stderr, _("not mapping: data=%lx mapped=%d\n"),
|
||||
(unsigned long) i->data, (int) i->mapped);
|
||||
else
|
||||
fprintf (stderr, _("not mapping: env var not set\n"));
|
||||
}
|
||||
#else
|
||||
ok_to_map = 0;
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_MPROTECT
|
||||
if (!writable)
|
||||
{
|
||||
size_to_alloc += pagesize - 1;
|
||||
size_to_alloc -= size_to_alloc % pagesize;
|
||||
}
|
||||
#endif
|
||||
if (debug_windows)
|
||||
fprintf (stderr, "\n\t%s(%6ld)",
|
||||
i->data ? "realloc" : " malloc", (long) size_to_alloc);
|
||||
i->data = (PTR) bfd_realloc (i->data, size_to_alloc);
|
||||
if (debug_windows)
|
||||
fprintf (stderr, "\t-> %p\n", i->data);
|
||||
i->refcount = 1;
|
||||
if (i->data == NULL)
|
||||
{
|
||||
if (size_to_alloc == 0)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
if (bfd_seek (abfd, offset, SEEK_SET) != 0)
|
||||
return false;
|
||||
i->size = bfd_bread (i->data, size, abfd);
|
||||
if (i->size != size)
|
||||
return false;
|
||||
i->mapped = 0;
|
||||
#ifdef HAVE_MPROTECT
|
||||
if (!writable)
|
||||
{
|
||||
if (debug_windows)
|
||||
fprintf (stderr, "\tmprotect (%p, %ld, PROT_READ)\n", i->data,
|
||||
(long) i->size);
|
||||
mprotect (i->data, i->size, PROT_READ);
|
||||
}
|
||||
#endif
|
||||
windowp->data = i->data;
|
||||
windowp->size = i->size;
|
||||
return true;
|
||||
}
|
||||
|
||||
#endif /* USE_MMAP */
|
@ -25,9 +25,6 @@
|
||||
/* Define to `long' if <sys/types.h> doesn't define. */
|
||||
#undef off_t
|
||||
|
||||
/* Define if you need to in order for stat and other things to work. */
|
||||
#undef _POSIX_SOURCE
|
||||
|
||||
/* Define to `unsigned' if <sys/types.h> doesn't define. */
|
||||
#undef size_t
|
||||
|
||||
|
970
bfd/configure
vendored
970
bfd/configure
vendored
File diff suppressed because it is too large
Load Diff
@ -711,6 +711,9 @@ do
|
||||
m68ksysvcoff_vec) tb="$tb coff-svm68k.lo cofflink.lo" ;;
|
||||
m88kbcs_vec) tb="$tb coff-m88k.lo" ;;
|
||||
m88kmach3_vec) tb="$tb m88kmach3.lo aout32.lo" ;;
|
||||
mach_o_be_vec) tb="$tb mach-o.lo" ;;
|
||||
mach_o_le_vec) tb="$tb mach-o.lo" ;;
|
||||
mach_o_fat_vec) tb="$tb mach-o.lo" ;;
|
||||
mcore_pe_big_vec) tb="$tb pe-mcore.lo peigen.lo cofflink.lo" ;;
|
||||
mcore_pe_little_vec) tb="$tb pe-mcore.lo peigen.lo cofflink.lo" ;;
|
||||
mcore_pei_big_vec) tb="$tb pei-mcore.lo peigen.lo cofflink.lo" ;;
|
||||
@ -725,6 +728,8 @@ do
|
||||
or32coff_big_vec) tb="$tb coff-or32.lo cofflink.lo" ;;
|
||||
pc532machaout_vec) tb="$tb pc532-mach.lo aout-ns32k.lo" ;;
|
||||
pc532netbsd_vec) tb="$tb ns32knetbsd.lo aout-ns32k.lo" ;;
|
||||
pef_vec) tb="$tb pef.lo" ;;
|
||||
pef_xlib_vec) tb="$tb pef.lo" ;;
|
||||
pdp11_aout_vec) tb="$tb pdp11.lo" ;;
|
||||
pmac_xcoff_vec) tb="$tb coff-rs6000.lo xcofflink.lo" ;;
|
||||
ppcboot_vec) tb="$tb ppcboot.lo" ;;
|
||||
@ -745,6 +750,7 @@ do
|
||||
sparclynx_coff_vec) tb="$tb cf-sparclynx.lo lynx-core.lo" ;;
|
||||
sparcnetbsd_vec) tb="$tb sparcnetbsd.lo aout32.lo" ;;
|
||||
sunos_big_vec) tb="$tb sunos.lo aout32.lo" ;;
|
||||
sym_vec) tb="$tb xsym.lo" ;;
|
||||
tic30_aout_vec) tb="$tb aout-tic30.lo" ;;
|
||||
tic30_coff_vec) tb="$tb coff-tic30.lo" ;;
|
||||
tic4x_coff0_vec) tb="$tb coff-tic4x.lo" ;;
|
||||
|
@ -1,3 +1,15 @@
|
||||
2002-11-18 Klee Dienes <kdienes@apple.com>
|
||||
|
||||
* Makefile.am (DOCFILES): Add bfdwin.texi, bfdio.texi.
|
||||
(PROTOS): Add bfdio.p, bfdwin.p.
|
||||
(SRCDOC): Add bfdio.c, bfdwin.c.
|
||||
(SRCPROT): Add bfdio.c, bfdwin.c.
|
||||
(SRCIPROT): Add bfdio.c, bfdwin.c.
|
||||
(LIBBFD_H_DEP): Add bfdio.c, bfdwin.c.
|
||||
(BFD_H_DEP): Add bfdio.c, bfdwin.c.
|
||||
Add rules for bfdio.texi, bfdwin.text.
|
||||
* bfd.texinfo: Include bfdio.texi.
|
||||
|
||||
2002-10-14 Alan Modra <amodra@bigpond.net.au>
|
||||
|
||||
* Makefile.in: Regenerate.
|
||||
|
@ -4,13 +4,15 @@ AUTOMAKE_OPTIONS = cygnus
|
||||
|
||||
DOCFILES = aoutx.texi archive.texi archures.texi \
|
||||
bfdt.texi cache.texi coffcode.texi \
|
||||
core.texi elf.texi elfcode.texi format.texi libbfd.texi \
|
||||
core.texi elf.texi elfcode.texi format.texi \
|
||||
libbfd.texi bfdwin.texi bfdio.texi \
|
||||
opncls.texi reloc.texi section.texi \
|
||||
syms.texi targets.texi init.texi hash.texi linker.texi \
|
||||
mmo.texi
|
||||
|
||||
PROTOS = archive.p archures.p bfd.p \
|
||||
core.p format.p \
|
||||
bfdio.p bfdwin.p \
|
||||
libbfd.p opncls.p reloc.p \
|
||||
section.p syms.p targets.p \
|
||||
format.p core.p init.p
|
||||
@ -22,6 +24,7 @@ IPROTOS = cache.ip libbfd.ip reloc.ip init.ip archures.ip coffcode.ip
|
||||
# you don't need these three:
|
||||
SRCDOC = $(srcdir)/../aoutx.h $(srcdir)/../archive.c \
|
||||
$(srcdir)/../archures.c $(srcdir)/../bfd.c \
|
||||
$(srcdir)/../bfdio.c $(srcdir)/../bfdwin.c \
|
||||
$(srcdir)/../cache.c $(srcdir)/../coffcode.h \
|
||||
$(srcdir)/../corefile.c $(srcdir)/../elf.c \
|
||||
$(srcdir)/../elfcode.h $(srcdir)/../format.c \
|
||||
@ -34,11 +37,13 @@ SRCDOC = $(srcdir)/../aoutx.h $(srcdir)/../archive.c \
|
||||
SRCPROT = $(srcdir)/../archive.c $(srcdir)/../archures.c \
|
||||
$(srcdir)/../bfd.c $(srcdir)/../coffcode.h $(srcdir)/../corefile.c \
|
||||
$(srcdir)/../format.c $(srcdir)/../libbfd.c \
|
||||
$(srcdir)/../bfdio.c $(srcdir)/../bfdwin.c \
|
||||
$(srcdir)/../opncls.c $(srcdir)/../reloc.c \
|
||||
$(srcdir)/../section.c $(srcdir)/../syms.c \
|
||||
$(srcdir)/../targets.c $(srcdir)/../init.c
|
||||
|
||||
SRCIPROT = $(srcdir)/../cache.c $(srcdir)/../libbfd.c \
|
||||
$(srcdir)/../bfdio.c $(srcdir)/../bfdwin.c \
|
||||
$(srcdir)/../reloc.c $(srcdir)/../cpu-h8300.c \
|
||||
$(srcdir)/../cpu-i960.c $(srcdir)/../archures.c \
|
||||
$(srcdir)/../init.c
|
||||
@ -143,6 +148,18 @@ s-libbfd: $(MKDOC) $(srcdir)/../libbfd.c $(srcdir)/doc.str
|
||||
touch s-libbfd
|
||||
libbfd.texi: s-libbfd
|
||||
|
||||
s-bfdio: $(MKDOC) $(srcdir)/../bfdio.c $(srcdir)/doc.str
|
||||
./$(MKDOC) -f $(srcdir)/doc.str < $(srcdir)/../bfdio.c >bfdio.tmp
|
||||
$(srcdir)/../../move-if-change bfdio.tmp bfdio.texi
|
||||
touch s-bfdio
|
||||
bfdio.texi: s-bfdio
|
||||
|
||||
s-bfdwin: $(MKDOC) $(srcdir)/../bfdwin.c $(srcdir)/doc.str
|
||||
./$(MKDOC) -f $(srcdir)/doc.str < $(srcdir)/../bfdwin.c >bfdwin.tmp
|
||||
$(srcdir)/../../move-if-change bfdwin.tmp bfdwin.texi
|
||||
touch s-bfdwin
|
||||
bfdwin.texi: s-bfdwin
|
||||
|
||||
s-opncls: $(MKDOC) $(srcdir)/../opncls.c $(srcdir)/doc.str
|
||||
./$(MKDOC) -f $(srcdir)/doc.str <$(srcdir)/../opncls.c >opncls.tmp
|
||||
$(srcdir)/../../move-if-change opncls.tmp opncls.texi
|
||||
@ -195,6 +212,8 @@ LIBBFD_H_DEP = \
|
||||
$(srcdir)/../libbfd-in.h \
|
||||
$(srcdir)/../init.c \
|
||||
$(srcdir)/../libbfd.c \
|
||||
$(srcdir)/../bfdio.c \
|
||||
$(srcdir)/../bfdwin.c \
|
||||
$(srcdir)/../cache.c \
|
||||
$(srcdir)/../reloc.c \
|
||||
$(srcdir)/../archures.c \
|
||||
@ -239,6 +258,8 @@ BFD_H_DEP = \
|
||||
$(srcdir)/../init.c \
|
||||
$(srcdir)/../opncls.c \
|
||||
$(srcdir)/../libbfd.c \
|
||||
$(srcdir)/../bfdio.c \
|
||||
$(srcdir)/../bfdwin.c \
|
||||
$(srcdir)/../section.c \
|
||||
$(srcdir)/../archures.c \
|
||||
$(srcdir)/../reloc.c \
|
||||
|
@ -130,7 +130,8 @@ AUTOMAKE_OPTIONS = cygnus
|
||||
|
||||
DOCFILES = aoutx.texi archive.texi archures.texi \
|
||||
bfdt.texi cache.texi coffcode.texi \
|
||||
core.texi elf.texi elfcode.texi format.texi libbfd.texi \
|
||||
core.texi elf.texi elfcode.texi format.texi \
|
||||
libbfd.texi bfdwin.texi bfdio.texi \
|
||||
opncls.texi reloc.texi section.texi \
|
||||
syms.texi targets.texi init.texi hash.texi linker.texi \
|
||||
mmo.texi
|
||||
@ -138,6 +139,7 @@ DOCFILES = aoutx.texi archive.texi archures.texi \
|
||||
|
||||
PROTOS = archive.p archures.p bfd.p \
|
||||
core.p format.p \
|
||||
bfdio.p bfdwin.p \
|
||||
libbfd.p opncls.p reloc.p \
|
||||
section.p syms.p targets.p \
|
||||
format.p core.p init.p
|
||||
@ -150,6 +152,7 @@ IPROTOS = cache.ip libbfd.ip reloc.ip init.ip archures.ip coffcode.ip
|
||||
# you don't need these three:
|
||||
SRCDOC = $(srcdir)/../aoutx.h $(srcdir)/../archive.c \
|
||||
$(srcdir)/../archures.c $(srcdir)/../bfd.c \
|
||||
$(srcdir)/../bfdio.c $(srcdir)/../bfdwin.c \
|
||||
$(srcdir)/../cache.c $(srcdir)/../coffcode.h \
|
||||
$(srcdir)/../corefile.c $(srcdir)/../elf.c \
|
||||
$(srcdir)/../elfcode.h $(srcdir)/../format.c \
|
||||
@ -163,12 +166,14 @@ SRCDOC = $(srcdir)/../aoutx.h $(srcdir)/../archive.c \
|
||||
SRCPROT = $(srcdir)/../archive.c $(srcdir)/../archures.c \
|
||||
$(srcdir)/../bfd.c $(srcdir)/../coffcode.h $(srcdir)/../corefile.c \
|
||||
$(srcdir)/../format.c $(srcdir)/../libbfd.c \
|
||||
$(srcdir)/../bfdio.c $(srcdir)/../bfdwin.c \
|
||||
$(srcdir)/../opncls.c $(srcdir)/../reloc.c \
|
||||
$(srcdir)/../section.c $(srcdir)/../syms.c \
|
||||
$(srcdir)/../targets.c $(srcdir)/../init.c
|
||||
|
||||
|
||||
SRCIPROT = $(srcdir)/../cache.c $(srcdir)/../libbfd.c \
|
||||
$(srcdir)/../bfdio.c $(srcdir)/../bfdwin.c \
|
||||
$(srcdir)/../reloc.c $(srcdir)/../cpu-h8300.c \
|
||||
$(srcdir)/../cpu-i960.c $(srcdir)/../archures.c \
|
||||
$(srcdir)/../init.c
|
||||
@ -184,6 +189,8 @@ LIBBFD_H_DEP = \
|
||||
$(srcdir)/../libbfd-in.h \
|
||||
$(srcdir)/../init.c \
|
||||
$(srcdir)/../libbfd.c \
|
||||
$(srcdir)/../bfdio.c \
|
||||
$(srcdir)/../bfdwin.c \
|
||||
$(srcdir)/../cache.c \
|
||||
$(srcdir)/../reloc.c \
|
||||
$(srcdir)/../archures.c \
|
||||
@ -206,6 +213,8 @@ BFD_H_DEP = \
|
||||
$(srcdir)/../init.c \
|
||||
$(srcdir)/../opncls.c \
|
||||
$(srcdir)/../libbfd.c \
|
||||
$(srcdir)/../bfdio.c \
|
||||
$(srcdir)/../bfdwin.c \
|
||||
$(srcdir)/../section.c \
|
||||
$(srcdir)/../archures.c \
|
||||
$(srcdir)/../reloc.c \
|
||||
@ -553,6 +562,18 @@ s-libbfd: $(MKDOC) $(srcdir)/../libbfd.c $(srcdir)/doc.str
|
||||
touch s-libbfd
|
||||
libbfd.texi: s-libbfd
|
||||
|
||||
s-bfdio: $(MKDOC) $(srcdir)/../bfdio.c $(srcdir)/doc.str
|
||||
./$(MKDOC) -f $(srcdir)/doc.str < $(srcdir)/../bfdio.c >bfdio.tmp
|
||||
$(srcdir)/../../move-if-change bfdio.tmp bfdio.texi
|
||||
touch s-bfdio
|
||||
bfdio.texi: s-bfdio
|
||||
|
||||
s-bfdwin: $(MKDOC) $(srcdir)/../bfdwin.c $(srcdir)/doc.str
|
||||
./$(MKDOC) -f $(srcdir)/doc.str < $(srcdir)/../bfdwin.c >bfdwin.tmp
|
||||
$(srcdir)/../../move-if-change bfdwin.tmp bfdwin.texi
|
||||
touch s-bfdwin
|
||||
bfdwin.texi: s-bfdwin
|
||||
|
||||
s-opncls: $(MKDOC) $(srcdir)/../opncls.c $(srcdir)/doc.str
|
||||
./$(MKDOC) -f $(srcdir)/doc.str <$(srcdir)/../opncls.c >opncls.tmp
|
||||
$(srcdir)/../../move-if-change opncls.tmp opncls.texi
|
||||
|
@ -64,7 +64,7 @@ notice identical to this one except for the removal of this paragraph
|
||||
|
||||
@tex
|
||||
\def\$#1${{#1}} % Kluge: collect RCS revision info without $...$
|
||||
\xdef\manvers{\$Revision$} % For use in headers, footers too
|
||||
\xdef\manvers{\1.5} % For use in headers, footers too
|
||||
{\parskip=0pt
|
||||
\hfill Free Software Foundation\par
|
||||
\hfill sac\@www.gnu.org\par
|
||||
@ -207,6 +207,7 @@ IEEE-695.
|
||||
@node BFD front end, BFD back ends, Overview, Top
|
||||
@chapter BFD front end
|
||||
@include bfdt.texi
|
||||
@include bfdio.texi
|
||||
|
||||
@menu
|
||||
* Memory Usage::
|
||||
|
548
bfd/libbfd.c
548
bfd/libbfd.c
@ -28,8 +28,6 @@
|
||||
#define getpagesize() 2048
|
||||
#endif
|
||||
|
||||
static size_t real_read PARAMS ((PTR, size_t, size_t, FILE *));
|
||||
|
||||
/*
|
||||
SECTION
|
||||
Internal functions
|
||||
@ -222,372 +220,6 @@ bfd_zmalloc (size)
|
||||
|
||||
return ptr;
|
||||
}
|
||||
|
||||
/* Some IO code */
|
||||
|
||||
/* Note that archive entries don't have streams; they share their parent's.
|
||||
This allows someone to play with the iostream behind BFD's back.
|
||||
|
||||
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
|
||||
first octet in the file, NOT the beginning of the archive header. */
|
||||
|
||||
static size_t
|
||||
real_read (where, a, b, file)
|
||||
PTR where;
|
||||
size_t a;
|
||||
size_t b;
|
||||
FILE *file;
|
||||
{
|
||||
/* 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 (a == 0 || b == 0)
|
||||
return 0;
|
||||
|
||||
|
||||
#if defined (__VAX) && defined (VMS)
|
||||
/* Apparently fread on Vax VMS does not keep the record length
|
||||
information. */
|
||||
return read (fileno (file), where, a * b);
|
||||
#else
|
||||
return fread (where, a, b, file);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Return value is amount read. */
|
||||
|
||||
bfd_size_type
|
||||
bfd_bread (ptr, size, abfd)
|
||||
PTR ptr;
|
||||
bfd_size_type size;
|
||||
bfd *abfd;
|
||||
{
|
||||
size_t nread;
|
||||
|
||||
if ((abfd->flags & BFD_IN_MEMORY) != 0)
|
||||
{
|
||||
struct bfd_in_memory *bim;
|
||||
bfd_size_type get;
|
||||
|
||||
bim = (struct bfd_in_memory *) abfd->iostream;
|
||||
get = size;
|
||||
if (abfd->where + get > bim->size)
|
||||
{
|
||||
if (bim->size < (bfd_size_type) abfd->where)
|
||||
get = 0;
|
||||
else
|
||||
get = bim->size - abfd->where;
|
||||
bfd_set_error (bfd_error_file_truncated);
|
||||
}
|
||||
memcpy (ptr, bim->buffer + abfd->where, (size_t) get);
|
||||
abfd->where += get;
|
||||
return get;
|
||||
}
|
||||
|
||||
nread = real_read (ptr, 1, (size_t) size, bfd_cache_lookup (abfd));
|
||||
if (nread != (size_t) -1)
|
||||
abfd->where += nread;
|
||||
|
||||
/* 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.
|
||||
|
||||
A BFD backend may wish to override bfd_error_file_truncated to
|
||||
provide something more useful (eg. no_symbols or wrong_format). */
|
||||
if (nread != size)
|
||||
{
|
||||
if (ferror (bfd_cache_lookup (abfd)))
|
||||
bfd_set_error (bfd_error_system_call);
|
||||
else
|
||||
bfd_set_error (bfd_error_file_truncated);
|
||||
}
|
||||
|
||||
return nread;
|
||||
}
|
||||
|
||||
/* The window support stuff should probably be broken out into
|
||||
another file.... */
|
||||
/* The idea behind the next and refcount fields is that one mapped
|
||||
region can suffice for multiple read-only windows or multiple
|
||||
non-overlapping read-write windows. It's not implemented yet
|
||||
though. */
|
||||
struct _bfd_window_internal {
|
||||
struct _bfd_window_internal *next;
|
||||
PTR data;
|
||||
bfd_size_type size;
|
||||
int refcount : 31; /* should be enough... */
|
||||
unsigned mapped : 1; /* 1 = mmap, 0 = malloc */
|
||||
};
|
||||
|
||||
void
|
||||
bfd_init_window (windowp)
|
||||
bfd_window *windowp;
|
||||
{
|
||||
windowp->data = 0;
|
||||
windowp->i = 0;
|
||||
windowp->size = 0;
|
||||
}
|
||||
|
||||
/* Currently, if USE_MMAP is undefined, none if the window stuff is
|
||||
used. Okay, so it's mis-named. At least the command-line option
|
||||
"--without-mmap" is more obvious than "--without-windows" or some
|
||||
such. */
|
||||
#ifdef USE_MMAP
|
||||
|
||||
#undef HAVE_MPROTECT /* code's not tested yet */
|
||||
|
||||
#if HAVE_MMAP || HAVE_MPROTECT || HAVE_MADVISE
|
||||
#include <sys/mman.h>
|
||||
#endif
|
||||
|
||||
#ifndef MAP_FILE
|
||||
#define MAP_FILE 0
|
||||
#endif
|
||||
|
||||
static int debug_windows;
|
||||
|
||||
void
|
||||
bfd_free_window (windowp)
|
||||
bfd_window *windowp;
|
||||
{
|
||||
bfd_window_internal *i = windowp->i;
|
||||
windowp->i = 0;
|
||||
windowp->data = 0;
|
||||
if (i == 0)
|
||||
return;
|
||||
i->refcount--;
|
||||
if (debug_windows)
|
||||
fprintf (stderr, "freeing window @%p<%p,%lx,%p>\n",
|
||||
windowp, windowp->data, windowp->size, windowp->i);
|
||||
if (i->refcount != 0)
|
||||
return;
|
||||
|
||||
if (i->mapped)
|
||||
{
|
||||
#ifdef HAVE_MMAP
|
||||
munmap (i->data, i->size);
|
||||
goto no_free;
|
||||
#else
|
||||
abort ();
|
||||
#endif
|
||||
}
|
||||
#ifdef HAVE_MPROTECT
|
||||
mprotect (i->data, i->size, PROT_READ | PROT_WRITE);
|
||||
#endif
|
||||
free (i->data);
|
||||
#ifdef HAVE_MMAP
|
||||
no_free:
|
||||
#endif
|
||||
i->data = 0;
|
||||
/* There should be no more references to i at this point. */
|
||||
free (i);
|
||||
}
|
||||
|
||||
static int ok_to_map = 1;
|
||||
|
||||
boolean
|
||||
bfd_get_file_window (abfd, offset, size, windowp, writable)
|
||||
bfd *abfd;
|
||||
file_ptr offset;
|
||||
bfd_size_type size;
|
||||
bfd_window *windowp;
|
||||
boolean writable;
|
||||
{
|
||||
static size_t pagesize;
|
||||
bfd_window_internal *i = windowp->i;
|
||||
bfd_size_type size_to_alloc = size;
|
||||
|
||||
if (debug_windows)
|
||||
fprintf (stderr, "bfd_get_file_window (%p, %6ld, %6ld, %p<%p,%lx,%p>, %d)",
|
||||
abfd, (long) offset, (long) size,
|
||||
windowp, windowp->data, (unsigned long) windowp->size,
|
||||
windowp->i, writable);
|
||||
|
||||
/* Make sure we know the page size, so we can be friendly to mmap. */
|
||||
if (pagesize == 0)
|
||||
pagesize = getpagesize ();
|
||||
if (pagesize == 0)
|
||||
abort ();
|
||||
|
||||
if (i == 0)
|
||||
{
|
||||
i = ((bfd_window_internal *)
|
||||
bfd_zmalloc ((bfd_size_type) sizeof (bfd_window_internal)));
|
||||
windowp->i = i;
|
||||
if (i == 0)
|
||||
return false;
|
||||
i->data = 0;
|
||||
}
|
||||
#ifdef HAVE_MMAP
|
||||
if (ok_to_map
|
||||
&& (i->data == 0 || i->mapped == 1)
|
||||
&& (abfd->flags & BFD_IN_MEMORY) == 0)
|
||||
{
|
||||
file_ptr file_offset, offset2;
|
||||
size_t real_size;
|
||||
int fd;
|
||||
FILE *f;
|
||||
|
||||
/* Find the real file and the real offset into it. */
|
||||
while (abfd->my_archive != NULL)
|
||||
{
|
||||
offset += abfd->origin;
|
||||
abfd = abfd->my_archive;
|
||||
}
|
||||
f = bfd_cache_lookup (abfd);
|
||||
fd = fileno (f);
|
||||
|
||||
/* Compute offsets and size for mmap and for the user's data. */
|
||||
offset2 = offset % pagesize;
|
||||
if (offset2 < 0)
|
||||
abort ();
|
||||
file_offset = offset - offset2;
|
||||
real_size = offset + size - file_offset;
|
||||
real_size = real_size + pagesize - 1;
|
||||
real_size -= real_size % pagesize;
|
||||
|
||||
/* If we're re-using a memory region, make sure it's big enough. */
|
||||
if (i->data && i->size < size)
|
||||
{
|
||||
munmap (i->data, i->size);
|
||||
i->data = 0;
|
||||
}
|
||||
i->data = mmap (i->data, real_size,
|
||||
writable ? PROT_WRITE | PROT_READ : PROT_READ,
|
||||
(writable
|
||||
? MAP_FILE | MAP_PRIVATE
|
||||
: MAP_FILE | MAP_SHARED),
|
||||
fd, file_offset);
|
||||
if (i->data == (PTR) -1)
|
||||
{
|
||||
/* An error happened. Report it, or try using malloc, or
|
||||
something. */
|
||||
bfd_set_error (bfd_error_system_call);
|
||||
i->data = 0;
|
||||
windowp->data = 0;
|
||||
if (debug_windows)
|
||||
fprintf (stderr, "\t\tmmap failed!\n");
|
||||
return false;
|
||||
}
|
||||
if (debug_windows)
|
||||
fprintf (stderr, "\n\tmapped %ld at %p, offset is %ld\n",
|
||||
(long) real_size, i->data, (long) offset2);
|
||||
i->size = real_size;
|
||||
windowp->data = (PTR) ((bfd_byte *) i->data + offset2);
|
||||
windowp->size = size;
|
||||
i->mapped = 1;
|
||||
return true;
|
||||
}
|
||||
else if (debug_windows)
|
||||
{
|
||||
if (ok_to_map)
|
||||
fprintf (stderr, _("not mapping: data=%lx mapped=%d\n"),
|
||||
(unsigned long) i->data, (int) i->mapped);
|
||||
else
|
||||
fprintf (stderr, _("not mapping: env var not set\n"));
|
||||
}
|
||||
#else
|
||||
ok_to_map = 0;
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_MPROTECT
|
||||
if (!writable)
|
||||
{
|
||||
size_to_alloc += pagesize - 1;
|
||||
size_to_alloc -= size_to_alloc % pagesize;
|
||||
}
|
||||
#endif
|
||||
if (debug_windows)
|
||||
fprintf (stderr, "\n\t%s(%6ld)",
|
||||
i->data ? "realloc" : " malloc", (long) size_to_alloc);
|
||||
i->data = (PTR) bfd_realloc (i->data, size_to_alloc);
|
||||
if (debug_windows)
|
||||
fprintf (stderr, "\t-> %p\n", i->data);
|
||||
i->refcount = 1;
|
||||
if (i->data == NULL)
|
||||
{
|
||||
if (size_to_alloc == 0)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
if (bfd_seek (abfd, offset, SEEK_SET) != 0)
|
||||
return false;
|
||||
i->size = bfd_bread (i->data, size, abfd);
|
||||
if (i->size != size)
|
||||
return false;
|
||||
i->mapped = 0;
|
||||
#ifdef HAVE_MPROTECT
|
||||
if (!writable)
|
||||
{
|
||||
if (debug_windows)
|
||||
fprintf (stderr, "\tmprotect (%p, %ld, PROT_READ)\n", i->data,
|
||||
(long) i->size);
|
||||
mprotect (i->data, i->size, PROT_READ);
|
||||
}
|
||||
#endif
|
||||
windowp->data = i->data;
|
||||
windowp->size = i->size;
|
||||
return true;
|
||||
}
|
||||
|
||||
#endif /* USE_MMAP */
|
||||
|
||||
bfd_size_type
|
||||
bfd_bwrite (ptr, size, abfd)
|
||||
const PTR ptr;
|
||||
bfd_size_type size;
|
||||
bfd *abfd;
|
||||
{
|
||||
size_t nwrote;
|
||||
|
||||
if ((abfd->flags & BFD_IN_MEMORY) != 0)
|
||||
{
|
||||
struct bfd_in_memory *bim = (struct bfd_in_memory *) (abfd->iostream);
|
||||
size = (size_t) size;
|
||||
if (abfd->where + size > bim->size)
|
||||
{
|
||||
bfd_size_type newsize, oldsize;
|
||||
|
||||
oldsize = (bim->size + 127) & ~(bfd_size_type) 127;
|
||||
bim->size = abfd->where + size;
|
||||
/* Round up to cut down on memory fragmentation */
|
||||
newsize = (bim->size + 127) & ~(bfd_size_type) 127;
|
||||
if (newsize > oldsize)
|
||||
{
|
||||
bim->buffer = (bfd_byte *) bfd_realloc (bim->buffer, newsize);
|
||||
if (bim->buffer == 0)
|
||||
{
|
||||
bim->size = 0;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
memcpy (bim->buffer + abfd->where, ptr, (size_t) size);
|
||||
abfd->where += size;
|
||||
return size;
|
||||
}
|
||||
|
||||
nwrote = fwrite (ptr, 1, (size_t) size, bfd_cache_lookup (abfd));
|
||||
if (nwrote != (size_t) -1)
|
||||
abfd->where += nwrote;
|
||||
if (nwrote != size)
|
||||
{
|
||||
#ifdef ENOSPC
|
||||
errno = ENOSPC;
|
||||
#endif
|
||||
bfd_set_error (bfd_error_system_call);
|
||||
}
|
||||
return nwrote;
|
||||
}
|
||||
|
||||
/*
|
||||
INTERNAL_FUNCTION
|
||||
bfd_write_bigendian_4byte_int
|
||||
@ -611,186 +243,6 @@ bfd_write_bigendian_4byte_int (abfd, i)
|
||||
return (boolean) (bfd_bwrite ((PTR) buffer, (bfd_size_type) 4, abfd) == 4);
|
||||
}
|
||||
|
||||
bfd_vma
|
||||
bfd_tell (abfd)
|
||||
bfd *abfd;
|
||||
{
|
||||
file_ptr ptr;
|
||||
|
||||
if ((abfd->flags & BFD_IN_MEMORY) != 0)
|
||||
return abfd->where;
|
||||
|
||||
ptr = ftell (bfd_cache_lookup (abfd));
|
||||
|
||||
if (abfd->my_archive)
|
||||
ptr -= abfd->origin;
|
||||
abfd->where = ptr;
|
||||
return ptr;
|
||||
}
|
||||
|
||||
int
|
||||
bfd_flush (abfd)
|
||||
bfd *abfd;
|
||||
{
|
||||
if ((abfd->flags & BFD_IN_MEMORY) != 0)
|
||||
return 0;
|
||||
return fflush (bfd_cache_lookup(abfd));
|
||||
}
|
||||
|
||||
/* Returns 0 for success, negative value for failure (in which case
|
||||
bfd_get_error can retrieve the error code). */
|
||||
int
|
||||
bfd_stat (abfd, statbuf)
|
||||
bfd *abfd;
|
||||
struct stat *statbuf;
|
||||
{
|
||||
FILE *f;
|
||||
int result;
|
||||
|
||||
if ((abfd->flags & BFD_IN_MEMORY) != 0)
|
||||
abort ();
|
||||
|
||||
f = bfd_cache_lookup (abfd);
|
||||
if (f == NULL)
|
||||
{
|
||||
bfd_set_error (bfd_error_system_call);
|
||||
return -1;
|
||||
}
|
||||
result = fstat (fileno (f), statbuf);
|
||||
if (result < 0)
|
||||
bfd_set_error (bfd_error_system_call);
|
||||
return result;
|
||||
}
|
||||
|
||||
/* Returns 0 for success, nonzero for failure (in which case bfd_get_error
|
||||
can retrieve the error code). */
|
||||
|
||||
int
|
||||
bfd_seek (abfd, position, direction)
|
||||
bfd *abfd;
|
||||
file_ptr position;
|
||||
int direction;
|
||||
{
|
||||
int result;
|
||||
FILE *f;
|
||||
long file_position;
|
||||
/* For the time being, a BFD may not seek to it's end. The problem
|
||||
is that we don't easily have a way to recognize the end of an
|
||||
element in an archive. */
|
||||
|
||||
BFD_ASSERT (direction == SEEK_SET || direction == SEEK_CUR);
|
||||
|
||||
if (direction == SEEK_CUR && position == 0)
|
||||
return 0;
|
||||
|
||||
if ((abfd->flags & BFD_IN_MEMORY) != 0)
|
||||
{
|
||||
struct bfd_in_memory *bim;
|
||||
|
||||
bim = (struct bfd_in_memory *) abfd->iostream;
|
||||
|
||||
if (direction == SEEK_SET)
|
||||
abfd->where = position;
|
||||
else
|
||||
abfd->where += position;
|
||||
|
||||
if (abfd->where > bim->size)
|
||||
{
|
||||
if ((abfd->direction == write_direction) ||
|
||||
(abfd->direction == both_direction))
|
||||
{
|
||||
bfd_size_type newsize, oldsize;
|
||||
oldsize = (bim->size + 127) & ~(bfd_size_type) 127;
|
||||
bim->size = abfd->where;
|
||||
/* Round up to cut down on memory fragmentation */
|
||||
newsize = (bim->size + 127) & ~(bfd_size_type) 127;
|
||||
if (newsize > oldsize)
|
||||
{
|
||||
bim->buffer = (bfd_byte *) bfd_realloc (bim->buffer, newsize);
|
||||
if (bim->buffer == 0)
|
||||
{
|
||||
bim->size = 0;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
abfd->where = bim->size;
|
||||
bfd_set_error (bfd_error_file_truncated);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (abfd->format != bfd_archive && abfd->my_archive == 0)
|
||||
{
|
||||
#if 0
|
||||
/* Explanation for this code: I'm only about 95+% sure that the above
|
||||
conditions are sufficient and that all i/o calls are properly
|
||||
adjusting the `where' field. So this is sort of an `assert'
|
||||
that the `where' field is correct. If we can go a while without
|
||||
tripping the abort, we can probably safely disable this code,
|
||||
so that the real optimizations happen. */
|
||||
file_ptr where_am_i_now;
|
||||
where_am_i_now = ftell (bfd_cache_lookup (abfd));
|
||||
if (abfd->my_archive)
|
||||
where_am_i_now -= abfd->origin;
|
||||
if (where_am_i_now != abfd->where)
|
||||
abort ();
|
||||
#endif
|
||||
if (direction == SEEK_SET && (bfd_vma) position == abfd->where)
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* We need something smarter to optimize access to archives.
|
||||
Currently, anything inside an archive is read via the file
|
||||
handle for the archive. Which means that a bfd_seek on one
|
||||
component affects the `current position' in the archive, as
|
||||
well as in any other component.
|
||||
|
||||
It might be sufficient to put a spike through the cache
|
||||
abstraction, and look to the archive for the file position,
|
||||
but I think we should try for something cleaner.
|
||||
|
||||
In the meantime, no optimization for archives. */
|
||||
}
|
||||
|
||||
f = bfd_cache_lookup (abfd);
|
||||
file_position = position;
|
||||
if (direction == SEEK_SET && abfd->my_archive != NULL)
|
||||
file_position += abfd->origin;
|
||||
|
||||
result = fseek (f, file_position, direction);
|
||||
if (result != 0)
|
||||
{
|
||||
int hold_errno = errno;
|
||||
|
||||
/* Force redetermination of `where' field. */
|
||||
bfd_tell (abfd);
|
||||
|
||||
/* An EINVAL error probably means that the file offset was
|
||||
absurd. */
|
||||
if (hold_errno == EINVAL)
|
||||
bfd_set_error (bfd_error_file_truncated);
|
||||
else
|
||||
{
|
||||
bfd_set_error (bfd_error_system_call);
|
||||
errno = hold_errno;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Adjust `where' field. */
|
||||
if (direction == SEEK_SET)
|
||||
abfd->where = position;
|
||||
else
|
||||
abfd->where += position;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/** The do-it-yourself (byte) sex-change kit */
|
||||
|
||||
|
13
bfd/libbfd.h
13
bfd/libbfd.h
@ -1,6 +1,6 @@
|
||||
/* DO NOT EDIT! -*- buffer-read-only: t -*- This file is automatically
|
||||
generated from "libbfd-in.h", "init.c", "libbfd.c", "cache.c",
|
||||
"reloc.c", "archures.c" and "elf.c".
|
||||
generated from "libbfd-in.h", "init.c", "libbfd.c", "bfdio.c",
|
||||
"bfdwin.c", "cache.c", "reloc.c", "archures.c" and "elf.c".
|
||||
Run "make headers" in your build bfd/ to regenerate. */
|
||||
|
||||
/* libbfd.h -- Declarations used by bfd library *implementation*.
|
||||
@ -609,6 +609,15 @@ bfd_write_bigendian_4byte_int PARAMS ((bfd *, unsigned int));
|
||||
unsigned int
|
||||
bfd_log2 PARAMS ((bfd_vma x));
|
||||
|
||||
/* Extracted from bfdio.c. */
|
||||
/* Extracted from bfdwin.c. */
|
||||
struct _bfd_window_internal {
|
||||
struct _bfd_window_internal *next;
|
||||
PTR data;
|
||||
bfd_size_type size;
|
||||
int refcount : 31; /* should be enough... */
|
||||
unsigned mapped : 1; /* 1 = mmap, 0 = malloc */
|
||||
};
|
||||
/* Extracted from cache.c. */
|
||||
#define BFD_CACHE_MAX_OPEN 10
|
||||
extern bfd *bfd_last_cache;
|
||||
|
Loading…
Reference in New Issue
Block a user