Changes for mmap; details in change log.

Added some new interfaces, and a new entry in the target vector.  Under the new
interfaces, mmap will be used if available, otherwise malloc/seek/read, as
before.  Old interfaces all still intact.

Most configurations (including all used by "--enable-targets=all") simply
changed to call the default routine for that entry in the target vector.  I
might've missed some targets only included in special configurations.

Support for a.out symbol and string table reading now goes through new
interfaces, and will use mmap when available.

Linker hooks (e.g., avoiding reallocation under malloc) not ready yet.
This commit is contained in:
Ken Raeburn 1995-11-06 10:08:03 +00:00
parent ffacb892eb
commit 4fe6d901bd
12 changed files with 625 additions and 112 deletions

View File

@ -8,6 +8,40 @@ Sun Nov 5 21:44:13 1995 Ken Raeburn <raeburn@cygnus.com>
* ecoff.c (_bfd_ecoff_slurp_armap): Cast _bfd_read_ar_hdr return
value.
Permit use of mmap when available:
* configure.in: Check for mmap, madvise, mprotect.
* config.in, configure: Regenerated.
* libbfd.c (struct _bfd_window_internal): Define type.
(bfd_init_window, bfd_free_window, bfd_get_file_window): New
functions.
(ok_to_map): New static variable for debugging.
(_bfd_generic_get_section_contents_in_window): New function.
* bfd-in.h (bfd_window_internal): Declare type.
(bfd_window): Define type.
(bfd_init_window, bfd_free_window, bfd_get_file_window): Declare.
* libbfd-in.h (_bfd_generic_get_section_contents_in_window):
Declare.
* libaout.h (struct aoutdata): Add two window fields.
(obj_aout_sym_window, obj_aout_string_window): New macros.
* aoutx.h (some_aout_object_p): Initialize windows.
(aout_get_external_symbols): Get symbol data and strings in
windows instead of explicitly allocated buffers.
(slurp_symbol_table): Free window instead of memory.
(bfd_free_cached_info): Release windows instead of freeing storage
directly.
(aout_link_free_symbols): Ditto.
* targets.c (bfd_target): Add new field for
get_section_contents_in_window.
(BFD_JUMP_TABLE_GENERIC): Updated.
* aout-adobe.c, aout-target.h, binary.c, bout.c, coff-alpha.c,
coff-mips.c, elfxx-target.h, i386msdos.c, i386os9k.c, ieee.c,
libcoff-in.h, oasys.c, srec.c, tekhex.c, versados.c: Added new
macros for get_section_contents_in_window field.
Sat Nov 4 12:23:26 1995 Fred Fish <fnf@cygnus.com>
* core.c: Renamed to corefile.c

View File

