]> Git Repo - binutils.git/blobdiff - bfd/coffcode.h
Fixes related to handling of C++ methods (handle destructors
[binutils.git] / bfd / coffcode.h
index b359f51cfe1e090c1c6d9f1041926b27537a4569..fbb04063b08ea10f8336cf2e0d5944d7918a8c06 100644 (file)
@@ -1,4 +1,4 @@
-/* Support for Intel 960 COFF and Motorola 88k BCS COFF (and maybe others)
+/* Support for the generic parts of most COFF variants, for BFD.
    Copyright (C) 1990-1991 Free Software Foundation, Inc.
    Written by Cygnus Support.
 
@@ -34,12 +34,12 @@ which defines the internal structure. @code{m88k-bcs.c} also defines
 the relocations used by the 88k format @xref{Relocations}. Then the
 major portion of coff code is included (@code{coffcode.h}) which
 defines the methods used to act upon the types defined in
-@code{m88k-bcs.h} and @code{internalcoff.h}. 
+@code{m88k-bcs.h} and @code{internalcoff.h}.
 
 The Intel i960 processor version of coff is implemented in
-@code{icoff.c}. This file has the same structure as 
+@code{icoff.c}. This file has the same structure as
 @code{m88k-bcs.c}, except that it includes @code{intel-coff.h} rather
-than @code{m88k-bcs.h}. 
+than @code{m88k-bcs.h}.
 
 @subsection Porting To A New Version of Coff
 
@@ -49,7 +49,7 @@ our purposes, we'll say that i386 coff is the one you select, and that
 your coff flavour is called foo. Copy the @code{i386coff.c} to @code{foocoff.c},
 copy @code{../include/i386coff.h} to @code{../include/foocoff.h} and
 add the lines to @code{targets.c} and @code{Makefile.in} so that your
-new back end is used. 
+new back end is used.
 
 Alter the shapes of the structures in @code{../include/foocoff.h} so
 that they match what you need. You will probably also have to add
@@ -105,7 +105,7 @@ avenue to disaster disappear.
 The simple canonical form for symbols used by BFD is not rich enough
 to keep all the information available in a coff symbol table. The back
 end gets around this by keeping the original symbol table around,
-"behind the sceens". 
+"behind the scenes".
 
 When a symbol table is requested (through a call to
 @code{bfd_canonicalize_symtab}, a request gets through to
@@ -147,14 +147,14 @@ makes sure that the same destination target as source target is
 present.
 
 When the symbols have come from a coff file then all the debugging
-information is preserved. 
+information is preserved.
 
 Symbol tables are provided for writing to the back end in a vector of
 pointers to pointers. This allows applications like the linker to
 accumulate and output large symbol tables without having to do too
 much byte copying.
 
-The symbol table is not output to a writable BFD until it is closed. 
+The symbol table is not output to a writable BFD until it is closed.
 The order of operations on the canonical symbol table at that point
 are:
 @table @code
@@ -163,7 +163,7 @@ This function runs through the provided symbol table and patches each
 symbol marked as a file place holder (@code{C_FILE}) to point to the
 next file place holder in the list. It also marks each @code{offset}
 field in the list with the offset from the first symbol of the current
-symbol. 
+symbol.
 
 Another function of this procedure is to turn the canonical value form
 of BFD into the form used by coff. Internally, BFD expects symbol
@@ -246,12 +246,12 @@ $ } coff_symbol_type;
 
 */
 
-/* $Id$ */
 /* Most of this hacked by Steve Chamberlain, [email protected] */
 
 
 #define PUTWORD bfd_h_put_32
 #define PUTHALF bfd_h_put_16
+#define        PUTBYTE bfd_h_put_8
 
 #ifndef GET_FCN_LNNOPTR
 #define GET_FCN_LNNOPTR(abfd, ext)  bfd_h_get_32(abfd, (bfd_byte *) ext->x_sym.x_fcnary.x_fcn.x_lnnoptr)
@@ -279,7 +279,7 @@ $ } coff_symbol_type;
 #ifndef PUT_LNSZ_SIZE
 #define PUT_LNSZ_SIZE(abfd, in, ext) bfd_h_put_16(abfd, in, (bfd_byte*) ext->x_sym.x_misc.x_lnsz.x_size)
 #endif
-#ifndef GET_SCN_SCNLEN 
+#ifndef GET_SCN_SCNLEN
 #define GET_SCN_SCNLEN(abfd,  ext) bfd_h_get_32(abfd, (bfd_byte *) ext->x_scn.x_scnlen)
 #endif
 #ifndef GET_SCN_NRELOC
@@ -288,27 +288,32 @@ $ } coff_symbol_type;
 #ifndef GET_SCN_NLINNO
 #define GET_SCN_NLINNO(abfd, ext)  bfd_h_get_16(abfd, (bfd_byte *)ext->x_scn.x_nlinno)
 #endif
-#ifndef PUT_SCN_SCNLEN 
+#ifndef PUT_SCN_SCNLEN
 #define PUT_SCN_SCNLEN(abfd,in, ext) bfd_h_put_32(abfd, in, (bfd_byte *) ext->x_scn.x_scnlen)
 #endif
 #ifndef PUT_SCN_NRELOC
 #define PUT_SCN_NRELOC(abfd,in, ext) bfd_h_put_16(abfd, in, (bfd_byte *)ext->x_scn.x_nreloc)
 #endif
 #ifndef PUT_SCN_NLINNO
-#define PUT_SCN_NLINNO(abfd,in, ext)  bfd_h_put_16(abfd,in, (bfd_byte *) ext->x_scn.x_nlinno)
+#define PUT_SCN_NLINNO(abfd,in, ext)  bfd_h_put_16(abfd,in, (bfd_byte  *) ext->x_scn.x_nlinno)
+#endif
+#ifndef GET_LINENO_LNNO
+#define GET_LINENO_LNNO(abfd, ext) bfd_h_get_16(abfd, (bfd_byte *) (ext->l_lnno));
+#endif
+#ifndef PUT_LINNO_LNNO
+#define PUT_LINENO_LNNO(abfd,val, ext) bfd_h_put_16(abfd,val,  (bfd_byte *) (ext->l_lnno));
 #endif
-
 
 \f
 /* void warning(); */
 
-/* 
- * Return a word with STYP_* (scnhdr.s_flags) flags set to represent the 
+/*
+ * Return a word with STYP_* (scnhdr.s_flags) flags set to represent the
  * incoming SEC_* flags.  The inverse of this function is styp_to_sec_flags().
  * NOTE: If you add to/change this routine, you should mirror the changes
  *     in styp_to_sec_flags().
  */
-static long 
+static long
 DEFUN(sec_to_styp_flags, (sec_name, sec_flags),
        CONST char *            sec_name        AND
        flagword        sec_flags)
@@ -321,16 +326,16 @@ DEFUN(sec_to_styp_flags, (sec_name, sec_flags),
        return((long)STYP_DATA);
     } else if (!strcmp(sec_name, _BSS)) {
        return((long)STYP_BSS);
-    } 
+    }
 
 /* Try and figure out what it should be */
-   if (sec_flags & SEC_CODE) styp_flags = STYP_TEXT; 
-   if (sec_flags & SEC_DATA) styp_flags = STYP_DATA; 
-   else if (sec_flags & SEC_READONLY) 
+   if (sec_flags & SEC_CODE) styp_flags = STYP_TEXT;
+   if (sec_flags & SEC_DATA) styp_flags = STYP_DATA;
+   else if (sec_flags & SEC_READONLY)
 #ifdef STYP_LIT        /* 29k readonly text/data section */
-       styp_flags = STYP_LIT; 
+       styp_flags = STYP_LIT;
 #else
-       styp_flags = STYP_TEXT; 
+       styp_flags = STYP_TEXT;
 #endif /* STYP_LIT */
    else if (sec_flags & SEC_LOAD) styp_flags = STYP_TEXT;
 
@@ -338,14 +343,14 @@ DEFUN(sec_to_styp_flags, (sec_name, sec_flags),
 
    return(styp_flags);
 }
-/* 
+/*
  * Return a word with SEC_* flags set to represent the incoming
- * STYP_* flags (from scnhdr.s_flags).   The inverse of this 
- * function is sec_to_styp_flags().  
+ * STYP_* flags (from scnhdr.s_flags).   The inverse of this
+ * function is sec_to_styp_flags().
  * NOTE: If you add to/change this routine, you should mirror the changes
  *      in sec_to_styp_flags().
  */
