[time to file a PR on cvs...]

Various changes to get linker working again for a.out:
 * don't set/adjust section file positions or vmas more than once
 * use correct page size and segment size when calculating them
 * deal with some variations in a.out implementations
Tested on sun4 and sun4->sun3 so far, will be testing further but
needed to get wider exposure&testing.  See ChangeLog for details.

Also:
* coffcode.h (coff_write_relocs): Write out swapped reloc, not
pre-swapped version.
* hosts/sparc.h (abort, exit): Hide these names if compiling with
gcc version 2, to avoid warnings.
This commit is contained in:
Ken Raeburn 1992-06-16 12:04:03 +00:00
parent 41729eb4b0
commit ce07dd7c0c
5 changed files with 437 additions and 220 deletions

View file

@ -1,3 +1,4 @@
#define BFD_AOUT_DEBUG
/* BFD semi-generic back-end for a.out binaries
Copyright (C) 1990-1991 Free Software Foundation, Inc.
Written by Cygnus Support.
@ -108,6 +109,15 @@ DESCRIPTION
*/
/* Some assumptions:
* Any BFD with D_PAGED set is ZMAGIC, and vice versa.
Doesn't matter what the setting of WP_TEXT is on output, but it'll
get set on input.
* Any BFD with D_PAGED clear and WP_TEXT set is NMAGIC.
* Any BFD with both flags clear is OMAGIC.
(Just want to make these explicit, so the conditions tested in this
file make sense if you're more familiar with a.out than with BFD.) */
#define KEEPIT flags
#define KEEPITTYPE int
@ -122,7 +132,7 @@ struct external_exec;
#include "aout/stab_gnu.h"
#include "aout/ar.h"
void (*bfd_error_trap)();
extern void (*bfd_error_trap)();
/*
SUBSECTION
@ -140,8 +150,10 @@ DESCRIPTION
*/
#define CTOR_TABLE_RELOC_IDX 2
#define howto_table_ext NAME(aout,ext_howto_table)
#define howto_table_std NAME(aout,std_howto_table)
static reloc_howto_type howto_table_ext[] =
reloc_howto_type howto_table_ext[] =
{
HOWTO(RELOC_8, 0, 0, 8, false, 0, true, true,0,"8", false, 0,0x000000ff, false),
HOWTO(RELOC_16, 0, 1, 16, false, 0, true, true,0,"16", false, 0,0x0000ffff, false),
@ -172,7 +184,7 @@ static reloc_howto_type howto_table_ext[] =
/* Convert standard reloc records to "arelent" format (incl byte swap). */
static reloc_howto_type howto_table_std[] = {
reloc_howto_type howto_table_std[] = {
/* type rs size bsz pcrel bitpos abs ovrf sf name part_inpl readmask setmask pcdone */
HOWTO( 0, 0, 0, 8, false, 0, true, true,0,"8", true, 0x000000ff,0x000000ff, false),
HOWTO( 1, 0, 1, 16, false, 0, true, true,0,"16", true, 0x0000ffff,0x0000ffff, false),
@ -185,7 +197,7 @@ HOWTO( 7, 0, 3, 64, true, 0, false, true,0,"DISP64", true, 0xfeedfac
};
bfd_error_vector_type bfd_error_vector;
extern bfd_error_vector_type bfd_error_vector;
/*
SUBSECTION
@ -318,8 +330,18 @@ DEFUN(NAME(aout,some_aout_object_p),(abfd, execp, callback_to_real_object_p),
if (execp->a_syms)
abfd->flags |= HAS_LINENO | HAS_DEBUG | HAS_SYMS | HAS_LOCALS;
if (N_MAGIC (*execp) == ZMAGIC) abfd->flags |= D_PAGED;
if (N_MAGIC (*execp) == NMAGIC) abfd->flags |= WP_TEXT;
if (N_MAGIC (*execp) == ZMAGIC)
{
abfd->flags |= D_PAGED|WP_TEXT;
adata(abfd).magic = z_magic;
}
else if (N_MAGIC (*execp) == NMAGIC)
{
abfd->flags |= WP_TEXT;
adata(abfd).magic = n_magic;
}
else
adata(abfd).magic = o_magic;
bfd_get_start_address (abfd) = execp->a_entry;
@ -569,13 +591,248 @@ DEFUN(NAME(aout,set_arch_mach),(abfd, arch, machine),
enum bfd_architecture arch AND
unsigned long machine)
{
bfd_arch_info_type *ainfo;
bfd_default_set_arch_mach(abfd, arch, machine);
if (arch != bfd_arch_unknown &&
NAME(aout,machine_type) (arch, machine) == M_UNKNOWN)
return false; /* We can't represent this type */
BFD_ASSERT (&adata(abfd) != 0);
ainfo = bfd_get_arch_info (abfd);
if (ainfo->segment_size)
adata(abfd).segment_size = ainfo->segment_size;
if (ainfo->page_size)
adata(abfd).page_size = ainfo->page_size;
return true; /* We're easy ... */
}
boolean
DEFUN (NAME (aout,adjust_sizes_and_vmas), (abfd, text_size, text_end),
bfd *abfd AND bfd_size_type *text_size AND file_ptr *text_end)
{
struct internal_exec *execp = exec_hdr (abfd);
if ((obj_textsec (abfd) == NULL) || (obj_datasec (abfd) == NULL))
{
bfd_error = invalid_operation;
return false;
}
if (adata(abfd).magic != undecided_magic) return true;
obj_textsec(abfd)->_raw_size =
align_power(obj_textsec(abfd)->_raw_size,
obj_textsec(abfd)->alignment_power);
*text_size = obj_textsec (abfd)->_raw_size;
/* Rule (heuristic) for when to pad to a new page. Note that there
* are (at least) two ways demand-paged (ZMAGIC) files have been
* handled. Most Berkeley-based systems start the text segment at
* (PAGE_SIZE). However, newer versions of SUNOS start the text
* segment right after the exec header; the latter is counted in the
* text segment size, and is paged in by the kernel with the rest of
* the text. */
/* This perhaps isn't the right way to do this, but made it simpler for me
to understand enough to implement it. Better would probably be to go
right from BFD flags to alignment/positioning characteristics. But the
old code was sloppy enough about handling the flags, and had enough
other magic, that it was a little hard for me to understand. I think
I understand it better now, but I haven't time to do the cleanup this
minute. */
if (adata(abfd).magic == undecided_magic)
{
if (abfd->flags & D_PAGED)
/* whether or not WP_TEXT is set */
adata(abfd).magic = z_magic;
else if (abfd->flags & WP_TEXT)
adata(abfd).magic = n_magic;
else
adata(abfd).magic = o_magic;
}
#ifdef BFD_AOUT_DEBUG /* requires gcc2 */
#if __GNUC__ >= 2
fprintf (stderr, "%s text=<%x,%x,%x> data=<%x,%x,%x> bss=<%x,%x,%x>\n",
({ char *str;
switch (adata(abfd).magic) {
case n_magic: str = "NMAGIC"; break;
case o_magic: str = "OMAGIC"; break;
case z_magic: str = "ZMAGIC"; break;
default: abort ();
}
str;
}),
obj_textsec(abfd)->vma, obj_textsec(abfd)->_raw_size, obj_textsec(abfd)->alignment_power,
obj_datasec(abfd)->vma, obj_datasec(abfd)->_raw_size, obj_datasec(abfd)->alignment_power,
obj_bsssec(abfd)->vma, obj_bsssec(abfd)->_raw_size, obj_bsssec(abfd)->alignment_power);
#endif
#endif
switch (adata(abfd).magic)
{
case o_magic:
{
file_ptr pos = adata (abfd).exec_bytes_size;
bfd_vma vma = 0;
int pad;
obj_textsec(abfd)->filepos = pos;
pos += obj_textsec(abfd)->_raw_size;
vma += obj_textsec(abfd)->_raw_size;
if (!obj_datasec(abfd)->user_set_vma)
{
/* ?? Does alignment in the file image really matter? */
pad = align_power (vma, obj_datasec(abfd)->alignment_power) - vma;
obj_textsec(abfd)->_raw_size += pad;
pos += pad;
vma += pad;
obj_datasec(abfd)->vma = vma;
}
obj_datasec(abfd)->filepos = pos;
pos += obj_datasec(abfd)->_raw_size;
vma += obj_datasec(abfd)->_raw_size;
if (!obj_bsssec(abfd)->user_set_vma)
{
pad = align_power (vma, obj_bsssec(abfd)->alignment_power) - vma;
obj_datasec(abfd)->_raw_size += pad;
pos += pad;
vma += pad;
obj_bsssec(abfd)->vma = vma;
}
obj_bsssec(abfd)->filepos = pos;
execp->a_text = obj_textsec(abfd)->_raw_size;
execp->a_data = obj_datasec(abfd)->_raw_size;
execp->a_bss = obj_bsssec(abfd)->_raw_size;
N_SET_MAGIC (*execp, OMAGIC);
}
break;
case z_magic:
{
bfd_size_type data_pad, text_pad;
file_ptr text_end;
CONST struct aout_backend_data *abdp;
int ztih;
bfd_vma data_vma;
abdp = aout_backend_info (abfd);
ztih = abdp && abdp->text_includes_header;
obj_textsec(abfd)->filepos = (ztih
? adata(abfd).exec_bytes_size
: adata(abfd).page_size);
if (! obj_textsec(abfd)->user_set_vma)
/* ?? Do we really need to check for relocs here? */
obj_textsec(abfd)->vma = ((abfd->flags & HAS_RELOC)
? 0
: (ztih
? (abdp->default_text_vma
+ adata(abfd).exec_bytes_size)
: abdp->default_text_vma));
/* Could take strange alignment of text section into account here? */
/* Find start of data. */
text_end = obj_textsec(abfd)->filepos + obj_textsec(abfd)->_raw_size;
text_pad = BFD_ALIGN (text_end, adata(abfd).page_size) - text_end;
obj_textsec(abfd)->_raw_size += text_pad;
text_end += text_pad;
if (!obj_datasec(abfd)->user_set_vma)
{
bfd_vma vma;
vma = obj_textsec(abfd)->vma + obj_textsec(abfd)->_raw_size;
obj_datasec(abfd)->vma = BFD_ALIGN (vma, adata(abfd).segment_size);
}
data_vma = obj_datasec(abfd)->vma;
if (abdp && abdp->zmagic_mapped_contiguous)
{
text_pad = (obj_datasec(abfd)->vma
- obj_textsec(abfd)->vma
- obj_textsec(abfd)->_raw_size);
obj_textsec(abfd)->_raw_size += text_pad;
}
obj_datasec(abfd)->filepos = (obj_textsec(abfd)->filepos
+ obj_textsec(abfd)->_raw_size);
/* Fix up exec header while we're at it. */
execp->a_text = obj_textsec(abfd)->_raw_size;
if (ztih)
execp->a_text += adata(abfd).exec_bytes_size;
N_SET_MAGIC (*execp, ZMAGIC);
/* Spec says data section should be rounded up to page boundary. */
/* If extra space in page is left after data section, fudge data
in the header so that the bss section looks smaller by that
amount. We'll start the bss section there, and lie to the OS. */
obj_datasec(abfd)->_raw_size
= align_power (obj_datasec(abfd)->_raw_size,
obj_bsssec(abfd)->alignment_power);
execp->a_data = BFD_ALIGN (obj_datasec(abfd)->_raw_size,
adata(abfd).page_size);
data_pad = execp->a_data - obj_datasec(abfd)->_raw_size;
/* This code is almost surely botched. It'll only get tested
for the case where the application does explicitly set the VMA
of the BSS section. */
if (obj_bsssec(abfd)->user_set_vma
&& (obj_bsssec(abfd)->vma
> BFD_ALIGN (obj_datasec(abfd)->vma
+ obj_datasec(abfd)->_raw_size,
adata(abfd).page_size)))
{
/* Can't play with squeezing into data pages; fix this code. */
abort ();
}
if (!obj_bsssec(abfd)->user_set_vma)
obj_bsssec(abfd)->vma = (obj_datasec(abfd)->vma
+ obj_datasec(abfd)->_raw_size);
if (data_pad > obj_bsssec(abfd)->_raw_size)
execp->a_bss = 0;
else
execp->a_bss = obj_bsssec(abfd)->_raw_size - data_pad;
}
break;
case n_magic:
{
CONST struct aout_backend_data *abdp;
file_ptr pos = adata(abfd).exec_bytes_size;
bfd_vma vma = 0;
int pad;
obj_textsec(abfd)->filepos = pos;
if (!obj_textsec(abfd)->user_set_vma)
obj_textsec(abfd)->vma = vma;
else
vma = obj_textsec(abfd)->vma;
pos += obj_textsec(abfd)->_raw_size;
vma += obj_textsec(abfd)->_raw_size;
obj_datasec(abfd)->filepos = pos;
if (!obj_datasec(abfd)->user_set_vma)
obj_datasec(abfd)->vma = BFD_ALIGN (vma, adata(abfd).segment_size);
vma = obj_datasec(abfd)->vma;
/* Since BSS follows data immediately, see if it needs alignment. */
vma += obj_datasec(abfd)->_raw_size;
pad = align_power (vma, obj_bsssec(abfd)->alignment_power) - vma;
obj_datasec(abfd)->_raw_size += pad;
pos += obj_datasec(abfd)->_raw_size;
if (!obj_bsssec(abfd)->user_set_vma)
obj_bsssec(abfd)->vma = vma;
else
vma = obj_bsssec(abfd)->vma;
}
execp->a_text = obj_textsec(abfd)->_raw_size;
execp->a_data = obj_datasec(abfd)->_raw_size;
execp->a_bss = obj_bsssec(abfd)->_raw_size;
N_SET_MAGIC (*execp, NMAGIC);
break;
default:
abort ();
}
#ifdef BFD_AOUT_DEBUG
fprintf (stderr, " text=<%x,%x,%x> data=<%x,%x,%x> bss=<%x,%x>\n",
obj_textsec(abfd)->vma, obj_textsec(abfd)->_raw_size, obj_textsec(abfd)->filepos,
obj_datasec(abfd)->vma, obj_datasec(abfd)->_raw_size, obj_datasec(abfd)->filepos,
obj_bsssec(abfd)->vma, obj_bsssec(abfd)->_raw_size);
#endif
}
/*
FUNCTION
aout_<size>new_section_hook
@ -634,6 +891,7 @@ boolean
{
file_ptr text_end;
bfd_size_type text_size;
if (abfd->output_has_begun == false)
{ /* set by bfd.c handler */
switch (abfd->direction)
@ -642,55 +900,14 @@ boolean
case no_direction:
bfd_error = invalid_operation;
return false;
case write_direction:
if (NAME(aout,adjust_sizes_and_vmas) (abfd,
&text_size,
&text_end) == false)
return false;
case both_direction:
break;
case write_direction:
if ((obj_textsec (abfd) == NULL) || (obj_datasec (abfd) == NULL))
{
bfd_error = invalid_operation;
return false;
}
obj_textsec(abfd)->_raw_size =
align_power(obj_textsec(abfd)->_raw_size,
obj_textsec(abfd)->alignment_power);
text_size = obj_textsec (abfd)->_raw_size;
/* Rule (heuristic) for when to pad to a new page.
* Note that there are (at least) two ways demand-paged
* (ZMAGIC) files have been handled. Most Berkeley-based systems
* start the text segment at (PAGE_SIZE). However, newer
* versions of SUNOS start the text segment right after the
* exec header; the latter is counted in the text segment size,
* and is paged in by the kernel with the rest of the text. */
if (!(abfd->flags & D_PAGED))
{ /* Not demand-paged. */
obj_textsec(abfd)->filepos = adata(abfd).exec_bytes_size;
}
else if (obj_textsec(abfd)->vma % adata(abfd).page_size
< adata(abfd).exec_bytes_size)
{ /* Old-style demand-paged. */
obj_textsec(abfd)->filepos = adata(abfd).page_size;
}
else
{ /* Sunos-style demand-paged. */
obj_textsec(abfd)->filepos = adata(abfd).exec_bytes_size;
text_size += adata(abfd).exec_bytes_size;
}
text_end = obj_textsec(abfd)->_raw_size + obj_textsec(abfd)->filepos;
if (abfd->flags & (D_PAGED|WP_TEXT))
{
bfd_size_type text_pad =
BFD_ALIGN(text_size, adata(abfd).page_size)
- text_size;
text_end += text_pad;
obj_textsec(abfd)->_raw_size += text_pad;
}
obj_datasec(abfd)->filepos = text_end;
obj_datasec(abfd)->_raw_size =
align_power(obj_datasec(abfd)->_raw_size,
obj_datasec(abfd)->alignment_power);
}
}
@ -1162,13 +1379,13 @@ DEFUN(NAME(aout,get_symtab),(abfd, location),
{
unsigned int counter = 0;
aout_symbol_type *symbase;
if (!NAME(aout,slurp_symbol_table)(abfd)) return 0;
for (symbase = obj_aout_symbols(abfd); counter++ < bfd_get_symcount (abfd);)
*(location++) = (asymbol *)( symbase++);
*location++ =0;
return bfd_get_symcount(abfd);
return bfd_get_symcount (abfd);
}
@ -1189,9 +1406,9 @@ DEFUN(NAME(aout,swap_std_reloc_out),(abfd, g, natptr),
int r_baserel, r_jmptable, r_relative;
unsigned int r_addend;
asection *output_section = sym->section->output_section;
PUT_WORD(abfd, g->address, natptr->r_address);
r_length = g->howto->size ; /* Size as a power of two */
r_pcrel = (int) g->howto->pc_relative; /* Relative to PC? */
/* r_baserel, r_jmptable, r_relative??? FIXME-soon */
@ -1203,21 +1420,21 @@ DEFUN(NAME(aout,swap_std_reloc_out),(abfd, g, natptr),
/* name was clobbered by aout_write_syms to be symbol index */
if (output_section == &bfd_com_section
|| output_section == &bfd_abs_section
|| output_section == &bfd_und_section)
{
/* Fill in symbol */
r_extern = 1;
r_index = stoi((*(g->sym_ptr_ptr))->KEEPIT);
}
if (output_section == &bfd_com_section
|| output_section == &bfd_abs_section
|| output_section == &bfd_und_section)
{
/* Fill in symbol */
r_extern = 1;
r_index = stoi((*(g->sym_ptr_ptr))->KEEPIT);
}
else
{
/* Just an ordinary section */
r_extern = 0;
r_index = output_section->target_index;
}
{
/* Just an ordinary section */
r_extern = 0;
r_index = output_section->target_index;
}
/* now the fun stuff */
if (abfd->xvec->header_byteorder_big_p != false) {
natptr->r_index[0] = r_index >> 16;

View file

@ -24,8 +24,6 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
SECTION
Architectures
DESCRIPTION
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
@ -132,7 +130,8 @@ DESCRIPTION
. long mach;
. char *arch_name;
. CONST char *printable_name;
.{* true if this is the default machine for the architecture *}
. unsigned int section_align_power;
. {* 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,
@ -141,12 +140,11 @@ DESCRIPTION
. 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));
.
. unsigned int segment_size;
. unsigned int page_size;
.
. struct bfd_arch_info *next;
.
.} bfd_arch_info_type;
*/
@ -154,17 +152,16 @@ bfd_arch_info_type *bfd_arch_info_list;
/*
FUNCTION
bfd_printable_name
SYNOPSIS
CONST char *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);
*/
CONST char *
@ -180,14 +177,15 @@ DEFUN(bfd_printable_name, (abfd),
FUNCTION
bfd_scan_arch
SYNOPSIS
bfd_arch_info_type *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 *
@ -213,19 +211,17 @@ DEFUN(bfd_scan_arch,(string),
FUNCTION
bfd_arch_get_compatible
DESCRIPTION
SYNOPSIS
CONST bfd_arch_info_type *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 *
@ -239,14 +235,15 @@ CONST bfd *bbfd)
/*
INTERNAL
SUBSECTION
INTERNAL_DEFINITION
bfd_default_arch_struct
DESCRIPTION
What bfds are seeded with
The <<bfd_default_arch_struct>> is an item of
<<bfd_arch_info_type>> which has been initialized to a fairly
generic state. A BFD starts life by pointing to this
structure, until the correct back end has determined the real
architecture of the file.
.extern bfd_arch_info_type bfd_default_arch_struct;
@ -254,12 +251,10 @@ DESCRIPTION
bfd_arch_info_type bfd_default_arch_struct =
{
32,32,8,bfd_arch_unknown,0,"unknown","unknown",true,
32,32,8,bfd_arch_unknown,0,"unknown","unknown",1,true,
bfd_default_compatible,
bfd_default_scan,
0,
bfd_default_reloc_type_lookup
};
/*
@ -279,20 +274,18 @@ bfd_arch_info_type *arg)
}
/*
INTERNAL FUNCTION
INTERNAL_FUNCTION
bfd_default_set_arch_mach
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.
SYNOPSIS
boolean bfd_default_set_arch_mach(bfd *abfd,
enum bfd_architecture arch,
unsigned long mach);
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 DEFUN(bfd_default_set_arch_mach,(abfd, arch, mach),
@ -341,12 +334,13 @@ boolean DEFUN(bfd_default_set_arch_mach,(abfd, arch, mach),
FUNCTION
bfd_get_arch
SYNOPSIS
enum bfd_architecture bfd_get_arch(bfd *abfd);
DESCRIPTION
Returns the enumerated type which describes the supplied bfd's
architecture
SYNOPSIS
enum bfd_architecture bfd_get_arch(bfd *abfd);
*/
enum bfd_architecture DEFUN(bfd_get_arch, (abfd), bfd *abfd)
@ -358,12 +352,12 @@ enum bfd_architecture DEFUN(bfd_get_arch, (abfd), bfd *abfd)
FUNCTION
bfd_get_mach
SYNOPSIS
unsigned long bfd_get_mach(bfd *abfd);
DESCRIPTION
Returns the long type which describes the supplied bfd's
machine
SYNOPSIS
unsigned long bfd_get_mach(bfd *abfd);
*/
unsigned long
@ -376,11 +370,12 @@ DEFUN(bfd_get_mach, (abfd), bfd *abfd)
FUNCTION
bfd_arch_bits_per_byte
SYNOPSIS
unsigned int bfd_arch_bits_per_byte(bfd *abfd);
DESCRIPTION
Returns the number of bits in one of the architectures bytes
SYNOPSIS
unsigned int bfd_arch_bits_per_byte(bfd *abfd);
*/
unsigned int DEFUN(bfd_arch_bits_per_byte, (abfd), bfd *abfd)
@ -392,11 +387,11 @@ unsigned int DEFUN(bfd_arch_bits_per_byte, (abfd), bfd *abfd)
FUNCTION
bfd_arch_bits_per_address
DESCRIPTION
Returns the number of bits in one of the architectures addresses
SYNOPSIS
unsigned int bfd_arch_bits_per_address(bfd *abfd);
DESCRIPTION
Returns the number of bits in one of the architectures addresses
*/
unsigned int DEFUN(bfd_arch_bits_per_address, (abfd), bfd *abfd)
@ -442,17 +437,16 @@ static void EXFUN((*archures_init_table[]),()) =
/*
INTERNAL FUNCTION
INTERNAL_FUNCTION
bfd_arch_init
SYNOPSIS
void bfd_arch_init(void);
DESCRIPTION
This routine initializes the architecture dispatch table by
calling all installed architecture packages and getting them
to poke around.
SYNOPSIS
void bfd_arch_init(void);
*/
void
@ -469,15 +463,14 @@ DEFUN_VOID(bfd_arch_init)
/*
INTERNAL FUNCTION
INTERNAL_FUNCTION
bfd_arch_linkin
DESCRIPTION
Link the provided arch info structure into the list
SYNOPSIS
void bfd_arch_linkin(bfd_arch_info_type *);
DESCRIPTION
Link the provided arch info structure into the list
*/
void DEFUN(bfd_arch_linkin,(ptr),
@ -489,16 +482,16 @@ void DEFUN(bfd_arch_linkin,(ptr),
/*
INTERNAL FUNCTION
INTERNAL_FUNCTION
bfd_default_compatible
DESCRIPTION
The default function for testing for compatibility.
SYNOPSIS
CONST bfd_arch_info_type *bfd_default_compatible
(CONST bfd_arch_info_type *a,
CONST bfd_arch_info_type *b);
DESCRIPTION
The default function for testing for compatibility.
*/
CONST bfd_arch_info_type *
@ -519,16 +512,15 @@ DEFUN(bfd_default_compatible,(a,b),
/*
INTERNAL FUNCTION
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 *);
DESCRIPTION
The default function for working out whether this is an
architecture hit and a machine hit.
*/
boolean
@ -648,21 +640,17 @@ bfd *abfd)
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);
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.
*/
bfd_arch_info_type *
@ -690,15 +678,15 @@ long machine)
FUNCTION
bfd_printable_arch_mach
SYNOPSIS
CONST char * bfd_printable_arch_mach
(enum bfd_architecture arch, unsigned long machine);
DESCRIPTION
Return a printable string representing the architecture and
machine type.
NB. The use of this routine is depreciated.
SYNOPSIS
CONST char * bfd_printable_arch_mach
(enum bfd_architecture arch, unsigned long machine);
*/
CONST char *

View file

@ -391,6 +391,10 @@ DEFUN(styp_to_sec_flags, (styp_flags),
{
sec_flags = SEC_ALLOC;
}
else if (styp_flags & STYP_INFO)
{
sec_flags = SEC_NEVER_LOAD;
}
else
{
sec_flags = SEC_ALLOC | SEC_LOAD;
@ -1820,7 +1824,7 @@ DEFUN(coff_write_relocs,(abfd),
n.r_type = q->howto->type;
#endif
coff_swap_reloc_out(abfd, &n, &dst);
bfd_write((PTR) &n, 1, RELSZ, abfd);
bfd_write((PTR) &dst, 1, RELSZ, abfd);
}
}
}

View file

@ -53,6 +53,29 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
struct external_exec;
struct internal_exec;
/* Back-end information for various a.out targets. */
struct aout_backend_data
{
/* Are ZMAGIC files mapped contiguously? If so, the text section may
need more padding, if the segment size (granularity for memory access
control) is larger than the page size. */
unsigned char zmagic_mapped_contiguous : 1;
/* If this flag is set, ZMAGIC/NMAGIC file headers get mapped in with the
text section, which starts immediately after the file header.
If not, the text section starts on the next page. */
unsigned char text_includes_header : 1;
/* If the text section VMA isn't specified, and we need an absolute
address, use this as the default. If we're producing a relocatable
file, zero is always used. */
/* ?? Perhaps a callback would be a better choice? Will this do anything
reasonable for a format that handles multiple CPUs with different
load addresses for each? */
bfd_vma default_text_vma;
};
#define aout_backend_info(abfd) \
((CONST struct aout_backend_data *)((abfd)->xvec->backend_data))
/* This is the layout in memory of a "struct exec" while we process it.
All 'lengths' are given as a number of bytes.
All 'alignments' are for relinkable files only; an alignment of
@ -92,7 +115,7 @@ enum machine_type {
M_29K = 101,
M_HP200 = 200, /* HP 200 (68010) BSD binary */
M_HP300 = (300 % 256), /* HP 300 (68020+68881) BSD binary */
M_HPUX = (0x20c % 256),/* HP 200/300 HPUX binary */
M_HPUX = (0x20c % 256)/* HP 200/300 HPUX binary */
};
#define N_DYNAMIC(exec) ((exec).a_info & 0x8000000)
@ -154,18 +177,30 @@ struct aoutdata {
unsigned long segment_size;
unsigned exec_bytes_size;
unsigned vma_adjusted : 1;
enum {
undecided_magic = 0,
z_magic,
o_magic,
n_magic } magic;
};
#define adata(bfd) ((struct aoutdata *) ((bfd)->tdata))
#define exec_hdr(bfd) (adata(bfd)->hdr)
#define obj_aout_symbols(bfd) (adata(bfd)->symbols)
#define obj_textsec(bfd) (adata(bfd)->textsec)
#define obj_datasec(bfd) (adata(bfd)->datasec)
#define obj_bsssec(bfd) (adata(bfd)->bsssec)
#define obj_sym_filepos(bfd) (adata(bfd)->sym_filepos)
#define obj_str_filepos(bfd) (adata(bfd)->str_filepos)
#define obj_reloc_entry_size(bfd) (adata(bfd)->reloc_entry_size)
#define obj_symbol_entry_size(bfd) (adata(bfd)->symbol_entry_size)
struct aout_data_struct {
struct aoutdata a;
struct internal_exec e;
};
#define adata(bfd) ((bfd)->tdata.aout_data->a)
#define exec_hdr(bfd) (adata(bfd).hdr)
#define obj_aout_symbols(bfd) (adata(bfd).symbols)
#define obj_textsec(bfd) (adata(bfd).textsec)
#define obj_datasec(bfd) (adata(bfd).datasec)
#define obj_bsssec(bfd) (adata(bfd).bsssec)
#define obj_sym_filepos(bfd) (adata(bfd).sym_filepos)
#define obj_str_filepos(bfd) (adata(bfd).str_filepos)
#define obj_reloc_entry_size(bfd) (adata(bfd).reloc_entry_size)
#define obj_symbol_entry_size(bfd) (adata(bfd).symbol_entry_size)
/* We take the address of the first element of an asymbol to ensure that the
macro is only ever applied to an asymbol */
@ -209,7 +244,6 @@ PROTO (boolean, NAME(aout,find_nearest_line), (bfd *abfd, asection *section,
CONST char **functionname_ptr, unsigned int *line_ptr));
PROTO (int, NAME(aout,sizeof_headers), (bfd *abfd, boolean exec));
PROTO (void, NAME(aout,swap_exec_header_in), (bfd *abfd,
struct external_exec *raw_bytes, struct internal_exec *execp));
@ -227,64 +261,17 @@ PROTO(char *, aout_stab_name, (int code));
#define aout_64_get_section_contents bfd_generic_get_section_contents
#define aout_64_close_and_cleanup bfd_generic_close_and_cleanup
#ifndef NO_WRITE_HEADER_KLUDGE
#define NO_WRITE_HEADER_KLUDGE 0
#endif
/* Calculate the file positions of the parts of a newly read aout header */
#define WORK_OUT_FILE_POSITIONS(abfd, execp) \
obj_textsec (abfd)->size = N_TXTSIZE(*execp); \
\
/* The virtual memory addresses of the sections */ \
obj_textsec (abfd)->vma = N_TXTADDR(*execp); \
obj_datasec (abfd)->vma = N_DATADDR(*execp); \
obj_bsssec (abfd)->vma = N_BSSADDR(*execp); \
\
/* The file offsets of the sections */ \
obj_textsec (abfd)->filepos = N_TXTOFF (*execp); \
obj_datasec (abfd)->filepos = N_DATOFF (*execp); \
\
/* The file offsets of the relocation info */ \
obj_textsec (abfd)->rel_filepos = N_TRELOFF(*execp); \
obj_datasec (abfd)->rel_filepos = N_DRELOFF(*execp); \
\
/* The file offsets of the string table and symbol table. */ \
obj_sym_filepos (abfd) = N_SYMOFF (*execp); \
obj_str_filepos (abfd) = N_STROFF (*execp); \
#ifndef WRITE_HEADERS
#define WRITE_HEADERS(abfd, execp) \
{ \
if (abfd->flags & D_PAGED) \
{ \
execp->a_text = obj_textsec (abfd)->size; \
/* Kludge to distinguish old- and new-style ZMAGIC. \
The latter includes the exec header in the text size. */ \
if (obj_textsec(abfd)->filepos == EXEC_BYTES_SIZE) \
execp->a_text += EXEC_BYTES_SIZE; \
N_SET_MAGIC (*execp, ZMAGIC); \
} \
else \
{ \
execp->a_text = obj_textsec (abfd)->size; \
if (abfd->flags & WP_TEXT) \
{ N_SET_MAGIC (*execp, NMAGIC); } \
else \
{ N_SET_MAGIC(*execp, OMAGIC); } \
} \
if (abfd->flags & D_PAGED) \
{ \
data_pad = ALIGN(obj_datasec(abfd)->size, PAGE_SIZE) \
- obj_datasec(abfd)->size; \
\
if (data_pad > obj_bsssec(abfd)->size) \
execp->a_bss = 0; \
else \
execp->a_bss = obj_bsssec(abfd)->size - data_pad; \
execp->a_data = obj_datasec(abfd)->size + data_pad; \
} \
else \
{ \
execp->a_data = obj_datasec (abfd)->size; \
execp->a_bss = obj_bsssec (abfd)->size; \
} \
bfd_size_type text_size; /* dummy vars */ \
file_ptr text_end; \
if (adata(abfd).magic == undecided_magic) \
NAME(aout,adjust_sizes_and_vmas) (abfd, &text_size, &text_end); \
\
execp->a_syms = bfd_get_symcount (abfd) * EXTERNAL_NLIST_SIZE; \
execp->a_entry = bfd_get_start_address (abfd); \
@ -314,3 +301,4 @@ PROTO(char *, aout_stab_name, (int code));
if (!NAME(aout,squirt_out_relocs)(abfd, obj_datasec (abfd))) return false; \
} \
}
#endif

View file

@ -104,6 +104,8 @@ DESCRIPTION
argument must be parenthesized; it contains all the arguments
to the called function.
They make the documentation (more) unpleasant to read, so if
someone wants to fix this and not break the above, please do.
.#define BFD_SEND(bfd, message, arglist) \
. ((*((bfd)->xvec->message)) arglist)
@ -126,7 +128,7 @@ DESCRIPTION
.typedef struct bfd_target
.{
identifies the kind of target, eg SunOS4, Ultrix, etc
Identifies the kind of target, eg SunOS4, Ultrix, etc.
. char *name;
@ -239,7 +241,7 @@ Standard stuff.
. file_ptr, bfd_size_type));
. SDEF (boolean, _new_section_hook, (bfd *, sec_ptr));
Symbols and reloctions
Symbols and relocations
. SDEF (unsigned int, _get_symtab_upper_bound, (bfd *));
. SDEF (unsigned int, _bfd_canonicalize_symtab,
@ -268,7 +270,7 @@ Symbols and reloctions
. SDEF (void, _bfd_debug_info_start, (bfd *));
. SDEF (void, _bfd_debug_info_end, (bfd *));
. SDEF (void, _bfd_debug_info_accumulate, (bfd *, struct sec *));
. SDEF (bfd_byte *, _bfd_get_relocated_section_contents, (bfd*,struct bfd_seclet_struct *));
. SDEF (bfd_byte *, _bfd_get_relocated_section_contents, (bfd*,struct bfd_seclet_struct *, bfd_byte *data));
. SDEF (boolean,_bfd_relax_section,(bfd *, struct sec *, struct symbol_cache_entry **));
Special entry points for gdb to swap in coff symbol table parts
@ -329,6 +331,24 @@ Special entry points for gas to swap coff parts
. PTR in,
. PTR out));
.
. {* See documentation on reloc types. *}
. SDEF (CONST struct reloc_howto_struct *,
. reloc_type_lookup,
. (bfd *abfd, bfd_reloc_code_type code));
.
. {* Complete and utter crock, currently used for the assembler
. when creating COFF files. *}
. SDEF (asymbol *, _bfd_make_debug_symbol, (
. bfd *abfd,
. void *ptr,
. unsigned long size));
Data for use by back-end routines; e.g., for a.out, includes whether
this particular target maps ZMAGIC files contiguously or with text and
data separated. Could perhaps also be used to eliminate some of the
above COFF-specific fields.
. PTR backend_data;
.} bfd_target;
*/
@ -397,7 +417,7 @@ bfd_target *target_vector[] = {
&ecoff_little_vec,
&ecoff_big_vec,
&ieee_vec,
#if 0
#if 1
/* We have no oasys tools anymore, so we can't test any of this
anymore. If you want to test the stuff yourself, go ahead...
steve@cygnus.com */