New documentation style

This commit is contained in:
Steve Chamberlain 1991-11-30 21:41:22 +00:00
parent 8978401fd1
commit 9fda1a399c
2 changed files with 628 additions and 500 deletions

View File

@ -19,81 +19,88 @@ 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. */
/*doc*
@section Architectures
BFD's idea of an architecture is implimented in @code{archures.c}. BFD
keeps one atom in a BFD describing the architecture of the data
attached to the BFD; a pointer to a @code{bfd_arch_info_type}.
/*
Pointers to structures can be requested independently of a bfd so that
an architecture's information can be interrogated without access to an
open bfd.
SECTION
Architectures
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
@code{config\/h\-} file of your choice. If the name is not defined,
then all the architectures supported are included.
DESCRIPTION
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).
BFD's idea of an architecture is implimented in
<<archures.c>>. BFD keeps one atom in a BFD describing the
architecture of the data attached to the BFD; a pointer to a
<<bfd_arch_info_type>>.
Pointers to structures can be requested independently of a bfd
so that an architecture's 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
<<SELECT_ARCHITECTURES>>. This is normally set up in the
<<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
This enum gives the object file's CPU
architecture, in a global sense. E.g. what processor family does it
belong to? There is another field, which indicates what processor
within the family is in use. The machine gives a number which
distingushes different versions of the architecture, containing for
example 2 and 3 for Intel i960 KA and i960 KB, and 68020 and 68030 for
Motorola 68020 and 68030.
/*
*+
enum bfd_architecture
{
bfd_arch_unknown, {* File arch not known *}
bfd_arch_obscure, {* Arch known, not one of these *}
bfd_arch_m68k, {* Motorola 68xxx *}
bfd_arch_vax, {* DEC Vax *}
bfd_arch_i960, {* Intel 960 *}
{* The order of the following is important.
lower number indicates a machine type that
only accepts a subset of the instructions
available to machines with higher numbers.
The exception is the "ca", which is
incompatible with all other machines except
"core". *}
SUBSECTION
bfd_architecture
#define bfd_mach_i960_core 1
#define bfd_mach_i960_ka_sa 2
#define bfd_mach_i960_kb_sb 3
#define bfd_mach_i960_mc 4
#define bfd_mach_i960_xa 5
#define bfd_mach_i960_ca 6
DESCRIPTION
This enum gives the object file's CPU architecture, in a
global sense. E.g. what processor family does it belong to?
There is another field, which indicates what processor within
the family is in use. The machine gives a number which
distingushes different versions of the architecture,
containing for example 2 and 3 for Intel i960 KA and i960 KB,
and 68020 and 68030 for Motorola 68020 and 68030.
bfd_arch_a29k, {* AMD 29000 *}
bfd_arch_sparc, {* SPARC *}
bfd_arch_mips, {* MIPS Rxxxx *}
bfd_arch_i386, {* Intel 386 *}
bfd_arch_ns32k, {* National Semiconductor 32xxx *}
bfd_arch_tahoe, {* CCI/Harris Tahoe *}
bfd_arch_i860, {* Intel 860 *}
bfd_arch_romp, {* IBM ROMP PC/RT *}
bfd_arch_alliant, {* Alliant *}
bfd_arch_convex, {* Convex *}
bfd_arch_m88k, {* Motorola 88xxx *}
bfd_arch_pyramid, {* Pyramid Technology *}
bfd_arch_h8300, {* Hitachi H8/300 *}
bfd_arch_rs6000, {* IBM RS/6000 *}
bfd_arch_last
};
*-
.enum bfd_architecture
.{
. bfd_arch_unknown, {* File arch not known *}
. bfd_arch_obscure, {* Arch known, not one of these *}
. bfd_arch_m68k, {* Motorola 68xxx *}
. bfd_arch_vax, {* DEC Vax *}
. bfd_arch_i960, {* Intel 960 *}
. {* The order of the following is important.
. lower number indicates a machine type that
. only accepts a subset of the instructions
. available to machines with higher numbers.
. The exception is the "ca", which is
. incompatible with all other machines except
. "core". *}
.
.#define bfd_mach_i960_core 1
.#define bfd_mach_i960_ka_sa 2
.#define bfd_mach_i960_kb_sb 3
.#define bfd_mach_i960_mc 4
.#define bfd_mach_i960_xa 5
.#define bfd_mach_i960_ca 6
.
. bfd_arch_a29k, {* AMD 29000 *}
. bfd_arch_sparc, {* SPARC *}
. bfd_arch_mips, {* MIPS Rxxxx *}
. bfd_arch_i386, {* Intel 386 *}
. bfd_arch_ns32k, {* National Semiconductor 32xxx *}
. bfd_arch_tahoe, {* CCI/Harris Tahoe *}
. bfd_arch_i860, {* Intel 860 *}
. bfd_arch_romp, {* IBM ROMP PC/RT *}
. bfd_arch_alliant, {* Alliant *}
. bfd_arch_convex, {* Convex *}
. bfd_arch_m88k, {* Motorola 88xxx *}
. bfd_arch_pyramid, {* Pyramid Technology *}
. bfd_arch_h8300, {* Hitachi H8/300 *}
. bfd_arch_rs6000, {* IBM RS/6000 *}
. bfd_arch_last
. };
stuff
*/
@ -105,49 +112,58 @@ stuff
#include "sysdep.h"
#include "libbfd.h"
/*proto* bfd_arch_info
This structure contains information on architectures.
*+
typedef int bfd_reloc_code_type;
/*
typedef struct bfd_arch_info
{
int bits_per_word;
int bits_per_address;
int bits_per_byte;
enum bfd_architecture arch;
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 * EXFUN((*compatible),(CONST struct bfd_arch_info *a,
CONST struct bfd_arch_info *b));
SUBSECTION
bfd_arch_info
boolean EXFUN((*scan),(CONST struct bfd_arch_info *,CONST char *));
unsigned int EXFUN((*disassemble),(bfd_vma addr, CONST char *data,
PTR stream));
CONST struct reloc_howto_struct *EXFUN((*reloc_type_lookup), (CONST struct
bfd_arch_info *,
bfd_reloc_code_type code));
DESCRIPTION
This structure contains information on architectures for use
within BFD.
struct bfd_arch_info *next;
} bfd_arch_info_type;
*-
.typedef int bfd_reloc_code_type;
.
.typedef struct bfd_arch_info
.{
. int bits_per_word;
. int bits_per_address;
. int bits_per_byte;
. enum bfd_architecture arch;
. 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 * EXFUN((*compatible),
. (CONST struct bfd_arch_info *a,
. CONST struct bfd_arch_info *b));
.
. boolean EXFUN((*scan),(CONST struct bfd_arch_info *,CONST char *));
. unsigned int EXFUN((*disassemble),(bfd_vma addr, CONST char *data,
. PTR stream));
. CONST struct reloc_howto_struct *EXFUN((*reloc_type_lookup),
. (CONST struct bfd_arch_info *,
. bfd_reloc_code_type code));
.
. struct bfd_arch_info *next;
.
.} bfd_arch_info_type;
*/
bfd_arch_info_type *bfd_arch_info_list;
/*proto* bfd_printable_name
/*
Return a printable string representing the architecture and machine
from the pointer to the arch info structure
FUNCTION
bfd_printable_name
*; CONST char *EXFUN(bfd_printable_name,(bfd *abfd));
DESCRIPTION
Return a printable string representing the architecture and machine
from the pointer to the arch info structure
SYNOPSIS
CONST char *bfd_printable_name(bfd *abfd);
*/
@ -160,14 +176,18 @@ DEFUN(bfd_printable_name, (abfd),
/*proto*
*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.
/*
FUNCTION
bfd_scan_arch
*; bfd_arch_info_type *EXFUN(bfd_scan_arch,(CONST char *));
DESCRIPTION
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.
SYNOPSIS
bfd_arch_info_type *bfd_scan_arch(CONST char *);
*/
bfd_arch_info_type *
@ -189,16 +209,23 @@ DEFUN(bfd_scan_arch,(string),
/*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.
/*
FUNCTION
bfd_arch_get_compatible
*; CONST bfd_arch_info_type *EXFUN(bfd_arch_get_compatible,
(CONST bfd *abfd,
CONST bfd *bbfd));
DESCRIPTION
This routine is used to determine whether two BFDs'
architectures and achine 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.
SYNOPSIS
CONST bfd_arch_info_type *bfd_arch_get_compatible(
CONST bfd *abfd,
CONST bfd *bbfd);
*/
CONST bfd_arch_info_type *
@ -211,25 +238,36 @@ CONST bfd *bbfd)
}
/*proto-internal* bfd_default_arch_struct
/*
INTERNAL
What bfds are seeded with
SUBSECTION
bfd_default_arch_struct
DESCRIPTION
What bfds are seeded with
.extern bfd_arch_info_type bfd_default_arch_struct;
*+
extern bfd_arch_info_type bfd_default_arch_struct;
*-
*/
bfd_arch_info_type bfd_default_arch_struct =
{
{
32,32,8,bfd_arch_unknown,0,"unknown","unknown",true,
bfd_default_compatible, bfd_default_scan,
bfd_default_compatible,
bfd_default_scan,
0,
bfd_default_reloc_type_lookup
};
};
/*proto* bfd_set_arch_info
/*
FUNCTION
bfd_set_arch_info
*; void EXFUN(bfd_set_arch_info,(bfd *, bfd_arch_info_type *));
SYNOPSIS
void bfd_set_arch_info(bfd *, bfd_arch_info_type *);
*/
@ -240,14 +278,20 @@ bfd_arch_info_type *arg)
abfd->arch_info = arg;
}
/*proto-internal* bfd_default_set_arch_mach
/*
INTERNAL FUNCTION
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.
DESCRIPTION
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));
SYNOPSIS
boolean bfd_default_set_arch_mach(bfd *abfd,
enum bfd_architecture arch,
unsigned long mach);
*/
@ -293,39 +337,50 @@ boolean DEFUN(bfd_default_set_arch_mach,(abfd, arch, mach),
/*proto* bfd_get_arch
/*
FUNCTION
bfd_get_arch
Returns the enumerated type which describes the supplied bfd's
architecture
DESCRIPTION
Returns the enumerated type which describes the supplied bfd's
architecture
*; enum bfd_architecture EXFUN(bfd_get_arch, (bfd *abfd));
SYNOPSIS
enum bfd_architecture bfd_get_arch(bfd *abfd);
*/
enum bfd_architecture DEFUN(bfd_get_arch, (abfd), bfd *abfd)
{
enum bfd_architecture DEFUN(bfd_get_arch, (abfd), bfd *abfd)
{
return abfd->arch_info->arch;
}
/*
FUNCTION
bfd_get_mach
}
DESCRIPTION
Returns the long type which describes the supplied bfd's
machine
/*proto* bfd_get_mach
Returns the long type which describes the supplied bfd's
machine
*; unsigned long EXFUN(bfd_get_mach, (bfd *abfd));
SYNOPSIS
unsigned long bfd_get_mach(bfd *abfd);
*/
unsigned long DEFUN(bfd_get_mach, (abfd), bfd *abfd)
unsigned long
DEFUN(bfd_get_mach, (abfd), bfd *abfd)
{
return abfd->arch_info->mach;
}
}
/*proto* bfd_arch_bits_per_byte
/*
FUNCTION
bfd_arch_bits_per_byte
Returns the number of bits in one of the architectures bytes
DESCRIPTION
Returns the number of bits in one of the architectures bytes
*; unsigned int EXFUN(bfd_arch_bits_per_byte, (bfd *abfd));
SYNOPSIS
unsigned int bfd_arch_bits_per_byte(bfd *abfd);
*/
unsigned int DEFUN(bfd_arch_bits_per_byte, (abfd), bfd *abfd)
@ -333,11 +388,15 @@ unsigned int DEFUN(bfd_arch_bits_per_byte, (abfd), bfd *abfd)
return abfd->arch_info->bits_per_byte;
}
/*proto* bfd_arch_bits_per_address
/*
FUNCTION
bfd_arch_bits_per_address
Returns the number of bits in one of the architectures addresses
DESCRIPTION
Returns the number of bits in one of the architectures addresses
*; unsigned int EXFUN(bfd_arch_bits_per_address, (bfd *abfd));
SYNOPSIS
unsigned int bfd_arch_bits_per_address(bfd *abfd);
*/
unsigned int DEFUN(bfd_arch_bits_per_address, (abfd), bfd *abfd)
@ -382,33 +441,42 @@ static void EXFUN((*archures_init_table[]),()) =
/*proto-internal*
/*
INTERNAL FUNCTION
bfd_arch_init
This routine initializes the architecture dispatch table by calling
all installed architecture packages and getting them to poke around.
DESCRIPTION
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));
SYNOPSIS
void bfd_arch_init(void);
*/
void
DEFUN_VOID(bfd_arch_init)
{
void EXFUN((**ptable),());
for (ptable = archures_init_table;
*ptable ;
ptable++)
{
void EXFUN((**ptable),());
for (ptable = archures_init_table;
*ptable ;
ptable++)
{
(*ptable)();
}
}
}
/*proto-internal* bfd_arch_linkin
/*
INTERNAL FUNCTION
bfd_arch_linkin
Link the provided arch info structure into the list
DESCRIPTION
Link the provided arch info structure into the list
*; void EXFUN(bfd_arch_linkin,(bfd_arch_info_type *));
SYNOPSIS
void bfd_arch_linkin(bfd_arch_info_type *);
*/
@ -420,13 +488,17 @@ void DEFUN(bfd_arch_linkin,(ptr),
}
/*proto-internal* bfd_default_compatible
/*
INTERNAL FUNCTION
bfd_default_compatible
The default function for testing for compatibility
DESCRIPTION
The default function for testing for compatibility.
*; CONST bfd_arch_info_type *EXFUN(bfd_default_compatible,
(CONST bfd_arch_info_type *a,
CONST bfd_arch_info_type *b));
SYNOPSIS
CONST bfd_arch_info_type *bfd_default_compatible
(CONST bfd_arch_info_type *a,
CONST bfd_arch_info_type *b);
*/
CONST bfd_arch_info_type *
@ -445,11 +517,17 @@ DEFUN(bfd_default_compatible,(a,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 *, CONST char *));
/*
INTERNAL FUNCTION
bfd_default_scan
DESCRIPTION
The default function for working out whether this is an
architecture hit and a machine hit.
SYNOPSIS
boolean bfd_default_scan(CONST struct bfd_arch_info *, CONST char *);
*/
@ -458,98 +536,103 @@ DEFUN(bfd_default_scan,(info, string),
CONST struct bfd_arch_info *info AND
CONST char *string)
{
CONST char *ptr_src;
CONST char *ptr_tst;
unsigned long number;
enum bfd_architecture arch;
/* First test for an exact match */
if (strcmp(string, info->printable_name) == 0) return true;
CONST char *ptr_src;
CONST char *ptr_tst;
unsigned long number;
enum bfd_architecture arch;
/* First test for an exact match */
if (strcmp(string, info->printable_name) == 0) return true;
/* 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 */
/* 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 */
for (ptr_src = string,
ptr_tst = info->arch_name;
*ptr_src && *ptr_tst;
ptr_src++,
ptr_tst++)
{
for (ptr_src = string,
ptr_tst = info->arch_name;
*ptr_src && *ptr_tst;
ptr_src++,
ptr_tst++)
{
if (*ptr_src != *ptr_tst) break;
}
}
/* Chewed up as much of the architecture as will match, skip any
colons */
if (*ptr_src == ':') ptr_src++;
/* Chewed up as much of the architecture as will match, skip any
colons */
if (*ptr_src == ':') ptr_src++;
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++;
}
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:
case 68000:
arch = bfd_arch_m68k;
break;
case 386:
case 80386:
case 486:
arch = bfd_arch_i386;
break;
case 29000:
arch = bfd_arch_a29k;
break;
switch (number)
{
case 68010:
case 68020:
case 68030:
case 68040:
case 68332:
case 68050:
case 68000:
arch = bfd_arch_m68k;
break;
case 386:
case 80386:
case 486:
arch = bfd_arch_i386;
break;
case 29000:
arch = bfd_arch_a29k;
break;
case 32016:
case 32032:
case 32132:
case 32232:
case 32332:
case 32432:
case 32532:
case 32000:
arch = bfd_arch_ns32k;
break;
case 32016:
case 32032:
case 32132:
case 32232:
case 32332:
case 32432:
case 32532:
case 32000:
arch = bfd_arch_ns32k;
break;
case 860:
case 80860:
arch = bfd_arch_i860;
break;
case 860:
case 80860:
arch = bfd_arch_i860;
break;
case 6000:
arch = bfd_arch_rs6000;
break;
case 6000:
arch = bfd_arch_rs6000;
break;
default:
return false;
}
if (arch != info->arch)
return false;
default:
return false;
}
if (arch != info->arch)
return false;
if (number != info->mach)
return false;
if (number != info->mach)
return false;
return true;
return true;
}
/*proto* bfd_get_arch_info
/*
FUNCTION
bfd_get_arch_info
*; bfd_arch_info_type * EXFUN(bfd_get_arch_info,(bfd *));
SYNOPSIS
bfd_arch_info_type * bfd_get_arch_info(bfd *);
*/
@ -561,14 +644,24 @@ bfd *abfd)
}
/*proto* bfd_lookup_arch
*; bfd_arch_info_type * EXFUN(bfd_lookup_arch,(enum
bfd_architecture arch,long machine));
/*
FUNCTION
bfd_lookup_arch
DESCRIPTION
Look for the architecure info struct which matches the
arguments given. A machine of 0 will match the
machine/architecture structure which marks itself as the
default.
SYNOPSIS
bfd_arch_info_type *bfd_lookup_arch
(enum bfd_architecture
arch,
long machine);
Look for the architecure info struct which matches the arguments
given. A machine of 0 will match the machine/architecture structure which
marks itself as the default.
*/
@ -577,29 +670,35 @@ DEFUN(bfd_lookup_arch,(arch, machine),
enum bfd_architecture arch AND
long machine)
{
bfd_arch_info_type *ap;
bfd_check_init();
for (ap = bfd_arch_info_list;
ap != (bfd_arch_info_type *)NULL;
ap = ap->next) {
if (ap->arch == arch &&
((ap->mach == machine) || (ap->the_default && machine == 0))) {
return ap;
}
}
return (bfd_arch_info_type *)NULL;
bfd_arch_info_type *ap;
bfd_check_init();
for (ap = bfd_arch_info_list;
ap != (bfd_arch_info_type *)NULL;
ap = ap->next) {
if (ap->arch == arch &&
((ap->mach == machine)
|| (ap->the_default && machine == 0))) {
return ap;
}
}
return (bfd_arch_info_type *)NULL;
}
/*proto* bfd_printable_arch_mach
Return a printable string representing the architecture and machine
type.
/*
FUNCTION
bfd_printable_arch_mach
NB. The use of this routine is depreciated.
DESCRIPTION
Return a printable string representing the architecture and
machine type.
*; PROTO(CONST char *,bfd_printable_arch_mach,
(enum bfd_architecture arch, unsigned long machine));
NB. The use of this routine is depreciated.
SYNOPSIS
CONST char * bfd_printable_arch_mach
(enum bfd_architecture arch, unsigned long machine);
*/
CONST char *
@ -607,7 +706,7 @@ DEFUN(bfd_printable_arch_mach,(arch, machine),
enum bfd_architecture arch AND
unsigned long machine)
{
bfd_arch_info_type *ap = bfd_lookup_arch(arch, machine);
if(ap) return ap->printable_name;
return "UNKNOWN!";
bfd_arch_info_type *ap = bfd_lookup_arch(arch, machine);
if(ap) return ap->printable_name;
return "UNKNOWN!";
}

