* write.c (relax_frag): Make non-static.
[deliverable/binutils-gdb.git] / bfd / coffgen.c
index 14c0e3856c4a6a74f8ed897dd0f085840e9b830a..76e9430312c48bd2f2a18d0f1c3946a8c17955d3 100644 (file)
@@ -1,5 +1,5 @@
 /* Support for the generic parts of COFF, for BFD.
-   Copyright 1990, 91, 92, 93, 94, 1995 Free Software Foundation, Inc.
+   Copyright 1990, 91, 92, 93, 94, 95, 1996 Free Software Foundation, Inc.
    Written by Cygnus Support.
 
 This file is part of BFD, the Binary File Descriptor library.
@@ -81,10 +81,8 @@ make_a_section_from_file (abfd, hdr, target_index)
   if (return_section == NULL)
     return false;
 
-  /* s_paddr is presumed to be = to s_vaddr */
-
   return_section->vma = hdr->s_vaddr;
-  return_section->lma = return_section->vma;
+  return_section->lma = hdr->s_paddr;
   return_section->_raw_size = hdr->s_size;
   return_section->filepos = hdr->s_scnptr;
   return_section->rel_filepos = hdr->s_relptr;
@@ -397,12 +395,9 @@ _bfd_coff_read_internal_relocs (abfd, sec, cache, external_relocs,
 
   if (external_relocs == NULL)
     {
-      free_external = (bfd_byte *) malloc (sec->reloc_count * relsz);
+      free_external = (bfd_byte *) bfd_malloc (sec->reloc_count * relsz);
       if (free_external == NULL && sec->reloc_count > 0)
-       {
-         bfd_set_error (bfd_error_no_memory);
-         goto error_return;
-       }
+       goto error_return;
       external_relocs = free_external;
     }
 
@@ -414,13 +409,10 @@ _bfd_coff_read_internal_relocs (abfd, sec, cache, external_relocs,
   if (internal_relocs == NULL)
     {
       free_internal = ((struct internal_reloc *)
-                      malloc (sec->reloc_count
-                              * sizeof (struct internal_reloc)));
+                      bfd_malloc (sec->reloc_count
+                                  * sizeof (struct internal_reloc)));
       if (free_internal == NULL && sec->reloc_count > 0)
-       {
-         bfd_set_error (bfd_error_no_memory);
-         goto error_return;
-       }
+       goto error_return;
       internal_relocs = free_internal;
     }
 
@@ -1280,6 +1272,11 @@ coff_get_lineno (ignore_abfd, symbol)
   return coffsymbol (symbol)->lineno;
 }
 
+#if 0
+
+/* This is only called from coff_add_missing_symbols, which has been
+   disabled.  */
+
 asymbol *
 coff_section_symbol (abfd, name)
      bfd *abfd;
@@ -1326,6 +1323,8 @@ coff_section_symbol (abfd, name)
   return sym;
 }
 
+#endif /* 0 */
+
 /* This function transforms the offsets into the symbol table into
    pointers to syments.  */
 
@@ -1356,7 +1355,7 @@ coff_pointerize_aux (abfd, table_base, symbol, indaux, auxent)
   /* Otherwise patch up */
 #define N_TMASK coff_data (abfd)->local_n_tmask
 #define N_BTSHFT coff_data (abfd)->local_n_btshft
