* coffgen.c (coff_write_symbol): Reindented. Changed to return
authorIan Lance Taylor <ian@airs.com>
Thu, 31 Mar 1994 16:58:23 +0000 (16:58 +0000)
committerIan Lance Taylor <ian@airs.com>
Thu, 31 Mar 1994 16:58:23 +0000 (16:58 +0000)
boolean, and changed written to unsigned int *.  Check error
returns from called functions.
(coff_write_alien_symbol): Likewise.
(coff_write_native_symbol): Likewise.
(coff_write_symbols): Likewise.  Reworked checks on whether to
write symbol name to string table for clarity and to avoid core
dumping when given a non COFF symbol.
* libcoff-in.h (coff_write_symbols): Declare as returning boolean.
* libcoff.h: Rebuilt.
* coffcode.h (coff_write_object_contents): Check return value of
coff_write_symbols.

bfd/ChangeLog
bfd/coffcode.h
bfd/coffgen.c

index c2d010550bf751d2c633eec19197a9c750525459..0732eaa07e5276f4fd45db6460f715d7a1320c27 100644 (file)
@@ -1,3 +1,18 @@
+Thu Mar 31 11:52:15 1994  Ian Lance Taylor  (ian@tweedledumb.cygnus.com)
+
+       * coffgen.c (coff_write_symbol): Reindented.  Changed to return
+       boolean, and changed written to unsigned int *.  Check error
+       returns from called functions.
+       (coff_write_alien_symbol): Likewise.
+       (coff_write_native_symbol): Likewise.
+       (coff_write_symbols): Likewise.  Reworked checks on whether to
+       write symbol name to string table for clarity and to avoid core
+       dumping when given a non COFF symbol.
+       * libcoff-in.h (coff_write_symbols): Declare as returning boolean.
+       * libcoff.h: Rebuilt.
+       * coffcode.h (coff_write_object_contents): Check return value of
+       coff_write_symbols.
+
 Wed Mar 30 16:25:41 1994  Ian Lance Taylor  (ian@tweedledumb.cygnus.com)
 
        Changes to let BFD return an error indication from
index 0f984fecae4828d90b93552df8962f2815e3cdb3..10cf9ff0cec1473c009011cc18aa872c76bf687b 100644 (file)
@@ -1768,7 +1768,8 @@ coff_write_object_contents (abfd)
       if (!coff_renumber_symbols (abfd))
        return false;
       coff_mangle_symbols (abfd);
-      coff_write_symbols (abfd);
+      if (! coff_write_symbols (abfd))
+       return false;
       if (!coff_write_linenumbers (abfd))
        return false;
       coff_write_relocs (abfd);
index e0880482122f9b1ba7ded94904da879f7ff64af6..d7fd2af3e4e696eedf5b257cd2764b310a0e6fc5 100644 (file)
@@ -41,6 +41,14 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
 #include "coff/internal.h"
 #include "libcoff.h"
 
+static boolean coff_write_symbol PARAMS ((bfd *, asymbol *,
+                                         combined_entry_type *,
+                                         unsigned int *));
+static boolean coff_write_alien_symbol PARAMS ((bfd *, asymbol *,
+                                               unsigned int *));
+static boolean coff_write_native_symbol PARAMS ((bfd *, coff_symbol_type *,
+                                                unsigned int *));
+
 static asection bfd_debug_section = { "*DEBUG*" };
 
 /* Take a section header read from a coff file (in HOST byte order),
@@ -645,56 +653,62 @@ coff_fix_symbol_name (abfd, symbol, native)
     }
 }
 
-#define        set_index(symbol, idx)  ((symbol)->udata =(PTR) (idx))
+/* We need to keep track of the symbol index so that when we write out
+   the relocs we can get the index for a symbol.  This method is a
+   hack.  FIXME.  */
+
+#define set_index(symbol, idx) ((symbol)->udata = (PTR) (idx))
+
+/* Write a symbol out to a COFF file.  */
 
-static unsigned int
+static boolean
 coff_write_symbol (abfd, symbol, native, written)
      bfd *abfd;
      asymbol *symbol;
      combined_entry_type *native;