-static flagword 
+static flagword
 DEFUN(styp_to_sec_flags, (styp_flags),
        long    styp_flags)
 {
@@ -369,7 +374,7 @@ DEFUN(styp_to_sec_flags, (styp_flags),
 
 /*  **********************************************************************
 Here are all the routines for swapping the structures seen in the
-outside world into the internal forms. 
+outside world into the internal forms.
 */
 
 
@@ -381,7 +386,14 @@ DEFUN(bfd_swap_reloc_in,(abfd, reloc_src, reloc_dst),
 {
   reloc_dst->r_vaddr = bfd_h_get_32(abfd, (bfd_byte *)reloc_src->r_vaddr);
   reloc_dst->r_symndx = bfd_h_get_32(abfd, (bfd_byte *) reloc_src->r_symndx);
+
+#ifdef RS6000COFF_C
+  reloc_dst->r_type = bfd_h_get_8(abfd, reloc_src->r_type);
+  reloc_dst->r_size = bfd_h_get_8(abfd, reloc_src->r_size);
+#else
   reloc_dst->r_type = bfd_h_get_16(abfd, (bfd_byte *) reloc_src->r_type);
+#endif
+
 #if M88
   reloc_dst->r_offset = bfd_h_get_16(abfd, (bfd_byte *) reloc_src->r_offset);
 #endif
@@ -441,7 +453,7 @@ DEFUN(coff_swap_filehdr_out,(abfd, in, out),
 
 #ifndef NO_COFF_SYMBOLS
 
-static void 
+static void
 DEFUN(coff_swap_sym_in,(abfd, ext1, in1),
       bfd            *abfd AND
       PTR ext1 AND
@@ -494,7 +506,7 @@ DEFUN(coff_swap_sym_out,(abfd, inp, extp),
   }
   bfd_h_put_32(abfd,  in->n_value , (bfd_byte *) ext->e_value);
   bfd_h_put_16(abfd,  in->n_scnum , (bfd_byte *) ext->e_scnum);
-  if (sizeof(ext->e_type) == 2) 
+  if (sizeof(ext->e_type) == 2)
       {
        bfd_h_put_16(abfd,  in->n_type , (bfd_byte *) ext->e_type);
       }
@@ -521,7 +533,8 @@ DEFUN(coff_swap_aux_in,(abfd, ext1, type, class, in1),
   case C_FILE:
     if (ext->x_file.x_fname[0] == 0) {
       in->x_file.x_n.x_zeroes = 0;
-      in->x_file.x_n.x_offset  = bfd_h_get_32(abfd, (bfd_byte *) ext->x_file.x_n.x_offset);
+      in->x_file.x_n.x_offset = 
+       bfd_h_get_32(abfd, (bfd_byte *) ext->x_file.x_n.x_offset);
     } else {
 #if FILNMLEN != E_FILNMLEN
    -> Error, we need to cope with truncating or extending FILNMLEN!;
@@ -529,8 +542,24 @@ DEFUN(coff_swap_aux_in,(abfd, ext1, type, class, in1),
       memcpy (in->x_file.x_fname, ext->x_file.x_fname, FILNMLEN);
 #endif
     }
+    break;
 
+  /* RS/6000 "csect" auxents */
+#ifdef RS6000COFF_C
+  case C_EXT:
+  case C_HIDEXT:
+    in->x_csect.x_scnlen   = bfd_h_get_32 (abfd, (bfd_byte *) ext->x_csect.x_scnlen);
+    in->x_csect.x_parmhash = bfd_h_get_32 (abfd, (bfd_byte *) ext->x_csect.x_parmhash);
+    in->x_csect.x_snhash   = bfd_h_get_16 (abfd, (bfd_byte *) ext->x_csect.x_snhash);
+    /* We don't have to hack bitfields in x_smtyp because it's defined by
+       shifts-and-ands, which are equivalent on all byte orders.  */
+    in->x_csect.x_smtyp    = bfd_h_get_8  (abfd, (bfd_byte *) ext->x_csect.x_smtyp);
+    in->x_csect.x_smclas   = bfd_h_get_8  (abfd, (bfd_byte *) ext->x_csect.x_smclas);
+    in->x_csect.x_stab     = bfd_h_get_32 (abfd, (bfd_byte *) ext->x_csect.x_stab);
+    in->x_csect.x_snstab   = bfd_h_get_16 (abfd, (bfd_byte *) ext->x_csect.x_snstab);
     break;
+#endif
+
   case C_STAT:
 #ifdef C_LEAFSTAT
   case C_LEAFSTAT:
@@ -584,7 +613,7 @@ DEFUN(coff_swap_aux_out,(abfd, inp, type, class, extp),
   switch (class) {
   case C_FILE:
     if (in->x_file.x_fname[0] == 0) {
-      PUTWORD(abfd, 0, (bfd_byte *) ext->x_file.x_n.x_zeroes );
+      PUTWORD(abfd, 0, (bfd_byte *) ext->x_file.x_n.x_zeroes);
       PUTWORD(abfd,
              in->x_file.x_n.x_offset,
              (bfd_byte *) ext->x_file.x_n.x_offset);
@@ -595,15 +624,31 @@ DEFUN(coff_swap_aux_out,(abfd, inp, type, class, extp),
 #else
       memcpy (ext->x_file.x_fname, in->x_file.x_fname, FILNMLEN);
 #endif
-    }    
+    }
+    break;
+
+#ifdef RS6000COFF_C
+  /* RS/6000 "csect" auxents */
+  case C_EXT:
+  case C_HIDEXT:
+    PUTWORD (abfd, in->x_csect.x_scnlen,       ext->x_csect.x_scnlen);
+    PUTWORD (abfd, in->x_csect.x_parmhash,     ext->x_csect.x_parmhash);
+    PUTHALF (abfd, in->x_csect.x_snhash,       ext->x_csect.x_snhash);
+    /* We don't have to hack bitfields in x_smtyp because it's defined by
+       shifts-and-ands, which are equivalent on all byte orders.  */
+    PUTBYTE (abfd, in->x_csect.x_smtyp,                ext->x_csect.x_smtyp);
+    PUTBYTE (abfd, in->x_csect.x_smclas,       ext->x_csect.x_smclas);
+    PUTWORD (abfd, in->x_csect.x_stab,         ext->x_csect.x_stab);
+    PUTHALF (abfd, in->x_csect.x_snstab,       ext->x_csect.x_snstab);
     break;
+#endif
+
   case C_STAT:
 #ifdef C_LEAFSTAT
   case C_LEAFSTAT:
 #endif
   case C_HIDDEN:
     if (type == T_NULL) {
-
       PUT_SCN_SCNLEN(abfd, in->x_scn.x_scnlen, ext);
       PUT_SCN_NRELOC(abfd, in->x_scn.x_nreloc, ext);
       PUT_SCN_NLINNO(abfd, in->x_scn.x_nlinno, ext);
@@ -658,11 +703,7 @@ DEFUN(coff_swap_lineno_in,(abfd, ext1, in1),
   struct internal_lineno      *in = (struct internal_lineno *)in1;
 
   in->l_addr.l_symndx = bfd_h_get_32(abfd, (bfd_byte *) ext->l_addr.l_symndx);
-#if defined(M88)
-  in->l_lnno = bfd_h_get_32(abfd, (bfd_byte *) ext->l_lnno);
-#else
-  in->l_lnno = bfd_h_get_16(abfd, (bfd_byte *) ext->l_lnno);
-#endif
+  in->l_lnno = GET_LINENO_LNNO(abfd, ext);
 }
 
 static unsigned int
@@ -673,19 +714,17 @@ DEFUN(coff_swap_lineno_out,(abfd, inp, outp),
 {
   struct internal_lineno *in = (struct internal_lineno *)inp;
   struct external_lineno *ext = (struct external_lineno *)outp;
-  PUTWORD(abfd, in->l_addr.l_symndx, (bfd_byte *) ext->l_addr.l_symndx);
-#if defined(M88)
-  PUTWORD(abfd, in->l_lnno, (bfd_byte *) ext->l_lnno);
-#else
-  PUTHALF(abfd, in->l_lnno, (bfd_byte *) ext->l_lnno);
-#endif
+  PUTWORD(abfd, in->l_addr.l_symndx, (bfd_byte *)
+         ext->l_addr.l_symndx);
+
+  PUT_LINENO_LNNO (abfd, in->l_lnno, ext);
   return sizeof(struct external_lineno);
 }
 
 #endif /* NO_COFF_LINENOS */
 
 
-static void 
+static void
 DEFUN(bfd_swap_aouthdr_in,(abfd, aouthdr_ext1, aouthdr_int1),
       bfd            *abfd AND
       PTR aouthdr_ext1 AND
@@ -705,6 +744,20 @@ DEFUN(bfd_swap_aouthdr_in,(abfd, aouthdr_ext1, aouthdr_int1),
 #ifdef I960
   aouthdr_int->tagentries = bfd_h_get_32(abfd, (bfd_byte *) aouthdr_ext->tagentries);
 #endif
+
+#ifdef RS6000COFF_C
+  aouthdr_int->o_toc = bfd_h_get_32(abfd, aouthdr_ext->o_toc);
+  aouthdr_int->o_snentry = bfd_h_get_16(abfd, aouthdr_ext->o_snentry);
+  aouthdr_int->o_sntext = bfd_h_get_16(abfd, aouthdr_ext->o_sntext);
+  aouthdr_int->o_sndata = bfd_h_get_16(abfd, aouthdr_ext->o_sndata);
+  aouthdr_int->o_sntoc = bfd_h_get_16(abfd, aouthdr_ext->o_sntoc);
+  aouthdr_int->o_snloader = bfd_h_get_16(abfd, aouthdr_ext->o_snloader);
+  aouthdr_int->o_snbss = bfd_h_get_16(abfd, aouthdr_ext->o_snbss);
+  aouthdr_int->o_algntext = bfd_h_get_16(abfd, aouthdr_ext->o_algntext);
+  aouthdr_int->o_algndata = bfd_h_get_16(abfd, aouthdr_ext->o_algndata);
+  aouthdr_int->o_modtype = bfd_h_get_16(abfd, aouthdr_ext->o_modtype);
+  aouthdr_int->o_maxstack = bfd_h_get_32(abfd, aouthdr_ext->o_maxstack);
+#endif
 }
 
 static unsigned int
@@ -730,7 +783,7 @@ DEFUN(coff_swap_aouthdr_out,(abfd, in, out),
   return sizeof(AOUTHDR);
 }
 
-static void 
+static void
 DEFUN(coff_swap_scnhdr_in,(abfd, scnhdr_ext, scnhdr_int),
       bfd            *abfd AND
       SCNHDR         *scnhdr_ext AND
@@ -756,7 +809,7 @@ DEFUN(coff_swap_scnhdr_in,(abfd, scnhdr_ext, scnhdr_int),
 #endif
 }
 
-static unsigned int 
+static unsigned int
 DEFUN(coff_swap_scnhdr_out,(abfd, in, out),
       bfd       *abfd AND
       PTR      in AND
@@ -780,7 +833,7 @@ DEFUN(coff_swap_scnhdr_out,(abfd, in, out),
   PUTHALF(abfd, scnhdr_int->s_nreloc, (bfd_byte *) scnhdr_ext->s_nreloc);
 #endif
 
-#if defined(I960) 
+#if defined(I960)
   PUTWORD(abfd, scnhdr_int->s_align, (bfd_byte *) scnhdr_ext->s_align);
 #endif
   return sizeof(SCNHDR);
@@ -821,6 +874,8 @@ DEFUN(make_a_section_from_file,(abfd, hdr),
        name[sizeof (hdr->s_name)] = 0;
 
        return_section = bfd_make_section(abfd, name);
+       if (return_section == NULL)
+           return false;
     }
 
     /* s_paddr is presumed to be = to s_vaddr */
@@ -890,20 +945,20 @@ DEFUN(coff_real_object_p,(abfd, nscns, internal_f, internal_a),
   long machine;
   size_t          readsize;    /* length of file_info */
   SCNHDR *external_sections;
-  
+
   /* Build a play area */
   if (coff_mkobject(abfd) != true)
     return 0;
   coff = coff_data(abfd);
-  
-  
+
+
   external_sections = (SCNHDR *)bfd_alloc(abfd, readsize = (nscns * SCNHSZ));
-  
+
   if (bfd_read((PTR)external_sections, 1, readsize, abfd) != readsize) {
     goto fail;
   }
-  
-  
+
+
   /* Now copy data as required; construct all asections etc */
   coff->symbol_index_slew = 0;
   coff->relocbase =0;
@@ -929,15 +984,15 @@ machine = 0;
     machine = 0;
     break;
 #endif
-    
-#ifdef A29K_MAGIC_BIG 
+
+#ifdef A29K_MAGIC_BIG
   case  A29K_MAGIC_BIG:
   case  A29K_MAGIC_LITTLE:
     arch = bfd_arch_a29k;
     machine = 0;
     break;
 #endif
-    
+
 #ifdef MIPS
   case  MIPS_MAGIC_1:
   case  MIPS_MAGIC_2:
@@ -946,7 +1001,7 @@ machine = 0;
     machine = 0;
     break;
 #endif
-    
+
 #ifdef MC68MAGIC
   case MC68MAGIC:
   case M68MAGIC:
@@ -967,7 +1022,7 @@ machine = 0;
   case I960ROMAGIC:
   case I960RWMAGIC:
     arch = bfd_arch_i960;
-    switch (F_I960TYPE & internal_f->f_flags) 
+    switch (F_I960TYPE & internal_f->f_flags)
        {
        default:
        case F_I960CORE:
@@ -988,17 +1043,26 @@ machine = 0;
        case F_I960KA:
          machine = bfd_mach_i960_ka_sa;
          break;
-         
        }
     break;
 #endif
 #endif
-    
+
+#ifdef U802ROMAGIC
+  case U802ROMAGIC:
+  case U802WRMAGIC:
+  case U802TOCMAGIC:
+    arch = bfd_arch_rs6000;
+    machine = 6000;
+    break;
+#endif
+
+
   default:                     /* Unreadable input file type */
  arch = bfd_arch_obscure;
     break;
   }
-  
+
   bfd_default_set_arch_mach(abfd, arch, machine);
   if (!(internal_f->f_flags & F_RELFLG))
     abfd->flags |= HAS_RELOC;
@@ -1008,14 +1072,14 @@ machine = 0;
     abfd->flags |= HAS_LINENO;
   if (!(internal_f->f_flags & F_LSYMS))
     abfd->flags |= HAS_LOCALS;
-  
-  
+
+
   bfd_get_symcount(abfd) = internal_f->f_nsyms;
   if (internal_f->f_nsyms)
     abfd->flags |= HAS_SYMS;
-  
+
   coff->sym_filepos = internal_f->f_symptr;
-  
+
   /* These members communicate important constants about the symbol table
     to GDB's symbol-reading code.  These `constants' unfortunately vary
       from coff implementation to implementation...  */
@@ -1028,10 +1092,10 @@ machine = 0;
   coff->local_auxesz   = AUXESZ;
   coff->local_linesz   = LINESZ;
 #endif
-  
+
   coff->symbols = (coff_symbol_type *) NULL;
   bfd_get_start_address(abfd) = internal_f->f_opthdr ? internal_a->entry : 0;
-  
+
   return abfd->xvec;
  fail:
   bfd_release(abfd, coff);
@@ -1047,45 +1111,45 @@ DEFUN(coff_object_p,(abfd),
   AOUTHDR opthdr;
   struct internal_filehdr internal_f;
   struct internal_aouthdr internal_a;
-    
+
   bfd_error = system_call_error;
-    
+
   /* figure out how much to read */
   if (bfd_read((PTR) &filehdr, 1, FILHSZ, abfd) != FILHSZ)
     return 0;
-    
+
   bfd_swap_filehdr_in(abfd, &filehdr, &internal_f);
-    
+
   if (BADMAG(internal_f)) {
     bfd_error = wrong_format;
     return 0;
   }
   nscns =internal_f.f_nscns;
-    
+
   if (internal_f.f_opthdr) {
     if (bfd_read((PTR) &opthdr, 1,AOUTSZ, abfd) != AOUTSZ) {
       return 0;
     }
     bfd_swap_aouthdr_in(abfd, (char *)&opthdr, (char *)&internal_a);
   }
-    
+
   /* Seek past the opt hdr stuff */
   bfd_seek(abfd, internal_f.f_opthdr + FILHSZ, SEEK_SET);
-    
+
   /* if the optional header is NULL or not the correct size then
      quit; the only difference I can see between m88k dgux headers (MC88DMAGIC)
      and Intel 960 readwrite headers (I960WRMAGIC) is that the
      optional header is of a different size.
-     
+
      But the mips keeps extra stuff in it's opthdr, so dont check
      when doing that
      */
-    
+
 #if defined(M88) || defined(I960)
   if (internal_f.f_opthdr != 0 && AOUTSZ != internal_f.f_opthdr)
     return (bfd_target *)NULL;
 #endif
-    
+
   return coff_real_object_p(abfd, nscns, &internal_f, &internal_a);
 }
 
@@ -1093,7 +1157,7 @@ DEFUN(coff_object_p,(abfd),
 
 #ifndef NO_COFF_LINENOS
 
-static void 
+static void
 DEFUN(coff_count_linenumbers,(abfd),
       bfd            *abfd)
 {
@@ -1107,8 +1171,8 @@ DEFUN(coff_count_linenumbers,(abfd),
        s = s->next;
       }
     }
-    
-    
+
+
   for (p = abfd->outsymbols, i = 0; i < limit; i++, p++) {
     asymbol        *q_maybe = *p;
     if (q_maybe->the_bfd->xvec->flavour == bfd_target_coff_flavour) {
@@ -1134,7 +1198,7 @@ DEFUN(coff_count_linenumbers,(abfd),
 
 #ifndef NO_COFF_SYMBOLS
 
-/* 
+/*
   Takes a bfd and a symbol, returns a pointer to the coff specific area
   of the symbol if there is one.
   */
@@ -1143,12 +1207,12 @@ DEFUN(coff_symbol_from,(ignore_abfd, symbol),
       bfd            *ignore_abfd AND
       asymbol        *symbol)
 {
-  if (symbol->the_bfd->xvec->flavour != bfd_target_coff_flavour) 
+  if (symbol->the_bfd->xvec->flavour != bfd_target_coff_flavour)
     return (coff_symbol_type *)NULL;
-    
+
   if (symbol->the_bfd->tdata == (PTR)NULL)
     return (coff_symbol_type *)NULL;
-    
+
   return  (coff_symbol_type *) symbol;
 }
 
@@ -1172,17 +1236,17 @@ struct internal_syment *syment)
   else if (coff_symbol_ptr->symbol.flags & BSF_UNDEFINED) {
     syment->n_scnum = N_UNDEF;
     syment->n_value = 0;
-  }      
+  }
   else if (coff_symbol_ptr->symbol.flags & BSF_ABSOLUTE) {
     syment->n_scnum = N_ABS;
     syment->n_value = coff_symbol_ptr->symbol.value;
-  }      
+  }
   else {
     if (coff_symbol_ptr->symbol.section) {
-      syment->n_scnum   = 
+      syment->n_scnum   =
        coff_symbol_ptr->symbol.section->output_section->index+1;
-           
-      syment->n_value = 
+
+      syment->n_value =
        coff_symbol_ptr->symbol.value +
        coff_symbol_ptr->symbol.section->output_offset +
         coff_symbol_ptr->symbol.section->output_section->vma;
@@ -1190,13 +1254,13 @@ struct internal_syment *syment)
     else {
       /* This can happen, but I don't know why yet ([email protected]) */
       syment->n_scnum = N_ABS;
-      syment->n_value = coff_symbol_ptr->symbol.value; 
+      syment->n_value = coff_symbol_ptr->symbol.value;
     }
   }
 }
 
 /* run through all the symbols in the symbol table and work out what
-   their indexes into the symbol table will be when output 
+   their indexes into the symbol table will be when output
 
  Coff requires that each C_FILE symbol points to the next one in the
  chain, and that the last one points to the first external symbol. We
@@ -1212,14 +1276,14 @@ DEFUN(coff_renumber_symbols,(bfd_ptr),
   unsigned int native_index = 0;
   struct internal_syment *last_file = (struct internal_syment *)NULL;
   unsigned int symbol_index;
-  for (symbol_index = 0; symbol_index < symbol_count; symbol_index++) 
+  for (symbol_index = 0; symbol_index < symbol_count; symbol_index++)
       {
        coff_symbol_type *coff_symbol_ptr = coff_symbol_from(bfd_ptr, symbol_ptr_ptr[symbol_index]);
        if (coff_symbol_ptr && coff_symbol_ptr->native) {
          combined_entry_type *s = coff_symbol_ptr->native;
          int i;
 
-         if (s->u.syment.n_sclass == C_FILE) 
+         if (s->u.syment.n_sclass == C_FILE)
              {
                if (last_file != (struct internal_syment *)NULL) {
                  last_file->n_value = native_index;
@@ -1249,31 +1313,28 @@ DEFUN(coff_renumber_symbols,(bfd_ptr),
  entries are changed to the entries' index in the output symbol table.
 
 */
-static void 
+static void
 DEFUN(coff_mangle_symbols,(bfd_ptr),
       bfd *bfd_ptr)
 {
   unsigned int symbol_count = bfd_get_symcount(bfd_ptr);
   asymbol **symbol_ptr_ptr = bfd_ptr->outsymbols;
-
   unsigned int symbol_index;
 
-
-  for (symbol_index = 0; symbol_index < symbol_count; symbol_index++) 
+  for (symbol_index = 0; symbol_index < symbol_count; symbol_index++)
       {
-       coff_symbol_type *coff_symbol_ptr = coff_symbol_from(bfd_ptr, symbol_ptr_ptr[symbol_index]);
-       if (coff_symbol_ptr && coff_symbol_ptr->native ) {
+       coff_symbol_type *coff_symbol_ptr =
+         coff_symbol_from(bfd_ptr, symbol_ptr_ptr[symbol_index]);
+
+       if (coff_symbol_ptr && coff_symbol_ptr->native) {
          int i;
          combined_entry_type *s = coff_symbol_ptr->native;
 
-
-
-
-
          for (i = 0; i < s->u.syment.n_numaux ; i++) {
            combined_entry_type *a = s + i + 1;
            if (a->fix_tag) {
-             a->u.auxent.x_sym.x_tagndx.l = a->u.auxent.x_sym.x_tagndx.p->offset;
+             a->u.auxent.x_sym.x_tagndx.l =
+               a->u.auxent.x_sym.x_tagndx.p->offset;
            }
            if (a->fix_end) {
              a->u.auxent.x_sym.x_fcnary.x_fcn.x_endndx.l =
@@ -1285,176 +1346,7 @@ DEFUN(coff_mangle_symbols,(bfd_ptr),
       }
 }
 
-#if 0
-    unsigned int symbol_count = bfd_get_symcount(bfd_ptr);
-    asymbol **symbol_ptr_ptr = bfd_ptr->outsymbols;
-    struct internal_syment *last_tagndx = (struct internal_syment *)NULL;
-    struct internal_syment *last_file = (struct internal_syment *)NULL;
-    struct internal_syment *last_fcn = (struct internal_syment *)NULL;
-    struct internal_syment *block_stack[50];
-    struct internal_syment **last_block = &block_stack[0];
-    boolean first_time = true;  
-    unsigned int symbol_index;
-    unsigned int native_index = 0;
-    
-    for (symbol_index = 0; symbol_index < symbol_count; symbol_index++) {
-      coff_symbol_type *coff_symbol_ptr =
-       coff_symbol_from(bfd_ptr, symbol_ptr_ptr[symbol_index]);
-      if (coff_symbol_ptr == (coff_symbol_type *)NULL) {
-       /* 
-         This symbol has no coff information in it, it will take up
-           only one slot in the output symbol table
-             */
-       native_index++;
-      }
-      else {
-       struct internal_syment *syment = coff_symbol_ptr->native;
-       if (syment == (struct internal_syment *)NULL) {
-         native_index++;
-       }
-       else {
-         /* Normalize the symbol flags */
-         if (coff_symbol_ptr->symbol.flags & BSF_FORT_COMM) {
-           /* a common symbol is undefined with a value */
-           syment->n_scnum = N_UNDEF;
-           syment->n_value = coff_symbol_ptr->symbol.value;
-         }
-         else if (coff_symbol_ptr->symbol.flags & BSF_DEBUGGING) {
-           syment->n_value = coff_symbol_ptr->symbol.value;
-         }
-         else if (coff_symbol_ptr->symbol.flags & BSF_UNDEFINED) {
-           syment->n_scnum = N_UNDEF;
-           syment->n_value = 0;
-         }       
-         else if (coff_symbol_ptr->symbol.flags & BSF_ABSOLUTE) {
-           syment->n_scnum = N_ABS;
-           syment->n_value = coff_symbol_ptr->symbol.value;
-         }       
-         else {
-           syment->n_scnum      = 
-             coff_symbol_ptr->symbol.section->output_section->index+1;
-           
-           syment->n_value = 
-             coff_symbol_ptr->symbol.value +
-               coff_symbol_ptr->symbol.section->output_offset +
-                 coff_symbol_ptr->symbol.section->output_section->vma;
-         }
-         
-         
-         /* If this symbol ties up something then do it */
-         
-         if (syment->n_sclass == C_FILE && last_file != (struct internal_syment *)NULL)
-             {
-               last_file->n_value = native_index;
-             }
-         else if ((syment->n_sclass == C_EXT 
-                   || syment->n_sclass == C_STAT 
-#ifdef C_LEAFEXT
-                   || syment->n_sclass == C_LEAFEXT 
-                     || syment->n_sclass == C_LEAFSTAT
-#endif
-                 )
-                && last_fcn != (struct internal_syment *)NULL) 
-           {
-             union internal_auxent *auxent = (union internal_auxent *)(last_fcn+1);
-             auxent->x_sym.x_fcnary.x_fcn.x_endndx.l = native_index;
-             last_fcn = (struct internal_syment *)NULL;
-             
-           }
-       else if (syment->n_sclass == C_EOS && last_tagndx != (struct internal_syment*)NULL)
-           {
-             union internal_auxent *auxent = (union internal_auxent *)(last_tagndx+1);
-             /* Remember that we keep the native index in the offset 
-                so patch the beginning of the struct to point to this
-                */
-/*if (last_
-             auxent->x_sym.x_tagndx =    last_tagndx->_n._n_n._n_offset;*/
-             auxent->x_sym.x_fcnary.x_fcn.x_endndx.l = syment->n_numaux + 1 + native_index;
-             /* Now point the eos to the structure */
-             auxent = (union internal_auxent *)(syment+1);
-             auxent->x_sym.x_tagndx.l =  last_tagndx->_n._n_n._n_offset;
-           }
-       else if (syment->n_sclass == C_BLOCK 
-                && coff_symbol_ptr->symbol.name[1] == 'e') 
-           {
-             union internal_auxent *auxent = (union internal_auxent *)((*(--last_block))+1);
-             auxent->x_sym.x_fcnary.x_fcn.x_endndx.l = native_index + syment->n_numaux + 1;
-           }
-       if (syment->n_sclass == C_EXT 
-           && !ISFCN(syment->n_type) 
-           && first_time == true 
-           && last_file != (struct internal_syment *)NULL) {
-         /* This is the first external symbol seen which isn't a 
-            function place it in the last .file entry */
-         last_file->n_value = native_index;
-         first_time = false;
-       }
-#ifdef C_LEAFPROC
-       if (syment->n_sclass == C_LEAFPROC &&
-           syment->n_numaux == 2) {
-         union internal_auxent *auxent = (union internal_auxent *)(syment+2);
-         /* This is the definition of a leaf proc, we'll relocate the 
-            address */
-         auxent->x_bal.x_balntry =       
-           coff_symbol_ptr->symbol.section->output_offset + 
-             coff_symbol_ptr->symbol.section->output_section->vma +
-               auxent->x_bal.x_balntry   ;
-       }
-#endif
-       /* If this symbol needs to be tied up then remember some facts */
-       if (syment->n_sclass == C_FILE) 
-           {
-             last_file = syment;
-           }
-       if (syment->n_numaux != 0) {
-         /*
-           If this symbol would like to point to something in the
-           future then remember where it is 
-           */
-         if (uses_x_sym_x_tagndx_p(bfd_ptr, syment)) {
-           /* 
-             If this is a ref to a structure then we'll tie it up 
-             now - there are never any forward refs for one 
-             */
-           if (syment->n_sclass == C_STRTAG ||
-               syment->n_sclass == C_ENTAG ||
-               syment->n_sclass == C_UNTAG) {
-             last_tagndx = syment;
-           }
-           else {
-             /*
-               This is a ref to a structure - the structure must
-               have been defined within the same file, and previous
-               to this point, so we can deduce the new tagndx
-               directly.
-               */
-             union internal_auxent *auxent = (union internal_auxent *)(syment+1);
-             bfd *bfd_ptr = coff_symbol_ptr->symbol.the_bfd;
-             struct internal_syment *base = obj_raw_syments(bfd_ptr);        
-/*           auxent->x_sym.x_tagndx = base[auxent->x_sym.x_tagndx]._n._n_n._n_offset;*/
-             
-             
-           }
-         }
-         if (ISFCN(syment->n_type)) {
-           last_fcn = syment;
-         }
-         if (syment->n_sclass == C_BLOCK 
-             && coff_symbol_ptr->symbol.name[1] == 'b')
-             {
-               *last_block++ = syment;
-             }
-       }
-       syment->_n._n_n._n_offset = native_index;
-       native_index = native_index + 1 + syment->n_numaux;
-      }
-    }
-  }
-}
-
-
-#endif
-static int string_size; 
+static int string_size;
 static void
 DEFUN(coff_fix_symbol_name,(ignore_abfd, symbol, native),
   bfd *ignore_abfd AND
@@ -1471,11 +1363,11 @@ DEFUN(coff_fix_symbol_name,(ignore_abfd, symbol, native),
     name = (char *)symbol->name;
   }
   name_length = strlen(name);
-             
+
   if (native->u.syment.n_sclass == C_FILE) {
     strncpy(native->u.syment._n._n_name, ".file", SYMNMLEN);
     auxent = &(native+1)->u.auxent;
-               
+
 #ifdef COFF_LONG_FILENAMES
     if (name_length <= FILNMLEN) {
       strncpy(auxent->x_file.x_fname, name, FILNMLEN);
@@ -1508,7 +1400,7 @@ DEFUN(coff_fix_symbol_name,(ignore_abfd, symbol, native),
 
 
 
-static unsigned int 
+static unsigned int
 DEFUN(coff_write_symbol,(abfd, symbol, native, written),
 bfd *abfd AND
 asymbol *symbol AND
@@ -1524,7 +1416,7 @@ unsigned int written)
   coff_fix_symbol_name(abfd, symbol, native);
   coff_swap_sym_out(abfd, &native->u.syment, &buf);
   bfd_write((PTR)& buf, 1, SYMESZ, abfd);
-  for (j = 0; j != native->u.syment.n_numaux;  j++) 
+  for (j = 0; j != native->u.syment.n_numaux;  j++)
       {
        AUXENT buf1;
        bzero((PTR)&buf, AUXESZ);
@@ -1588,23 +1480,23 @@ DEFUN(coff_write_alien_symbol,(abfd, symbol, written),
       }
 #endif
   }
-  
+
 #ifdef HASPAD1
   native->u.syment.pad1[0] = 0;
   native->u.syment.pad1[0] = 0;
 #endif
-  
+
   native->u.syment.n_type =  0;
   if (symbol->flags & BSF_LOCAL)
     native->u.syment.n_sclass =  C_STAT;
-  else 
+  else
     native->u.syment.n_sclass =  C_EXT;
   native->u.syment.n_numaux =  0;
 
   return   coff_write_symbol(abfd, symbol, native, written);
 }
 
-static unsigned int 
+static unsigned int
 DEFUN(coff_write_native_symbol,(abfd, symbol,   written),
 bfd *abfd AND
 coff_symbol_type *symbol AND
@@ -1624,8 +1516,8 @@ unsigned int written)
     lineno[count].u.offset = written;
     if (native->u.syment.n_numaux) {
       union internal_auxent  *a = &((native+1)->u.auxent);
-                   
-      a->x_sym.x_fcnary.x_fcn.x_lnnoptr =  
+
+      a->x_sym.x_fcnary.x_fcn.x_lnnoptr =
        symbol->symbol.section->output_section->moving_line_filepos;
     }
     /*
@@ -1640,12 +1532,11 @@ unsigned int written)
     }
     symbol->symbol.section->output_section->moving_line_filepos +=
       count * LINESZ;
-                 
   }
   return coff_write_symbol(abfd, &( symbol->symbol), native,written);
 }
 
-static void 
+static void
 DEFUN(coff_write_symbols,(abfd),
       bfd            *abfd)
 {
@@ -1656,20 +1547,18 @@ DEFUN(coff_write_symbols,(abfd),
   asymbol       **p;
 
   string_size = 0;
-    
-    
+
+
   /* Seek to the right place */
   bfd_seek(abfd, obj_sym_filepos(abfd), SEEK_SET);
-    
+
   /* Output all the symbols we have */
-    
+
   written = 0;
-  for (p = abfd->outsymbols, i = 0; i < limit; i++, p++) 
+  for (p = abfd->outsymbols, i = 0; i < limit; i++, p++)
       {
        asymbol        *symbol = *p;
        coff_symbol_type *c_symbol = coff_symbol_from(abfd, symbol);
-         
-
 
        if (c_symbol == (coff_symbol_type *) NULL ||
            c_symbol->native == (combined_entry_type *)NULL)
@@ -1686,15 +1575,17 @@ DEFUN(coff_write_symbols,(abfd),
   bfd_get_symcount(abfd) = written;
 
   /* Now write out strings */
-    
-  if (string_size != 0) 
+
+  if (string_size != 0)
    {
      unsigned int    size = string_size + 4;
      bfd_byte buffer[4];
 
      bfd_h_put_32(abfd, size, buffer);
      bfd_write((PTR) buffer, 1, sizeof(buffer), abfd);
-     for (p = abfd->outsymbols, i = 0; i < limit; i++, p++) 
+     for (p = abfd->outsymbols, i = 0;
+         i < limit;
+         i++, p++)
         {
           asymbol        *q = *p;
           size_t          name_length = strlen(q->name);
@@ -1703,7 +1594,7 @@ DEFUN(coff_write_symbols,(abfd),
           maxlen = ((c_symbol != NULL && c_symbol->native != NULL) &&
                     (c_symbol->native->u.syment.n_sclass == C_FILE)) ?
             FILNMLEN : SYMNMLEN;
-       
+
           if (name_length > maxlen) {
             bfd_write((PTR) (q->name), 1, name_length + 1, abfd);
           }
@@ -1714,11 +1605,11 @@ DEFUN(coff_write_symbols,(abfd),
        out 4 so that any stupid coff reader which tries to read
        the string table even when there isn't one won't croak.
        */
-      
+
     uint32e_type size = 4;
     size =  size;
     bfd_write((PTR)&size, 1, sizeof(size), abfd);
-      
+
   }
 }
 
@@ -1735,7 +1626,7 @@ Then the @code{internal_reloc} is swapped into the shape of an
 @code{external_reloc} and written out to disk.
 */
 
-static void 
+static void
 DEFUN(coff_write_relocs,(abfd),
       bfd            *abfd)
 {
@@ -1743,7 +1634,7 @@ DEFUN(coff_write_relocs,(abfd),
   for (s = abfd->sections; s != (asection *) NULL; s = s->next) {
     unsigned int    i;
     struct external_reloc dst;
-      
+
     arelent       **p = s->orelocation;
     bfd_seek(abfd, s->rel_filepos, SEEK_SET);
     for (i = 0; i < s->reloc_count; i++) {
@@ -1769,7 +1660,7 @@ DEFUN(coff_write_relocs,(abfd),
 
 #ifndef NO_COFF_LINENOS
 
-static void 
+static void
 DEFUN(coff_write_linenumbers,(abfd),
       bfd            *abfd)
 {
@@ -1833,7 +1724,7 @@ bfd            *abfd;
 
 #ifndef NO_COFF_SYMBOLS
 
-static void 
+static void
 DEFUN(coff_print_symbol,(ignore_abfd, filep, symbol, how),
       bfd            *ignore_abfd AND
       PTR           filep AND
@@ -1849,20 +1740,21 @@ DEFUN(coff_print_symbol,(ignore_abfd, filep, symbol, how),
     fprintf(file, "coff %lx %lx", (unsigned long) coffsymbol(symbol)->native,
            (unsigned long) coffsymbol(symbol)->lineno);
     break;
+  case bfd_print_symbol_nm:
   case bfd_print_symbol_all:
       {
        CONST char           *section_name = symbol->section == (asection *) NULL ?
          "*abs" : symbol->section->name;
        bfd_print_symbol_vandf((PTR) file, symbol);
-         
+
        fprintf(file, " %-5s %s %s %s",
                section_name,
                coffsymbol(symbol)->native ? "n" : "g",
                coffsymbol(symbol)->lineno ? "l" : " ",
                symbol->name);
       }
-      
-      
+
+
     break;
   }
 }
@@ -1879,11 +1771,11 @@ DEFUN(coff_set_flags,(abfd, magicp, flagsp),
       unsigned short *flagsp)
 {
   switch (bfd_get_arch(abfd)) {
-      
+
 #ifdef I960ROMAGIC
-      
+
   case bfd_arch_i960:
-      
+
       {
        unsigned        flags;
        *magicp = I960ROMAGIC;
@@ -1934,7 +1826,7 @@ DEFUN(coff_set_flags,(abfd, magicp, flagsp),
     *magicp = MC68MAGIC;
     return true;
 #endif
-       
+
 #ifdef MC88MAGIC
   case bfd_arch_m88k:
     *magicp = MC88OMAGIC;
@@ -1951,13 +1843,19 @@ DEFUN(coff_set_flags,(abfd, magicp, flagsp),
     return true;
     break;
 #endif
-       
+
+#ifdef U802TOCMAGIC
+  case bfd_arch_rs6000:
+    *magicp = U802TOCMAGIC;
+    break;
+#endif
+
   default:                     /* Unknown architecture */
     /* return false;  -- fall through to "return false" below, to avoid
-       "statement never reached" errors on the one below. */   
+       "statement never reached" errors on the one below. */
     break;
   }
-    
+
   return false;
 }
 
@@ -1981,47 +1879,65 @@ DEFUN(coff_set_arch_mach,(abfd, arch, machine),
 
 /* Calculate the file position for each section. */
 
-static void 
+static void
 DEFUN(coff_compute_section_file_positions,(abfd),
       bfd            *abfd)
 {
-  asection       *current;
-  file_ptr        sofar = FILHSZ;
-  if (bfd_get_start_address(abfd)) {
-    /*
-      A start address may have been added to the original file. In this
-      case it will need an optional header to record it.
-      */
-    abfd->flags |= EXEC_P;
-  }
-  if (abfd->flags & EXEC_P)
-    sofar += AOUTSZ;
-  
-  
-  sofar += abfd->section_count * SCNHSZ;
-  for (current = abfd->sections;       
-       current != (asection *)NULL;
-       current = current->next) {
-    /* Only deal with sections which have contents */
-    if (!(current->flags & SEC_HAS_CONTENTS))
-      continue;
-    
-    /* Align the sections in the file to the same boundary on 
-       which they are aligned in virtual memory.  I960 doesn't
-       do this (FIXME) so we can stay in sync with Intel.  960
-       doesn't yet page from files... */
+    asection       *current;
+    asection   *previous = (asection *)NULL;
+    file_ptr        sofar = FILHSZ;
+    file_ptr   old_sofar;
+    if (bfd_get_start_address(abfd)) 
+    {
+       /*  A start address may have been added to the original file. In this
+         case it will need an optional header to record it.  */
+       abfd->flags |= EXEC_P;
+    }
+
+    if (abfd->flags & EXEC_P)
+     sofar += AOUTSZ;
+
+    sofar += abfd->section_count * SCNHSZ;
+    for (current = abfd->sections;
+        current != (asection *)NULL;
+        current = current->next) {
+
+       /* Only deal with sections which have contents */
+       if (!(current->flags & SEC_HAS_CONTENTS))
+        continue;
+
+       /* Align the sections in the file to the same boundary on
+          which they are aligned in virtual memory.  I960 doesn't
+          do this (FIXME) so we can stay in sync with Intel.  960
+          doesn't yet page from files... */
 #ifndef I960
-    sofar = ALIGN(sofar, 1 << current->alignment_power);
-#endif
-    /* FIXME, in demand paged files, the low order bits of the file
-       offset must match the low order bits of the virtual address.
-       "Low order" is apparently implementation defined.  Add code
-       here to round sofar up to match the virtual address.  */
-    
-    current->filepos = sofar;
-    sofar += current->size;
-  }
-  obj_relocbase(abfd) = sofar;
+       {
+          /* make sure this section is aligned on the right boundary - by
+             padding the previous section up if necessary */
+
+          old_sofar= sofar;
+          sofar = ALIGN(sofar, 1 << current->alignment_power);
+          if (previous != (asection *)NULL) {
+              previous->size += sofar - old_sofar;
+          }
+       }
+
+#endif
+       /* FIXME, in demand paged files, the low order bits of the file
+          offset must match the low order bits of the virtual address.
+          "Low order" is apparently implementation defined.  Add code
+          here to round sofar up to match the virtual address.  */
+
+       current->filepos = sofar;
+
+       /* make sure that this section is of the right size too */
+       old_sofar =  sofar += current->size;
+       sofar = ALIGN(sofar, 1 << current->alignment_power);
+       current->size += sofar - old_sofar ;
+
+       previous = current;
+    }
+    obj_relocbase(abfd) = sofar;
 }
 
 
@@ -2046,18 +1962,18 @@ DEFUN(coff_write_object_contents,(abfd),
     asection       *text_sec = NULL;
     asection       *data_sec = NULL;
     asection       *bss_sec = NULL;
-    
+
     struct internal_filehdr internal_f;
     struct internal_aouthdr internal_a;
-    
-    
+
+
     bfd_error = system_call_error;
-    
-    
+
+
     if(abfd->output_has_begun == false) {
       coff_compute_section_file_positions(abfd);
     }
-    
+
     if (abfd->sections != (asection *)NULL) {
       scn_base = abfd->sections->filepos;
   }
@@ -2067,17 +1983,17 @@ DEFUN(coff_write_object_contents,(abfd),
   if (bfd_seek(abfd, scn_base, SEEK_SET) != 0)
     return false;
   reloc_base = obj_relocbase(abfd);
-    
+
   /* Make a pass through the symbol table to count line number entries and
      put them into the correct asections */
-    
+
 #ifndef NO_COFF_LINENOS
   coff_count_linenumbers(abfd);
 #endif
   data_base = scn_base;
-    
+
   /* Work out the size of the reloc and linno areas */
-    
+
   for (current = abfd->sections; current != NULL; current = current->next) {
     reloc_size += current->reloc_count * RELSZ;
 #ifndef NO_COFF_LINENOS
@@ -2085,10 +2001,10 @@ DEFUN(coff_write_object_contents,(abfd),
 #endif
     data_base += SCNHSZ;
   }
-    
+
   lineno_base = reloc_base + reloc_size;
   sym_base = lineno_base + lnno_size;
-    
+
   /* Indicate in each section->line_filepos its actual file address */
   for (current = abfd->sections; current != NULL; current = current->next) {
     if (current->lineno_count) {
@@ -2109,20 +2025,20 @@ DEFUN(coff_write_object_contents,(abfd),
       current->rel_filepos = 0;
     }
   }
-    
+
   /* Write section headers to the file.  */
-    
+
   bfd_seek(abfd,
           (file_ptr) ((abfd->flags & EXEC_P) ?
                       (FILHSZ + AOUTSZ) : FILHSZ),
           SEEK_SET);
-    
+
     {
 #if 0
       unsigned int    pad = abfd->flags & D_PAGED ? data_base : 0;
 #endif
       unsigned int    pad = 0;
-       
+
       for (current = abfd->sections; current != NULL; current = current->next) {
        struct internal_scnhdr section;
        strncpy(&(section.s_name[0]), current->name, 8);
@@ -2136,7 +2052,6 @@ DEFUN(coff_write_object_contents,(abfd),
        if (current->size - pad == 0 ||
            (current->flags & SEC_LOAD) == 0) {
          section.s_scnptr = 0;
-           
        }
        else {
          section.s_scnptr = current->filepos;
@@ -2149,7 +2064,7 @@ DEFUN(coff_write_object_contents,(abfd),
          hasrelocs = true;
        if (current->lineno_count != 0)
          haslinno = true;
-         
+
        section.s_flags = sec_to_styp_flags(current->name,current->flags);
 
        if (!strcmp(current->name, _TEXT)) {
@@ -2158,8 +2073,8 @@ DEFUN(coff_write_object_contents,(abfd),
          data_sec = current;
        } else if (!strcmp(current->name, _BSS)) {
          bss_sec = current;
-       } 
-         
+       }
+
 #ifdef I960
        section.s_align = (current->alignment_power
                           ? 1 << current->alignment_power
@@ -2235,12 +2150,12 @@ DEFUN(coff_write_object_contents,(abfd),
       internal_f.f_flags |= flags;
       /* ...and the "opt"hdr... */
 
-#ifdef A29K 
+#ifdef A29K
 # ifdef ULTRA3 /* NYU's machine */
        /* FIXME: This is a bogus check.  I really want to see if there
         * is a .shbss or a .shdata section, if so then set the magic
         * number to indicate a shared data executable.
-        */ 
+        */
       if (internal_f.f_nscns >= 7)
        internal_a.magic = SHMAGIC;     /* Shared magic */
       else
@@ -2249,7 +2164,7 @@ DEFUN(coff_write_object_contents,(abfd),
 #define __A_MAGIC_SET__
 #endif /* A29K */
 #ifdef I960
-      internal_a.magic = (magic == I960ROMAGIC ? NMAGIC : OMAGIC); 
+      internal_a.magic = (magic == I960ROMAGIC ? NMAGIC : OMAGIC);
 #define __A_MAGIC_SET__
 #endif         /* I960 */
 #if M88
@@ -2259,9 +2174,16 @@ DEFUN(coff_write_object_contents,(abfd),
 
 #if M68 || I386 || MIPS
 #define __A_MAGIC_SET__
-     /* Never was anything here for the 68k */ 
+     /* Never was anything here for the 68k */
 #endif /* M88 */
 
+#if RS6000COFF_C
+#define __A_MAGIC_SET__
+      internal_a.magic = (abfd->flags & D_PAGED)? RS6K_AOUTHDR_ZMAGIC:
+                        (abfd->flags & WP_TEXT)? RS6K_AOUTHDR_NMAGIC:
+                                                 RS6K_AOUTHDR_OMAGIC;
+#endif
+
 #ifndef __A_MAGIC_SET__
 # include "Your aouthdr magic number is not being set!"
 #else
@@ -2389,7 +2311,7 @@ coff_close_and_cleanup(abfd)
 }
 
 #endif
-static PTR 
+static PTR
 buy_and_read(abfd, where, seek_direction, size)
     bfd            *abfd;
     file_ptr        where;
@@ -2419,20 +2341,18 @@ bfd *abfd)
   char string_table_size_buffer[4];
   unsigned int string_table_size;
   char *string_table;
-  /*
-    At this point we should be "seek"'d to the end of the
-    symbols === the symbol table size.
-    */
-         
+
+  /* At this point we should be "seek"'d to the end of the
+     symbols === the symbol table size.  */
   if (bfd_read((char *) string_table_size_buffer,
               sizeof(string_table_size_buffer),
               1, abfd) != sizeof(string_table_size)) {
     bfd_error = system_call_error;
     return (NULL);
   }                            /* on error */
-         
+
   string_table_size = bfd_h_get_32(abfd, (bfd_byte *) string_table_size_buffer);
-         
+
   if ((string_table = (PTR) bfd_alloc(abfd, string_table_size -= 4)) == NULL) {
     bfd_error = no_memory;
     return (NULL);
@@ -2440,10 +2360,50 @@ bfd *abfd)
   if (bfd_read(string_table, string_table_size, 1, abfd) != string_table_size) {
     bfd_error = system_call_error;
     return (NULL);
-  }                    
+  }
   return string_table;
 }
 
+/* Allocate space for the ".debug" section, and read it.
+   We did not read the debug section until now, because
+   we didn't want to go to the trouble until someone needed it. */
+
+static char *
+DEFUN(build_debug_section,(abfd),
+       bfd *abfd)
+{
+  char *debug_section;
+  long position;
+
+  asection *sect = bfd_get_section_by_name (abfd, ".debug");
+
+  if (!sect) {
+     bfd_error = no_debug_section;
+     return NULL;
+  }
+
+  debug_section = (PTR) bfd_alloc (abfd, bfd_section_size (abfd, sect));
+  if (debug_section == NULL) {
+    bfd_error = no_memory;
+    return NULL;
+  }
+
+  /* Seek to the beginning of the `.debug' section and read it. 
+     Save the current position first; it is needed by our caller.
+     Then read debug section and reset the file pointer.  */
+
+  position = bfd_tell (abfd);
+  bfd_seek (abfd, sect->filepos, SEEK_SET);
+  if (bfd_read (debug_section, bfd_section_size (abfd, sect), 1, abfd)
+      != bfd_section_size (abfd, sect)) {
+    bfd_error = system_call_error;
+    return NULL;
+  }
+  bfd_seek (abfd, position, SEEK_SET);
+  return debug_section;
+}
+
+
 /* Return a pointer to a malloc'd copy of 'name'.  'name' may not be
  \0-terminated, but will not exceed 'maxlen' characters.  The copy *will*
  be \0-terminated.  */
@@ -2455,13 +2415,13 @@ DEFUN(copy_name,(abfd, name, maxlen),
 {
   int  len;
   char *newname;
+
   for (len = 0; len < maxlen; ++len) {
     if (name[len] == '\0') {
       break;
     }
   }
+
   if ((newname = (PTR) bfd_alloc(abfd, len+1)) == NULL) {
     bfd_error = no_memory;
     return (NULL);
@@ -2472,19 +2432,19 @@ DEFUN(copy_name,(abfd, name, maxlen),
 }
 
 
-/*
-read a symbol table into freshly mallocated memory, swap it, and knit the
-symbol names into a normalized form. By normalized here I mean that all
-symbols have an n_offset pointer that points to a NULL terminated string.
-Oh, and the first symbol MUST be a C_FILE.  If there wasn't one there
-before, put one there.
-*/
+/* Read a symbol table into freshly bfd_allocated memory, swap it, and
+   knit the symbol names into a normalized form.  By normalized here I
+   mean that all symbols have an n_offset pointer that points to a null-
+   terminated string.  */
+
+#ifndef SYMNAME_IN_DEBUG
+#define        SYMNAME_IN_DEBUG(x)  0
+#endif
 
 static combined_entry_type *
 DEFUN(get_normalized_symtab,(abfd),
 bfd            *abfd)
 {
-
   combined_entry_type          *internal;
   combined_entry_type          *internal_ptr;
   combined_entry_type         *internal_end;
@@ -2492,9 +2452,9 @@ bfd            *abfd)
   SYMENT *raw_src;
   SYMENT *raw_end;
   char           *string_table = NULL;
+  char          *debug_section = NULL;
   unsigned long   size;
 
-
   unsigned int raw_size;
   if (obj_raw_syments(abfd) != (combined_entry_type *)NULL) {
     return obj_raw_syments(abfd);
@@ -2523,39 +2483,46 @@ bfd            *abfd)
     */
 
   /* Swap all the raw entries */
-  for (raw_src = raw, internal_ptr = internal; raw_src < raw_end; raw_src++, internal_ptr++) {
+  for (raw_src = raw, internal_ptr = internal;
+       raw_src < raw_end;
+       raw_src++, internal_ptr++) {
+
     unsigned int i;
-    coff_swap_sym_in(abfd, (char *)raw_src, (char *)&internal_ptr->u.syment);    
+    coff_swap_sym_in(abfd, (char *)raw_src, (char *)&internal_ptr->u.syment);
     internal_ptr->fix_tag = 0;
     internal_ptr->fix_end = 0;
 
-    for (i = internal_ptr->u.syment.n_numaux; i; --i, raw_src++, internal_ptr++) {
+    for (i = internal_ptr->u.syment.n_numaux;
+        i;
+        --i, raw_src++, internal_ptr++) {
+
       (internal_ptr+1)->fix_tag = 0;
       (internal_ptr+1)->fix_end = 0;
 
-      coff_swap_aux_in(abfd, (char *)(raw_src +1), internal_ptr->u.syment.n_type,
-                      internal_ptr->u.syment.n_sclass, &       (internal_ptr+1)->u.auxent);
+      coff_swap_aux_in(abfd, (char *)(raw_src +1),
+                      internal_ptr->u.syment.n_type,
+                      internal_ptr->u.syment.n_sclass,
+                      &(internal_ptr+1)->u.auxent);
 
-      coff_pointerize_aux(abfd, 
+      coff_pointerize_aux(abfd,
                          internal,
                          internal_ptr->u.syment.n_type,
                          internal_ptr->u.syment.n_sclass,
                          internal_ptr +1);
     }
   }
-      
+
   /* Free all the raw stuff */
   bfd_release(abfd, raw);
 
   for (internal_ptr = internal; internal_ptr < internal_end;
-       internal_ptr ++) 
+       internal_ptr ++)
       {
        if (internal_ptr->u.syment.n_sclass == C_FILE) {
          /* make a file symbol point to the name in the auxent, since
             the text ".file" is redundant */
          if ((internal_ptr+1)->u.auxent.x_file.x_n.x_zeroes == 0) {
-           /* the filename is a long one, point into the string table
-            */
+           /* the filename is a long one, point into the string table */
            if (string_table == NULL) {
              string_table = build_string_table(abfd);
            }
@@ -2567,28 +2534,24 @@ bfd            *abfd)
          else {
            /* ordinary short filename, put into memory anyway */
            internal_ptr->u.syment._n._n_n._n_offset = (int)
-             copy_name(abfd, (internal_ptr+1)->u.auxent.x_file.x_fname, FILNMLEN);
-           
+             copy_name(abfd, (internal_ptr+1)->u.auxent.x_file.x_fname,
+                       FILNMLEN);
          }
        }
        else {
          if (internal_ptr->u.syment._n._n_n._n_zeroes != 0) {
-           /*
-             This is a "short" name.  Make it long.
-             */
+           /* This is a "short" name.  Make it long.  */
            unsigned long   i = 0;
            char           *newstring = NULL;
-           /*
-             find the length of this string without walking into memory
-             that isn't ours.
-             */
-       
+
+           /* find the length of this string without walking into memory
+              that isn't ours.  */
            for (i = 0; i < 8; ++i) {
              if (internal_ptr->u.syment._n._n_name[i] == '\0') {
                break;
              }                 /* if end of string */
            }                   /* possible lengths of this string. */
-       
+
            if ((newstring = (PTR) bfd_alloc(abfd, ++i)) == NULL) {
              bfd_error = no_memory;
              return (NULL);
@@ -2597,23 +2560,29 @@ bfd            *abfd)
            strncpy(newstring, internal_ptr->u.syment._n._n_name, i-1);
            internal_ptr->u.syment._n._n_n._n_offset =  (int) newstring;
            internal_ptr->u.syment._n._n_n._n_zeroes = 0;
-       
          }
-         else {
-           /*  This is a long name already. Just point it at the string in memory.   */
+         else if (!SYMNAME_IN_DEBUG(&internal_ptr->u.syment)) {
+           /* Long name already.  Point symbol at the string in the table.  */
            if (string_table == NULL) {
              string_table = build_string_table(abfd);
            }
-           internal_ptr->u.syment._n._n_n._n_offset =
-             (int) (string_table - 4 +  internal_ptr->u.syment._n._n_n._n_offset);
-         }     
+           internal_ptr->u.syment._n._n_n._n_offset = (int)
+             (string_table - 4 + internal_ptr->u.syment._n._n_n._n_offset);
+         }
+         else {
+           /* Long name in debug section.  Very similar.  */
+           if (debug_section == NULL) {
+             debug_section = build_debug_section(abfd);
+           }
+           internal_ptr->u.syment._n._n_n._n_offset = (int)
+             (debug_section + internal_ptr->u.syment._n._n_n._n_offset);
+         }
        }
        internal_ptr += internal_ptr->u.syment.n_numaux;
-      }        
+      }
 
   obj_raw_syments(abfd) = internal;
-  obj_string_table(abfd) = string_table;
-    
+
   return (internal);
 }                              /* get_normalized_symtab() */
 
@@ -2662,9 +2631,9 @@ asection       *asect;
   {
     LINENO  *native_lineno;
     alent          *lineno_cache;
-    
+
     BFD_ASSERT(asect->lineno == (alent *) NULL);
-    
+
     native_lineno = (LINENO *) buy_and_read(abfd,
                                            asect->line_filepos,
                                            SEEK_SET,
@@ -2675,16 +2644,16 @@ asection       *asect;
     if (lineno_cache == NULL) {
       bfd_error = no_memory;
       return false;
-    } else {   
+    } else {
       unsigned int    counter = 0;
       alent          *cache_ptr = lineno_cache;
       LINENO  *src = native_lineno;
-      
+
       while (counter < asect->lineno_count) {
        struct internal_lineno dst;
        coff_swap_lineno_in(abfd, src, &dst);
        cache_ptr->line_number = dst.l_lnno;
-       
+
        if (cache_ptr->line_number == 0) {
          coff_symbol_type *sym =
            (coff_symbol_type *) (dst.l_addr.l_symndx
@@ -2697,13 +2666,13 @@ asection       *asect;
          cache_ptr->u.offset = dst.l_addr.l_paddr
            - bfd_section_vma(abfd, asect);
        }                               /* If no linenumber expect a symbol index */
-       
+
        cache_ptr++;
        src++;
        counter++;
       }
       cache_ptr->line_number = 0;
-      
+
     }
     asect->lineno = lineno_cache;
     /* FIXME, free native_lineno here, or use alloca or something. */
@@ -2721,23 +2690,22 @@ DEFUN(coff_slurp_symbol_table,(abfd),
   combined_entry_type         *native_symbols;
   coff_symbol_type *cached_area;
   unsigned int   *table_ptr;
-    
+
   unsigned int    number_of_symbols = 0;
   if (obj_symbols(abfd))
     return true;
   bfd_seek(abfd, obj_sym_filepos(abfd), SEEK_SET);
-    
+
   /* Read in the symbol table */
   if ((native_symbols = get_normalized_symtab(abfd)) == NULL) {
     return (false);
   }                            /* on error */
-    
-    
+
   /* Allocate enough room for all the symbols in cached form */
   cached_area =
     (coff_symbol_type *)
       bfd_alloc(abfd, (size_t) (bfd_get_symcount(abfd) * sizeof(coff_symbol_type)));
-    
+
   if (cached_area == NULL) {
     bfd_error = no_memory;
     return false;
@@ -2745,11 +2713,13 @@ DEFUN(coff_slurp_symbol_table,(abfd),
   table_ptr =
     (unsigned int *)
       bfd_alloc(abfd, (size_t) (bfd_get_symcount(abfd) * sizeof(unsigned int)));
-    
+
   if (table_ptr == NULL) {
     bfd_error = no_memory;
     return false;
-  } else {
+  } 
+  else 
+  {
     coff_symbol_type *dst = cached_area;
     unsigned int    last_native_index = bfd_get_symcount(abfd);
     unsigned int    this_index = 0;
@@ -2757,7 +2727,7 @@ DEFUN(coff_slurp_symbol_table,(abfd),
       combined_entry_type         *src = native_symbols + this_index;
       table_ptr[this_index] = number_of_symbols;
       dst->symbol.the_bfd = abfd;
-       
+
       dst->symbol.name = (char *)(src->u.syment._n._n_n._n_offset);
       /*
        We use the native name field to point to the cached field
@@ -2774,10 +2744,13 @@ DEFUN(coff_slurp_symbol_table,(abfd),
        dst->symbol.flags |= BSF_NOT_AT_END;
 #endif
        /* Fall through to next case */
-         
+
 #endif
-         
+
       case C_EXT:
+#ifdef RS6000COFF_C
+      case C_HIDEXT:
+#endif
        if ((src->u.syment.n_scnum) == 0) {
          if ((src->u.syment.n_value) == 0) {
            dst->symbol.flags = BSF_UNDEFINED;
@@ -2808,8 +2781,10 @@ DEFUN(coff_slurp_symbol_table,(abfd),
            dst->symbol.flags |= BSF_NOT_AT_END;
          }
        }
-         
+
+
        break;
+
       case C_STAT:             /* static                        */
 #ifdef I960
       case C_LEAFSTAT:         /* static leaf procedure        */
@@ -2829,7 +2804,7 @@ DEFUN(coff_slurp_symbol_table,(abfd),
        else
          dst->symbol.value = (src->u.syment.n_value) ;
        break;
-         
+
       case C_MOS:              /* member of structure   */
       case C_EOS:              /* end of structure              */
 #ifdef NOTDEF  /* C_AUTOARG has the same value */
@@ -2843,7 +2818,6 @@ DEFUN(coff_slurp_symbol_table,(abfd),
       case C_AUTOARG:          /* 960-specific storage class */
 #endif
       case C_TPDEF:            /* type definition               */
-         
       case C_ARG:
       case C_AUTO:             /* automatic variable */
       case C_FIELD:            /* bit field */
@@ -2851,17 +2825,31 @@ DEFUN(coff_slurp_symbol_table,(abfd),
       case C_MOE:              /* member of enumeration         */
       case C_MOU:              /* member of union               */
       case C_UNTAG:            /* union tag                     */
-         
        dst->symbol.flags = BSF_DEBUGGING;
        dst->symbol.value = (src->u.syment.n_value);
        break;
-         
+
       case C_FILE:             /* file name                     */
       case C_STRTAG:           /* structure tag                 */
+#ifdef RS6000COFF_C
+      case C_BINCL:            /* beginning of include file     */
+      case C_EINCL:            /* ending of include file        */
+      case C_GSYM:
+      case C_LSYM:
+      case C_PSYM:
+      case C_RSYM:
+      case C_RPSYM:
+      case C_STSYM:
+      case C_DECL:
+      case C_ENTRY:
+      case C_FUN:
+      case C_BSTAT:
+      case C_ESTAT:
+#endif
        dst->symbol.flags = BSF_DEBUGGING;
        dst->symbol.value = (src->u.syment.n_value);
-         
        break;
+
       case C_BLOCK:            /* ".bb" or ".eb"                */
       case C_FCN:              /* ".bf" or ".ef"                */
       case C_EFCN:             /* physical end of function      */
@@ -2870,8 +2858,8 @@ DEFUN(coff_slurp_symbol_table,(abfd),
          Base the value as an index from the base of the section
          */
        dst->symbol.value = (src->u.syment.n_value) - dst->symbol.section->vma;
-         
        break;
+
       case C_NULL:
       case C_EXTDEF:           /* external definition           */
       case C_ULABEL:           /* undefined label               */
@@ -2879,22 +2867,20 @@ DEFUN(coff_slurp_symbol_table,(abfd),
       case C_LINE:             /* line # reformatted as symbol table entry */
       case C_ALIAS:            /* duplicate tag                 */
       case C_HIDDEN:           /* ext symbol in dmert public lib */
-         
       default:
-         
-       fprintf(stderr,"Unrecognized storage class %d\n", 
+
+       fprintf(stderr,"Unrecognized storage class %d\n",
                                src->u.syment.n_sclass);
        abort();
        dst->symbol.flags = BSF_DEBUGGING;
        dst->symbol.value = (src->u.syment.n_value);
-         
        break;
       }
-       
+
       BFD_ASSERT(dst->symbol.flags != 0);
-       
+
       dst->native = src;
-       
+
       dst->symbol.udata = 0;
       dst->lineno = (alent *) NULL;
       this_index += (src->u.syment.n_numaux) + 1;
@@ -2902,10 +2888,10 @@ DEFUN(coff_slurp_symbol_table,(abfd),
       number_of_symbols++;
     }                          /* walk the native symtab */
   }                            /* bfdize the native symtab */
-    
+
   obj_symbols(abfd) = cached_area;
   obj_raw_syments(abfd) = native_symbols;
-    
+
   bfd_get_symcount(abfd) = number_of_symbols;
   obj_convert(abfd) = table_ptr;
   /* Slurp the line tables for each section too */
@@ -2926,27 +2912,43 @@ bfd            *abfd;
   {
     if (!coff_slurp_symbol_table(abfd))
       return 0;
-    
+
     return (bfd_get_symcount(abfd) + 1) * (sizeof(coff_symbol_type *));
   }
 
 
 static unsigned int
-coff_get_symtab(abfd, alocation)
-bfd            *abfd;
-asymbol       **alocation;
-  {
+DEFUN(coff_get_symtab, (abfd, alocation),
+      bfd            *abfd AND
+      asymbol       **alocation)
+{
     unsigned int    counter = 0;
     coff_symbol_type *symbase;
     coff_symbol_type **location = (coff_symbol_type **) (alocation);
     if (!coff_slurp_symbol_table(abfd))
-      return 0;
-    
-    for (symbase = obj_symbols(abfd); counter++ < bfd_get_symcount(abfd);)
-      *(location++) = symbase++;
+     return 0;
+
+    symbase = obj_symbols(abfd);
+    while (counter <  bfd_get_symcount(abfd))
+    {
+       /* This nasty code looks at the symbol to decide whether or
+          not it is descibes a constructor/destructor entry point. It
+          is structured this way to (hopefully) speed non matches */
+       
+       if (symbase->symbol.name[9] == '$') 
+       {
+           bfd_constructor_entry(abfd, 
+                                (asymbol **)location,
+                                 symbase->symbol.name[10] == 'I' ?
+                                 "CTOR" : "DTOR");
+       }
+
+       *(location++) = symbase++;
+       counter++;
+    }
     *location++ = 0;
     return bfd_get_symcount(abfd);
-  }
+}
 
 #endif /* NO_COFF_SYMBOLS */
 
@@ -2965,11 +2967,11 @@ sec_ptr         asect;
 /*doc*
 @subsubsection Reading Relocations
 Coff relocations are easily transformed into the internal BFD form
-(@code{arelent}). 
+(@code{arelent}).
 
 Reading a coff relocation table is done in the following stages:
 @itemize @bullet
-@item 
+@item
 The entire coff relocation table is read into memory.
 @item
 Each relocation is processed in turn, first it is swapped from the
@@ -2994,145 +2996,163 @@ DEFUN(coff_slurp_reloc_table,(abfd, asect, symbols),
       bfd            *abfd AND
       sec_ptr         asect AND
       asymbol       **symbols)
-  {
+{
     RELOC   *native_relocs;
     arelent        *reloc_cache;
     if (asect->relocation)
       return true;
     if (asect->reloc_count == 0)
-      return true;
+     return true;
+    if (asect->flags & SEC_CONSTRUCTOR)
+     return true;
 #ifndef NO_COFF_SYMBOLS
     if (!coff_slurp_symbol_table(abfd))
-      return false;
+     return false;
 #endif
     native_relocs =
-      (RELOC *) buy_and_read(abfd,
-                            asect->rel_filepos,
-                            SEEK_SET,
-                            (size_t) (RELSZ *
-                                      asect->reloc_count));
+     (RELOC *) buy_and_read(abfd,
+                           asect->rel_filepos,
+                           SEEK_SET,
+                           (size_t) (RELSZ *
+                                     asect->reloc_count));
     reloc_cache = (arelent *)
-      bfd_alloc(abfd, (size_t) (asect->reloc_count * sizeof(arelent)));
-    
+     bfd_alloc(abfd, (size_t) (asect->reloc_count * sizeof(arelent)));
+
     if (reloc_cache == NULL) {
-      bfd_error = no_memory;
-      return false;
+       bfd_error = no_memory;
+       return false;
     } {                                /* on error */
-      arelent        *cache_ptr;
-      RELOC   *src;
-      for (cache_ptr = reloc_cache,
-          src = native_relocs;
-          cache_ptr < reloc_cache + asect->reloc_count;
-          cache_ptr++,
-          src++) {
-       struct internal_reloc dst;
-       asymbol        *ptr;
-       bfd_swap_reloc_in(abfd, src, &dst);
-       
-       dst.r_symndx += obj_symbol_slew(abfd);
-       cache_ptr->sym_ptr_ptr = symbols + obj_convert(abfd)[dst.r_symndx];
-#ifdef A29K 
-       /* AMD has two relocation entries for the 'consth' instruction.
-        * The first is R_IHIHALF (part 1), the second is R_IHCONST
-        * (part 2).  The second entry's r_symndx does not contain
-        * an index to a symbol but rather a value (apparently).
-        * Also, see the ifdef below for saving the r_symndx value in addend.
-        */
-       if (dst.r_type == R_IHCONST)  {
+       arelent        *cache_ptr;
+       RELOC   *src;
+       for (cache_ptr = reloc_cache,
+            src = native_relocs;
+            cache_ptr < reloc_cache + asect->reloc_count;
+            cache_ptr++,
+            src++) {
+           struct internal_reloc dst;
+           asymbol        *ptr;
+           bfd_swap_reloc_in(abfd, src, &dst);
+
+           dst.r_symndx += obj_symbol_slew(abfd);
+           cache_ptr->sym_ptr_ptr = symbols + obj_convert(abfd)[dst.r_symndx];
+#ifdef A29K
+           /* AMD has two relocation entries for the 'consth' instruction.
+            * The first is R_IHIHALF (part 1), the second is R_IHCONST
+            * (part 2).  The second entry's r_symndx does not contain
+            * an index to a symbol but rather a value (apparently).
+            * Also, see the ifdef below for saving the r_symndx value in addend.
+            */
+           if (dst.r_type == R_IHCONST)  {
                ptr = NULL;
-       } else
+           } else
 #endif
-       ptr = *(cache_ptr->sym_ptr_ptr);
-       cache_ptr->address = dst.r_vaddr;
-       /*
-         The symbols definitions that we have read in have been
-         relocated as if their sections started at 0. But the offsets
-         refering to the symbols in the raw data have not been
-         modified, so we have to have a negative addend to compensate.
-         
-         Note that symbols which used to be common must be left alone
-         */
-       
-       if (ptr && ptr->the_bfd == abfd 
-           && ptr->section != (asection *) NULL 
-           && ((ptr->flags & BSF_OLD_COMMON)== 0)) 
+            ptr = *(cache_ptr->sym_ptr_ptr);
+           cache_ptr->address = dst.r_vaddr;
+           /*
+             The symbols definitions that we have read in have been
+             relocated as if their sections started at 0. But the offsets
+             refering to the symbols in the raw data have not been
+             modified, so we have to have a negative addend to compensate.
+             
+             Note that symbols which used to be common must be left alone */
+
+           if (ptr && ptr->the_bfd == abfd
+               && ptr->section != (asection *) NULL
+               && ((ptr->flags & BSF_OLD_COMMON)== 0))
            {
 #ifndef M88
-             cache_ptr->addend = -(ptr->section->vma + ptr->value);
+               cache_ptr->addend = -(ptr->section->vma + ptr->value);
 #else
-             cache_ptr->addend = 0;
+               cache_ptr->addend = 0;
 #endif
 
            }
-       else {
-         cache_ptr->addend = 0;
-       }
-       
-       cache_ptr->address -= asect->vma;
-       
-       cache_ptr->section = (asection *) NULL;
-
-#ifdef A29K 
-        if (dst.r_type == R_IHCONST) {
-          /* Add in the value which was stored in the symbol index */
-         /* See above comment */
-          cache_ptr->addend += dst.r_symndx;
-          /* Throw away the bogus symbol pointer */
-          cache_ptr->sym_ptr_ptr = 0;
-        }
-       cache_ptr->howto = howto_table + dst.r_type;
+           else {
+               cache_ptr->addend = 0;
+           }
+
+           cache_ptr->address -= asect->vma;
+
+           cache_ptr->section = (asection *) NULL;
+
+#ifdef A29K
+           if (dst.r_type == R_IHCONST) {
+               /* Add in the value which was stored in the symbol index */
+               /* See above comment */
+               cache_ptr->addend += dst.r_symndx;
+               /* Throw away the bogus symbol pointer */
+               cache_ptr->sym_ptr_ptr = 0;
+           }
+           cache_ptr->howto = howto_table + dst.r_type;
 #endif
 #if I386
-       cache_ptr->howto = howto_table + dst.r_type;
+           cache_ptr->howto = howto_table + dst.r_type;
 #endif
 #if I960
-       cache_ptr->howto = howto_table + dst.r_type;
+           cache_ptr->howto = howto_table + dst.r_type;
 #endif
 #if M68
-       cache_ptr->howto = howto_table + dst.r_type - R_RELBYTE;
+           cache_ptr->howto = howto_table + dst.r_type - R_RELBYTE;
 #endif
 #if M88
-       if (dst.r_type >= R_PCR16L && dst.r_type <= R_VRT32) {
-         cache_ptr->howto = howto_table + dst.r_type - R_PCR16L;
-         cache_ptr->addend += dst.r_offset << 16;
-       }
-       else {
-         BFD_ASSERT(0);
-       }
+           if (dst.r_type >= R_PCR16L && dst.r_type <= R_VRT32) {
+               cache_ptr->howto = howto_table + dst.r_type - R_PCR16L;
+               cache_ptr->addend += dst.r_offset << 16;
+           }
+           else {
+               BFD_ASSERT(0);
+           }
 #endif
-       
-      }
-      
+       }
     }
-    
+
     asect->relocation = reloc_cache;
     return true;
-  }
+}
 
 
 /* This is stupid.  This function should be a boolean predicate */
 static unsigned int
-coff_canonicalize_reloc(abfd, section, relptr, symbols)
-bfd            *abfd;
-sec_ptr         section;
-arelent       **relptr;
-asymbol       **symbols;
-  {
+DEFUN(coff_canonicalize_reloc, (abfd, section, relptr, symbols),
+bfd            *abfd AND
+sec_ptr         section AND
+arelent       **relptr AND
+asymbol       **symbols)
+{
     arelent        *tblptr = section->relocation;
     unsigned int    count = 0;
-    if (!(tblptr || coff_slurp_reloc_table(abfd, section, symbols)))
-      return 0;
-    tblptr = section->relocation;
-    if (!tblptr)
-      return 0;
-    
-    for (; count++ < section->reloc_count;)
-      *relptr++ = tblptr++;
-    
-    *relptr = 0;
-    
+
+
+    if (section->flags & SEC_CONSTRUCTOR) 
+    {
+       /* this section has relocs made up by us, they are not in the
+          file, so take them out of their chain and place them into
+          the data area provided */
+       arelent_chain *chain = section->constructor_chain;
+       for (count = 0; count < section->reloc_count; count ++) 
+       {
+           *relptr ++ = &chain->relent;
+           chain = chain->next;
+       }
+
+    }
+    else 
+    { 
+       coff_slurp_reloc_table(abfd, section, symbols);
+
+
+       tblptr = section->relocation;
+       if (!tblptr)
+        return 0;
+
+       for (; count++ < section->reloc_count;)
+        *relptr++ = tblptr++;
+
+
+    }
+       *relptr = 0;
     return section->reloc_count;
-  }
+}
 
 #ifndef NO_COFF_SYMBOLS
 
@@ -3163,28 +3183,28 @@ DEFUN(coff_find_nearest_line,(abfd,
   static bfd_vma  cache_offset;
   static unsigned int cache_i;
   static alent   *cache_l;
-    
+
   unsigned int    i = 0;
   coff_data_type *cof = coff_data(abfd);
   /* Run through the raw syments if available */
   combined_entry_type *p;
   alent          *l;
   unsigned int    line_base = 0;
-    
-    
+
+
   *filename_ptr = 0;
   *functionname_ptr = 0;
   *line_ptr = 0;
-    
+
   /* Don't try and find line numbers in a non coff file */
   if (abfd->xvec->flavour != bfd_target_coff_flavour)
     return false;
-    
+
   if (cof == NULL)
     return false;
 
   p = cof->raw_syments;
-    
+
   for (i = 0; i < cof->raw_syment_count; i++) {
     if (p->u.syment.n_sclass == C_FILE) {
       /* File name has been moved into symbol */
@@ -3209,7 +3229,7 @@ DEFUN(coff_find_nearest_line,(abfd,
     i = 0;
     l = section->lineno;
   }
-    
+
   for (; i < section->lineno_count; i++) {
     if (l->line_number == 0) {
       /* Get the symbol this line number points at */
@@ -3237,7 +3257,7 @@ DEFUN(coff_find_nearest_line,(abfd,
     }
     l++;
   }
-    
+
   cache_abfd = abfd;
   cache_section = section;
   cache_offset = offset;
@@ -3259,23 +3279,23 @@ bfd *abfd;
 #endif /* NO_COFF_SYMBOLS */
 
 
-static int 
+static int
 DEFUN(coff_sizeof_headers,(abfd, reloc),
       bfd *abfd AND
       boolean reloc)
-  {
+{
     size_t size;
-    
+
     if (reloc == false) {
-      size = FILHSZ + AOUTSZ;
+       size = FILHSZ + AOUTSZ;
     }
     else {
-      size = FILHSZ;
+       size = FILHSZ;
     }
-    
+
     size +=  abfd->section_count * SCNHSZ;
     return size;
-  }
+}
 
 
 #define coff_core_file_failing_command _bfd_dummy_core_file_failing_command
@@ -3292,4 +3312,3 @@ DEFUN(coff_sizeof_headers,(abfd, reloc),
 #define coff_bfd_debug_info_start              bfd_void
 #define coff_bfd_debug_info_end                bfd_void
 #define coff_bfd_debug_info_accumulate (PROTO(void,(*),(bfd*, struct sec *))) bfd_void
-
This page took 0.103356 seconds and 4 git commands to generate.