-  if ((ISFCN (type) || ISTAG (class) || class == C_BLOCK)
+  if ((ISFCN (type) || ISTAG (class) || class == C_BLOCK || class == C_FCN)
       && auxent->u.auxent.x_sym.x_fcnary.x_fcn.x_endndx.l > 0)
     {
       auxent->u.auxent.x_sym.x_fcnary.x_fcn.x_endndx.p =
@@ -1456,12 +1455,9 @@ _bfd_coff_get_external_symbols (abfd)
 
   size = obj_raw_syment_count (abfd) * symesz;
 
-  syms = (PTR) malloc (size);
+  syms = (PTR) bfd_malloc (size);
   if (syms == NULL && size != 0)
-    {
-      bfd_set_error (bfd_error_no_memory);
-      return false;
-    }
+    return false;
 
   if (bfd_seek (abfd, obj_sym_filepos (abfd), SEEK_SET) != 0
       || bfd_read (syms, size, 1, abfd) != size)
@@ -1523,12 +1519,9 @@ _bfd_coff_read_string_table (abfd)
       return NULL;
     }
 
-  strings = (char *) malloc (strsize);
+  strings = (char *) bfd_malloc (strsize);
   if (strings == NULL)
-    {
-      bfd_set_error (bfd_error_no_memory);
-      return NULL;
-    }
+    return NULL;
 
   if (bfd_read (strings + STRING_SIZE_SIZE,
                strsize - STRING_SIZE_SIZE, 1, abfd)
@@ -1588,7 +1581,7 @@ coff_get_normalized_symtab (abfd)
     return obj_raw_syments (abfd);
 
   size = obj_raw_syment_count (abfd) * sizeof (combined_entry_type);
-  internal = (combined_entry_type *) bfd_alloc (abfd, size);
+  internal = (combined_entry_type *) bfd_zalloc (abfd, size);
   if (internal == NULL && size != 0)
     return NULL;
   internal_end = internal + obj_raw_syment_count (abfd);
@@ -1614,10 +1607,6 @@ coff_get_normalized_symtab (abfd)
       unsigned int i;
       bfd_coff_swap_sym_in (abfd, (PTR) raw_src,
                            (PTR) & internal_ptr->u.syment);
-      internal_ptr->fix_value = 0;
-      internal_ptr->fix_tag = 0;
-      internal_ptr->fix_end = 0;
-      internal_ptr->fix_scnlen = 0;
       symbol_ptr = internal_ptr;
 
       for (i = 0;
@@ -1626,11 +1615,6 @@ coff_get_normalized_symtab (abfd)
        {
          internal_ptr++;
          raw_src += symesz;
-
-         internal_ptr->fix_value = 0;
-         internal_ptr->fix_tag = 0;
-         internal_ptr->fix_end = 0;
-         internal_ptr->fix_scnlen = 0;
          bfd_coff_swap_aux_in (abfd, (PTR) raw_src,
                                symbol_ptr->u.syment.n_type,
                                symbol_ptr->u.syment.n_sclass,
@@ -1778,7 +1762,8 @@ coff_bfd_make_debug_symbol (abfd, ptr, sz)
   coff_symbol_type *new = (coff_symbol_type *) bfd_alloc (abfd, sizeof (coff_symbol_type));
   if (new == NULL)
     return (NULL);
-  /* @@ This shouldn't be using a constant multiplier.  */
+  /* @@ The 10 is a guess at a plausible maximum number of aux entries
+     (but shouldn't be a constant).  */
   new->native = (combined_entry_type *) bfd_zalloc (abfd, sizeof (combined_entry_type) * 10);
   if (!new->native)
     return (NULL);
@@ -1809,6 +1794,78 @@ coff_get_symbol_info (abfd, symbol, ret)
     }
 }
 
+/* Return the COFF syment for a symbol.  */
+
+boolean
+bfd_coff_get_syment (abfd, symbol, psyment)
+     bfd *abfd;
+     asymbol *symbol;
+     struct internal_syment *psyment;
+{
+  coff_symbol_type *csym;
+
+  csym = coff_symbol_from (abfd, symbol);
+  if (csym == NULL || csym->native == NULL)
+    {
+      bfd_set_error (bfd_error_invalid_operation);
+      return false;
+    }
+
+  *psyment = csym->native->u.syment;
+
+  if (csym->native->fix_value)
+    psyment->n_value = ((combined_entry_type *) psyment->n_value
+                       - obj_raw_syments (abfd));
+
+  /* FIXME: We should handle fix_line here.  */
+
+  return true;
+}
+
+/* Return the COFF auxent for a symbol.  */
+
+boolean
+bfd_coff_get_auxent (abfd, symbol, indx, pauxent)
+     bfd *abfd;
+     asymbol *symbol;
+     int indx;
+     union internal_auxent *pauxent;
+{
+  coff_symbol_type *csym;
+  combined_entry_type *ent;
+
+  csym = coff_symbol_from (abfd, symbol);
+
+  if (csym == NULL
+      || csym->native == NULL
+      || indx >= csym->native->u.syment.n_numaux)
+    {
+      bfd_set_error (bfd_error_invalid_operation);
+      return false;
+    }
+
+  ent = csym->native + indx + 1;
+
+  *pauxent = ent->u.auxent;
+
+  if (ent->fix_tag)
+    pauxent->x_sym.x_tagndx.l =
+      ((combined_entry_type *) pauxent->x_sym.x_tagndx.p
+       - obj_raw_syments (abfd));
+
+  if (ent->fix_end)
+    pauxent->x_sym.x_fcnary.x_fcn.x_endndx.l =
+      ((combined_entry_type *) pauxent->x_sym.x_fcnary.x_fcn.x_endndx.p
+       - obj_raw_syments (abfd));
+
+  if (ent->fix_scnlen)
+    pauxent->x_csect.x_scnlen.l =
+      ((combined_entry_type *) pauxent->x_csect.x_scnlen.p
+       - obj_raw_syments (abfd));
+
+  return true;
+}
+
 /* Print out information about COFF symbol.  */
 
 void
@@ -1889,6 +1946,13 @@ coff_print_symbol (abfd, filep, symbol, how)
                               (long) auxp->u.auxent.x_scn.x_scnlen,
                               auxp->u.auxent.x_scn.x_nreloc,
                               auxp->u.auxent.x_scn.x_nlinno);
+                     if (auxp->u.auxent.x_scn.x_checksum != 0
+                         || auxp->u.auxent.x_scn.x_associated != 0
+                         || auxp->u.auxent.x_scn.x_comdat != 0)
+                       fprintf (file, " checksum 0x%lx assoc %d comdat %d",
+                                auxp->u.auxent.x_scn.x_checksum,
+                                auxp->u.auxent.x_scn.x_associated,
+                                auxp->u.auxent.x_scn.x_comdat);
                      break;
                    }
                  /* else fall through */
@@ -1939,16 +2003,17 @@ coff_print_symbol (abfd, filep, symbol, how)
 
 /*ARGSUSED*/
 boolean
-coff_find_nearest_line (abfd, section, ignore_symbols, offset, filename_ptr,
+coff_find_nearest_line (abfd, section, symbols, offset, filename_ptr,
                        functionname_ptr, line_ptr)
      bfd *abfd;
      asection *section;
-     asymbol **ignore_symbols;
+     asymbol **symbols;
      bfd_vma offset;
      CONST char **filename_ptr;
      CONST char **functionname_ptr;
      unsigned int *line_ptr;
 {
+  boolean found;
   unsigned int i;
   unsigned int line_base;
   coff_data_type *cof = coff_data (abfd);
@@ -1958,6 +2023,16 @@ coff_find_nearest_line (abfd, section, ignore_symbols, offset, filename_ptr,
   alent *l;
   struct coff_section_tdata *sec_data;
 
+  /* Before looking through the symbol table, try to use a .stab
+     section to find the information.  */
+  if (! _bfd_stab_section_find_nearest_line (abfd, symbols, section, offset,
+                                            &found, filename_ptr,
+                                            functionname_ptr, line_ptr,
+                                            &coff_data (abfd)->line_info))
+    return false;
+  if (found)
+    return true;
+
   *filename_ptr = 0;
   *functionname_ptr = 0;
   *line_ptr = 0;
@@ -2043,52 +2118,51 @@ coff_find_nearest_line (abfd, section, ignore_symbols, offset, filename_ptr,
       line_base = 0;
     }
 
-  l = &section->lineno[i];
-
-  for (; i < section->lineno_count; i++)
+  if (section->lineno != NULL)
     {
-      if (l->line_number == 0)
+      l = &section->lineno[i];
+
+      for (; i < section->lineno_count; i++)
        {
-         /* Get the symbol this line number points at */
-         coff_symbol_type *coff = (coff_symbol_type *) (l->u.sym);
-         if (coff->symbol.value > offset)
-           break;
-         *functionname_ptr = coff->symbol.name;
-         if (coff->native)
+         if (l->line_number == 0)
            {
-             combined_entry_type *s = coff->native;
-             s = s + 1 + s->u.syment.n_numaux;
-
-             /* In XCOFF a debugging symbol can follow the function
-                symbol.  */
-             if (s->u.syment.n_scnum == N_DEBUG)
-               s = s + 1 + s->u.syment.n_numaux;
-
-             /*
-                S should now point to the .bf of the function
-              */
-             if (s->u.syment.n_numaux)
+             /* Get the symbol this line number points at */
+             coff_symbol_type *coff = (coff_symbol_type *) (l->u.sym);
+             if (coff->symbol.value > offset)
+               break;
+             *functionname_ptr = coff->symbol.name;
+             if (coff->native)
                {
-                 /*
-                    The linenumber is stored in the auxent
-                  */
-                 union internal_auxent *a = &((s + 1)->u.auxent);
-                 line_base = a->x_sym.x_misc.x_lnsz.x_lnno;
-                 *line_ptr = line_base;
+                 combined_entry_type *s = coff->native;
+                 s = s + 1 + s->u.syment.n_numaux;
+
+                 /* In XCOFF a debugging symbol can follow the
+                    function symbol.  */
+                 if (s->u.syment.n_scnum == N_DEBUG)
+                   s = s + 1 + s->u.syment.n_numaux;
+
+                 /* S should now point to the .bf of the function.  */
+                 if (s->u.syment.n_numaux)
+                   {
+                     /* The linenumber is stored in the auxent.  */
+                     union internal_auxent *a = &((s + 1)->u.auxent);
+                     line_base = a->x_sym.x_misc.x_lnsz.x_lnno;
+                     *line_ptr = line_base;
+                   }
                }
            }
+         else
+           {
+             if (l->u.offset + bfd_get_section_vma (abfd, section) > offset)
+               break;
+             *line_ptr = l->line_number + line_base - 1;
+           }
+         l++;
        }
-      else
-       {
-         if (l->u.offset + bfd_get_section_vma (abfd, section) > offset)
-           break;
-         *line_ptr = l->line_number + line_base - 1;
-       }
-      l++;
     }
 
   /* Cache the results for the next call.  */
-  if (sec_data == NULL)
+  if (sec_data == NULL && section->owner == abfd)
     {
       section->used_by_bfd =
        ((PTR) bfd_zalloc (abfd,
This page took 0.027715 seconds and 4 git commands to generate.