+#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.
*/
+/* 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
#include "aout/stab_gnu.h"
#include "aout/ar.h"
-void (*bfd_error_trap)();
+extern void (*bfd_error_trap)();
/*
SUBSECTION
*/
#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),
/* 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),
};
-bfd_error_vector_type bfd_error_vector;
+extern bfd_error_vector_type bfd_error_vector;
/*
SUBSECTION
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;
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
{
file_ptr text_end;
bfd_size_type text_size;
+
if (abfd->output_has_begun == false)
{ /* set by bfd.c handler */
switch (abfd->direction)
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);
}
}
{
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);
}
\f
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 */
/* 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;
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
. 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,
. 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;
+. unsigned int segment_size;
+. unsigned int page_size;
.
+. struct bfd_arch_info *next;
.} bfd_arch_info_type;
*/
/*
-
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 *
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 *
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 *
/*
-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;
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
-
};
/*
}
/*
-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),
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)
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
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)
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)
/*
-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
/*
-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),
/*
-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 *
/*
-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
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 *
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 *
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
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)
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 */
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));
#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); \
if (!NAME(aout,squirt_out_relocs)(abfd, obj_datasec (abfd))) return false; \
} \
}
+#endif