Lint (saber actually).
[binutils-gdb.git] / bfd / aoutf1.h
index 62797611f3a27c997b319eda79f5728d65120d25..2ced6eb9c6ea12ba0f1af058014154cd5077c475 100644 (file)
@@ -1,38 +1,55 @@
-/* BFD backend for generic a.out flavour 1 */
+/* A.out "format 1" file handling code
+   Copyright (C) 1990-1991 Free Software Foundation, Inc.
+   Written by Cygnus Support.
 
-/* Copyright (C) 1990, 1991 Free Software Foundation, Inc.
+This file is part of BFD, the Binary File Descriptor library.
 
-This file is part of BFD, the Binary File Diddler.
-
-BFD is free software; you can redistribute it and/or modify
+This program is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 1, or (at your option)
-any later version.
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
 
-BFD is distributed in the hope that it will be useful,
+This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
-along with BFD; see the file COPYING.  If not, write to
-the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+along with this program; if not, write to the Free Software
+Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
 
 #include <ansidecl.h>
 #include <sysdep.h>
-struct external_exec;
 #include <a.out.sun4.h>
 #include "bfd.h"
-#include "liba.out.h"           
+#include "libaout.h"           
 #include "libbfd.h"
 
-
-
 #include "aout64.h"
 #include "stab.gnu.h"
 #include "ar.h"
 
+/*
+The file @code{aoutf1.h} contains the code for BFD's
+a.out back end. Control over the generated back end is given by these
+two preprocessor names:
+@table @code
+@item ARCH_SIZE
+This value should be either 32 or 64, depending upon the size of an
+int in the target format. It changes the sizes of the structs which
+perform the memory/disk mapping of structures.
+
+The 64 bit backend may only be used if the host compiler supports 64
+ints (eg long long with gcc), by defining the name @code{HOST_64_BIT} in @code{bfd.h}.
+With this name defined, @emph{all} bfd operations are performed with 64bit
+arithmetic, not just those to a 64bit target.
 
+@item TARGETNAME
+The name put into the target vector.
+@item
+@end table
+
+*/
 
 void (*bfd_error_trap)();
 
