[time to file a PR on cvs...]
authorKen Raeburn <raeburn@cygnus>
Tue, 16 Jun 1992 12:04:03 +0000 (12:04 +0000)
committerKen Raeburn <raeburn@cygnus>
Tue, 16 Jun 1992 12:04:03 +0000 (12:04 +0000)
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.

bfd/aoutx.h
bfd/archures.c
bfd/coffcode.h
bfd/libaout.h
bfd/targets.c

index a97cd58147e9ddbe3946b4ea098b6ff3d35f5d05..71b56e831a96f83ed108a7fb2be6cbb9fb7a5c59 100644 (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);
 }
 
 \f
@@ -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;
index ffc1dd2428f6fcd99c2de2ca47ba0363344c80fe..33063dbef3cb5423bedeb3bd51586fb0f42e4fcd 100644 (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));
 .
-.  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 <<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 *
index 09a4744791d4cd2878f48fa759484b47acd19262..cceb59641cc622e6813a91a7299841cec763e568 100644 (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);
     }
   }
 }
index 01eb50e07265f3fbac8997cc92254639fe47acfd..2e0f9e9e068f49663c5ab64727bcb916eb8b8571 100644 (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
index 27100c46efe8319f829a1427414ccab4e5da2135..884e011f56df2cd948fc25ab40255253ba0a4c6c 100644 (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 */