Mon Sep 30 15:13:46 1991 Steve Chamberlain (steve at cygnus.com)
* cpu-a29k.c, cpu-i386.c, cpu-m68k.c, cpu-mips.c, cpu-vax.c, cpu-h8300.c, cpu-i960.c, cpu-m88k.c, cpu-sparc.c: added. These files will eventually contain processor specific bits for bfd, like strange relocation information and dis/assembly. So far only the H8 has been even partially done. This work also ties in with the change in handling architectures. * aout-f1.h: (choose_reloc_size) now calls bfd_get_arch to discover the architecture of the bfd. (sunos4_callback) calls the function bfd_set_arch_mach rather than stuffing stuff directly into the bfd. (sunos4_write_object_contents), changed names of accessor functions. * aoutx.h: (set_arch_mach) now calls bfd_default_set_arch_mach to setup the environment. * archive.c: (bfd_slurp_coff_armap) coff archives always have the headers in big endian format, regardless of the endianess of the host or target. * archures.c: totally changed. Now an architecture is represented with a pointer to an info structure rather than an enumerated type and a long. The old info is available as two elements in the structure. Future enhancements to architecure support will involve pointers to methods being placed into the info structure. * bfd.c: changed the definition of the bfd structure for the new architecture stuff. * bout.c: (b_out_set_arch_mach) changed to use the new architecture mechanism. * coffcode.h: (coff_set_arch_mach, coff_set_flags) changed to use the new architecture mechanism. * configure.in: added h8 stuff. * ieee.c: too many changes to note. Now ieee files written with bfd gas and ld can be read by gld and ieee only linkers and simulators. * libbfd.c, libbfd.h: changed prototype of bfd_write. * newsos3.c: (newos3_callback) now calls bfd_set_arch_mach rather than fixing the structure directly. * oasys.c: (oasys_object_p) now calls bfd_default_set_arch_mach rather than fixing the structure directly. * opncls.c: (new_bfd) makes sure that bfd_init has been called before opening a bfd. * srec.c: (srec_set_arch_mach) now calls bfd_default_set_arch_mach rather than fixing the structure directly. * targets.c: (target_vector) now by defining SELECT_VECS (perhaps in the t/hmake file) a user can select which backends they want linked with bfd without changing the source. * init.c: new, looks after initializing modules. * howto.c: for future use, will allow an application to work out what cookie to use as a handle on a relcoatio howto.
This commit is contained in:
parent
e89f2fbe00
commit
4e6f9223b1
|
@ -1,3 +1,69 @@
|
|||
Mon Sep 30 15:13:46 1991 Steve Chamberlain (steve at cygnus.com)
|
||||
|
||||
* cpu-a29k.c, cpu-i386.c, cpu-m68k.c, cpu-mips.c, cpu-vax.c,
|
||||
cpu-h8300.c, cpu-i960.c, cpu-m88k.c, cpu-sparc.c: added. These
|
||||
files will eventually contain processor specific bits for bfd,
|
||||
like strange relocation information and dis/assembly. So far only
|
||||
the H8 has been even partially done. This work also ties in with
|
||||
the change in handling architectures.
|
||||
|
||||
* aout-f1.h: (choose_reloc_size) now calls bfd_get_arch to
|
||||
discover the architecture of the bfd. (sunos4_callback) calls the
|
||||
function bfd_set_arch_mach rather than stuffing stuff directly
|
||||
into the bfd. (sunos4_write_object_contents), changed names of
|
||||
accessor functions.
|
||||
|
||||
* aoutx.h: (set_arch_mach) now calls bfd_default_set_arch_mach to
|
||||
setup the environment.
|
||||
|
||||
* archive.c: (bfd_slurp_coff_armap) coff archives always have the
|
||||
headers in big endian format, regardless of the endianess of the
|
||||
host or target.
|
||||
|
||||
* archures.c: totally changed. Now an architecture is represented
|
||||
with a pointer to an info structure rather than an enumerated type
|
||||
and a long. The old info is available as two elements in the
|
||||
structure. Future enhancements to architecure support will
|
||||
involve pointers to methods being placed into the info structure.
|
||||
|
||||
* bfd.c: changed the definition of the bfd structure for the new
|
||||
architecture stuff.
|
||||
|
||||
* bout.c: (b_out_set_arch_mach) changed to use the new
|
||||
architecture mechanism.
|
||||
|
||||
* coffcode.h: (coff_set_arch_mach, coff_set_flags) changed to use
|
||||
the new architecture mechanism.
|
||||
|
||||
* configure.in: added h8 stuff.
|
||||
|
||||
* ieee.c: too many changes to note. Now ieee files written with
|
||||
bfd gas and ld can be read by gld and ieee only linkers and
|
||||
simulators.
|
||||
|
||||
* libbfd.c, libbfd.h: changed prototype of bfd_write.
|
||||
|
||||
* newsos3.c: (newos3_callback) now calls bfd_set_arch_mach rather
|
||||
than fixing the structure directly.
|
||||
|
||||
* oasys.c: (oasys_object_p) now calls bfd_default_set_arch_mach rather
|
||||
than fixing the structure directly.
|
||||
|
||||
* opncls.c: (new_bfd) makes sure that bfd_init has been called
|
||||
before opening a bfd.
|
||||
|
||||
* srec.c: (srec_set_arch_mach) now calls bfd_default_set_arch_mach
|
||||
rather than fixing the structure directly.
|
||||
|
||||
* targets.c: (target_vector) now by defining SELECT_VECS (perhaps
|
||||
in the t/hmake file) a user can select which backends they want
|
||||
linked with bfd without changing the source.
|
||||
|
||||
* init.c: new, looks after initializing modules.
|
||||
|
||||
* howto.c: for future use, will allow an application to work out
|
||||
what cookie to use as a handle on a relcoatio howto.
|
||||
|
||||
Mon Sep 30 13:31:15 1991 John Gilmore (gnu at cygnus.com)
|
||||
|
||||
* srec.c: Better error checking, partly from Peter Schauer.
|
||||
|
|
761
bfd/archures.c
761
bfd/archures.c
|
@ -1,6 +1,7 @@
|
|||
/* BFD library support routines for architectures.
|
||||
Copyright (C) 1990-1991 Free Software Foundation, Inc.
|
||||
Hacked by John Gilmore of Cygnus Support.
|
||||
Hacked by John Gilmore and Steve Chamberlain of Cygnus Support.
|
||||
|
||||
|
||||
This file is part of BFD, the Binary File Descriptor library.
|
||||
|
||||
|
@ -21,9 +22,25 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
|||
/*doc*
|
||||
@section Architectures
|
||||
BFD's idea of an architecture is implimented in @code{archures.c}. BFD
|
||||
keeps two atoms in a BFD describing the architecture of the data
|
||||
attached to the BFD, the @code{enum bfd_architecture arch} field and
|
||||
the @code{unsigned long machine} field.
|
||||
keeps one atoms in a BFD describing the architecture of the data
|
||||
attached to the BFD; a pointer to a @code{bfd_arch_info_struct}.
|
||||
|
||||
Pointers to structures can be requested independently of a bfd so that
|
||||
an archictectures information can be interrogated without access to an
|
||||
open bfd.
|
||||
|
||||
The arch information is provided by each architecture package. The
|
||||
set of default architectures is selected by the #define
|
||||
@code{SELECT_ARCHITECTURES}. This is normally set up in the
|
||||
@ital{config/h-} file of your choice. If the name is not defined,
|
||||
then all the architectures supported are included.
|
||||
|
||||
When BFD starts up, all the architectures are called with an
|
||||
initialize method. It is up to the architecture back end to insert as
|
||||
many items into the list of arches as it wants to, generally this
|
||||
would be one for each machine and one for the default case (an item
|
||||
with a machine field of 0).
|
||||
|
||||
*/
|
||||
|
||||
/*proto* bfd_architecture
|
||||
|
@ -70,7 +87,7 @@ enum bfd_architecture
|
|||
bfd_arch_convex, {* Convex *}
|
||||
bfd_arch_m88k, {* Motorola 88xxx *}
|
||||
bfd_arch_pyramid, {* Pyramid Technology *}
|
||||
bfd_arch_h8_300, {* Hitachi H8/300 *}
|
||||
bfd_arch_h8300, {* Hitachi H8/300 *}
|
||||
bfd_arch_last
|
||||
};
|
||||
*-
|
||||
|
@ -85,44 +102,49 @@ stuff
|
|||
|
||||
#include <sysdep.h>
|
||||
#include "bfd.h"
|
||||
#include "libbfd.h"
|
||||
|
||||
static char *prt_num_mach ();
|
||||
static boolean scan_num_mach ();
|
||||
static char *prt_960_mach ();
|
||||
static boolean scan_960_mach ();
|
||||
/*proto* bfd_arch_info_struct
|
||||
This structure contains information on architectures.
|
||||
*+
|
||||
typedef int bfd_reloc_code_enum_type;
|
||||
|
||||
struct arch_print {
|
||||
typedef struct bfd_arch_info_struct
|
||||
{
|
||||
int bits_per_word;
|
||||
int bits_per_address;
|
||||
int bits_per_byte;
|
||||
enum bfd_architecture arch;
|
||||
char *astr;
|
||||
char *(*mach_print)();
|
||||
boolean (*mach_scan)();
|
||||
} arch_print[] = {
|
||||
long mach;
|
||||
char *arch_name;
|
||||
CONST char *printable_name;
|
||||
{* true if this is the default machine for the architecture *}
|
||||
boolean the_default;
|
||||
CONST struct bfd_arch_info_struct * EXFUN((*compatible),(CONST struct bfd_arch_info_struct *a,
|
||||
CONST struct bfd_arch_info_struct *b));
|
||||
|
||||
{bfd_arch_unknown, "unknown", prt_num_mach, scan_num_mach},
|
||||
{bfd_arch_obscure, "obscure", prt_num_mach, scan_num_mach},
|
||||
{bfd_arch_m68k, "m68k", prt_num_mach, scan_num_mach},
|
||||
{bfd_arch_vax, "vax", prt_num_mach, scan_num_mach},
|
||||
{bfd_arch_i960, "i960", prt_960_mach, scan_960_mach},
|
||||
{bfd_arch_a29k, "a29k", prt_num_mach, scan_num_mach},
|
||||
{bfd_arch_sparc, "sparc", prt_num_mach, scan_num_mach},
|
||||
{bfd_arch_mips, "mips", prt_num_mach, scan_num_mach},
|
||||
{bfd_arch_i386, "i386", prt_num_mach, scan_num_mach},
|
||||
{bfd_arch_ns32k, "ns32k", prt_num_mach, scan_num_mach},
|
||||
{bfd_arch_tahoe, "tahoe", prt_num_mach, scan_num_mach},
|
||||
{bfd_arch_i860, "i860", prt_num_mach, scan_num_mach},
|
||||
{bfd_arch_romp, "romp", prt_num_mach, scan_num_mach},
|
||||
{bfd_arch_alliant, "alliant", prt_num_mach, scan_num_mach},
|
||||
{bfd_arch_convex, "convex", prt_num_mach, scan_num_mach},
|
||||
{bfd_arch_m88k, "m88k", prt_num_mach, scan_num_mach},
|
||||
{bfd_arch_pyramid, "pyramid", prt_num_mach, scan_num_mach},
|
||||
{bfd_arch_h8_300, "H8/300", prt_num_mach, scan_num_mach},
|
||||
{bfd_arch_unknown, (char *)0, prt_num_mach, scan_num_mach},
|
||||
};
|
||||
|
||||
/*proto* bfd_prinable_arch_mach
|
||||
boolean EXFUN((*scan),(CONST struct bfd_arch_info_struct *,CONST char *));
|
||||
unsigned int EXFUN((*disassemble),(bfd_vma addr, CONST char *data,
|
||||
PTR stream));
|
||||
CONST struct reloc_howto_struct *EXFUN((*reloc_type_lookup), (bfd_reloc_code_enum_type code));
|
||||
|
||||
struct bfd_arch_info_struct *next;
|
||||
|
||||
} bfd_arch_info_struct_type;
|
||||
|
||||
|
||||
*-
|
||||
*/
|
||||
|
||||
bfd_arch_info_struct_type *bfd_arch_info_list;
|
||||
|
||||
/*proto* bfd_printable_arch_mach
|
||||
Return a printable string representing the architecture and machine
|
||||
type. The result is only good until the next call to
|
||||
@code{bfd_printable_arch_mach}.
|
||||
type.
|
||||
|
||||
NB. The use of this routine is depreciated.
|
||||
|
||||
*; PROTO(CONST char *,bfd_printable_arch_mach,
|
||||
(enum bfd_architecture arch, unsigned long machine));
|
||||
*/
|
||||
|
@ -132,118 +154,389 @@ DEFUN(bfd_printable_arch_mach,(arch, machine),
|
|||
enum bfd_architecture arch AND
|
||||
unsigned long machine)
|
||||
{
|
||||
struct arch_print *ap;
|
||||
bfd_arch_info_struct_type *ap;
|
||||
|
||||
for (ap = arch_print; ap->astr; ap++) {
|
||||
if (ap->arch == arch) {
|
||||
if (machine == 0)
|
||||
return ap->astr;
|
||||
return (*ap->mach_print)(ap, machine);
|
||||
for (ap = bfd_arch_info_list;
|
||||
ap != (bfd_arch_info_struct_type *)NULL;
|
||||
ap = ap->next) {
|
||||
if (ap->arch == arch &&
|
||||
((ap->mach == machine) || (ap->the_default && machine == 0))) {
|
||||
return ap->printable_name;
|
||||
}
|
||||
}
|
||||
return "UNKNOWN!";
|
||||
}
|
||||
|
||||
static char *
|
||||
prt_num_mach (ap, machine)
|
||||
struct arch_print *ap;
|
||||
unsigned long machine;
|
||||
{
|
||||
static char result[20];
|
||||
|
||||
sprintf(result, "%s:%ld", ap->astr, (long) machine);
|
||||
return result;
|
||||
/*proto* bfd_printable_name
|
||||
|
||||
Return a printable string representing the architecture and machine
|
||||
from the pointer to the arch info structure
|
||||
|
||||
*; CONST char *EXFUN(bfd_printable_name,(bfd *abfd));
|
||||
|
||||
*/
|
||||
|
||||
CONST char *
|
||||
DEFUN(bfd_printable_name, (abfd),
|
||||
bfd *abfd)
|
||||
{
|
||||
return abfd->arch_info->printable_name;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*proto*
|
||||
*i bfd_scan_arch_mach
|
||||
Scan a string and attempt to turn it into an archive and machine type combination.
|
||||
*; PROTO(boolean, bfd_scan_arch_mach,
|
||||
(CONST char *, enum bfd_architecture *, unsigned long *));
|
||||
*i bfd_scan_arch
|
||||
This routine is provided with a string and tries to work out if bfd
|
||||
supports any cpu which could be described with the name provided. The
|
||||
routine returns a pointer to an arch_info structure if a machine is
|
||||
found, otherwise NULL.
|
||||
|
||||
*; bfd_arch_info_struct_type *EXFUN(bfd_scan_arch,(CONST char *));
|
||||
*/
|
||||
|
||||
bfd_arch_info_struct_type *
|
||||
DEFUN(bfd_scan_arch,(string),
|
||||
CONST char *string)
|
||||
{
|
||||
struct bfd_arch_info_struct *ap;
|
||||
|
||||
/* Look through all the installed architectures */
|
||||
for (ap = bfd_arch_info_list;
|
||||
ap != (bfd_arch_info_struct_type *)NULL;
|
||||
ap = ap->next) {
|
||||
/* Don't bother with anything if the first chars don't match */
|
||||
if (ap->arch_name[0] != string[0])
|
||||
continue;
|
||||
if (ap->scan(ap, string))
|
||||
return ap;
|
||||
}
|
||||
return (bfd_arch_info_struct_type *)NULL;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*proto* bfd_arch_get_compatible
|
||||
This routine is used to determine whether two BFDs' architectures and
|
||||
machine types are compatible. It calculates the lowest common
|
||||
denominator between the two architectures and machine types implied by
|
||||
the BFDs and returns a pointer to an arch_info structure describing
|
||||
the compatible machine.
|
||||
|
||||
*; CONST bfd_arch_info_struct_type *EXFUN(bfd_arch_get_compatible,
|
||||
(CONST bfd *abfd,
|
||||
CONST bfd *bbfd));
|
||||
*/
|
||||
|
||||
CONST bfd_arch_info_struct_type *
|
||||
DEFUN(bfd_arch_get_compatible,(abfd, bbfd),
|
||||
CONST bfd *abfd AND
|
||||
CONST bfd *bbfd)
|
||||
|
||||
{
|
||||
return abfd->arch_info->compatible(abfd->arch_info,bbfd->arch_info);
|
||||
}
|
||||
|
||||
|
||||
/*proto-internal* bfd_default_arch_struct
|
||||
|
||||
What bfds are seeded with
|
||||
|
||||
*+
|
||||
extern bfd_arch_info_struct_type bfd_default_arch_struct;
|
||||
*-
|
||||
*/
|
||||
|
||||
bfd_arch_info_struct_type bfd_default_arch_struct =
|
||||
{
|
||||
32,32,8,bfd_arch_unknown,0,"unknown","unknown",true,
|
||||
bfd_default_compatible, bfd_default_scan,
|
||||
|
||||
};
|
||||
|
||||
/*proto* bfd_set_arch_info
|
||||
|
||||
*; void EXFUN(bfd_set_arch_info,(bfd *, bfd_arch_info_struct_type *));
|
||||
|
||||
*/
|
||||
|
||||
void DEFUN(bfd_set_arch_info,(abfd, arg),
|
||||
bfd *abfd AND
|
||||
bfd_arch_info_struct_type *arg)
|
||||
{
|
||||
abfd->arch_info = arg;
|
||||
}
|
||||
|
||||
/*proto-internal* bfd_default_set_arch_mach
|
||||
|
||||
Set the architecture and machine type in a bfd. This finds the correct
|
||||
pointer to structure and inserts it into the arch_info pointer.
|
||||
|
||||
*; boolean EXFUN(bfd_default_set_arch_mach,(bfd *abfd,
|
||||
enum bfd_architecture arch,
|
||||
unsigned long mach));
|
||||
|
||||
*/
|
||||
|
||||
boolean DEFUN(bfd_default_set_arch_mach,(abfd, arch, mach),
|
||||
bfd *abfd AND
|
||||
enum bfd_architecture arch AND
|
||||
unsigned long mach)
|
||||
{
|
||||
static struct bfd_arch_info_struct *old_ptr = &bfd_default_arch_struct;
|
||||
boolean found = false;
|
||||
/* run through the table to find the one we want, we keep a little
|
||||
cache to speed things up */
|
||||
if (old_ptr == 0 || arch != old_ptr->arch || mach != old_ptr->mach) {
|
||||
bfd_arch_info_struct_type *ptr;
|
||||
old_ptr = (bfd_arch_info_struct_type *)NULL;
|
||||
for (ptr = bfd_arch_info_list;
|
||||
ptr != (bfd_arch_info_struct_type *)NULL;
|
||||
ptr= ptr->next) {
|
||||
if (ptr->arch == arch &&
|
||||
((ptr->mach == mach) || (ptr->the_default && mach == 0))) {
|
||||
old_ptr = ptr;
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (found==false) {
|
||||
/*looked for it and it wasn't there, so put in the default */
|
||||
old_ptr = &bfd_default_arch_struct;
|
||||
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* it was in the cache */
|
||||
found = true;
|
||||
}
|
||||
|
||||
abfd->arch_info = old_ptr;
|
||||
|
||||
return found;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/*proto* bfd_get_arch
|
||||
|
||||
Returns the enumerated type which describes the supplied bfd's
|
||||
architecture
|
||||
|
||||
*; enum bfd_architecture EXFUN(bfd_get_arch, (bfd *abfd));
|
||||
*/
|
||||
|
||||
enum bfd_architecture DEFUN(bfd_get_arch, (abfd), bfd *abfd)
|
||||
{
|
||||
return abfd->arch_info->arch;
|
||||
|
||||
|
||||
}
|
||||
|
||||
/*proto* bfd_get_mach
|
||||
|
||||
Returns the long type which describes the supplied bfd's
|
||||
machine
|
||||
|
||||
*; unsigned long EXFUN(bfd_get_mach, (bfd *abfd));
|
||||
*/
|
||||
|
||||
unsigned long DEFUN(bfd_get_mach, (abfd), bfd *abfd)
|
||||
{
|
||||
return abfd->arch_info->mach;
|
||||
}
|
||||
|
||||
/*proto* bfd_arch_bits_per_byte
|
||||
|
||||
Returns the number of bits in one of the architectures bytes
|
||||
|
||||
*; unsigned int EXFUN(bfd_arch_bits_per_byte, (bfd *abfd));
|
||||
*/
|
||||
|
||||
unsigned int DEFUN(bfd_arch_bits_per_byte, (abfd), bfd *abfd)
|
||||
{
|
||||
return abfd->arch_info->bits_per_byte;
|
||||
}
|
||||
|
||||
/*proto* bfd_arch_bits_per_address
|
||||
|
||||
Returns the number of bits in one of the architectures addresses
|
||||
|
||||
*; unsigned int EXFUN(bfd_arch_bits_per_address, (bfd *abfd));
|
||||
*/
|
||||
|
||||
unsigned int DEFUN(bfd_arch_bits_per_address, (abfd), bfd *abfd)
|
||||
{
|
||||
return abfd->arch_info->bits_per_address;
|
||||
}
|
||||
|
||||
|
||||
|
||||
extern void EXFUN(bfd_h8300_arch,(void));
|
||||
extern void EXFUN(bfd_i960_arch,(void));
|
||||
extern void EXFUN(bfd_empty_arch,(void));
|
||||
extern void EXFUN(bfd_sparc_arch,(void));
|
||||
extern void EXFUN(bfd_m88k_arch,(void));
|
||||
extern void EXFUN(bfd_m68k_arch,(void));
|
||||
extern void EXFUN(bfd_vax_arch,(void));
|
||||
extern void EXFUN(bfd_a29k_arch,(void));
|
||||
extern void EXFUN(bfd_mips_arch,(void));
|
||||
extern void EXFUN(bfd_i386_arch,(void));
|
||||
|
||||
|
||||
|
||||
static void EXFUN((*archures_init_table[]),()) =
|
||||
{
|
||||
#ifdef SELECT_ARCHITECTURES
|
||||
SELECT_ARCHITECTURES,
|
||||
#else
|
||||
bfd_sparc_arch,
|
||||
bfd_a29k_arch,
|
||||
bfd_mips_arch,
|
||||
bfd_h8300_arch,
|
||||
bfd_i386_arch,
|
||||
bfd_m88k_arch,
|
||||
bfd_i960_arch,
|
||||
bfd_m68k_arch,
|
||||
bfd_vax_arch,
|
||||
#endif
|
||||
0
|
||||
};
|
||||
|
||||
|
||||
|
||||
/*proto-internal*
|
||||
|
||||
This routine initializes the architecture dispatch table by calling
|
||||
all installed architecture packages and getting them to poke around.
|
||||
|
||||
*; PROTO(void, bfd_arch_init,(void));
|
||||
|
||||
*/
|
||||
|
||||
void
|
||||
DEFUN_VOID(bfd_arch_init)
|
||||
{
|
||||
void EXFUN((**ptable),());
|
||||
for (ptable = archures_init_table;
|
||||
*ptable ;
|
||||
ptable++)
|
||||
{
|
||||
(*ptable)();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*proto-internal* bfd_arch_linkin
|
||||
|
||||
Link the provided arch info structure into the list
|
||||
|
||||
*; void EXFUN(bfd_arch_linkin,(bfd_arch_info_struct_type *));
|
||||
|
||||
*/
|
||||
|
||||
void DEFUN(bfd_arch_linkin,(ptr),
|
||||
bfd_arch_info_struct_type *ptr)
|
||||
{
|
||||
ptr->next = bfd_arch_info_list;
|
||||
bfd_arch_info_list = ptr;
|
||||
}
|
||||
|
||||
|
||||
/*proto-internal* bfd_default_compatible
|
||||
|
||||
The default function for testing for compatibility
|
||||
|
||||
*; CONST bfd_arch_info_struct_type *EXFUN(bfd_default_compatible,
|
||||
(CONST bfd_arch_info_struct_type *a,
|
||||
CONST bfd_arch_info_struct_type *b));
|
||||
*/
|
||||
|
||||
CONST bfd_arch_info_struct_type *
|
||||
DEFUN(bfd_default_compatible,(a,b),
|
||||
CONST bfd_arch_info_struct_type *a AND
|
||||
CONST bfd_arch_info_struct_type *b)
|
||||
{
|
||||
if(a->arch != b->arch) return (bfd_arch_info_struct_type *)NULL;
|
||||
|
||||
if (a->mach > b->mach) {
|
||||
return a;
|
||||
}
|
||||
if (b->mach > a->mach) {
|
||||
return b;
|
||||
}
|
||||
return a;
|
||||
}
|
||||
|
||||
/*proto-internal* bfd_default_scan
|
||||
The default function for working out whether this is an architecture
|
||||
hit and a machine hit
|
||||
|
||||
*; boolean EXFUN(bfd_default_scan,(CONST struct bfd_arch_info_struct *, CONST char *));
|
||||
|
||||
*/
|
||||
|
||||
boolean
|
||||
DEFUN(bfd_scan_arch_mach,(string, archp, machinep),
|
||||
CONST char *string AND
|
||||
enum bfd_architecture *archp AND
|
||||
unsigned long *machinep)
|
||||
{
|
||||
struct arch_print *ap;
|
||||
int len;
|
||||
|
||||
/* First look for an architecture, possibly followed by machtype. */
|
||||
for (ap = arch_print; ap->astr; ap++) {
|
||||
if (ap->astr[0] != string[0])
|
||||
continue;
|
||||
len = strlen (ap->astr);
|
||||
if (!strncmp (ap->astr, string, len)) {
|
||||
/* We found the architecture, now see about the machine type */
|
||||
if (archp)
|
||||
*archp = ap->arch;
|
||||
if (string[len] != '\0') {
|
||||
if (ap->mach_scan (string+len, ap, archp, machinep, 1))
|
||||
return true;
|
||||
}
|
||||
if (machinep)
|
||||
*machinep = 0;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/* Couldn't find an architecture -- try for just a machine type */
|
||||
for (ap = arch_print; ap->astr; ap++) {
|
||||
if (ap->mach_scan (string, ap, archp, machinep, 0))
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static boolean
|
||||
scan_num_mach (string, ap, archp, machinep, archspec)
|
||||
char *string;
|
||||
struct arch_print *ap;
|
||||
enum bfd_architecture *archp;
|
||||
unsigned long *machinep;
|
||||
int archspec;
|
||||
DEFUN(bfd_default_scan,(info, string),
|
||||
CONST struct bfd_arch_info_struct *info AND
|
||||
CONST char *string)
|
||||
{
|
||||
CONST char *ptr_src;
|
||||
CONST char *ptr_tst;
|
||||
unsigned long number;
|
||||
enum bfd_architecture arch;
|
||||
unsigned long machine;
|
||||
char achar;
|
||||
/* First test for an exact match */
|
||||
if (strcmp(string, info->printable_name) == 0) return true;
|
||||
|
||||
if (archspec) {
|
||||
/* See how much of the supplied string matches with the
|
||||
architecture, eg the string m68k:68020 would match the 68k entry
|
||||
up to the :, then we get left with the machine number */
|
||||
|
||||
/* Architecture already specified, now go for machine type. */
|
||||
if (string[0] != ':')
|
||||
return false;
|
||||
/* We'll take any valid number that occupies the entire string */
|
||||
if (1 != sscanf (string+1, "%lu%c", &machine, &achar))
|
||||
return false;
|
||||
arch = ap->arch;
|
||||
for (ptr_src = string,
|
||||
ptr_tst = info->arch_name;
|
||||
*ptr_src && *ptr_tst;
|
||||
ptr_src++,
|
||||
ptr_tst++)
|
||||
{
|
||||
if (*ptr_src != *ptr_tst) break;
|
||||
}
|
||||
|
||||
} else {
|
||||
/* Chewed up as much of the architecture as will match, skip any
|
||||
colons */
|
||||
if (*ptr_src == ':') ptr_src++;
|
||||
|
||||
/* We couldn't identify an architecture prefix. Perhaps the entire
|
||||
thing is a machine type. Be a lot picker. */
|
||||
if (1 != sscanf (string, "%lu%c", &machine, &achar))
|
||||
return false;
|
||||
switch (machine) {
|
||||
if (*ptr_src == 0) {
|
||||
/* nothing more, then only keep this one if it is the default
|
||||
machine for this architecture */
|
||||
return info->the_default;
|
||||
}
|
||||
number = 0;
|
||||
while (isdigit(*ptr_src)) {
|
||||
number = number * 10 + *ptr_src - '0';
|
||||
ptr_src++;
|
||||
}
|
||||
|
||||
switch (number) {
|
||||
case 68010:
|
||||
case 68020:
|
||||
case 68030:
|
||||
case 68040:
|
||||
case 68332:
|
||||
case 68050: arch = bfd_arch_m68k; break;
|
||||
case 68000: arch = bfd_arch_m68k; machine = 0; break;
|
||||
|
||||
case 80960:
|
||||
case 960: arch = bfd_arch_i960; machine = 0; break;
|
||||
|
||||
case 68050:
|
||||
case 68000:
|
||||
arch = bfd_arch_m68k;
|
||||
break;
|
||||
case 386:
|
||||
case 80386: arch = bfd_arch_i386; machine = 0; break;
|
||||
case 486: arch = bfd_arch_i386; break;
|
||||
|
||||
case 29000: arch = bfd_arch_a29k; machine = 0; break;
|
||||
case 80386:
|
||||
case 486:
|
||||
arch = bfd_arch_i386;
|
||||
break;
|
||||
case 29000:
|
||||
arch = bfd_arch_a29k;
|
||||
break;
|
||||
|
||||
case 32016:
|
||||
case 32032:
|
||||
|
@ -251,214 +544,40 @@ scan_num_mach (string, ap, archp, machinep, archspec)
|
|||
case 32232:
|
||||
case 32332:
|
||||
case 32432:
|
||||
case 32532: arch = bfd_arch_ns32k; break;
|
||||
case 32000: arch = bfd_arch_ns32k; machine = 0; break;
|
||||
case 32532:
|
||||
case 32000:
|
||||
arch = bfd_arch_ns32k;
|
||||
break;
|
||||
|
||||
case 860:
|
||||
case 80860: arch = bfd_arch_i860; machine = 0; break;
|
||||
|
||||
default: return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (archp)
|
||||
*archp = arch;
|
||||
if (machinep)
|
||||
*machinep = machine;
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Intel 960 machine variants. */
|
||||
|
||||
static char *
|
||||
prt_960_mach (ap, machine)
|
||||
struct arch_print *ap;
|
||||
unsigned long machine;
|
||||
{
|
||||
static char result[20];
|
||||
char *str;
|
||||
|
||||
switch (machine) {
|
||||
case bfd_mach_i960_core: str = "core"; break;
|
||||
case bfd_mach_i960_kb_sb: str = "kb"; break;
|
||||
case bfd_mach_i960_mc: str = "mc"; break;
|
||||
case bfd_mach_i960_xa: str = "xa"; break;
|
||||
case bfd_mach_i960_ca: str = "ca"; break;
|
||||
case bfd_mach_i960_ka_sa: str = "ka"; break;
|
||||
default:
|
||||
return prt_num_mach (ap, machine);
|
||||
}
|
||||
sprintf (result, "%s:%s", ap->astr, str);
|
||||
return result;
|
||||
}
|
||||
|
||||
static boolean
|
||||
scan_960_mach (string, ap, archp, machinep, archspec)
|
||||
char *string;
|
||||
struct arch_print *ap;
|
||||
enum bfd_architecture *archp;
|
||||
unsigned long *machinep;
|
||||
int archspec;
|
||||
{
|
||||
unsigned long machine;
|
||||
|
||||
if (!archspec)
|
||||
return false;
|
||||
if (string[0] != ':')
|
||||
return false;
|
||||
string++;
|
||||
if (string[0] == '\0')
|
||||
return false;
|
||||
if (string[0] == 'c' && string[1] == 'o' && string[2] == 'r' &&
|
||||
string[3] == 'e' && string[4] == '\0')
|
||||
machine = bfd_mach_i960_core;
|
||||
else if (string[1] == '\0' || string[2] != '\0') /* rest are 2-char */
|
||||
return false;
|
||||
else if (string[0] == 'k' && string[1] == 'b')
|
||||
machine = bfd_mach_i960_kb_sb;
|
||||
else if (string[0] == 's' && string[1] == 'b')
|
||||
machine = bfd_mach_i960_kb_sb;
|
||||
else if (string[0] == 'm' && string[1] == 'c')
|
||||
machine = bfd_mach_i960_mc;
|
||||
else if (string[0] == 'x' && string[1] == 'a')
|
||||
machine = bfd_mach_i960_xa;
|
||||
else if (string[0] == 'c' && string[1] == 'a')
|
||||
machine = bfd_mach_i960_ca;
|
||||
else if (string[0] == 'k' && string[1] == 'a')
|
||||
machine = bfd_mach_i960_ka_sa;
|
||||
else if (string[0] == 's' && string[1] == 'a')
|
||||
machine = bfd_mach_i960_ka_sa;
|
||||
else
|
||||
return false;
|
||||
|
||||
if (archp)
|
||||
*archp = ap->arch;
|
||||
if (machinep)
|
||||
*machinep = machine;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*proto*
|
||||
*i bfd_arch_compatible
|
||||
This routine is used to determine whether two BFDs' architectures and machine types are
|
||||
compatible. It calculates the lowest common denominator between the
|
||||
two architectures and machine types implied by the BFDs and sets the
|
||||
objects pointed at by @var{archp} and @var{machine} if non NULL.
|
||||
|
||||
This routine returns @code{true} if the BFDs are of compatible type,
|
||||
otherwise @code{false}.
|
||||
*; PROTO(boolean, bfd_arch_compatible,
|
||||
(bfd *abfd,
|
||||
bfd *bbfd,
|
||||
enum bfd_architecture *archp,
|
||||
unsigned long *machinep));
|
||||
*-*/
|
||||
|
||||
boolean
|
||||
DEFUN(bfd_arch_compatible,(abfd, bbfd, archp, machinep),
|
||||
bfd *abfd AND
|
||||
bfd *bbfd AND
|
||||
enum bfd_architecture *archp AND
|
||||
unsigned long *machinep)
|
||||
{
|
||||
enum bfd_architecture archa, archb;
|
||||
unsigned long macha, machb;
|
||||
int pick_a;
|
||||
|
||||
archa = bfd_get_architecture (abfd);
|
||||
archb = bfd_get_architecture (bbfd);
|
||||
macha = bfd_get_machine (abfd);
|
||||
machb = bfd_get_machine (bbfd);
|
||||
|
||||
if (archb == bfd_arch_unknown)
|
||||
pick_a = 1;
|
||||
else if (archa == bfd_arch_unknown)
|
||||
pick_a = 0;
|
||||
else if (archa != archb)
|
||||
return false; /* Not compatible */
|
||||
else {
|
||||
/* Architectures are the same. Check machine types. */
|
||||
if (macha == machb) /* Same machine type */
|
||||
pick_a = 1;
|
||||
else if (machb == 0) /* B is default */
|
||||
pick_a = 1;
|
||||
else if (macha == 0) /* A is default */
|
||||
pick_a = 0;
|
||||
else switch (archa) {
|
||||
/* If particular machine types of one architecture are not
|
||||
compatible with each other, this is the place to put those tests
|
||||
(returning false if incompatible). */
|
||||
|
||||
case bfd_arch_i960:
|
||||
/* The i960 has two distinct subspecies which may not interbreed:
|
||||
CORE CA
|
||||
CORE KA KB MC
|
||||
Any architecture on the same line is compatible, the one on
|
||||
the right is the least restrictive. */
|
||||
/* So, if either is a ca then the other must be a be core or ca */
|
||||
if (macha == bfd_mach_i960_ca) {
|
||||
if (machb != bfd_mach_i960_ca &&
|
||||
machb != bfd_mach_i960_core) {
|
||||
return false;
|
||||
}
|
||||
pick_a = 1;
|
||||
}
|
||||
else if (machb == bfd_mach_i960_ca) {
|
||||
if (macha != bfd_mach_i960_ca &&
|
||||
macha != bfd_mach_i960_core) {
|
||||
return false;
|
||||
}
|
||||
pick_a = 0;
|
||||
}
|
||||
else {
|
||||
/* This must be from the bottom row, so take the higest */
|
||||
pick_a = (macha > machb);
|
||||
}
|
||||
case 80860:
|
||||
arch = bfd_arch_i860;
|
||||
break;
|
||||
|
||||
/* For these chips, as far as we care, "lower" numbers are included
|
||||
by "higher" numbers, e.g. merge 68010 and 68020 into 68020,
|
||||
386 and 486 into 486, etc. This will need to change
|
||||
if&when we care about things like 68332. */
|
||||
case bfd_arch_m68k:
|
||||
case bfd_arch_ns32k:
|
||||
case bfd_arch_i386:
|
||||
pick_a = (macha > machb);
|
||||
break;
|
||||
|
||||
/* By default, pick first file's type, for lack of something better. */
|
||||
default:
|
||||
pick_a = 1;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
if (arch != info->arch)
|
||||
return false;
|
||||
|
||||
/* Set result based on our pick */
|
||||
if (!pick_a) {
|
||||
archa = archb;
|
||||
macha = machb;
|
||||
}
|
||||
if (archp)
|
||||
*archp = archa;
|
||||
if (machinep)
|
||||
*machinep = macha;
|
||||
if (number != info->mach)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/*proto* bfd_set_arch_mach
|
||||
Set atch mach
|
||||
*+
|
||||
#define bfd_set_arch_mach(abfd, arch, mach) \
|
||||
BFD_SEND (abfd, _bfd_set_arch_mach,\
|
||||
(abfd, arch, mach))
|
||||
*-
|
||||
|
||||
|
||||
/*proto* bfd_get_arch_info
|
||||
|
||||
*; bfd_arch_info_struct_type * EXFUN(bfd_get_arch_info,(bfd *));
|
||||
|
||||
*/
|
||||
|
||||
|
||||
foo() { }
|
||||
|
||||
|
||||
|
||||
bfd_arch_info_struct_type *
|
||||
DEFUN(bfd_get_arch_info,(abfd),
|
||||
bfd *abfd)
|
||||
{
|
||||
return abfd->arch_info;
|
||||
}
|
||||
|
|
|
@ -16,6 +16,7 @@ else
|
|||
mips)
|
||||
case "${host_vendor}" in
|
||||
dec) bfd_host=dec3100 ;;
|
||||
sgi) bfd_host=irix3 ;;
|
||||
esac
|
||||
;;
|
||||
m88k)
|
||||
|
@ -27,7 +28,6 @@ else
|
|||
;;
|
||||
esac
|
||||
;;
|
||||
|
||||
m68k)
|
||||
case "${host_vendor}" in
|
||||
hp)
|
||||
|
@ -82,6 +82,15 @@ case "${target_vendor}" in
|
|||
aout | coff | bout) bfd_target=${target_cpu}-${target_vendor} ;;
|
||||
sony) bfd_target=news ;;
|
||||
intel) bfd_target=${target_cpu}-coff ;;
|
||||
|
||||
hitachi)
|
||||
case "${target_cpu}" in
|
||||
h8300) bfd_target=h8300-ieee ;;
|
||||
*) echo "bad hitachi cpu" ;;
|
||||
esac
|
||||
;;
|
||||
|
||||
|
||||
wrs)
|
||||
case "${target_cpu}" in
|
||||
i960) bfd_target=i960-bout ;;
|
||||
|
@ -109,7 +118,13 @@ hp)
|
|||
;;
|
||||
esac
|
||||
;;
|
||||
none)
|
||||
sgi)
|
||||
case "${target_cpu}" in
|
||||
mips)
|
||||
bfd_target=irix3 ;;
|
||||
esac
|
||||
;;
|
||||
none|nyu)
|
||||
case "${target_cpu}" in
|
||||
i386) bfd_target=i386-coff ;;
|
||||
a29k) case "${target_os}" in
|
||||
|
@ -118,6 +133,7 @@ none)
|
|||
sym1) bfd_target=a29k-coff ;;
|
||||
esac
|
||||
;;
|
||||
tahoe | vax) bfd_target=${target_cpu} ;;
|
||||
esac
|
||||
;;
|
||||
*)
|
||||
|
|
|
@ -0,0 +1,200 @@
|
|||
|
||||
/* libbfd.h -- Declarations used by bfd library *implementation*.
|
||||
(This include file is not for users of the library.)
|
||||
Copyright (C) 1990-1991 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., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
/* $Id$ */
|
||||
|
||||
/* If you want to read and write large blocks, you might want to do it
|
||||
in quanta of this amount */
|
||||
#define DEFAULT_BUFFERSIZE 8192
|
||||
|
||||
/* Set a tdata field. Can't use the other macros for this, since they
|
||||
do casts, and casting to the left of assignment isn't portable. */
|
||||
#define set_tdata(bfd, v) ((bfd)->tdata = (PTR) (v))
|
||||
|
||||
/* tdata for an archive. For an input archive, cache
|
||||
needs to be free()'d. For an output archive, symdefs do. */
|
||||
|
||||
struct artdata {
|
||||
file_ptr first_file_filepos;
|
||||
/* Speed up searching the armap */
|
||||
struct ar_cache *cache;
|
||||
bfd *archive_head; /* Only interesting in output routines */
|
||||
carsym *symdefs; /* the symdef entries */
|
||||
symindex symdef_count; /* how many there are */
|
||||
char *extended_names; /* clever intel extension */
|
||||
};
|
||||
|
||||
#define bfd_ardata(bfd) ((struct artdata *) ((bfd)->tdata))
|
||||
|
||||
/* Goes in bfd's arelt_data slot */
|
||||
struct areltdata {
|
||||
char * arch_header; /* it's actually a string */
|
||||
unsigned int parsed_size; /* octets of filesize not including ar_hdr */
|
||||
char *filename; /* null-terminated */
|
||||
};
|
||||
|
||||
#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));
|
||||
|
||||
/* 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));
|
||||
|
||||
#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));
|
||||
|
||||
|
||||
|
||||
PROTO (int, bfd_seek,(bfd* abfd, file_ptr fp , 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, ());
|
||||
|
||||
#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));
|
||||
|
||||
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));
|
||||
|
||||
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 *exec_bfd));
|
||||
PROTO (bfd_target *, _bfd_dummy_target, (bfd *abfd));
|
||||
|
||||
PROTO (void, bfd_dont_truncate_arname, (bfd *abfd, CONST char *filename,
|
||||
char *hdr));
|
||||
PROTO (void, bfd_bsd_truncate_arname, (bfd *abfd, CONST char *filename,
|
||||
char *hdr));
|
||||
PROTO (void, bfd_gnu_truncate_arname, (bfd *abfd, CONST char *filename,
|
||||
char *hdr));
|
||||
|
||||
PROTO (boolean, bsd_write_armap, (bfd *arch, unsigned int elength,
|
||||
struct orl *map, int orl_count, int stridx));
|
||||
|
||||
PROTO (boolean, coff_write_armap, (bfd *arch, unsigned int elength,
|
||||
struct orl *map, int orl_count, int stridx));
|
||||
|
||||
PROTO (bfd *, bfd_generic_openr_next_archived_file, (bfd *archive,
|
||||
bfd *last_file));
|
||||
|
||||
PROTO(int, bfd_generic_stat_arch_elt, (bfd *, struct stat *));
|
||||
|
||||
PROTO(boolean, bfd_generic_get_section_contents,
|
||||
(bfd *abfd, sec_ptr section, PTR location, file_ptr offset, bfd_size_type count));
|
||||
|
||||
/* Macros to tell if bfds are read or write enabled.
|
||||
|
||||
Note that bfds open for read may be scribbled into if the fd passed
|
||||
to bfd_fdopenr is actually open both for read and write
|
||||
simultaneously. However an output bfd will never be open for
|
||||
read. Therefore sometimes you want to check bfd_read_p or
|
||||
!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)
|
||||
|
||||
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 *));
|
||||
|
||||
extern bfd *bfd_last_cache;
|
||||
|
||||
/* Now Steve, what's the story here? */
|
||||
#ifdef lint
|
||||
#define itos(x) "l"
|
||||
#define stoi(x) 1
|
||||
#else
|
||||
#define itos(x) ((char*)(x))
|
||||
#define stoi(x) ((int)(x))
|
||||
#endif
|
||||
|
||||
/* Generic routine for close_and_cleanup is really just bfd_true. */
|
||||
#define bfd_generic_close_and_cleanup bfd_true
|
||||
|
||||
/* THE FOLLOWING IS EXTRACTED FROM THE SOURCE*/
|
||||
|
||||
/*:init.c*/
|
||||
|
||||
/*:libbfd.c*/
|
||||
|
||||
/*:cache.c*/
|
||||
|
||||
/*:reloc.c*/
|
||||
|
||||
/*:cpu-h8300.c*/
|
||||
|
||||
/*:cpu-i960.c*/
|
||||
|
||||
/*:cpu-empty.c*/
|
||||
|
||||
/*:howto.c*/
|
||||
|
||||
/*:archures.c*/
|
||||
|
|
@ -1,24 +1,25 @@
|
|||
/* Copyright (C) 1990, 1991 Free Software Foundation, Inc.
|
||||
/* Generic target-file-type support for the BFD library.
|
||||
Copyright (C) 1990-1991 Free Software Foundation, Inc.
|
||||
Written by Cygnus Support.
|
||||
|
||||
This file is part of BFD, the Binary File Diddler.
|
||||
This file is part of BFD, the Binary File Descriptor library.
|
||||
|
||||
BFD is free software; you can redistribute it and/or modify
|
||||
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 1, or (at your option)
|
||||
any later version.
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
BFD is distributed in the hope that it will be useful,
|
||||
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 BFD; see the file COPYING. If not, write to
|
||||
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
/* $Id$ */
|
||||
|
||||
|
||||
#include <sysdep.h>
|
||||
#include "bfd.h"
|
||||
#include "libbfd.h"
|
||||
|
@ -26,7 +27,7 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
|||
/*doc*
|
||||
@section Targets
|
||||
Each port of BFD to a different machine requries the creation of a
|
||||
target back end. All the back end provides to the root part of bfd is
|
||||
target back end. All the back end provides to the root part of BFD is
|
||||
a structure containing pointers to functions which perform certain low
|
||||
level operations on files. BFD translates the applications's requests
|
||||
through a pointer into calls to the back end routines.
|
||||
|
@ -36,9 +37,9 @@ unknown. BFD uses various mechanisms to determine how to interpret the
|
|||
file. The operatios performed are:
|
||||
@itemize @bullet
|
||||
@item
|
||||
First a bfd is created by calling the internal routine
|
||||
First a BFD is created by calling the internal routine
|
||||
@code{new_bfd}, then @code{bfd_find_target} is called with the target
|
||||
string supplied to @code{bfd_openr} and the new bfd pointer.
|
||||
string supplied to @code{bfd_openr} and the new BFD pointer.
|
||||
@item
|
||||
If a null target string was provided to
|
||||
@code{bfd_find_target}, it looks up the environment variable
|
||||
|
@ -46,7 +47,7 @@ If a null target string was provided to
|
|||
@item
|
||||
If the target string is still NULL, or the target string
|
||||
is @code{default}, then the first item in the target vector is used as
|
||||
the target type. @xref{targets}.
|
||||
the target type. @xref{bfd_target}.
|
||||
@item
|
||||
Otherwise, the elements in the target vector are
|
||||
inspected one by one, until a match on target name is found. When
|
||||
|
@ -56,11 +57,11 @@ Otherwise the error @code{invalid_target} is returned to
|
|||
@code{bfd_openr}.
|
||||
@item
|
||||
@code{bfd_openr} attempts to open the file using
|
||||
@code{bfd_open_file}, and returns the bfd.
|
||||
@code{bfd_open_file}, and returns the BFD.
|
||||
@end itemize
|
||||
Once the bfd has been opened and the target selected, the file format
|
||||
Once the BFD has been opened and the target selected, the file format
|
||||
may be determined. This is done by calling @code{bfd_check_format} on
|
||||
the bfd with a suggested format. The routine returns @code{true} when
|
||||
the BFD with a suggested format. The routine returns @code{true} when
|
||||
the application guesses right.
|
||||
*/
|
||||
|
||||
|
@ -84,21 +85,21 @@ $#define SDEF_FMT(ret, name, arglist) \
|
|||
$ PROTO(ret,(*name[bfd_type_end]),arglist)
|
||||
|
||||
These macros are used to dispatch to functions through the bfd_target
|
||||
vector. They are used in a number of macros further down in bfd.h, and
|
||||
are also used when calling various routines by hand inside the bfd
|
||||
vector. They are used in a number of macros further down in @file{bfd.h}, and
|
||||
are also used when calling various routines by hand inside the BFD
|
||||
implementation. The "arglist" argument must be parenthesized; it
|
||||
contains all the arguments to the called function.
|
||||
|
||||
$#define BFD_SEND(bfd, message, arglist) \
|
||||
$ ((*((bfd)->xvec->message)) arglist)
|
||||
|
||||
For operations which index on the bfd format
|
||||
For operations which index on the BFD format
|
||||
|
||||
$#define BFD_SEND_FMT(bfd, message, arglist) \
|
||||
$ (((bfd)->xvec->message[(int)((bfd)->format)]) arglist)
|
||||
|
||||
This is the struct which defines the type of BFD this is. The
|
||||
"xvec" member of the struct bfd itself points here. Each module
|
||||
"xvec" member of the struct @code{bfd} itself points here. Each module
|
||||
that implements access to a different target under BFD, defines
|
||||
one of these.
|
||||
|
||||
|
@ -156,7 +157,7 @@ The minimum alignment restriction for any section.
|
|||
$ unsigned int align_power_min;
|
||||
|
||||
Entries for byte swapping for data. These are different to the other
|
||||
entry points, since they don't take bfd as first arg. Certain other handlers
|
||||
entry points, since they don't take BFD as first arg. Certain other handlers
|
||||
could do the same.
|
||||
|
||||
$ SDEF (bfd_vma, bfd_getx64, (bfd_byte *));
|
||||
|
@ -168,7 +169,7 @@ $ SDEF (void, bfd_putx16, (bfd_vma, bfd_byte *));
|
|||
|
||||
Byte swapping for the headers
|
||||
|
||||
$ SDEF (bfd_64_type, bfd_h_getx64, (bfd_byte *));
|
||||
$ SDEF (bfd_vma, bfd_h_getx64, (bfd_byte *));
|
||||
$ SDEF (void, bfd_h_putx64, (bfd_vma, bfd_byte *));
|
||||
$ SDEF (bfd_vma, bfd_h_getx32, (bfd_byte *));
|
||||
$ SDEF (void, bfd_h_putx32, (bfd_vma, bfd_byte *));
|
||||
|
@ -290,6 +291,15 @@ extern bfd_target m88k_bcs_vec;
|
|||
extern bfd_target m68kcoff_vec;
|
||||
extern bfd_target i386coff_vec;
|
||||
extern bfd_target a29kcoff_big_vec;
|
||||
|
||||
#ifdef SELECT_VECS
|
||||
|
||||
bfd_target *target_vector[] = {
|
||||
SELECT_VECS,
|
||||
0
|
||||
|
||||
};
|
||||
#else
|
||||
#ifdef DEFAULT_VECTOR
|
||||
extern bfd_target DEFAULT_VECTOR;
|
||||
#endif
|
||||
|
@ -318,6 +328,7 @@ extern bfd_target DEFAULT_VECTOR;
|
|||
#define I386COFF_VEC i386coff_vec
|
||||
#define A29KCOFF_BIG_VEC a29kcoff_big_vec
|
||||
#endif
|
||||
|
||||
bfd_target *target_vector[] = {
|
||||
|
||||
#ifdef DEFAULT_VECTOR
|
||||
|
@ -389,6 +400,7 @@ bfd_target *target_vector[] = {
|
|||
NULL, /* end of list marker */
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
/* default_vector[0] contains either the address of the default vector,
|
||||
if there is one, or zero if there isn't. */
|
||||
|
@ -411,8 +423,8 @@ environment variable GNUTARGET; if that is null or not defined then
|
|||
the first entry in the target list is chosen. Passing in the
|
||||
string "default" or setting the environment variable to "default"
|
||||
will cause the first entry in the target list to be returned,
|
||||
and "target_defaulted" will be set in the bfd. This causes
|
||||
bfd_check_format to loop over all the targets to find the one
|
||||
and "target_defaulted" will be set in the BFD. This causes
|
||||
@code{bfd_check_format} to loop over all the targets to find the one
|
||||
that matches the file being read.
|
||||
*; PROTO(bfd_target *, bfd_find_target,(CONST char *, bfd *));
|
||||
*-*/
|
||||
|
@ -447,7 +459,7 @@ DEFUN(bfd_find_target,(target_name, abfd),
|
|||
/*proto*
|
||||
*i bfd_target_list
|
||||
This function returns a freshly malloced NULL-terminated vector of the
|
||||
names of all the valid bfd targets. Do not modify the names
|
||||
names of all the valid BFD targets. Do not modify the names
|
||||
*; PROTO(CONST char **,bfd_target_list,());
|
||||
|
||||
*-*/
|
||||
|
@ -470,8 +482,6 @@ CONST char **name_list, **name_ptr;
|
|||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
|
||||
for (target = &target_vector[0]; *target != NULL; target++)
|
||||
*(name_ptr++) = (*target)->name;
|
||||
|
||||
|
|
Loading…
Reference in New Issue