From: Ken Raeburn Date: Tue, 16 Jun 1992 12:04:03 +0000 (+0000) Subject: [time to file a PR on cvs...] X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=ce07dd7c0cc9034fd9aac351d34a99b1452c0203;p=binutils-gdb.git [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. --- diff --git a/bfd/aoutx.h b/bfd/aoutx.h index a97cd58147e..71b56e831a9 100644 --- a/bfd/aoutx.h +++ b/bfd/aoutx.h @@ -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_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; diff --git a/bfd/archures.c b/bfd/archures.c index ffc1dd2428f..33063dbef3c 100644 --- a/bfd/archures.c +++ b/bfd/archures.c @@ -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 <>. 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)); . -. struct bfd_arch_info *next; +. 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 <> is an item of + <> 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 * diff --git a/bfd/coffcode.h b/bfd/coffcode.h index 09a4744791d..cceb59641cc 100644 --- a/bfd/coffcode.h +++ b/bfd/coffcode.h @@ -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); } } } diff --git a/bfd/libaout.h b/bfd/libaout.h index 01eb50e0726..2e0f9e9e068 100644 --- a/bfd/libaout.h +++ b/bfd/libaout.h @@ -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 diff --git a/bfd/targets.c b/bfd/targets.c index 27100c46efe..884e011f56d 100644 --- a/bfd/targets.c +++ b/bfd/targets.c @@ -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 */