-     unsigned int written;
+     unsigned int *written;
 {
-  unsigned int    numaux = native->u.syment.n_numaux;
-  int             type = native->u.syment.n_type;
-  int             class =  native->u.syment.n_sclass;
+  unsigned int numaux = native->u.syment.n_numaux;
+  int type = native->u.syment.n_type;
+  int class =  native->u.syment.n_sclass;
   PTR buf;
   bfd_size_type symesz;
 
-  /* @@ bfd_debug_section isn't accessible outside this file, but we know
-     that C_FILE symbols belong there.  So move them.  */
+  /* @@ bfd_debug_section isn't accessible outside this file, but we
+     know that C_FILE symbols belong there.  So move them.  */
   if (native->u.syment.n_sclass == C_FILE)
     symbol->section = &bfd_debug_section;
 
   if (symbol->section == &bfd_abs_section) 
-  {
-    native->u.syment.n_scnum = N_ABS;
-  }
+    {
+      native->u.syment.n_scnum = N_ABS;
+    }
   else if (symbol->section == &bfd_debug_section) 
-  {
-    native->u.syment.n_scnum = N_DEBUG;
-  }
+    {
+      native->u.syment.n_scnum = N_DEBUG;
+    }
   else if (symbol->section == &bfd_und_section)   
-  {
-    native->u.syment.n_scnum = N_UNDEF;
-  }
+    {
+      native->u.syment.n_scnum = N_UNDEF;
+    }
   else 
-  {
-    native->u.syment.n_scnum =
-     symbol->section->output_section->target_index;
-  }
-  
+    {
+      native->u.syment.n_scnum =
+       symbol->section->output_section->target_index;
+    }
   
-  coff_fix_symbol_name(abfd, symbol, native);
+  coff_fix_symbol_name (abfd, symbol, native);
 
   symesz = bfd_coff_symesz (abfd);
   buf = bfd_alloc (abfd, symesz);
   if (!buf)
     {
       bfd_set_error (bfd_error_no_memory);
-      abort();                 /* FIXME */
+      return false;
     }
-  bfd_coff_swap_sym_out(abfd, &native->u.syment, buf);
-  bfd_write(buf, 1, symesz, abfd);
+  bfd_coff_swap_sym_out (abfd, &native->u.syment, buf);
+  if (bfd_write (buf, 1, symesz, abfd) != symesz)
+    return false;
   bfd_release (abfd, buf);
 
   if (native->u.syment.n_numaux > 0)
@@ -707,227 +721,270 @@ coff_write_symbol (abfd, symbol, native, written)
       if (!buf)
        {
          bfd_set_error (bfd_error_no_memory);
-         abort();              /* FIXME */
+         return false;
        }
       for (j = 0; j < native->u.syment.n_numaux;  j++)
        {
-         bfd_coff_swap_aux_out(abfd,
-                               &((native + j + 1)->u.auxent),
-                               type,
-                               class,
-                               j,
-                               native->u.syment.n_numaux,
-                               buf);
-         bfd_write(buf, 1, auxesz, abfd);
+         bfd_coff_swap_aux_out (abfd,
+                                &((native + j + 1)->u.auxent),
+                                type,
+                                class,
+                                j,
+                                native->u.syment.n_numaux,
+                                buf);
+         if (bfd_write (buf, 1, auxesz, abfd)!= auxesz)
+           return false;
        }
       bfd_release (abfd, buf);
     }
-  /*
-    Reuse somewhere in the symbol to keep the index
-    */
-  set_index(symbol, written);
-  return   written + 1 + numaux;
+
+  /* Store the index for use when we write out the relocs.  */
+  set_index (symbol, *written);
+
+  *written += numaux + 1;
+  return true;
 }
 
+/* Write out a symbol to a COFF file that does not come from a COFF
+   file originally.  This symbol may have been created by the linker,
+   or we may be linking a non COFF file to a COFF file.  */
 