View File

@ -18,231 +18,249 @@ 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. */
/*doc*
@section coff backends
/*
BFD supports a number of different flavours of coff format. The major
difference between formats are the sizes and alignments of fields in
structures on disk, and the occasional extra field.
SECTION
coff backends
Coff in all its varieties is implimented with a few common files and a
number of implementation specific files. For example, The 88k bcs coff
format is implemented in the file @code{coff-m88k.c}. This file
@code{#include}s @code{coff-m88k.h} which defines the external
structure of the coff format for the 88k, and @code{internalcoff.h}
which defines the internal structure. @code{coff-m88k.c} also defines
the relocations used by the 88k format @xref{Relocations}. Then the
major portion of coff code is included (@code{coffcode.h}) which
defines the methods used to act upon the types defined in
@code{coff-m88k.h} and @code{internalcoff.h}.
DESCRIPTION
BFD supports a number of different flavours of coff format.
The major difference between formats are the sizes and
alignments of fields in structures on disk, and the occasional
extra field.
The Intel i960 processor version of coff is implemented in
@code{coff-i960.c}. This file has the same structure as
@code{coff-m88k.c}, except that it includes @code{coff-i960.h} rather
than @code{coff-m88k.h}.
Coff in all its varieties is implimented with a few common
files and a number of implementation specific files. For
example, The 88k bcs coff format is implemented in the file
@code{coff-m88k.c}. This file @code{#include}s
@code{coff-m88k.h} which defines the external structure of the
coff format for the 88k, and @code{internalcoff.h} which
defines the internal structure. @code{coff-m88k.c} also
defines pthe relocations used by the 88k format
@xref{Relocations}. Then the major portion of coff code is
included (@code{coffcode.h}) which defines the methods used to
act upon the types defined in @code{coff-m88k.h} and
@code{internalcoff.h}.
@subsection Porting To A New Version of Coff
The recommended method is to select from the existing implimentations
the version of coff which is most like the one you want to use, for
our purposes, we'll say that i386 coff is the one you select, and that
your coff flavour is called foo. Copy the @code{i386coff.c} to @code{foocoff.c},
copy @code{../include/i386coff.h} to @code{../include/foocoff.h} and
add the lines to @code{targets.c} and @code{Makefile.in} so that your
new back end is used.
The Intel i960 processor version of coff is implemented in
@code{coff-i960.c}. This file has the same structure as
@code{coff-m88k.c}, except that it includes @code{coff-i960.h}
rather than @code{coff-m88k.h}.
Alter the shapes of the structures in @code{../include/foocoff.h} so
that they match what you need. You will probably also have to add
@code{#ifdef}s to the code in @code{internalcoff.h} and
@code{coffcode.h} if your version of coff is too wild.
SUBSECTION
Porting To A New Version of Coff
You can verify that your new BFD backend works quite simply by
building @code{objdump} from the @code{binutils} directory, and
making sure that its version of what's going on at your host systems
idea (assuming it has the pretty standard coff dump utility (usually
called @code{att-dump} or just @code{dump})) are the same.
DESCRIPTION
The recommended method is to select from the existing
implimentations the version of coff which is most like the one
you want to use, for our purposes, we'll say that i386 coff is
the one you select, and that your coff flavour is called foo.
Copy the @code{i386coff.c} to @code{foocoff.c}, copy
@code{../include/i386coff.h} to @code{../include/foocoff.h}
and add the lines to @code{targets.c} and @code{Makefile.in}
so that your new back end is used. Alter the shapes of the
structures in @code{../include/foocoff.h} so that they match
what you need. You will probably also have to add
@code{#ifdef}s to the code in @code{internalcoff.h} and
@code{coffcode.h} if your version of coff is too wild.
Then clean up your code, and send what you've done to Cygnus. Then your stuff
will be in the next release, and you won't have to keep integrating
it.
You can verify that your new BFD backend works quite simply by
building @code{objdump} from the @code{binutils} directory,
and making sure that its version of what's going on at your
host systems idea (assuming it has the pretty standard coff
dump utility (usually called @code{att-dump} or just
@code{dump})) are the same. Then clean up your code, and send
what you've done to Cygnus. Then your stuff will be in the
next release, and you won't have to keep integrating it.
@subsection How The Coff Backend Works
SUBSECTION
How The Coff Backend Works
@subsubsection Bit Twiddling
Each flavour of coff supported in BFD has its own header file
descibing the external layout of the structures. There is also an
internal description of the coff layout (in @code{internalcoff.h})
file (@code{}). A major function of the coff backend is swapping the
bytes and twiddling the bits to translate the external form of the
structures into the normal internal form. This is all performed in the
@code{bfd_swap}_@i{thing}_@i{direction} routines. Some elements are
different sizes between different versions of coff, it is the duty of
the coff version specific include file to override the definitions of
various packing routines in @code{coffcode.h}. Eg the size of line
number entry in coff is sometimes 16 bits, and sometimes 32 bits.
@code{#define}ing @code{PUT_LNSZ_LNNO} and @code{GET_LNSZ_LNNO} will
select the correct one. No doubt, some day someone will find a version
of coff which has a varying field size not catered for at the moment.
To port BFD, that person will have to add more @code{#defines}.
SUBSUBSECTION
Bit Twiddling
Three of the bit twiddling routines are exported to @code{gdb};
@code{coff_swap_aux_in}, @code{coff_swap_sym_in} and
@code{coff_swap_linno_in}. @code{GDB} reads the symbol table on its
own, but uses BFD to fix things up.
DESCRIPTION
Each flavour of coff supported in BFD has its own header file
descibing the external layout of the structures. There is also
an internal description of the coff layout (in
@code{internalcoff.h}) file (@code{}). A major function of the
coff backend is swapping the bytes and twiddling the bits to
translate the external form of the structures into the normal
internal form. This is all performed in the
@code{bfd_swap}_@i{thing}_@i{direction} routines. Some
elements are different sizes between different versions of
coff, it is the duty of the coff version specific include file
to override the definitions of various packing routines in
@code{coffcode.h}. Eg the size of line number entry in coff is
sometimes 16 bits, and sometimes 32 bits. @code{#define}ing
@code{PUT_LNSZ_LNNO} and @code{GET_LNSZ_LNNO} will select the
correct one. No doubt, some day someone will find a version of
coff which has a varying field size not catered for at the
moment. To port BFD, that person will have to add more @code{#defines}.
Three of the bit twiddling routines are exported to
@code{gdb}; @code{coff_swap_aux_in}, @code{coff_swap_sym_in}
and @code{coff_swap_linno_in}. @code{GDB} reads the symbol
table on its own, but uses BFD to fix things up. More of the
bit twiddlers are exported for @code{gas};
@code{coff_swap_aux_out}, @code{coff_swap_sym_out},
@code{coff_swap_lineno_out}, @code{coff_swap_reloc_out},
@code{coff_swap_filehdr_out}, @code{coff_swap_aouthdr_out},
@code{coff_swap_scnhdr_out}. @code{Gas} currently keeps track
of all the symbol table and reloc drudgery itself, thereby
saving the internal BFD overhead, but uses BFD to swap things
on the way out, making cross ports much safer. This also
allows BFD (and thus the linker) to use the same header files
as @code{gas}, which makes one avenue to disaster disappear.
More of the bit twiddlers are exported for @code{gas};
@code{coff_swap_aux_out}, @code{coff_swap_sym_out},
@code{coff_swap_lineno_out}, @code{coff_swap_reloc_out},
@code{coff_swap_filehdr_out}, @code{coff_swap_aouthdr_out},
@code{coff_swap_scnhdr_out}. @code{Gas} currently keeps track of all
the symbol table and reloc drudgery itself, thereby saving the
internal BFD overhead, but uses BFD to swap things on the way out,
making cross ports much safer. This also allows BFD (and thus the
linker) to use the same header files as @code{gas}, which makes one
avenue to disaster disappear.
SUBSUBSECTION
Symbol Reading
@subsubsection Symbol Reading
The simple canonical form for symbols used by BFD is not rich enough
to keep all the information available in a coff symbol table. The back
end gets around this by keeping the original symbol table around,
"behind the scenes".
DESCRIPTION
The simple canonical form for symbols used by BFD is not rich
enough to keep all the information available in a coff symbol
table. The back end gets around this by keeping the original
symbol table around, "behind the scenes".
When a symbol table is requested (through a call to
@code{bfd_canonicalize_symtab}, a request gets through to
@code{get_normalized_symtab}. This reads the symbol table from the
coff file and swaps all the structures inside into the internal form.
It also fixes up all the pointers in the table (represented in the file
by offsets from the first symbol in the table) into physical pointers
to elements in the new internal table. This involves some work since
the meanings of fields changes depending upon context; a field that is a
pointer to another structure in the symbol table at one moment may be
the size in bytes of a structure in the next.
When a symbol table is requested (through a call to
@code{bfd_canonicalize_symtab}, a request gets through to
@code{get_normalized_symtab}. This reads the symbol table from
the coff file and swaps all the structures inside into the
internal form. It also fixes up all the pointers in the table
(represented in the file by offsets from the first symbol in
the table) into physical pointers to elements in the new
internal table. This involves some work since the meanings of
fields changes depending upon context; a field that is a
pointer to another structure in the symbol table at one moment
may be the size in bytes of a structure in the next. Another
pass is made over the table. All symbols which mark file names
(@code{C_FILE} symbols) are modified so that the internal
string points to the value in the auxent (the real filename)
rather than the normal text associated with the symbol
(@code{".file"}).
Another pass is made over the table. All symbols which mark file names
(@code{C_FILE} symbols) are modified so that the internal string
points to the value in the auxent (the real filename) rather than the
normal text associated with the symbol (@code{".file"}).
At this time the symbol names are moved around. Coff stores
all symbols less than nine characters long physically
within the symbol table, longer strings are kept at the end of
the file in the string table. This pass moves all strings
into memory, and replaces them with pointers to the strings.
At this time the symbol names are moved around. Coff stores all
symbols less than nine characters long physically within the symbol
table, longer strings are kept at the end of the file in the string
table. This pass moves all strings into memory, and replaces them with
pointers to the strings.
The symbol table is massaged once again, this time to create the
canonical table used by the BFD application. Each symbol is inspected
in turn, and a decision made (using the @code{sclass} field) about the
various flags to set in the @code{asymbol} @xref{Symbols}. The
generated canonical table shares strings with the hidden internal
symbol table.
The symbol table is massaged once again, this time to create
the canonical table used by the BFD application. Each symbol
is inspected in turn, and a decision made (using the
@code{sclass} field) about the various flags to set in the
@code{asymbol} @xref{Symbols}. The generated canonical table
shares strings with the hidden internal symbol table.
Any linenumbers are read from the coff file too, and attached to the
symbols which own the functions the linenumbers belong to.
Any linenumbers are read from the coff file too, and attached
to the symbols which own the functions the linenumbers belong to.
@subsubsection Symbol Writing
Writing a symbol to a coff file which didn't come from a coff file
will lose any debugging information. The @code{asymbol} structure
remembers the BFD from which was born, and on output the back end
makes sure that the same destination target as source target is
present.
SUBSUBSECTION
Symbol Writing
When the symbols have come from a coff file then all the debugging
information is preserved.
Symbol tables are provided for writing to the back end in a vector of
pointers to pointers. This allows applications like the linker to
accumulate and output large symbol tables without having to do too
much byte copying.
DESCRIPTION
Writing a symbol to a coff file which didn't come from a coff
file will lose any debugging information. The @code{asymbol}
structure remembers the BFD from which was born, and on output
the back end makes sure that the same destination target as
source target is present.
The symbol table is not output to a writable BFD until it is closed.
The order of operations on the canonical symbol table at that point
are:
@table @code
@item coff_renumber_symbols
This function runs through the provided symbol table and patches each
symbol marked as a file place holder (@code{C_FILE}) to point to the
next file place holder in the list. It also marks each @code{offset}
field in the list with the offset from the first symbol of the current
symbol.
When the symbols have come from a coff file then all the
debugging information is preserved.
Symbol tables are provided for writing to the back end in a
vector of pointers to pointers. This allows applications like
the linker to accumulate and output large symbol tables
without having to do too much byte copying.
This function runs through the provided symbol table and
patches each symbol marked as a file place holder
(@code{C_FILE}) to point to the next file place holder in the
list. It also marks each @code{offset} field in the list with
the offset from the first symbol of the current symbol.
Another function of this procedure is to turn the canonical
value form of BFD into the form used by coff. Internally, BFD
expects symbol values to be offsets from a section base; so a
symbol physically at 0x120, but in a section starting at
0x100, would have the value 0x20. Coff expects symbols to
contain their final value, so symbols have their values
changed at this point to reflect their sum with their owning
section. Note that this transformation uses the
<<output_section>> field of the @code{asymbol}'s
@code{asection} @xref{Sections}.
o coff_mangle_symbols
This routine runs though the provided symbol table and uses
the offsets generated by the previous pass and the pointers
generated when the symbol table was read in to create the
structured hierachy required by coff. It changes each pointer
to a symbol to an index into the symbol table of the symbol
being referenced.
o coff_write_symbols
This routine runs through the symbol table and patches up the
symbols from their internal form into the coff way, calls the
bit twiddlers and writes out the tabel to the file.
Another function of this procedure is to turn the canonical value form
of BFD into the form used by coff. Internally, BFD expects symbol
values to be offsets from a section base; so a symbol physically at
0x120, but in a section starting at 0x100, would have the value 0x20.
Coff expects symbols to contain their final value, so symbols have
their values changed at this point to reflect their sum with their
owning section. Note that this transformation uses the
@code{output_section} field of the @code{asymbol}'s @code{asection}
@xref{Sections}.
@item coff_mangle_symbols
This routine runs though the provided symbol table and uses the
offsets generated by the previous pass and the pointers generated when
the symbol table was read in to create the structured hierachy
required by coff. It changes each pointer to a symbol to an index into
the symbol table of the symbol being referenced.
@item coff_write_symbols
This routine runs through the symbol table and patches up the symbols
from their internal form into the coff way, calls the bit twiddlers
and writes out the tabel to the file.
@end table
*/
/*proto*
/*
INTERNAL
The hidden information for an asymbol is:
*+++
The hidden information for an asymbol is described in a
coff_ptr_struct, which is typedefed to a combined_entry_type
$ typedef struct coff_ptr_struct
$ {
.typedef struct coff_ptr_struct
.{
Remembers the offset from the first symbol in the file for this
symbol. Generated by @code{coff_renumber_symbols}.
Remembers the offset from the first symbol in the file for
this symbol. Generated by @code{coff_renumber_symbols}.
$ unsigned int offset;
.unsigned int offset;
Should the tag field of this symbol be renumbered.
Created by @code{coff_pointerize_aux}.
Should the tag field of this symbol be renumbered.
Created by @code{coff_pointerize_aux}.
$ char fix_tag;
.char fix_tag;
Should the endidx field of this symbol be renumbered.
Created by @code{coff_pointerize_aux}.
Should the endidx field of this symbol be renumbered.
Created by @code{coff_pointerize_aux}.
$ char fix_end;
.char fix_end;
The container for the symbol structure as read and translated from the file.
The container for the symbol structure as read and translated
from the file.
$ union {
$ union internal_auxent auxent;
$ struct internal_syment syment;
$ } u;
$ } combined_entry_type;
$
.union {
. union internal_auxent auxent;
. struct internal_syment syment;
. } u;
.} combined_entry_type;
*---
Each canonical asymbol really looks like this:
Each canonical asymbol really looks like this:
.typedef struct coff_symbol_struct
.{
*+++
The actual symbol which the rest of BFD works with
$ typedef struct coff_symbol_struct
$ {
.asymbol symbol;
The actual symbol which the rest of BFD works with
A pointer to the hidden information for this symbol
$ asymbol symbol;
.combined_entry_type *native;
A pointer to the hidden information for this symbol
A pointer to the linenumber information for this symbol
$ combined_entry_type *native;
.struct lineno_cache_entry *lineno;
.} coff_symbol_type;
A pointer to the linenumber information for this symbol
$ struct lineno_cache_entry *lineno;
$ } coff_symbol_type;
*---
*/
@ -1635,17 +1653,21 @@ DEFUN(coff_write_symbols,(abfd),
}
}
/*doc*
@subsubsection Writing Relocations
To write a relocations, all the back end does is step though the
canonical relocation table, and create an @code{internal_reloc}. The
symbol index to use is removed from the @code{offset} field in the
symbol table supplied, the address comes directly from the sum of the
section base address and the relocation offset and the type is dug
directly from the howto field.
/*
SUBSUBSECTION
Writing Relocations
DESCRIPTION
To write relocations, all the back end does is step though the
canonical relocation table, and create an
@code{internal_reloc}. The symbol index to use is removed from
the @code{offset} field in the symbol table supplied, the
address comes directly from the sum of the section base
address and the relocation offset and the type is dug directly
from the howto field. Then the @code{internal_reloc} is
swapped into the shape of an @code{external_reloc} and written
out to disk.
Then the @code{internal_reloc} is swapped into the shape of an
@code{external_reloc} and written out to disk.
*/
static void
@ -2693,21 +2715,25 @@ DEFUN(section_from_bfd_index,(abfd, index),
#ifndef NO_COFF_LINENOS
/*doc*
@subsubsection Reading Linenumbers
Createing the linenumber table is done by reading in the entire coff
linenumber table, and creating another table for internal use.
/*
SUBSUBSECTION
Reading Linenumbers
A coff line number table is structured so that each
function is marked as having a line number of 0. Each line within the
function is an offset from the first line in the function. The base of
the line number information for the table is stored in the symbol
associated with the function.
DESCRIPTION
Creating the linenumber table is done by reading in the entire
coff linenumber table, and creating another table for internal use.
The information is copied from the external to the internal table, and
each symbol which marks a function is marked by pointing its...
A coff line number table is structured so that each function
is marked as having a line number of 0. Each line within the
function is an offset from the first line in the function. The
base of the line number information for the table is stored in
the symbol associated with the function.
**How does this work ?**
The information is copied from the external to the internal
table, and each symbol which marks a function is marked by
pointing its...
How does this work ?
*/
@ -3050,31 +3076,34 @@ sec_ptr asect;
return (asect->reloc_count + 1) * sizeof(arelent *);
}
/*doc*
@subsubsection Reading Relocations
Coff relocations are easily transformed into the internal BFD form
(@code{arelent}).
/*
SUBSUBSECTION
Reading Relocations
DESCRIPTION
Coff relocations are easily transformed into the internal BFD form
(@code{arelent}).
Reading a coff relocation table is done in the following stages:
o The entire coff relocation table is read into memory.
o Each relocation is processed in turn, first it is swapped from the
external to the internal form.
o The symbol referenced in the relocation's symbol index is
turned intoa pointer into the canonical symbol table. Note
that this table is the same as the one returned by a call to
@code{bfd_canonicalize_symtab}. The back end will call the
routine and save the result if a canonicalization hasn't been done.
o The reloc index is turned into a pointer to a howto
structure, in a back end specific way. For instance, the 386
and 960 use the @code{r_type} to directly produce an index
into a howto table vector; the 88k subtracts a number from the
@code{r_type} field and creates an addend field.
Reading a coff relocation table is done in the following stages:
@itemize @bullet
@item
The entire coff relocation table is read into memory.
@item
Each relocation is processed in turn, first it is swapped from the
external to the internal form.
@item
The symbol referenced in the relocation's symbol index is turned into
a pointer into the canonical symbol table. Note that this table is the
same as the one returned by a call to @code{bfd_canonicalize_symtab}.
The back end will call the routine and save the result if a
canonicalization hasn't been done.
@item
The reloc index is turned into a pointer to a howto structure, in a
back end specific way. For instance, the 386 and 960 use the
@code{r_type} to directly produce an index into a howto table vector;
the 88k subtracts a number from the @code{r_type} field and creates an
addend field.
@end itemize
*/
#ifndef CALC_ADDEND