@ -497,7 +497,9 @@ NAME(aout,some_aout_object_p) (abfd, execp, callback_to_real_object_p)
obj_symbol_entry_size (abfd) = EXTERNAL_NLIST_SIZE;
obj_aout_external_syms (abfd) = NULL;
bfd_init_window (&obj_aout_sym_window (abfd));
obj_aout_external_strings (abfd) = NULL;
bfd_init_window (&obj_aout_string_window (abfd));
obj_aout_sym_hashes (abfd) = NULL;
if (! NAME(aout,make_sections) (abfd))
@ -1226,24 +1228,11 @@ aout_get_external_symbols (abfd)
count = exec_hdr (abfd)->a_syms / EXTERNAL_NLIST_SIZE;
/* We allocate using malloc to make the values easy to free
later on. If we put them on the obstack it might not be
possible to free them. */
syms = ((struct external_nlist *)
malloc ((size_t) count * EXTERNAL_NLIST_SIZE));
if (syms == (struct external_nlist *) NULL && count != 0)
{
bfd_set_error (bfd_error_no_memory);
return false;
}
if (bfd_seek (abfd, obj_sym_filepos (abfd), SEEK_SET) != 0
|| (bfd_read (syms, 1, exec_hdr (abfd)->a_syms, abfd)
!= exec_hdr (abfd)->a_syms))
{
free (syms);
return false;
}
if (bfd_get_file_window (abfd,
obj_sym_filepos (abfd), exec_hdr (abfd)->a_syms,
&obj_aout_sym_window (abfd), 1) == false)
return false;
syms = (struct external_nlist *) obj_aout_sym_window (abfd).data;
obj_aout_external_syms (abfd) = syms;
obj_aout_external_sym_count (abfd) = count;
@ -1263,28 +1252,25 @@ aout_get_external_symbols (abfd)
return false;
stringsize = GET_WORD (abfd, string_chars);
strings = (char *) malloc ((size_t) stringsize + 1);
if (strings == NULL)
{
bfd_set_error (bfd_error_no_memory);
return false;
}
/* Skip space for the string count in the buffer for convenience
when using indexes. */
if (bfd_read (strings + BYTES_IN_WORD, 1, stringsize - BYTES_IN_WORD,
abfd)
!= stringsize - BYTES_IN_WORD)
{
free (strings);
return false;
}
if (bfd_get_file_window (abfd, obj_str_filepos (abfd), stringsize,
&obj_aout_string_window (abfd), 1) == false)
return false;
strings = (char *) obj_aout_string_window (abfd).data;
/* Ensure that a zero index yields an empty string. */
strings[0] = '\0';
/* Sanity preservation. */
strings[stringsize] = '\0';
/* Using the "window" interface, we don't know that there's
writeable storage after the last byte of the string table.
Besides, every string in the string table should be null
terminated. Check it here so the application doesn't crash,
but don't expend huge effort trying to correct a broken
object file. */
if (stringsize > BYTES_IN_WORD && strings[stringsize - 1] != 0)
{
fprintf (stderr, "string table missing ending null\n");
strings[stringsize - 1] = 0;
}
obj_aout_external_strings (abfd) = strings;
obj_aout_external_string_size (abfd) = stringsize;
@ -1755,7 +1741,7 @@ NAME(aout,slurp_symbol_table) (abfd)
if (old_external_syms == (struct external_nlist *) NULL
&& obj_aout_external_syms (abfd) != (struct external_nlist *) NULL)
{
free (obj_aout_external_syms (abfd));
bfd_free_window (&obj_aout_sym_window (abfd));
obj_aout_external_syms (abfd) = NULL;
}
@ -2784,8 +2770,10 @@ NAME(aout,bfd_free_cached_info) (abfd)
#define BFCI_FREE(x) if (x != NULL) { free (x); x = NULL; }
BFCI_FREE (obj_aout_symbols (abfd));
BFCI_FREE (obj_aout_external_syms (abfd));
BFCI_FREE (obj_aout_external_strings (abfd));
obj_aout_external_syms (abfd) = 0;
bfd_free_window (&obj_aout_sym_window (abfd));
bfd_free_window (&obj_aout_string_window (abfd));
obj_aout_external_strings (abfd) = 0;
for (o = abfd->sections; o != (asection *) NULL; o = o->next)
BFCI_FREE (o->relocation);
#undef BFCI_FREE
@ -2957,12 +2945,12 @@ aout_link_free_symbols (abfd)
{
if (obj_aout_external_syms (abfd) != (struct external_nlist *) NULL)
{
free ((PTR) obj_aout_external_syms (abfd));
bfd_free_window (&obj_aout_sym_window (abfd));
obj_aout_external_syms (abfd) = (struct external_nlist *) NULL;
}
if (obj_aout_external_strings (abfd) != (char *) NULL)
{
free ((PTR) obj_aout_external_strings (abfd));
bfd_free_window (&obj_aout_string_window (abfd));
obj_aout_external_strings (abfd) = (char *) NULL;
}
return true;

View File

@ -600,6 +600,28 @@ extern boolean bfd_sunos_size_dynamic_sections
extern boolean bfd_linux_size_dynamic_sections
PARAMS ((bfd *, struct bfd_link_info *));
/* mmap hacks */
struct _bfd_window_internal;
typedef struct _bfd_window_internal bfd_window_internal;
typedef struct _bfd_window {
/* What the user asked for. */
PTR data;
bfd_size_type size;
/* The actual window used by BFD. Small user-requested read-only
regions sharing a page may share a single window into the object
file. Read-write versions shouldn't until I've fixed things to
keep track of which portions have been claimed by the
application; don't want to give the same region back when the
application wants two writable copies! */
struct _bfd_window_internal *i;
} bfd_window;
void bfd_init_window PARAMS ((bfd_window *));
void bfd_free_window PARAMS ((bfd_window *));
int bfd_get_file_window PARAMS ((bfd *, file_ptr, bfd_size_type, bfd_window *, int));
/* XCOFF support routines for the linker. */
extern boolean bfd_xcoff_link_record_set

View File

@ -600,6 +600,28 @@ extern boolean bfd_sunos_size_dynamic_sections
extern boolean bfd_linux_size_dynamic_sections
PARAMS ((bfd *, struct bfd_link_info *));
/* mmap hacks */
struct _bfd_window_internal;
typedef struct _bfd_window_internal bfd_window_internal;
typedef struct _bfd_window {
/* What the user asked for. */
PTR data;
bfd_size_type size;
/* The actual window used by BFD. Small user-requested read-only
regions sharing a page may share a single window into the object
file. Read-write versions shouldn't until I've fixed things to
keep track of which portions have been claimed by the
application; don't want to give the same region back when the
application wants two writable copies! */
struct _bfd_window_internal *i;
} bfd_window;
void bfd_init_window PARAMS ((bfd_window *));
void bfd_free_window PARAMS ((bfd_window *));
int bfd_get_file_window PARAMS ((bfd *, file_ptr, bfd_size_type, bfd_window *, int));
/* XCOFF support routines for the linker. */
extern boolean bfd_xcoff_link_record_set
@ -2184,7 +2206,9 @@ typedef struct bfd_target
CAT(NAME,_close_and_cleanup),\
CAT(NAME,_bfd_free_cached_info),\
CAT(NAME,_new_section_hook),\
CAT(NAME,_get_section_contents)
CAT(NAME,_get_section_contents),\
CAT(NAME,_get_section_contents_in_window)
/* Called when the BFD is being closed to do any necessary cleanup. */
boolean (*_close_and_cleanup) PARAMS ((bfd *));
/* Ask the BFD to free all cached information. */
@ -2194,6 +2218,9 @@ CAT(NAME,_get_section_contents)
/* Read the contents of a section. */
boolean (*_bfd_get_section_contents) PARAMS ((bfd *, sec_ptr, PTR,
file_ptr, bfd_size_type));
boolean (*_bfd_get_section_contents_in_window)
PARAMS ((bfd *, sec_ptr, bfd_window *,
file_ptr, bfd_size_type));
/* Entry points to copy private data. */
#define BFD_JUMP_TABLE_COPY(NAME)\

55
bfd/config.in Normal file
View File

@ -0,0 +1,55 @@
/* config.in. Generated automatically from configure.in by autoheader. */
/* Define if you have a working `mmap' system call. */
#undef HAVE_MMAP
/* Do we need to use the b modifier when opening binary files? */
#undef USE_BINARY_FOPEN
/* Whether malloc must be declared even if <stdlib.h> is included. */
#undef NEED_DECLARATION_MALLOC
/* Whether free must be declared even if <stdlib.h> is included. */
#undef NEED_DECLARATION_FREE
/* Name of host specific header file to include in trad-core.c. */
#undef TRAD_HEADER
/* Define only if <sys/procfs.h> is available *and* it defines prstatus_t. */
#undef HAVE_SYS_PROCFS_H
/* Define if you have the fcntl function. */
#undef HAVE_FCNTL
/* Define if you have the getpagesize function. */
#undef HAVE_GETPAGESIZE
/* Define if you have the madvise function. */
#undef HAVE_MADVISE
/* Define if you have the mprotect function. */
#undef HAVE_MPROTECT
/* Define if you have the <fcntl.h> header file. */
#undef HAVE_FCNTL_H
/* Define if you have the <stddef.h> header file. */
#undef HAVE_STDDEF_H
/* Define if you have the <stdlib.h> header file. */
#undef HAVE_STDLIB_H
/* Define if you have the <string.h> header file. */
#undef HAVE_STRING_H
/* Define if you have the <strings.h> header file. */
#undef HAVE_STRINGS_H
/* Define if you have the <sys/file.h> header file. */
#undef HAVE_SYS_FILE_H
/* Define if you have the <time.h> header file. */
#undef HAVE_TIME_H
/* Define if you have the <unistd.h> header file. */
#undef HAVE_UNISTD_H

152
bfd/configure vendored
View File

@ -1502,6 +1502,158 @@ test -n "${selvecs}" && tdefaults="${tdefaults} -DSELECT_VECS='${selvecs}'"
test -n "${selarchs}" && tdefaults="${tdefaults} -DSELECT_ARCHITECTURES='${selarchs}'"
echo $ac_n "checking for working mmap""... $ac_c" 1>&6
if eval "test \"`echo '$''{'ac_cv_func_mmap'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
if test "$cross_compiling" = yes; then
ac_cv_func_mmap=no
else
cat > conftest.$ac_ext <<EOF
#line 1514 "configure"
#include "confdefs.h"
/* Thanks to Mike Haertel and Jim Avera for this test. */
#include <sys/types.h>
#include <fcntl.h>
#include <sys/mman.h>
#ifdef BSD
# ifndef BSD4_1
# define HAVE_GETPAGESIZE
# endif
#endif
#ifndef HAVE_GETPAGESIZE
# include <sys/param.h>
# ifdef EXEC_PAGESIZE
# define getpagesize() EXEC_PAGESIZE
# else
# ifdef NBPG
# define getpagesize() NBPG * CLSIZE
# ifndef CLSIZE
# define CLSIZE 1
# endif
# else
# ifdef NBPC
# define getpagesize() NBPC
# else
# define getpagesize() PAGESIZE /* SVR4 */
# endif
# endif
# endif
#endif
#ifdef __osf__
# define valloc malloc
#endif
#ifdef __cplusplus
extern "C" { void *valloc(unsigned), *malloc(unsigned); }
#else
char *valloc(), *malloc();
#endif
int
main()
{
char *buf1, *buf2, *buf3;
int i = getpagesize(), j;
int i2 = getpagesize()*2;
int fd;
buf1 = (char *)valloc(i2);
buf2 = (char *)valloc(i);
buf3 = (char *)malloc(i2);
for (j = 0; j < i2; ++j)
*(buf1 + j) = rand();
fd = open("conftestmmap", O_CREAT | O_RDWR, 0666);
write(fd, buf1, i2);
mmap(buf2, i, PROT_READ | PROT_WRITE, MAP_FIXED | MAP_PRIVATE, fd, 0);
for (j = 0; j < i; ++j)
if (*(buf1 + j) != *(buf2 + j))
exit(1);
lseek(fd, (long)i, 0);
read(fd, buf2, i); /* read into mapped memory -- file should not change */
/* (it does in i386 SVR4.0 - Jim Avera, jima@netcom.com) */
lseek(fd, (long)0, 0);
read(fd, buf3, i2);
for (j = 0; j < i2; ++j)
if (*(buf1 + j) != *(buf3 + j))
exit(1);
exit(0);
}
EOF
eval $ac_link
if test -s conftest && (./conftest; exit) 2>/dev/null; then
ac_cv_func_mmap=yes
else
ac_cv_func_mmap=no
fi
fi
rm -fr conftest*
fi
echo "$ac_t""$ac_cv_func_mmap" 1>&6
if test $ac_cv_func_mmap = yes; then
cat >> confdefs.h <<\EOF
#define HAVE_MMAP 1
EOF
fi
for ac_func in madvise mprotect
do
echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
#line 1613 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char $ac_func(); below. */
#include <assert.h>
/* Override any gcc2 internal prototype to avoid an error. */
char $ac_func();
int main() { return 0; }
int t() {
/* The GNU C library defines this for functions which it implements
to always fail with ENOSYS. Some functions are actually named
something starting with __ and the normal name is an alias. */
#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
choke me
#else
$ac_func();
#endif
; return 0; }
EOF
if eval $ac_link; then
rm -rf conftest*
eval "ac_cv_func_$ac_func=yes"
else
rm -rf conftest*
eval "ac_cv_func_$ac_func=no"
fi
rm -f conftest*
fi
if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
echo "$ac_t""yes" 1>&6
ac_tr_func=HAVE_`echo $ac_func | tr '[a-z]' '[A-Z]'`
cat >> confdefs.h <<EOF
#define $ac_tr_func 1
EOF
else
echo "$ac_t""no" 1>&6
fi
done
rm -f doc/config.status
trap '' 1 2 15
cat > confcache <<\EOF

View File

@ -528,6 +528,10 @@ test -n "${selvecs}" && tdefaults="${tdefaults} -DSELECT_VECS='${selvecs}'"
test -n "${selarchs}" && tdefaults="${tdefaults} -DSELECT_ARCHITECTURES='${selarchs}'"
AC_SUBST(tdefaults)
dnl AC_CHECK_HEADERS(sys/mman.h)
AC_FUNC_MMAP
AC_CHECK_FUNCS(madvise mprotect)
rm -f doc/config.status
AC_OUTPUT(Makefile doc/Makefile,
[case x$CONFIG_HEADERS in xconfig.h:config.in) echo > stamp-h ;; esac])

