[time to file a PR on cvs...]
[deliverable/binutils-gdb.git] / bfd / aoutx.h
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;
This page took 0.047612 seconds and 4 git commands to generate.