forked from Imagelibrary/binutils-gdb
Various changes to improve archive support. See ChangeLog.
This commit is contained in:
@@ -1,3 +1,24 @@
|
||||
Tue Dec 15 15:40:30 1992 Per Bothner (bothner@cygnus.com)
|
||||
|
||||
* archive.c (do_slurp_bsd_armap, do_slurp_coff_armap): New
|
||||
functions, with the "guts" of the old bfd_slurp_bsd_armap
|
||||
and bfd_slurp_coff_armap, but assuming we've already checked
|
||||
if the armap is present or not.
|
||||
Also, rewrite a bit to avoid keeping around obstack data
|
||||
that we don't need.
|
||||
* archive.c (snarf_ar_header, _bfd_slurp_extended_name_table):
|
||||
Various fixes to correctly handle COFF_style archives names.
|
||||
(Note that because these have a trailing '/', the names can
|
||||
have embedded spaces.)
|
||||
* archive.c (bfd_slurp_armap): New function, replaces old
|
||||
bfd_slurp_bsd_armap and bfd_slurp_coff_armap. Recognizes
|
||||
_either_ format, and calls do_slurp_bsd_armap or
|
||||
do_slurp_coff_armap if either form of map is seen.
|
||||
* libbfd-in.h: Changed bfd_slurp_bsd_armap and
|
||||
bfd_slurp_coff_armap into macro synonyms for bfd_slurp_armap.
|
||||
* elf.c (elf_slurp_armap, elf_write_armap): Fix.
|
||||
* Makefile.in (AR_FLAGS): Use rc instead of non-standard qc.
|
||||
|
||||
Mon Dec 14 17:08:08 1992 Stu Grossman (grossman at cygnus.com)
|
||||
|
||||
* hppa.c: #include "sysdep.h", not <sysdep.h>.
|
||||
|
||||
@@ -49,7 +49,7 @@ INSTALL_PROGRAM = $(INSTALL)
|
||||
INSTALL_DATA = $(INSTALL)
|
||||
|
||||
AR = ar
|
||||
AR_FLAGS = qc
|
||||
AR_FLAGS = rc
|
||||
CFLAGS = -g
|
||||
BISON = bison
|
||||
MAKEINFO = makeinfo
|
||||
@@ -89,6 +89,8 @@ OPTIONAL_BACKENDS = trad-core.o
|
||||
###
|
||||
|
||||
FLAGS_TO_PASS = \
|
||||
"prefix=$(prefix)" \
|
||||
"exec_prefix=$(exec_prefix)" \
|
||||
"against=$(against)" \
|
||||
"AR=$(AR)" \
|
||||
"AR_FLAGS=$(AR_FLAGS)" \
|
||||
|
||||
349
bfd/archive.c
349
bfd/archive.c
@@ -1,5 +1,5 @@
|
||||
/* BFD back-end for archive files (libraries).
|
||||
Copyright (C) 1990-1991 Free Software Foundation, Inc.
|
||||
Copyright 1990, 1991, 1992 Free Software Foundation, Inc.
|
||||
Written by Cygnus Support. Mostly Gumby Henkel-Wallace's fault.
|
||||
|
||||
This file is part of BFD, the Binary File Descriptor library.
|
||||
@@ -50,12 +50,12 @@ DESCRIPTION
|
||||
|
||||
As expected, the BFD archive code is more general than the
|
||||
archive code of any given environment. BFD archives may
|
||||
contain files of different formats (eg a.out and coff) and
|
||||
contain files of different formats (e.g., a.out and coff) and
|
||||
even different architectures. You may even place archives
|
||||
recursively into archives!
|
||||
|
||||
This can cause unexpected confusion, since some archive
|
||||
formats are more expressive than others. For instance intel
|
||||
formats are more expressive than others. For instance, Intel
|
||||
COFF archives can preserve long filenames; Sun a.out archives
|
||||
cannot. If you move a file from the first to the second
|
||||
format and back again, the filename may be truncated.
|
||||
@@ -273,9 +273,10 @@ get_extended_arelt_filename (arch, name)
|
||||
unsigned long index = 0;
|
||||
|
||||
/* Should extract string so that I can guarantee not to overflow into
|
||||
the next region, but I"m too lazy. */
|
||||
the next region, but I'm too lazy. */
|
||||
errno = 0;
|
||||
index = strtol (name, NULL, 10);
|
||||
/* Skip first char, which is '/' in SVR4 or ' ' in some other variants. */
|
||||
index = strtol (name+1, NULL, 10);
|
||||
if (errno != 0) {
|
||||
bfd_error = malformed_archive;
|
||||
return NULL;
|
||||
@@ -329,8 +330,10 @@ snarf_ar_hdr (abfd)
|
||||
|
||||
/* extract the filename from the archive - there are two ways to
|
||||
specify an extendend name table, either the first char of the
|
||||
name is a space, or it's a slash */
|
||||
if ((hdr.ar_name[0] == '/' || hdr.ar_name[0] == ' ')
|
||||
name is a space, or it's a slash. */
|
||||
if ((hdr.ar_name[0] == '/'
|
||||
|| (hdr.ar_name[0] == ' '
|
||||
&& memchr (hdr.ar_name, '/', ar_maxnamelen(abfd)) == NULL))
|
||||
&& bfd_ardata (abfd)->extended_names != NULL) {
|
||||
filename = get_extended_arelt_filename (abfd, hdr.ar_name);
|
||||
if (filename == NULL) {
|
||||
@@ -340,16 +343,22 @@ snarf_ar_hdr (abfd)
|
||||
}
|
||||
else
|
||||
{
|
||||
/* We judge the end of the name by looking for a space or a
|
||||
padchar */
|
||||
/* We judge the end of the name by looking for '/' or ' '.
|
||||
Note: The SYSV format (terminated by '/') allows embedded
|
||||
spaces, so only look for ' ' if we don't find '/'. */
|
||||
|
||||
namelen = 0;
|
||||
|
||||
while (namelen < (unsigned)ar_maxnamelen(abfd) &&
|
||||
( hdr.ar_name[namelen] != 0 &&
|
||||
hdr.ar_name[namelen] != ' ' &&
|
||||
hdr.ar_name[namelen] != ar_padchar(abfd))) {
|
||||
while (hdr.ar_name[namelen] != '\0' &&
|
||||
hdr.ar_name[namelen] != '/') {
|
||||
namelen++;
|
||||
if (namelen == (unsigned)ar_maxnamelen(abfd)) {
|
||||
namelen = 0;
|
||||
while (hdr.ar_name[namelen] != ' '
|
||||
&& namelen < (unsigned)ar_maxnamelen(abfd)) {
|
||||
namelen++;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
allocsize += namelen + 1;
|
||||
@@ -529,7 +538,7 @@ bfd_generic_archive_p (abfd)
|
||||
|
||||
bfd_ardata (abfd)->first_file_filepos = SARMAG;
|
||||
|
||||
if (!BFD_SEND (abfd, _bfd_slurp_armap, (abfd))) {
|
||||
if (!bfd_slurp_armap (abfd)) {
|
||||
bfd_release(abfd, bfd_ardata (abfd));
|
||||
abfd->tdata.aout_ar_data = NULL;
|
||||
return 0;
|
||||
@@ -545,85 +554,71 @@ bfd_generic_archive_p (abfd)
|
||||
}
|
||||
|
||||
/* Returns false on error, true otherwise */
|
||||
boolean
|
||||
bfd_slurp_bsd_armap (abfd)
|
||||
static boolean
|
||||
do_slurp_bsd_armap (abfd)
|
||||
bfd *abfd;
|
||||
{
|
||||
|
||||
struct areltdata *mapdata;
|
||||
char nextname[17];
|
||||
unsigned int counter = 0;
|
||||
int *raw_armap, *rbase;
|
||||
struct artdata *ardata = bfd_ardata (abfd);
|
||||
char *stringbase;
|
||||
struct areltdata *mapdata;
|
||||
char nextname[17];
|
||||
unsigned int counter = 0;
|
||||
int *raw_armap, *rbase;
|
||||
struct artdata *ardata = bfd_ardata (abfd);
|
||||
char *stringbase;
|
||||
unsigned int parsed_size;
|
||||
|
||||
/* FIXME, if the read fails, this routine quietly returns "true"!!
|
||||
It should probably do that if the read gives 0 bytes (empty archive),
|
||||
but fail for any other size... */
|
||||
if (bfd_read ((PTR)nextname, 1, 16, abfd) == 16) {
|
||||
/* The archive has at least 16 bytes in it */
|
||||
bfd_seek (abfd, (file_ptr) -16, SEEK_CUR);
|
||||
|
||||
/* This should be using RANLIBMAG, but at least it can be grepped for
|
||||
in this comment. */
|
||||
if (strncmp (nextname, "__.SYMDEF ", 16)) {
|
||||
bfd_has_map (abfd) = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
mapdata = snarf_ar_hdr (abfd);
|
||||
if (mapdata == NULL) return false;
|
||||
|
||||
raw_armap = (int *) bfd_zalloc(abfd,mapdata->parsed_size);
|
||||
if (raw_armap == NULL) {
|
||||
bfd_error = no_memory;
|
||||
byebye:
|
||||
bfd_release (abfd, (PTR)mapdata);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (bfd_read ((PTR)raw_armap, 1, mapdata->parsed_size, abfd) !=
|
||||
mapdata->parsed_size) {
|
||||
bfd_error = malformed_archive;
|
||||
byebyebye:
|
||||
bfd_release (abfd, (PTR)raw_armap);
|
||||
goto byebye;
|
||||
}
|
||||
|
||||
ardata->symdef_count = bfd_h_get_32(abfd, (PTR)raw_armap) / sizeof (struct symdef);
|
||||
|
||||
if (ardata->symdef_count * sizeof (struct symdef)
|
||||
> mapdata->parsed_size - sizeof (*raw_armap)) {
|
||||
/* Probably we're using the wrong byte ordering. */
|
||||
bfd_error = wrong_format;
|
||||
goto byebyebye;
|
||||
}
|
||||
|
||||
ardata->cache = 0;
|
||||
rbase = raw_armap+1;
|
||||
ardata->symdefs = (carsym *) rbase;
|
||||
stringbase = ((char *) (ardata->symdefs + ardata->symdef_count)) + 4;
|
||||
|
||||
for (;counter < ardata->symdef_count; counter++) {
|
||||
struct symdef *sym = ((struct symdef *) rbase) + counter;
|
||||
sym->s.name = bfd_h_get_32(abfd, (PTR)(&(sym->s.string_offset))) + stringbase;
|
||||
sym->file_offset = bfd_h_get_32(abfd, (PTR)( &(sym->file_offset)));
|
||||
}
|
||||
mapdata = snarf_ar_hdr (abfd);
|
||||
if (mapdata == NULL) return false;
|
||||
parsed_size = mapdata->parsed_size;
|
||||
bfd_release (abfd, (PTR)mapdata); /* Don't need it any more. */
|
||||
|
||||
raw_armap = (int *) bfd_zalloc(abfd, parsed_size);
|
||||
if (raw_armap == NULL) {
|
||||
bfd_error = no_memory;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (bfd_read ((PTR)raw_armap, 1, parsed_size, abfd) != parsed_size) {
|
||||
bfd_error = malformed_archive;
|
||||
byebye:
|
||||
bfd_release (abfd, (PTR)raw_armap);
|
||||
return false;
|
||||
}
|
||||
|
||||
ardata->symdef_count =
|
||||
bfd_h_get_32(abfd, (PTR)raw_armap) / sizeof (struct symdef);
|
||||
|
||||
if (ardata->symdef_count * sizeof (struct symdef)
|
||||
> parsed_size - sizeof (*raw_armap)) {
|
||||
/* Probably we're using the wrong byte ordering. */
|
||||
bfd_error = wrong_format;
|
||||
goto byebye;
|
||||
}
|
||||
|
||||
ardata->first_file_filepos = bfd_tell (abfd);
|
||||
/* Pad to an even boundary if you have to */
|
||||
ardata->first_file_filepos += (ardata-> first_file_filepos) %2;
|
||||
/* FIXME, we should provide some way to free raw_ardata when
|
||||
we are done using the strings from it. For now, it seems
|
||||
to be allocated on an obstack anyway... */
|
||||
bfd_has_map (abfd) = true;
|
||||
}
|
||||
return true;
|
||||
ardata->cache = 0;
|
||||
rbase = raw_armap+1;
|
||||
ardata->symdefs = (carsym *) rbase;
|
||||
stringbase = ((char *) (ardata->symdefs + ardata->symdef_count)) + 4;
|
||||
|
||||
for (;counter < ardata->symdef_count; counter++) {
|
||||
struct symdef *sym = ((struct symdef *) rbase) + counter;
|
||||
sym->s.name = bfd_h_get_32(abfd, (PTR)(&(sym->s.string_offset))) + stringbase;
|
||||
sym->file_offset = bfd_h_get_32(abfd, (PTR)( &(sym->file_offset)));
|
||||
}
|
||||
|
||||
ardata->first_file_filepos = bfd_tell (abfd);
|
||||
/* Pad to an even boundary if you have to */
|
||||
ardata->first_file_filepos += (ardata-> first_file_filepos) %2;
|
||||
/* FIXME, we should provide some way to free raw_ardata when
|
||||
we are done using the strings from it. For now, it seems
|
||||
to be allocated on an obstack anyway... */
|
||||
bfd_has_map (abfd) = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Returns false on error, true otherwise */
|
||||
boolean
|
||||
bfd_slurp_coff_armap (abfd)
|
||||
static boolean
|
||||
do_slurp_coff_armap (abfd)
|
||||
bfd *abfd;
|
||||
{
|
||||
struct areltdata *mapdata;
|
||||
@@ -632,104 +627,119 @@ bfd_slurp_coff_armap (abfd)
|
||||
struct artdata *ardata = bfd_ardata (abfd);
|
||||
char *stringbase;
|
||||
unsigned int stringsize;
|
||||
unsigned int parsed_size;
|
||||
carsym *carsyms;
|
||||
int result;
|
||||
unsigned int nsymz; /* Number of symbols in armap. */
|
||||
|
||||
bfd_vma (*swap)();
|
||||
char int_buf[sizeof(long)];
|
||||
unsigned int carsym_size, ptrsize, i;
|
||||
|
||||
result = bfd_read ((PTR)&nextname, 1, 1, abfd);
|
||||
bfd_seek (abfd, (file_ptr) -1, SEEK_CUR);
|
||||
|
||||
if (result != 1 || nextname != '/') {
|
||||
/* Actually I think this is an error for a COFF archive */
|
||||
bfd_has_map (abfd) = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
mapdata = snarf_ar_hdr (abfd);
|
||||
if (mapdata == NULL) return false;
|
||||
parsed_size = mapdata->parsed_size;
|
||||
bfd_release (abfd, (PTR)mapdata); /* Don't need it any more. */
|
||||
|
||||
raw_armap = (int *) bfd_alloc(abfd,mapdata->parsed_size);
|
||||
|
||||
if (raw_armap == NULL)
|
||||
{
|
||||
bfd_error = no_memory;
|
||||
byebye:
|
||||
bfd_release (abfd, (PTR)mapdata);
|
||||
if (bfd_read ((PTR)int_buf, 1, 4, abfd) != 4) {
|
||||
bfd_error = malformed_archive;
|
||||
return false;
|
||||
}
|
||||
|
||||
/* read in the raw map */
|
||||
if (bfd_read ((PTR)raw_armap, 1, mapdata->parsed_size, abfd) !=
|
||||
mapdata->parsed_size) {
|
||||
bfd_error = malformed_archive;
|
||||
oops:
|
||||
bfd_release (abfd, (PTR)raw_armap);
|
||||
goto byebye;
|
||||
}
|
||||
|
||||
/* The coff armap must be read sequentially. So we construct a bsd-style
|
||||
one in core all at once, for simplicity.
|
||||
|
||||
It seems that all numeric information in a coff archive is always
|
||||
/* It seems that all numeric information in a coff archive is always
|
||||
in big endian format, nomatter the host or target. */
|
||||
swap = _do_getb32;
|
||||
nsymz = _do_getb32((PTR)int_buf);
|
||||
stringsize = parsed_size - (4 * nsymz) - 4;
|
||||
|
||||
stringsize
|
||||
= mapdata->parsed_size - (4 * (_do_getb32((PTR)raw_armap))) - 4;
|
||||
/* Except that some archive formats are broken, and it may be our
|
||||
#if 1
|
||||
/* ... except that some archive formats are broken, and it may be our
|
||||
fault - the i960 little endian coff sometimes has big and sometimes
|
||||
little, because our tools changed. Here's a horrible hack to clean
|
||||
up the crap
|
||||
*/
|
||||
swap = _do_getb32;
|
||||
up the crap. */
|
||||
|
||||
if (stringsize > 0xfffff)
|
||||
{
|
||||
/* This looks dangerous, let's do it the other way around */
|
||||
stringsize = mapdata->parsed_size - (4 *
|
||||
(_do_getl32((PTR)raw_armap))) - 4;
|
||||
|
||||
swap = _do_getl32;
|
||||
if (stringsize > 0xfffff) {
|
||||
/* This looks dangerous, let's do it the other way around */
|
||||
nsymz = _do_getl32((PTR)int_buf);
|
||||
stringsize = parsed_size - (4 * nsymz) - 4;
|
||||
swap = _do_getl32;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* The coff armap must be read sequentially. So we construct a bsd-style
|
||||
one in core all at once, for simplicity. */
|
||||
|
||||
carsym_size = (nsymz * sizeof (carsym));
|
||||
ptrsize = (4 * nsymz);
|
||||
|
||||
{
|
||||
unsigned int nsymz = swap( (PTR)raw_armap);
|
||||
unsigned int carsym_size = (nsymz * sizeof (carsym));
|
||||
unsigned int ptrsize = (4 * nsymz);
|
||||
unsigned int i;
|
||||
ardata->symdefs = (carsym *) bfd_zalloc(abfd,carsym_size + stringsize + 1);
|
||||
if (ardata->symdefs == NULL) {
|
||||
bfd_error = no_memory;
|
||||
goto oops;
|
||||
}
|
||||
carsyms = ardata->symdefs;
|
||||
ardata->symdefs = (carsym *) bfd_zalloc(abfd, carsym_size + stringsize + 1);
|
||||
if (ardata->symdefs == NULL) {
|
||||
bfd_error = no_memory;
|
||||
return false;
|
||||
}
|
||||
carsyms = ardata->symdefs;
|
||||
stringbase = ((char *) ardata->symdefs) + carsym_size;
|
||||
|
||||
stringbase = ((char *) ardata->symdefs) + carsym_size;
|
||||
memcpy (stringbase, (char*)raw_armap + ptrsize + 4, stringsize);
|
||||
/* Allocate and read in the raw offsets. */
|
||||
raw_armap = (int *) bfd_alloc(abfd, ptrsize);
|
||||
if (raw_armap == NULL) {
|
||||
bfd_error = no_memory;
|
||||
goto release_symdefs;
|
||||
}
|
||||
if (bfd_read ((PTR)raw_armap, 1, ptrsize, abfd) != ptrsize
|
||||
|| bfd_read ((PTR)stringbase, 1, stringsize, abfd) != stringsize) {
|
||||
bfd_error = malformed_archive;
|
||||
goto release_raw_armap;
|
||||
}
|
||||
|
||||
/* OK, build the carsyms */
|
||||
for (i = 0; i < nsymz; i++) {
|
||||
rawptr = raw_armap + i;
|
||||
carsyms->file_offset = swap((PTR)rawptr);
|
||||
carsyms->name = stringbase;
|
||||
while (*stringbase++) ;
|
||||
carsyms++;
|
||||
}
|
||||
*stringbase = 0;
|
||||
|
||||
/* OK, build the carsyms */
|
||||
for (i = 0; i < nsymz; i++)
|
||||
{
|
||||
rawptr = raw_armap + i + 1;
|
||||
carsyms->file_offset = swap((PTR)rawptr);
|
||||
carsyms->name = stringbase;
|
||||
for (; *(stringbase++););
|
||||
carsyms++;
|
||||
}
|
||||
*stringbase = 0;
|
||||
}
|
||||
ardata->symdef_count = swap((PTR)raw_armap);
|
||||
ardata->first_file_filepos = bfd_tell (abfd);
|
||||
/* Pad to an even boundary if you have to */
|
||||
ardata->first_file_filepos += (ardata->first_file_filepos) %2;
|
||||
|
||||
/* We'd like to release these allocations, but we have allocated stuff
|
||||
since then (using the same obstack, if bfd_release is obstack based).
|
||||
So they will stick around until the BFD is closed. */
|
||||
/* bfd_release (abfd, (PTR)raw_armap);
|
||||
bfd_release (abfd, (PTR)mapdata); */
|
||||
bfd_has_map (abfd) = true;
|
||||
bfd_release (abfd, (PTR)raw_armap);
|
||||
return true;
|
||||
|
||||
release_raw_armap:
|
||||
bfd_release (abfd, (PTR)raw_armap);
|
||||
release_symdefs:
|
||||
bfd_release (abfd, (PTR)(ardata)->symdefs);
|
||||
return false;
|
||||
}
|
||||
|
||||
/* This routine can handle either coff-style or bsd-style armaps.
|
||||
Returns false on error, true otherwise */
|
||||
|
||||
boolean
|
||||
bfd_slurp_armap (abfd)
|
||||
bfd *abfd;
|
||||
{
|
||||
char nextname[17];
|
||||
int i = bfd_read ((PTR)nextname, 1, 16, abfd);
|
||||
|
||||
if (i == 0)
|
||||
return true;
|
||||
if (i != 16)
|
||||
return false;
|
||||
|
||||
bfd_seek (abfd, (file_ptr) -16, SEEK_CUR);
|
||||
|
||||
if (!strncmp (nextname, "__.SYMDEF ", 16))
|
||||
return do_slurp_bsd_armap (abfd);
|
||||
else if (!strncmp (nextname, "/ ", 16))
|
||||
return do_slurp_coff_armap (abfd);
|
||||
|
||||
bfd_has_map (abfd) = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -785,11 +795,14 @@ _bfd_slurp_extended_name_table (abfd)
|
||||
|
||||
/* Since the archive is supposed to be printable if it contains
|
||||
text, the entries in the list are newline-padded, not null
|
||||
padded. We'll fix that there.. */
|
||||
padded. In SVR4-style archives, the names also have a
|
||||
trailing '/'. We'll fix both problems here.. */
|
||||
{
|
||||
char *temp = bfd_ardata (abfd)->extended_names;
|
||||
for (; *temp != '\0'; ++temp)
|
||||
if (*temp == '\n') *temp = '\0';
|
||||
char *limit = temp + namedata->parsed_size;
|
||||
for (; temp < limit; ++temp)
|
||||
if (*temp == '\n')
|
||||
temp[temp[-1] == '/' ? -1 : 0] = '\0';
|
||||
}
|
||||
|
||||
/* Pad to an even boundary if you have to */
|
||||
@@ -1132,7 +1145,12 @@ _bfd_write_archive_contents (arch)
|
||||
bfd *current;
|
||||
char *etable = NULL;
|
||||
unsigned int elength = 0;
|
||||
boolean makemap = bfd_has_map (arch);
|
||||
|
||||
/* This used to be: boolean makemap = bfd_has_map (arch).
|
||||
But Posix.2 prohibits requiring a separate ranlib program, so we
|
||||
need to make a map whenever there are object files in the archive. */
|
||||
boolean makemap = true;
|
||||
|
||||
boolean hasobjects = false; /* if no .o's, don't bother to make a map */
|
||||
unsigned int i;
|
||||
|
||||
@@ -1295,9 +1313,10 @@ compute_and_write_armap (arch, elength)
|
||||
asection *sec =
|
||||
syms[src_count]->section;
|
||||
|
||||
if ((flags & BSF_GLOBAL) ||
|
||||
(flags & BSF_INDIRECT) ||
|
||||
(sec == &bfd_com_section)) {
|
||||
if ((flags & BSF_GLOBAL ||
|
||||
flags & BSF_INDIRECT ||
|
||||
sec == &bfd_com_section)
|
||||
&& (sec != &bfd_und_section)) {
|
||||
|
||||
/* This symbol will go into the archive header */
|
||||
if (orl_count == orl_max)
|
||||
|
||||
35
bfd/elf.c
35
bfd/elf.c
@@ -1,5 +1,5 @@
|
||||
/* ELF executable support for BFD.
|
||||
Copyright (C) 1991, 1992 Free Software Foundation, Inc.
|
||||
Copyright 1991, 1992 Free Software Foundation, Inc.
|
||||
|
||||
Written by Fred Fish @ Cygnus Support, from information published
|
||||
in "UNIX System V Release 4, Programmers Guide: ANSI C and
|
||||
@@ -90,6 +90,26 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
#define bfd_prpsinfo(abfd, descdata, descsz, filepos) /* Define away */
|
||||
#endif
|
||||
|
||||
/* Forward declarations of static functions */
|
||||
|
||||
static char *
|
||||
elf_read PARAMS ((bfd *, long, int));
|
||||
|
||||
static struct sec *
|
||||
section_from_elf_index PARAMS ((bfd *, int));
|
||||
|
||||
static int
|
||||
elf_section_from_bfd_section PARAMS ((bfd *, struct sec *));
|
||||
|
||||
static boolean
|
||||
elf_slurp_symbol_table PARAMS ((bfd *, asymbol **));
|
||||
|
||||
static void
|
||||
elf_info_to_howto PARAMS ((bfd *, arelent *, Elf_Internal_Rela *));
|
||||
|
||||
static char *
|
||||
elf_get_str_section PARAMS ((bfd *, unsigned int));
|
||||
|
||||
/* Forward data declarations */
|
||||
|
||||
extern bfd_target elf_little_vec, elf_big_vec;
|
||||
@@ -320,13 +340,6 @@ DEFUN(elf_swap_reloca_out,(abfd, src, dst),
|
||||
bfd_h_put_32 (abfd, src->r_addend, dst->r_addend);
|
||||
}
|
||||
|
||||
static char *EXFUN(elf_read, (bfd *, long, int));
|
||||
static struct sec * EXFUN(section_from_elf_index, (bfd *, int));
|
||||
static int EXFUN(elf_section_from_bfd_section, (bfd *, struct sec *));
|
||||
static boolean EXFUN(elf_slurp_symbol_table, (bfd *, asymbol **));
|
||||
static void EXFUN(elf_info_to_howto, (bfd *, arelent *, Elf_Internal_Rela *));
|
||||
static char *EXFUN(elf_get_str_section, (bfd *, unsigned int));
|
||||
|
||||
/*
|
||||
INTERNAL_FUNCTION
|
||||
bfd_elf_find_section
|
||||
@@ -2434,14 +2447,12 @@ DEFUN(elf_set_section_contents, (abfd, section, location, offset, count),
|
||||
one for little-endian machines. */
|
||||
|
||||
/* Archives are generic or unimplemented. */
|
||||
#define elf_slurp_armap bfd_false
|
||||
#define elf_slurp_armap bfd_slurp_coff_armap
|
||||
#define elf_slurp_extended_name_table _bfd_slurp_extended_name_table
|
||||
#define elf_truncate_arname bfd_dont_truncate_arname
|
||||
#define elf_openr_next_archived_file bfd_generic_openr_next_archived_file
|
||||
#define elf_generic_stat_arch_elt bfd_generic_stat_arch_elt
|
||||
#define elf_write_armap (PROTO (boolean, (*), \
|
||||
(bfd *arch, unsigned int elength, struct orl *map, unsigned int orl_count, \
|
||||
int stridx))) bfd_false
|
||||
#define elf_write_armap coff_write_armap
|
||||
|
||||
/* Ordinary section reading and writing */
|
||||
#define elf_new_section_hook _bfd_dummy_new_section_hook
|
||||
|
||||
151
bfd/libbfd.h
151
bfd/libbfd.h
@@ -57,100 +57,98 @@ struct areltdata {
|
||||
|
||||
#define arelt_size(bfd) (((struct areltdata *)((bfd)->arelt_data))->parsed_size)
|
||||
|
||||
/* FIXME -- a lot of my code allocates a large block and subdivides it.
|
||||
This can't always work, because of alignment restrictions. We should change
|
||||
it before it becomes a problem -- Gumby */
|
||||
|
||||
PROTO (char *, zalloc, (bfd_size_type size));
|
||||
char *zalloc PARAMS ((bfd_size_type size));
|
||||
|
||||
/* These routines allocate and free things on the BFD's obstack. Note
|
||||
that realloc can never occur in place. */
|
||||
|
||||
PROTO(PTR, bfd_alloc, (bfd *abfd, bfd_size_type size));
|
||||
PROTO(PTR, bfd_zalloc,(bfd *abfd, bfd_size_type size));
|
||||
PROTO(PTR, bfd_realloc,(bfd *abfd, PTR orig, bfd_size_type new));
|
||||
PROTO(void, bfd_alloc_grow,(bfd *abfd, PTR thing, bfd_size_type size));
|
||||
PROTO(PTR, bfd_alloc_finish,(bfd *abfd));
|
||||
PROTO(PTR, bfd_alloc_by_size_t,(bfd *abfd, size_t wanted));
|
||||
PTR bfd_alloc PARAMS ((bfd *abfd, bfd_size_type size));
|
||||
PTR bfd_zalloc PARAMS ((bfd *abfd, bfd_size_type size));
|
||||
PTR bfd_realloc PARAMS ((bfd *abfd, PTR orig, bfd_size_type new));
|
||||
void bfd_alloc_grow PARAMS ((bfd *abfd, PTR thing, bfd_size_type size));
|
||||
PTR bfd_alloc_finish PARAMS ((bfd *abfd));
|
||||
PTR bfd_alloc_by_size_t PARAMS ((bfd *abfd, size_t wanted));
|
||||
|
||||
#define bfd_release(x,y) (void) obstack_free(&(x->memory),y)
|
||||
#define bfd_release(x,y) (void) obstack_free(&(x->memory),y)
|
||||
|
||||
|
||||
PROTO (bfd_size_type, bfd_read, (PTR ptr, bfd_size_type size, bfd_size_type nitems, bfd *abfd));
|
||||
PROTO (bfd_size_type, bfd_write, (CONST PTR ptr, bfd_size_type size, bfd_size_type nitems, bfd *abfd));
|
||||
bfd_size_type bfd_read PARAMS ((PTR ptr, bfd_size_type size,
|
||||
bfd_size_type nitems, bfd *abfd));
|
||||
bfd_size_type bfd_write PARAMS ((CONST PTR ptr, bfd_size_type size,
|
||||
bfd_size_type nitems, bfd *abfd));
|
||||
int bfd_seek PARAMS ((bfd* CONST abfd, CONST file_ptr fp,
|
||||
CONST int direction));
|
||||
long bfd_tell PARAMS ((bfd *abfd));
|
||||
|
||||
|
||||
|
||||
PROTO (int, bfd_seek,(bfd* CONST abfd, CONST file_ptr fp , CONST int direction));
|
||||
PROTO (long, bfd_tell, (bfd *abfd));
|
||||
PROTO (bfd *, _bfd_create_empty_archive_element_shell, (bfd *obfd));
|
||||
PROTO (bfd *, look_for_bfd_in_cache, (bfd *arch_bfd, file_ptr index));
|
||||
PROTO (boolean, _bfd_generic_mkarchive, (bfd *abfd));
|
||||
PROTO (struct areltdata *, snarf_ar_hdr, (bfd *abfd));
|
||||
PROTO (bfd_target *, bfd_generic_archive_p, (bfd *abfd));
|
||||
PROTO (boolean, bfd_slurp_bsd_armap, (bfd *abfd));
|
||||
PROTO (boolean, bfd_slurp_coff_armap, (bfd *abfd));
|
||||
PROTO (boolean, _bfd_slurp_extended_name_table, (bfd *abfd));
|
||||
PROTO (boolean, _bfd_write_archive_contents, (bfd *abfd));
|
||||
PROTO (bfd *, new_bfd, ());
|
||||
bfd * _bfd_create_empty_archive_element_shell PARAMS ((bfd *obfd));
|
||||
bfd * look_for_bfd_in_cache PARAMS ((bfd *arch_bfd, file_ptr index));
|
||||
boolean _bfd_generic_mkarchive PARAMS ((bfd *abfd));
|
||||
struct areltdata * snarf_ar_hdr PARAMS ((bfd *abfd));
|
||||
bfd_target * bfd_generic_archive_p PARAMS ((bfd *abfd));
|
||||
boolean bfd_slurp_armap PARAMS ((bfd *abfd));
|
||||
#define bfd_slurp_bsd_armap bfd_slurp_armap
|
||||
#define bfd_slurp_coff_armap bfd_slurp_armap
|
||||
boolean _bfd_slurp_extended_name_table PARAMS ((bfd *abfd));
|
||||
boolean _bfd_write_archive_contents PARAMS ((bfd *abfd));
|
||||
bfd * new_bfd PARAMS (());
|
||||
|
||||
#define DEFAULT_STRING_SPACE_SIZE 0x2000
|
||||
PROTO (boolean, bfd_add_to_string_table, (char **table, char *new_string,
|
||||
unsigned int *table_length,
|
||||
char **free_ptr));
|
||||
PROTO (bfd_vma, _do_getb64, (unsigned char *addr));
|
||||
PROTO (bfd_vma, _do_getl64, (unsigned char *addr));
|
||||
PROTO (bfd_vma, _do_getb32, (unsigned char *addr));
|
||||
PROTO (bfd_vma, _do_getl32, (unsigned char *addr));
|
||||
PROTO (bfd_vma, _do_getb16, (unsigned char *addr));
|
||||
PROTO (bfd_vma, _do_getl16, (unsigned char *addr));
|
||||
PROTO (void, _do_putb64, (bfd_vma data, unsigned char *addr));
|
||||
PROTO (void, _do_putl64, (bfd_vma data, unsigned char *addr));
|
||||
PROTO (void, _do_putb32, (bfd_vma data, unsigned char *addr));
|
||||
PROTO (void, _do_putl32, (bfd_vma data, unsigned char *addr));
|
||||
PROTO (void, _do_putb16, (bfd_vma data, unsigned char *addr));
|
||||
PROTO (void, _do_putl16, (bfd_vma data, unsigned char *addr));
|
||||
boolean bfd_add_to_string_table PARAMS ((char **table, char *new_string,
|
||||
unsigned int *table_length,
|
||||
char **free_ptr));
|
||||
bfd_vma _do_getb64 PARAMS ((unsigned char *addr));
|
||||
bfd_vma _do_getl64 PARAMS ((unsigned char *addr));
|
||||
bfd_vma _do_getb32 PARAMS ((unsigned char *addr));
|
||||
bfd_vma _do_getl32 PARAMS ((unsigned char *addr));
|
||||
bfd_vma _do_getb16 PARAMS ((unsigned char *addr));
|
||||
bfd_vma _do_getl16 PARAMS ((unsigned char *addr));
|
||||
void _do_putb64 PARAMS ((bfd_vma data, unsigned char *addr));
|
||||
void _do_putl64 PARAMS ((bfd_vma data, unsigned char *addr));
|
||||
void _do_putb32 PARAMS ((bfd_vma data, unsigned char *addr));
|
||||
void _do_putl32 PARAMS ((bfd_vma data, unsigned char *addr));
|
||||
void _do_putb16 PARAMS ((bfd_vma data, unsigned char *addr));
|
||||
void _do_putl16 PARAMS ((bfd_vma data, unsigned char *addr));
|
||||
|
||||
PROTO (boolean, bfd_false, (bfd *ignore));
|
||||
PROTO (boolean, bfd_true, (bfd *ignore));
|
||||
PROTO (PTR, bfd_nullvoidptr, (bfd *ignore));
|
||||
PROTO (int, bfd_0, (bfd *ignore));
|
||||
PROTO (unsigned int, bfd_0u, (bfd *ignore));
|
||||
PROTO (void, bfd_void, (bfd *ignore));
|
||||
boolean bfd_false PARAMS ((bfd *ignore));
|
||||
boolean bfd_true PARAMS ((bfd *ignore));
|
||||
PTR bfd_nullvoidptr PARAMS ((bfd *ignore));
|
||||
int bfd_0 PARAMS ((bfd *ignore));
|
||||
unsigned int bfd_0u PARAMS ((bfd *ignore));
|
||||
void bfd_void PARAMS ((bfd *ignore));
|
||||
|
||||
PROTO (bfd *,new_bfd_contained_in,(bfd *));
|
||||
PROTO (boolean, _bfd_dummy_new_section_hook, (bfd *ignore, asection *newsect));
|
||||
PROTO (char *, _bfd_dummy_core_file_failing_command, (bfd *abfd));
|
||||
PROTO (int, _bfd_dummy_core_file_failing_signal, (bfd *abfd));
|
||||
PROTO (boolean, _bfd_dummy_core_file_matches_executable_p, (bfd *core_bfd,
|
||||
bfd * new_bfd_contained_in PARAMS ((bfd *));
|
||||
boolean _bfd_dummy_new_section_hook PARAMS ((bfd *ignore, asection *newsect));
|
||||
char * _bfd_dummy_core_file_failing_command PARAMS ((bfd *abfd));
|
||||
int _bfd_dummy_core_file_failing_signal PARAMS ((bfd *abfd));
|
||||
boolean _bfd_dummy_core_file_matches_executable_p PARAMS ((bfd *core_bfd,
|
||||
bfd *exec_bfd));
|
||||
PROTO (bfd_target *, _bfd_dummy_target, (bfd *abfd));
|
||||
bfd_target * _bfd_dummy_target PARAMS ((bfd *abfd));
|
||||
|
||||
PROTO (void, bfd_dont_truncate_arname, (bfd *abfd, CONST char *filename,
|
||||
void bfd_dont_truncate_arname PARAMS ((bfd *abfd, CONST char *filename,
|
||||
char *hdr));
|
||||
PROTO (void, bfd_bsd_truncate_arname, (bfd *abfd, CONST char *filename,
|
||||
void bfd_bsd_truncate_arname PARAMS ((bfd *abfd, CONST char *filename,
|
||||
char *hdr));
|
||||
PROTO (void, bfd_gnu_truncate_arname, (bfd *abfd, CONST char *filename,
|
||||
void bfd_gnu_truncate_arname PARAMS ((bfd *abfd, CONST char *filename,
|
||||
char *hdr));
|
||||
|
||||
PROTO (boolean, bsd_write_armap, (bfd *arch, unsigned int elength,
|
||||
boolean bsd_write_armap PARAMS ((bfd *arch, unsigned int elength,
|
||||
struct orl *map, unsigned int orl_count, int stridx));
|
||||
|
||||
PROTO (boolean, coff_write_armap, (bfd *arch, unsigned int elength,
|
||||
boolean coff_write_armap PARAMS ((bfd *arch, unsigned int elength,
|
||||
struct orl *map, unsigned int orl_count, int stridx));
|
||||
|
||||
PROTO (bfd *, bfd_generic_openr_next_archived_file, (bfd *archive,
|
||||
bfd * bfd_generic_openr_next_archived_file PARAMS ((bfd *archive,
|
||||
bfd *last_file));
|
||||
|
||||
PROTO(int, bfd_generic_stat_arch_elt, (bfd *, struct stat *));
|
||||
int bfd_generic_stat_arch_elt PARAMS ((bfd *, struct stat *));
|
||||
|
||||
PROTO(boolean, bfd_generic_get_section_contents,
|
||||
(bfd *abfd, sec_ptr section, PTR location, file_ptr offset,
|
||||
bfd_size_type count));
|
||||
boolean bfd_generic_get_section_contents PARAMS ((bfd *abfd, sec_ptr section,
|
||||
PTR location, file_ptr offset,
|
||||
bfd_size_type count));
|
||||
|
||||
PROTO(boolean, bfd_generic_set_section_contents,
|
||||
(bfd *abfd, sec_ptr section, PTR location, file_ptr offset,
|
||||
bfd_size_type count));
|
||||
boolean bfd_generic_set_section_contents PARAMS ((bfd *abfd, sec_ptr section,
|
||||
PTR location, file_ptr offset,
|
||||
bfd_size_type count));
|
||||
|
||||
/* Macros to tell if bfds are read or write enabled.
|
||||
|
||||
@@ -161,17 +159,18 @@ PROTO(boolean, bfd_generic_set_section_contents,
|
||||
!bfd_read_p, and only sometimes bfd_write_p.
|
||||
*/
|
||||
|
||||
#define bfd_read_p(abfd) ((abfd)->direction == read_direction || (abfd)->direction == both_direction)
|
||||
#define bfd_write_p(abfd) ((abfd)->direction == write_direction || (abfd)->direction == both_direction)
|
||||
#define bfd_read_p(abfd) ((abfd)->direction == read_direction || (abfd)->direction == both_direction)
|
||||
#define bfd_write_p(abfd) ((abfd)->direction == write_direction || (abfd)->direction == both_direction)
|
||||
|
||||
void bfd_assert PARAMS ((char*,int));
|
||||
|
||||
PROTO (void, bfd_assert,(char*,int));
|
||||
#define BFD_ASSERT(x) \
|
||||
{ if (!(x)) bfd_assert(__FILE__,__LINE__); }
|
||||
|
||||
#define BFD_FAIL() \
|
||||
{ bfd_assert(__FILE__,__LINE__); }
|
||||
|
||||
PROTO (FILE *, bfd_cache_lookup_worker, (bfd *));
|
||||
FILE * bfd_cache_lookup_worker PARAMS ((bfd *));
|
||||
|
||||
extern bfd *bfd_last_cache;
|
||||
|
||||
@@ -250,11 +249,9 @@ bfd_generic_relax_section
|
||||
|
||||
bfd_byte *
|
||||
|
||||
bfd_generic_get_relocated_section_contents PARAMS ((bfd *abfd,
|
||||
struct bfd_seclet_struct *seclet,
|
||||
bfd_byte *data)
|
||||
|
||||
);
|
||||
bfd_generic_get_relocated_section_contents PARAMS ((bfd *abfd,
|
||||
struct bfd_seclet *seclet,
|
||||
bfd_byte *data));
|
||||
|
||||
extern bfd_arch_info_type bfd_default_arch_struct;
|
||||
boolean
|
||||
|
||||
Reference in New Issue
Block a user