View File

@ -16,12 +16,14 @@ 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., 675 Mass Ave, Cambridge, MA 02139, USA. */
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#include "bfd.h"
#include "sysdep.h"
#include "libbfd.h"
static int real_read PARAMS ((PTR, size_t, size_t, FILE *));
/*
SECTION
Internal functions
@ -145,10 +147,11 @@ _bfd_nocore_core_file_failing_signal (ignore_abfd)
}
/*ARGSUSED*/
bfd_target *
const bfd_target *
_bfd_dummy_target (ignore_abfd)
bfd *ignore_abfd;
{
bfd_set_error (bfd_error_wrong_format);
return 0;
}
@ -179,15 +182,14 @@ bfd_zmalloc (size)
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
int
static int
real_read (where, a,b, file)
PTR where;
int a;
int b;
size_t a;
size_t b;
FILE *file;
{
return fread(where, a,b,file);
return fread (where, a, b, file);
}
/* Return value is amount read (FIXME: how are errors and end of file dealt
@ -201,7 +203,7 @@ bfd_read (ptr, size, nitems, abfd)
bfd *abfd;
{
int nread;
nread = real_read (ptr, 1, (int)(size*nitems), bfd_cache_lookup(abfd));
nread = real_read (ptr, 1, (size_t)(size*nitems), bfd_cache_lookup(abfd));
#ifdef FILE_OFFSET_IS_CHAR_INDEX
if (nread > 0)
abfd->where += nread;
@ -225,6 +227,219 @@ bfd_read (ptr, size, nitems, abfd)
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;
}
#undef HAVE_MPROTECT /* code's not tested yet */
#if HAVE_MMAP || HAVE_MPROTECT
#include <sys/types.h>
#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;
int
bfd_get_file_window (abfd, offset, size, windowp, writable)
bfd *abfd;
file_ptr offset;
bfd_size_type size;
bfd_window *windowp;
int writable;
{
static size_t pagesize;
bfd_window_internal *i = windowp->i;
size_t 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, 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)
{
windowp->i = i = (bfd_window_internal *) bfd_zmalloc (sizeof (bfd_window_internal));
if (i == 0)
return false;
i->data = 0;
}
#ifdef HAVE_MMAP
if (ok_to_map && (i->data == 0 || i->mapped == 1))
{
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,
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 = i->data + offset2;
windowp->size = size;
i->mapped = 1;
return true;
}
else if (debug_windows)
{
if (ok_to_map)
fprintf (stderr, "not mapping: data=%x mapped=%d\n",
i->data, 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);
if (i->data)
i->data = realloc (i->data, size_to_alloc);
else
i->data = malloc (size_to_alloc);
if (debug_windows)
fprintf (stderr, "\t-> %p\n", i->data);
i->refcount = 1;
if (i->data == 0)
return size_to_alloc == 0;
if (bfd_seek (abfd, offset, SEEK_SET) != 0)
return false;
i->size = bfd_read (i->data, size, 1, 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;
}
bfd_size_type
bfd_write (ptr, size, nitems, abfd)
CONST PTR ptr;
@ -232,12 +447,13 @@ bfd_write (ptr, size, nitems, abfd)
bfd_size_type nitems;
bfd *abfd;
{
int nwrote = fwrite (ptr, 1, (int) (size * nitems), bfd_cache_lookup (abfd));
long nwrote = fwrite (ptr, 1, (size_t) (size * nitems),
bfd_cache_lookup (abfd));
#ifdef FILE_OFFSET_IS_CHAR_INDEX
if (nwrote > 0)
abfd->where += nwrote;
#endif
if (nwrote != size * nitems)
if ((bfd_size_type) nwrote != size * nitems)
{
#ifdef ENOSPC
if (nwrote >= 0)
@ -293,12 +509,25 @@ bfd_flush (abfd)
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;
{
return fstat (fileno(bfd_cache_lookup(abfd)), statbuf);
FILE *f;
int result;
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
@ -306,9 +535,9 @@ bfd_stat (abfd, statbuf)
int
bfd_seek (abfd, position, direction)
bfd * CONST abfd;
CONST file_ptr position;
CONST int direction;
bfd *abfd;
file_ptr position;
int direction;
{
int result;
FILE *f;
@ -383,59 +612,6 @@ bfd_seek (abfd, position, direction)
return result;
}
/** Make a string table */
/*>bfd.h<
Add string to table pointed to by table, at location starting with free_ptr.
resizes the table if necessary (if it's NULL, creates it, ignoring
table_length). Updates free_ptr, table, table_length */
boolean
bfd_add_to_string_table (table, new_string, table_length, free_ptr)
char **table;
char *new_string;
unsigned int *table_length;
char **free_ptr;
{
size_t string_length = strlen (new_string) + 1; /* include null here */
char *base = *table;
size_t space_length = *table_length;
unsigned int offset = (base ? *free_ptr - base : 0);
if (base == NULL) {
/* Avoid a useless regrow if we can (but of course we still
take it next time). */
space_length = (string_length < DEFAULT_STRING_SPACE_SIZE ?
DEFAULT_STRING_SPACE_SIZE : string_length+1);
base = bfd_zmalloc ((bfd_size_type) space_length);
if (base == NULL) {
bfd_set_error (bfd_error_no_memory);
return false;
}
}
if ((size_t)(offset + string_length) >= space_length) {
/* Make sure we will have enough space */
while ((size_t)(offset + string_length) >= space_length)
space_length += space_length/2; /* grow by 50% */
base = (char *) realloc (base, space_length);
if (base == NULL) {
bfd_set_error (bfd_error_no_memory);
return false;
}
}
memcpy (base + offset, new_string, string_length);
*table = base;
*table_length = space_length;
*free_ptr = base + offset + string_length;
return true;
}
/** The do-it-yourself (byte) sex-change kit */
/* The middle letter e.g. get<b>short indicates Big or Little endian
@ -823,6 +999,47 @@ _bfd_generic_get_section_contents (abfd, section, location, offset, count)
return (true);
}
boolean
_bfd_generic_get_section_contents_in_window (abfd, section, w, offset, count)
bfd *abfd;
sec_ptr section;
bfd_window *w;
file_ptr offset;
bfd_size_type count;
{
if (count == 0)
return true;
if (abfd->xvec->_bfd_get_section_contents != _bfd_generic_get_section_contents)
{
/* We don't know what changes the bfd's get_section_contents
method may have to make. So punt trying to map the file
window, and let get_section_contents do its thing. */
/* @@ FIXME : If the internal window has a refcount of 1 and was
allocated with malloc instead of mmap, just reuse it. */
bfd_free_window (w);
w->i = (bfd_window_internal *) bfd_zmalloc (sizeof (bfd_window_internal));
if (w->i == NULL)
return false;
w->i->data = (PTR) malloc ((size_t) count);
if (w->i->data == NULL)
{
free (w->i);
w->i = NULL;
return false;
}
w->i->mapped = 0;
w->i->refcount = 1;
w->size = w->i->size = count;
w->data = w->i->data;
return bfd_get_section_contents (abfd, section, w->data, offset, count);
}
if ((bfd_size_type) (offset+count) > section->_raw_size
|| (bfd_get_file_window (abfd, section->filepos + offset, count, w, 1)
== false))
return false;
return true;
}
/* This generic function can only be used in implementations where creating
NEW sections is disallowed. It is useful in patching existing sections
in read-write files, though. See other set_section_contents functions

View File

@ -314,6 +314,9 @@ extern boolean _bfd_coff_generic_relocate_section
PARAMS ((bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *,
struct internal_reloc *, struct internal_syment *, asection **));
#define coff_get_section_contents_in_window \
_bfd_generic_get_section_contents_in_window
/* Functions in xcofflink.c. */
extern struct bfd_link_hash_table *_bfd_xcoff_bfd_link_hash_table_create

View File

@ -314,6 +314,9 @@ extern boolean _bfd_coff_generic_relocate_section
PARAMS ((bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *,
struct internal_reloc *, struct internal_syment *, asection **));
#define coff_get_section_contents_in_window \
_bfd_generic_get_section_contents_in_window
/* Functions in xcofflink.c. */
extern struct bfd_link_hash_table *_bfd_xcoff_bfd_link_hash_table_create

View File

@ -1484,6 +1484,7 @@ oasys_sizeof_headers (abfd, exec)
((boolean (*) \
PARAMS ((bfd *, unsigned int, struct orl *, unsigned int, int))) \
bfd_true)
#define oasys_read_ar_hdr bfd_nullvoidptr
#define oasys_update_armap_timestamp bfd_true
#define oasys_bfd_is_local_label bfd_generic_is_local_label
@ -1496,6 +1497,9 @@ oasys_sizeof_headers (abfd, exec)
#define oasys_set_arch_mach bfd_default_set_arch_mach
#define oasys_get_section_contents_in_window \
_bfd_generic_get_section_contents_in_window
#define oasys_bfd_get_relocated_section_contents \
bfd_generic_get_relocated_section_contents
#define oasys_bfd_relax_section bfd_generic_relax_section
@ -1519,7 +1523,6 @@ const bfd_target oasys_vec =
0, /* leading underscore */
' ', /* ar_pad_char */
16, /* ar_max_namelen */
1, /* minimum alignment */
bfd_getb64, bfd_getb_signed_64, bfd_putb64,
bfd_getb32, bfd_getb_signed_32, bfd_putb32,
bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* data */

View File

@ -246,7 +246,9 @@ The general target vector.
.CAT(NAME,_close_and_cleanup),\
.CAT(NAME,_bfd_free_cached_info),\
.CAT(NAME,_new_section_hook),\
.CAT(NAME,_get_section_contents)
.CAT(NAME,_get_section_contents),\
.CAT(NAME,_get_section_contents_in_window)
.
. {* Called when the BFD is being closed to do any necessary cleanup. *}
. boolean (*_close_and_cleanup) PARAMS ((bfd *));
. {* Ask the BFD to free all cached information. *}
@ -256,6 +258,9 @@ The general target vector.
. {* Read the contents of a section. *}
. boolean (*_bfd_get_section_contents) PARAMS ((bfd *, sec_ptr, PTR,
. file_ptr, bfd_size_type));
. boolean (*_bfd_get_section_contents_in_window)
. PARAMS ((bfd *, sec_ptr, bfd_window *,
. file_ptr, bfd_size_type));
.
. {* Entry points to copy private data. *}
.#define BFD_JUMP_TABLE_COPY(NAME)\
@ -315,7 +320,7 @@ The general target vector.
. struct orl *map,
. unsigned int orl_count,
. int stridx));
. PTR (*_bfd_read_ar_hdr) PARAMS ((bfd *));
. PTR (*_bfd_read_ar_hdr_fn) PARAMS ((bfd *));
. bfd * (*openr_next_archived_file) PARAMS ((bfd *arch, bfd *prev));
. int (*_bfd_stat_arch_elt) PARAMS ((bfd *, struct stat *));
. boolean (*_bfd_update_armap_timestamp) PARAMS ((bfd *));