@@ -177,7 +194,7 @@ DEFUN(NAME(aout,sunos4_write_object_contents),(abfd),
     choose_reloc_size(abfd);
 
     /* FIXME */
-    N_SET_FLAGS (*execp, 0x81);
+    N_SET_FLAGS (*execp, 0x1);
     
     WRITE_HEADERS(abfd, execp);
 
@@ -226,11 +243,12 @@ struct regs {
 neither of whose size we know, WITH STUFF IN BETWEEN THEM!  We can't
 even portably access the stuff in between!  */
 
-struct core {
+struct external_sparc_core {
   int c_magic;                 /* Corefile magic number */
   int c_len;                   /* Sizeof (struct core) */
-  struct regs c_regs;          /* General purpose registers -- MACHDEP SIZE */
-  struct internal_exec c_aouthdr;      /* A.out header */
+#define        SPARC_CORE_LEN  432
+  int c_regs[19];              /* General purpose registers -- MACHDEP SIZE */
+  struct external_exec c_aouthdr;      /* A.out header */
   int c_signo;                 /* Killing signal, if any */
   int c_tsize;                 /* Text size (bytes) */
   int c_dsize;                 /* Data size (bytes) */
@@ -245,26 +263,119 @@ struct core {
     portably know the size of fp_stuff.) */
 };
 
-/* Supposedly the user stack grows downward from the bottom of kernel memory.
-Presuming that this remains true, this definition will work. */
-#define USRSTACK (-(128*1024*1024))
+struct external_sun3_core {
+  int c_magic;                 /* Corefile magic number */
+  int c_len;                   /* Sizeof (struct core) */
+#define        SUN3_CORE_LEN   826     /* As of SunOS 4.1.1 */
+  int c_regs[18];              /* General purpose registers -- MACHDEP SIZE */
+  struct external_exec c_aouthdr;      /* A.out header */
+  int c_signo;                 /* Killing signal, if any */
+  int c_tsize;                 /* Text size (bytes) */
+  int c_dsize;                 /* Data size (bytes) */
+  int c_ssize;                 /* Stack size (bytes) */
+  char c_cmdname[CORE_NAMELEN + 1]; /* Command name */
+  double fp_stuff[1];              /* external FPU state (size unknown by us) */
+  /* The type "double" is critical here, for alignment.
+    SunOS declares a struct here, but the struct's alignment
+      is double since it contains doubles.  */
+  int c_ucode;                 /* Exception no. from u_code */
+  /* (this member is not accessible by name since we don't
+    portably know the size of fp_stuff.) */
+};
 
-PROTO (static void, swapcore, (bfd *abfd, struct core *core));
+struct internal_sunos_core {
+  int c_magic;                 /* Corefile magic number */
+  int c_len;                   /* Sizeof (struct core) */
+  long c_regs_pos;             /* file offset of General purpose registers */
+  int c_regs_size;             /* size of General purpose registers */
+  struct internal_exec c_aouthdr;      /* A.out header */
+  int c_signo;                 /* Killing signal, if any */
+  int c_tsize;                 /* Text size (bytes) */
+  int c_dsize;                 /* Data size (bytes) */
+  int c_ssize;                 /* Stack size (bytes) */
+  long c_stacktop;             /* Stack top (address) */
+  char c_cmdname[CORE_NAMELEN + 1]; /* Command name */
+  long fp_stuff_pos;           /* file offset of external FPU state (regs) */
+  int fp_stuff_size;           /* Size of it */
+  int c_ucode;                 /* Exception no. from u_code */
+};
 
-/* need this cast b/c ptr is really void * */
-#define core_hdr(bfd) (((struct suncordata *) (bfd->tdata))->hdr)
-#define core_datasec(bfd) (((struct suncordata *) ((bfd)->tdata))->data_section)
-#define core_stacksec(bfd) (((struct suncordata*)((bfd)->tdata))->stack_section)
-#define core_regsec(bfd) (((struct suncordata *) ((bfd)->tdata))->reg_section)
-#define core_reg2sec(bfd) (((struct suncordata *) ((bfd)->tdata))->reg2_section)
+/* byte-swap in the Sun-3 core structure */
+static void
+DEFUN(swapcore_sun3,(abfd, ext, intcore),
+      bfd *abfd AND
+      char *ext AND
+      struct internal_sunos_core *intcore)
+{
+  struct external_sun3_core *extcore = (struct external_sun3_core *)ext;
+  
+  intcore->c_magic = bfd_h_get_32 (abfd, (unsigned char *)&extcore->c_magic);
+  intcore->c_len   = bfd_h_get_32 (abfd, (unsigned char *)&extcore->c_len  );
+  intcore->c_regs_pos  = (long) (((struct external_sun3_core *)0)->c_regs);
+  intcore->c_regs_size = sizeof (extcore->c_regs);
+  NAME(aout,swap_exec_header_in)(abfd, &extcore->c_aouthdr,&intcore->c_aouthdr);
+  intcore->c_signo = bfd_h_get_32 (abfd, (unsigned char *)&extcore->c_signo);
+  intcore->c_tsize = bfd_h_get_32 (abfd, (unsigned char *)&extcore->c_tsize);
+  intcore->c_dsize = bfd_h_get_32 (abfd, (unsigned char *)&extcore->c_dsize);
+  intcore->c_ssize = bfd_h_get_32 (abfd, (unsigned char *)&extcore->c_ssize);
+  bcopy (extcore->c_cmdname, intcore->c_cmdname, sizeof (intcore->c_cmdname));
+  intcore->fp_stuff_pos = (long) (((struct external_sun3_core *)0)->fp_stuff);
+  /* FP stuff takes up whole rest of struct, except c_ucode. */
+  intcore->fp_stuff_size = intcore->c_len - (sizeof extcore->c_ucode) -
+    (file_ptr)(((struct external_sun3_core *)0)->fp_stuff);
+  /* Ucode is the last thing in the struct -- just before the end */
+  intcore->c_ucode = bfd_h_get_32 (abfd, 
+       intcore->c_len - sizeof (extcore->c_ucode) + (unsigned char *)extcore);
+  intcore->c_stacktop = 0x0E000000;    /* By experimentation */
+}
+
+
+/* byte-swap in the Sparc core structure */
+static void
+DEFUN(swapcore_sparc,(abfd, ext, intcore),
+      bfd *abfd AND
+      char *ext AND
+      struct internal_sunos_core *intcore)
+{
+  struct external_sparc_core *extcore = (struct external_sparc_core *)ext;
+  
+  intcore->c_magic = bfd_h_get_32 (abfd, (unsigned char *)&extcore->c_magic);
+  intcore->c_len   = bfd_h_get_32 (abfd, (unsigned char *)&extcore->c_len  );
+  intcore->c_regs_pos  = (long) (((struct external_sparc_core *)0)->c_regs);
+  intcore->c_regs_size = sizeof (extcore->c_regs);
+  NAME(aout,swap_exec_header_in)(abfd, &extcore->c_aouthdr,&intcore->c_aouthdr);
+  intcore->c_signo = bfd_h_get_32 (abfd, (unsigned char *)&extcore->c_signo);
+  intcore->c_tsize = bfd_h_get_32 (abfd, (unsigned char *)&extcore->c_tsize);
+  intcore->c_dsize = bfd_h_get_32 (abfd, (unsigned char *)&extcore->c_dsize);
+  intcore->c_ssize = bfd_h_get_32 (abfd, (unsigned char *)&extcore->c_ssize);
+  bcopy (extcore->c_cmdname, intcore->c_cmdname, sizeof (intcore->c_cmdname));
+  intcore->fp_stuff_pos = (long) (((struct external_sparc_core *)0)->fp_stuff);
+  /* FP stuff takes up whole rest of struct, except c_ucode. */
+  intcore->fp_stuff_size = intcore->c_len - (sizeof extcore->c_ucode) -
+    (file_ptr)(((struct external_sparc_core *)0)->fp_stuff);
+  /* Ucode is the last thing in the struct -- just before the end */
+  intcore->c_ucode = bfd_h_get_32 (abfd, 
+       intcore->c_len - sizeof (extcore->c_ucode) + (unsigned char *)extcore);
+  /* Supposedly the user stack grows downward from the bottom of kernel memory.
+     Presuming that this remains true, this definition will work. */
+#define SPARC_USRSTACK (-(128*1024*1024))
+  intcore->c_stacktop = SPARC_USRSTACK;        /* By experimentation */
+}
+
+/* need this cast because ptr is really void * */
+#define core_hdr(bfd) (((struct suncoredata *) (bfd->tdata))->hdr)
+#define core_datasec(bfd) (((struct suncoredata *) ((bfd)->tdata))->data_section)
+#define core_stacksec(bfd) (((struct suncoredata*)((bfd)->tdata))->stack_section)
+#define core_regsec(bfd) (((struct suncoredata *) ((bfd)->tdata))->reg_section)
+#define core_reg2sec(bfd) (((struct suncoredata *) ((bfd)->tdata))->reg2_section)
 
 /* These are stored in the bfd's tdata */
-struct suncordata {
-struct core *hdr;             /* core file header */
-asection *data_section;
-asection *stack_section;
-asection *reg_section;
-asection *reg2_section;
+struct suncoredata {
+  struct internal_sunos_core *hdr;             /* core file header */
+  asection *data_section;
+  asection *stack_section;
+  asection *reg_section;
+  asection *reg2_section;
 };
 
 static bfd_target *
@@ -274,8 +385,13 @@ DEFUN(sunos4_core_file_p,(abfd),
   unsigned char longbuf[4];    /* Raw bytes of various header fields */
   int core_size;
   int core_mag;
-  struct core *core;
-  char *rawptr;
+  struct internal_sunos_core *core;
+  char *extcore;
+  struct mergem {
+    struct suncoredata suncoredata;
+    struct internal_sunos_core internal_sunos_core;
+    char external_core[1];
+  } *mergem;
   
   bfd_error = system_call_error;
   
@@ -297,22 +413,38 @@ DEFUN(sunos4_core_file_p,(abfd),
 
   if (bfd_seek (abfd, 0L, false) < 0) return 0;
 
-  rawptr = bfd_zalloc (abfd, core_size + sizeof (struct suncordata));
-  if (rawptr == NULL) {
+  mergem = (struct mergem *)bfd_zalloc (abfd, core_size + sizeof (struct mergem));
+  if (mergem == NULL) {
     bfd_error = no_memory;
     return 0;
   }
 
-  core = (struct core *) (rawptr + sizeof (struct suncordata));
+  extcore = mergem->external_core;
 
-  if ((bfd_read ((PTR) core, 1, core_size, abfd)) != core_size) {
+  if ((bfd_read ((PTR) extcore, 1, core_size, abfd)) != core_size) {
     bfd_error = system_call_error;
-    bfd_release (abfd, rawptr);
+    bfd_release (abfd, (char *)mergem);
     return 0;
   }
 
-  swapcore (abfd, core);
-  set_tdata (abfd, ((struct suncordata *) rawptr));
+  /* Validate that it's a core file we know how to handle, due to sun
+     botching the positioning of registers and other fields in a machine
+     dependent way.  */
+  core = &mergem->internal_sunos_core;
+  switch (core_size) {
+  case SPARC_CORE_LEN:
+    swapcore_sparc (abfd, extcore, core);
+    break;
+  case SUN3_CORE_LEN:
+    swapcore_sun3 (abfd, extcore, core);
+    break;
+  default:
+    bfd_error = system_call_error;             /* FIXME */
+    bfd_release (abfd, (char *)mergem);
+    return 0;
+  }
+
+  set_tdata (abfd, &mergem->suncoredata);
   core_hdr (abfd) = core;
 
   /* create the sections.  This is raunchy, but bfd_close wants to reclaim
@@ -321,7 +453,7 @@ DEFUN(sunos4_core_file_p,(abfd),
   if (core_stacksec (abfd) == NULL) {
   loser:
     bfd_error = no_memory;
-    bfd_release (abfd, rawptr);
+    bfd_release (abfd, (char *)mergem);
     return 0;
   }
   core_datasec (abfd) = (asection *) bfd_zalloc (abfd, sizeof (asection));
@@ -347,28 +479,26 @@ DEFUN(sunos4_core_file_p,(abfd),
   core_regsec (abfd)->name = ".reg";
   core_reg2sec (abfd)->name = ".reg2";
 
-  core_stacksec (abfd)->flags = SEC_ALLOC + SEC_LOAD;
-  core_datasec (abfd)->flags = SEC_ALLOC + SEC_LOAD;
-  core_regsec (abfd)->flags = SEC_ALLOC;
-  core_reg2sec (abfd)->flags = SEC_ALLOC;
+  core_stacksec (abfd)->flags = SEC_ALLOC + SEC_LOAD + SEC_HAS_CONTENTS;
+  core_datasec (abfd)->flags = SEC_ALLOC + SEC_LOAD + SEC_HAS_CONTENTS;
+  core_regsec (abfd)->flags = SEC_ALLOC + SEC_HAS_CONTENTS;
+  core_reg2sec (abfd)->flags = SEC_ALLOC + SEC_HAS_CONTENTS;
 
   core_stacksec (abfd)->size = core->c_ssize;
   core_datasec (abfd)->size = core->c_dsize;
-  core_regsec (abfd)->size = (sizeof core->c_regs);
-  /* Float regs take up end of struct, except c_ucode.  */
-  core_reg2sec (abfd)->size = core_size - (sizeof core->c_ucode) -
-    (file_ptr)(((struct core *)0)->fp_stuff);
+  core_regsec (abfd)->size = core->c_regs_size;
+  core_reg2sec (abfd)->size = core->fp_stuff_size;
 
-  core_stacksec (abfd)->vma = (USRSTACK - core->c_ssize);
+  core_stacksec (abfd)->vma = (core->c_stacktop - core->c_ssize);
   core_datasec (abfd)->vma = N_DATADDR(core->c_aouthdr);
   core_regsec (abfd)->vma = -1;
   core_reg2sec (abfd)->vma = -1;
 
   core_stacksec (abfd)->filepos = core->c_len + core->c_dsize;
   core_datasec (abfd)->filepos = core->c_len;
-  /* In file header: */
-  core_regsec (abfd)->filepos = (file_ptr)(&((struct core *)0)->c_regs);
-  core_reg2sec (abfd)->filepos = (file_ptr)(((struct core *)0)->fp_stuff);
+  /* We'll access the regs afresh in the core file, like any section: */
+  core_regsec (abfd)->filepos = (file_ptr)core->c_regs_pos;
+  core_reg2sec (abfd)->filepos = (file_ptr)core->fp_stuff_pos;
 
   /* Align to word at least */
   core_stacksec (abfd)->alignment_power = 2;
@@ -409,31 +539,10 @@ DEFUN(sunos4_core_file_matches_executable_p, (core_bfd, exec_bfd),
     return false;
   }
 
-  return (bcmp ((char *)&core_hdr (core_bfd), (char*) &exec_hdr (exec_bfd),
+  return (bcmp ((char *)&core_hdr (core_bfd)->c_aouthdr, 
+               (char *) exec_hdr (exec_bfd),
                sizeof (struct internal_exec)) == 0) ? true : false;
 }
-
-/* byte-swap core structure */
-/* FIXME, this needs more work to swap IN a core struct from raw bytes */
-static void
-DEFUN(swapcore,(abfd, core),
-      bfd *abfd AND
-      struct core *core)
-{
-  struct external_exec exec_bytes;
-  
-  core->c_magic = bfd_h_get_32 (abfd, (unsigned char *)&core->c_magic);
-  core->c_len   = bfd_h_get_32 (abfd, (unsigned char *)&core->c_len  );
-  /* Leave integer registers in target byte order.  */
-  bcopy ((char *)&(core->c_aouthdr), (char *)&exec_bytes, EXEC_BYTES_SIZE);
-  NAME(aout,swap_exec_header_in)(abfd, &exec_bytes, &core->c_aouthdr);
-  core->c_signo = bfd_h_get_32 (abfd, (unsigned char *)&core->c_signo);
-  core->c_tsize = bfd_h_get_32 (abfd, (unsigned char *)&core->c_tsize);
-  core->c_dsize = bfd_h_get_32 (abfd, (unsigned char *)&core->c_dsize);
-  core->c_ssize = bfd_h_get_32 (abfd, (unsigned char *)&core->c_ssize);
-  /* Leave FP registers in target byte order.  */
-  /* Leave "c_ucode" unswapped for now, since we can't find it easily.  */
-}
 \f
 /* We use BFD generic archive files.  */
 #define        aout_32_openr_next_archived_file        bfd_generic_openr_next_archived_file
@@ -461,31 +570,42 @@ DEFUN(swapcore,(abfd, core),
 #define        aout_64_core_file_failing_signal        sunos4_core_file_failing_signal
 #define        aout_64_core_file_matches_executable_p  sunos4_core_file_matches_executable_p
 
+#define aout_64_bfd_debug_info_start           bfd_void
+#define aout_64_bfd_debug_info_end             bfd_void
+#define aout_64_bfd_debug_info_accumulate      bfd_void
+
+#define aout_32_bfd_debug_info_start           bfd_void
+#define aout_32_bfd_debug_info_end             bfd_void
+#define aout_32_bfd_debug_info_accumulate      (PROTO(void,(*),(bfd*, struct sec *))) bfd_void
+
+
+
 /* We implement these routines ourselves, rather than using the generic
 a.out versions.  */
 #define        aout_write_object_contents      sunos4_write_object_contents
 
 bfd_target VECNAME =
   {
-TARGETNAME,
-  bfd_target_aout_flavour_enum,
-  true,                                /* target byte order */
-  true,                                /* target headers byte order */
-  (HAS_RELOC | EXEC_P |                /* object flags */
-   HAS_LINENO | HAS_DEBUG |
-   HAS_SYMS | HAS_LOCALS | DYNAMIC | WP_TEXT | D_PAGED),
-   (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
-   ' ',                                                          /* ar_pad_char */
-   16,                                                   /* ar_max_namelen */
-   _do_getb64, _do_putb64, _do_getb32, _do_putb32, _do_getb16, _do_putb16, /* data */
-   _do_getb64, _do_putb64, _do_getb32, _do_putb32, _do_getb16, _do_putb16,  /* hdrs */
-   
-  {_bfd_dummy_target, NAME(sunos,object_p),
-   bfd_generic_archive_p, sunos4_core_file_p},
-  {bfd_false, NAME(aout,mkobject),
-   _bfd_generic_mkarchive, bfd_false},
-  {bfd_false, NAME(aout,sunos4_write_object_contents), /* bfd_write_contents */
-   _bfd_write_archive_contents, bfd_false},
-   
-   JUMP_TABLE(JNAME(aout))
-};
+    TARGETNAME,
+    bfd_target_aout_flavour_enum,
+    true,                      /* target byte order */
+    true,                      /* target headers byte order */
+    (HAS_RELOC | EXEC_P |      /* object flags */
+     HAS_LINENO | HAS_DEBUG |
+     HAS_SYMS | HAS_LOCALS | DYNAMIC | WP_TEXT | D_PAGED),
+    (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
+    ' ',                                                  /* ar_pad_char */
+    16,                                                           /* ar_max_namelen */
+    3,                                                    /* minimum alignment power */
+    _do_getb64, _do_putb64, _do_getb32, _do_putb32, _do_getb16, _do_putb16, /* data */
+    _do_getb64, _do_putb64, _do_getb32, _do_putb32, _do_getb16, _do_putb16, /* hdrs */
+    
+      {_bfd_dummy_target, NAME(sunos,object_p),
+       bfd_generic_archive_p, sunos4_core_file_p},
+      {bfd_false, NAME(aout,mkobject),
+       _bfd_generic_mkarchive, bfd_false},
+      {bfd_false, NAME(aout,sunos4_write_object_contents), /* bfd_write_contents */
+       _bfd_write_archive_contents, bfd_false},
+    
+    JUMP_TABLE(JNAME(aout))
+    };