-static unsigned int
+static boolean
 coff_write_alien_symbol (abfd, symbol, written)
      bfd *abfd;
      asymbol *symbol;
-     unsigned int written;
+     unsigned int *written;
 {
-  /*
-    This symbol has been created by the loader, or come from a non
-    coff format. It  has no native element to inherit, make our
-    own
-    */
   combined_entry_type *native;
   combined_entry_type dummy;
+
   native = &dummy;
   native->u.syment.n_type =  T_NULL;
   native->u.syment.n_flags =  0;
   if (symbol->section == &bfd_und_section) 
-  {
-      native->u.syment.n_scnum =  N_UNDEF;
-      native->u.syment.n_value =  symbol->value;
+    {
+      native->u.syment.n_scnum = N_UNDEF;
+      native->u.syment.n_value = symbol->value;
     }
   else if (bfd_is_com_section (symbol->section))
-  {
-      native->u.syment.n_scnum =  N_UNDEF;
-      native->u.syment.n_value =  symbol->value;
-
-  }
-  
-  else if (symbol->flags & BSF_DEBUGGING) {
-      /*
-       remove name so it doesn't take up any space
-       */
-      symbol->name = "";
+    {
+      native->u.syment.n_scnum = N_UNDEF;
+      native->u.syment.n_value = symbol->value;
     }
-  else {
-      native->u.syment.n_scnum  =   symbol->section->output_section->target_index;
-      native->u.syment.n_value =   symbol->value +
-       symbol->section->output_section->vma +
-       symbol->section->output_offset;
-      /* Copy the any flags from the the file hdr into the symbol  */
+  else if (symbol->flags & BSF_DEBUGGING)
     {
-      coff_symbol_type *c = coff_symbol_from(abfd, symbol);
-      if (c != (coff_symbol_type *)NULL) {
-         native->u.syment.n_flags =   bfd_asymbol_bfd(&c->symbol)->flags;
-       }
+      /* Remove the symbol name so that it does not take up any space.
+        COFF won't know what to do with it anyhow.  */
+      symbol->name = "";
     }
+  else
+    {
+      native->u.syment.n_scnum =
+       symbol->section->output_section->target_index;
+      native->u.syment.n_value = (symbol->value
+                                 + symbol->section->output_section->vma
+                                 + symbol->section->output_offset);
+
+      /* Copy the any flags from the the file header into the symbol.
+        FIXME: Why?  */
+      {
+       coff_symbol_type *c = coff_symbol_from (abfd, symbol);
+       if (c != (coff_symbol_type *) NULL)
+         native->u.syment.n_flags = bfd_asymbol_bfd (&c->symbol)->flags;
+      }
     }
 
-  native->u.syment.n_type =  0;
+  native->u.syment.n_type = 0;
   if (symbol->flags & BSF_LOCAL)
-   native->u.syment.n_sclass =  C_STAT;
+    native->u.syment.n_sclass = C_STAT;
   else
-   native->u.syment.n_sclass =  C_EXT;
-  native->u.syment.n_numaux =  0;
+    native->u.syment.n_sclass = C_EXT;
+  native->u.syment.n_numaux = 0;
 
-  return   coff_write_symbol(abfd, symbol, native, written);
+  return coff_write_symbol (abfd, symbol, native, written);
 }
 
-static unsigned int
+/* Write a native symbol to a COFF file.  */
+
+static boolean
 coff_write_native_symbol (abfd, symbol, written)
      bfd *abfd;
      coff_symbol_type *symbol;
-     unsigned int written;
+     unsigned int *written;
 {
-  /*
-    Does this symbol have an ascociated line number - if so then
-    make it remember this symbol index. Also tag the auxent of
-    this symbol to point to the right place in the lineno table
-    */
   combined_entry_type *native = symbol->native;
+  alent *lineno = symbol->lineno;
 
-  alent          *lineno = symbol->lineno;
-
-  if (lineno && !symbol->done_lineno) {
-    unsigned int    count = 0;
-    lineno[count].u.offset = written;
-    if (native->u.syment.n_numaux) {
-      union internal_auxent  *a = &((native+1)->u.auxent);
+  /* If this symbol has an associated line number, we must store the
+     symbol index in the line number field.  We also tag the auxent to
+     point to the right place in the lineno table.  */
+  if (lineno && !symbol->done_lineno)
+    {
+      unsigned int count = 0;
+      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 =
-       symbol->symbol.section->output_section->moving_line_filepos;
-    }
-    /*
-      And count and relocate all other linenumbers
-      */
+         a->x_sym.x_fcnary.x_fcn.x_lnnoptr =
+           symbol->symbol.section->output_section->moving_line_filepos;
+       }
 
-    count++;
-    while (lineno[count].line_number) {
+      /* Count and relocate all other linenumbers.  */
+      count++;
+      while (lineno[count].line_number != 0)
+       {
 #if 0
-/* 13 april 92. sac 
-I've been told this, but still need proof:
-> The second bug is also in `bfd/coffcode.h'.  This bug causes the linker to screw
-> up the pc-relocations for all the line numbers in COFF code.  This bug isn't
-> only specific to A29K implementations, but affects all systems using COFF
-> format binaries.  Note that in COFF object files, the line number core offsets
-> output by the assembler are relative to the start of each procedure, not
-> to the start of the .text section.  This patch relocates the line numbers
-> relative to the `native->u.syment.n_value' instead of the section virtual
-> address.  modular!olson@cs.arizona.edu (Jon Olson)
-*/
-       lineno[count].u.offset += native->u.syment.n_value;
-
+         /* 13 april 92. sac 
+            I've been told this, but still need proof:
+            > The second bug is also in `bfd/coffcode.h'.  This bug
+            > causes the linker to screw up the pc-relocations for
+            > all the line numbers in COFF code.  This bug isn't only
+            > specific to A29K implementations, but affects all
+            > systems using COFF format binaries.  Note that in COFF
+            > object files, the line number core offsets output by
+            > the assembler are relative to the start of each
+            > procedure, not to the start of the .text section.  This
+            > patch relocates the line numbers relative to the
+            > `native->u.syment.n_value' instead of the section
+            > virtual address.
+            > modular!olson@cs.arizona.edu (Jon Olson)
+            */
+         lineno[count].u.offset += native->u.syment.n_value;
 #else
-      lineno[count].u.offset +=
-       symbol->symbol.section->output_section->vma +
-         symbol->symbol.section->output_offset;
+         lineno[count].u.offset +=
+           (symbol->symbol.section->output_section->vma
+            + symbol->symbol.section->output_offset);
 #endif
-      count++;
-    }
-    symbol->done_lineno = true;
+         count++;
+       }
+      symbol->done_lineno = true;
     
-    symbol->symbol.section->output_section->moving_line_filepos +=
-      count * bfd_coff_linesz (abfd);
-  }
-  return coff_write_symbol(abfd, &( symbol->symbol), native,written);
+      symbol->symbol.section->output_section->moving_line_filepos +=
+       count * bfd_coff_linesz (abfd);
+    }
+
+  return coff_write_symbol (abfd, &(symbol->symbol), native, written);
 }
 
-void
+/* Write out the COFF symbols.  */
+
+boolean
 coff_write_symbols (abfd)
-     bfd            *abfd;
+     bfd *abfd;
 {
-  unsigned int    i;
-  unsigned int    limit = bfd_get_symcount(abfd);
-  unsigned int    written = 0;
-
-  asymbol       **p;
+  unsigned int i;
+  unsigned int limit = bfd_get_symcount(abfd);
+  unsigned int written = 0;
+  asymbol **p;
 
   string_size = 0;
   debug_string_size = 0;
 
   /* Seek to the right place */
-  bfd_seek(abfd, obj_sym_filepos(abfd), SEEK_SET);
+  if (bfd_seek (abfd, obj_sym_filepos(abfd), SEEK_SET) != 0)
+    return false;
 
   /* Output all the symbols we have */
 
   written = 0;
   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)
-           {
-             written = coff_write_alien_symbol(abfd, symbol, written);
-           }
-       else
-           {
-             written = coff_write_native_symbol(abfd, c_symbol, written);
-           }
+    {
+      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)
+       {
+         if (! coff_write_alien_symbol (abfd, symbol, &written))
+           return false;
+       }
+      else
+       {
+         if (! coff_write_native_symbol (abfd, c_symbol, &written))
+           return false;
+       }
+    }
 
-  bfd_get_symcount(abfd) = written;
+  bfd_get_symcount (abfd) = written;
 
   /* Now write out strings */
 
   if (string_size != 0)
    {
-     unsigned int    size = string_size + 4;
+     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);
+     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++)
-        {
-          asymbol        *q = *p;
-          size_t          name_length = strlen(q->name);
-          int maxlen;
-          coff_symbol_type*       c_symbol = coff_symbol_from(abfd, q);
-          maxlen = ((c_symbol != NULL && c_symbol->native != NULL) &&
-                    (c_symbol->native->u.syment.n_sclass == C_FILE)) ?
-            FILNMLEN : SYMNMLEN;
-
-          if (name_length > maxlen
-              && ! bfd_coff_symname_in_debug (abfd,
-                                              &c_symbol->native->u.syment))
-            bfd_write((PTR) (q->name), 1, name_length + 1, abfd);
-        }
+       {
+        asymbol *q = *p;
+        size_t name_length = strlen (q->name);
+        coff_symbol_type *c_symbol = coff_symbol_from (abfd, q);
+        size_t maxlen;
+
+        /* Figure out whether the symbol name should go in the string
+           table.  Symbol names that are short enough are stored
+           directly in the syment structure.  File names permit a
+           different, longer, length in the syment structure.  On
+           XCOFF, some symbol names are stored in the .debug section
+           rather than in the string table.  */
+
+        if (c_symbol == NULL
+            || c_symbol->native == NULL)
+          {
+            /* This is not a COFF symbol, so it certainly is not a
+               file name, nor does it go in the .debug section.  */
+            maxlen = SYMNMLEN;
+          }
+        else if (bfd_coff_symname_in_debug (abfd,
+                                            &c_symbol->native->u.syment))
+          {
+            /* This symbol name is in the XCOFF .debug section.
+               Don't write it into the string table.  */
+            maxlen = name_length;
+          }
+        else if (c_symbol->native->u.syment.n_sclass == C_FILE)
+          maxlen = FILNMLEN;
+        else
+          maxlen = SYMNMLEN;
+
+        if (name_length > maxlen)
+          {
+            if (bfd_write ((PTR) (q->name), 1, name_length + 1, abfd)
+                != name_length + 1)
+              return false;
+          }
+       }
    }
-  else {
-    /* We would normally not write anything here, but we'll write
-       out 4 so that any stupid coff reader which tries to read
-       the string table even when there isn't one won't croak.  */
-    unsigned int size = 4;
-    bfd_byte buffer[4];
-
-    bfd_h_put_32 (abfd, size, buffer);
-    bfd_write((PTR) buffer, 1, sizeof (buffer), abfd);
-  }
+  else
+    {
+      /* We would normally not write anything here, but we'll write
+        out 4 so that any stupid coff reader which tries to read the
+        string table even when there isn't one won't croak.  */
+      unsigned int size = 4;
+      bfd_byte buffer[4];
+
+      bfd_h_put_32 (abfd, size, buffer);
+      if (bfd_write ((PTR) buffer, 1, 4, abfd) != 4)
+       return false;
+    }
 
+  /* Make sure the .debug section was created to be the correct size.
+     We should create it ourselves on the fly, but we don't because
+     BFD won't let us write to any section until we know how large all
+     the sections are.  We could still do it by making another pass
+     over the symbols.  FIXME.  */
   BFD_ASSERT (debug_string_size == 0
              || (debug_string_section != (asection *) NULL
                  && (BFD_ALIGN (debug_string_size,
                                 1 << debug_string_section->alignment_power)
                      == bfd_section_size (abfd, debug_string_section))));
+
+  return true;
 }
 
 boolean