import gdb-1999-06-21 snapshot
[external/binutils.git] / bfd / coffgen.c
index 74414a1..a06ed66 100644 (file)
@@ -1,5 +1,6 @@
 /* Support for the generic parts of COFF, for BFD.
-   Copyright 1990, 91, 92, 93, 94, 95, 96, 1997 Free Software Foundation, Inc.
+   Copyright 1990, 91, 92, 93, 94, 95, 96, 97, 1998
+   Free Software Foundation, Inc.
    Written by Cygnus Support.
 
 This file is part of BFD, the Binary File Descriptor library.
@@ -283,11 +284,12 @@ coff_object_p (abfd)
       opthdr = bfd_alloc (abfd, aoutsz);
       if (opthdr == NULL)
        return 0;;
-      if (bfd_read (opthdr, 1, aoutsz, abfd) != aoutsz)
+      if (bfd_read (opthdr, 1, internal_f.f_opthdr, abfd)
+         != internal_f.f_opthdr)
        {
          return 0;
        }
-      bfd_coff_swap_aouthdr_in (abfd, opthdr, (PTR) & internal_a);
+      bfd_coff_swap_aouthdr_in (abfd, opthdr, (PTR) &internal_a);
     }
 
   return coff_real_object_p (abfd, nscns, &internal_f,
@@ -656,16 +658,18 @@ coff_renumber_symbols (bfd_ptr, first_undef)
       if ((symbol_ptr_ptr[i]->flags & BSF_NOT_AT_END) != 0
          || (!bfd_is_und_section (symbol_ptr_ptr[i]->section)
              && !bfd_is_com_section (symbol_ptr_ptr[i]->section)
-             && ((symbol_ptr_ptr[i]->flags & (BSF_GLOBAL | BSF_FUNCTION))
-                 != BSF_GLOBAL)))
+             && ((symbol_ptr_ptr[i]->flags & BSF_FUNCTION) != 0
+                 || ((symbol_ptr_ptr[i]->flags & (BSF_GLOBAL | BSF_WEAK))
+                     == 0))))
        *newsyms++ = symbol_ptr_ptr[i];
 
     for (i = 0; i < symbol_count; i++)
       if ((symbol_ptr_ptr[i]->flags & BSF_NOT_AT_END) == 0
          && !bfd_is_und_section (symbol_ptr_ptr[i]->section)
          && (bfd_is_com_section (symbol_ptr_ptr[i]->section)
-             || ((symbol_ptr_ptr[i]->flags & (BSF_GLOBAL | BSF_FUNCTION))
-                 == BSF_GLOBAL)))
+             || ((symbol_ptr_ptr[i]->flags & BSF_FUNCTION) == 0
+                 && ((symbol_ptr_ptr[i]->flags & (BSF_GLOBAL | BSF_WEAK))
+                     != 0))))
        *newsyms++ = symbol_ptr_ptr[i];
 
     *first_undef = newsyms - bfd_ptr->outsymbols;
@@ -1030,6 +1034,8 @@ coff_write_alien_symbol (abfd, symbol, written, string_size_p,
   native->u.syment.n_type = 0;
   if (symbol->flags & BSF_LOCAL)
     native->u.syment.n_sclass = C_STAT;
+  else if (symbol->flags & BSF_WEAK)
+    native->u.syment.n_sclass = obj_pe (abfd) ? C_NT_WEAK : C_WEAKEXT;
   else
     native->u.syment.n_sclass = C_EXT;
   native->u.syment.n_numaux = 0;
@@ -1415,8 +1421,8 @@ coff_pointerize_aux (abfd, table_base, symbol, indaux, auxent)
      unsigned int indaux;
      combined_entry_type *auxent;
 {
-  int type = symbol->u.syment.n_type;
-  int class = symbol->u.syment.n_sclass;
+  unsigned int type = symbol->u.syment.n_type;
+  unsigned int class = symbol->u.syment.n_sclass;
 
   if (coff_backend_info (abfd)->_bfd_coff_pointerize_aux_hook)
     {
@@ -1598,7 +1604,7 @@ _bfd_coff_read_string_table (abfd)
   if (strsize < STRING_SIZE_SIZE)
     {
       (*_bfd_error_handler)
-       ("%s: bad string table size %lu", bfd_get_filename (abfd),
+       (_("%s: bad string table size %lu"), bfd_get_filename (abfd),
         (unsigned long) strsize);
       bfd_set_error (bfd_error_bad_value);
       return NULL;
@@ -1741,9 +1747,19 @@ coff_get_normalized_symtab (abfd)
          else
            {
              /* ordinary short filename, put into memory anyway */
-             internal_ptr->u.syment._n._n_n._n_offset = (long)
-               copy_name (abfd, (internal_ptr + 1)->u.auxent.x_file.x_fname,
-                          FILNMLEN);
+             if (internal_ptr->u.syment.n_numaux > 1
+                 && coff_data (abfd)->pe)
+               {
+                 internal_ptr->u.syment._n._n_n._n_offset = (long)
+                   copy_name (abfd, (internal_ptr + 1)->u.auxent.x_file.x_fname,
+                              internal_ptr->u.syment.n_numaux * symesz);
+               }
+             else
+               {
+                 internal_ptr->u.syment._n._n_n._n_offset = (long)
+                   copy_name (abfd, (internal_ptr + 1)->u.auxent.x_file.x_fname,
+                              FILNMLEN);
+               }
            }
        }
       else
@@ -2157,9 +2173,11 @@ coff_find_nearest_line (abfd, section, symbols, offset, filename_ptr,
 
   if (p < pend)
     {
+      bfd_vma sec_vma;
       bfd_vma maxdiff;
 
       /* Look through the C_FILE symbols to find the best one.  */
+      sec_vma = bfd_get_section_vma (abfd, section);
       *filename_ptr = (char *) p->u.syment._n._n_n._n_offset;
       maxdiff = (bfd_vma) 0 - (bfd_vma) 1;
       while (1)
@@ -2183,11 +2201,11 @@ coff_find_nearest_line (abfd, section, symbols, offset, filename_ptr,
            }
 
          if (p2 < pend
-             && offset >= (bfd_vma) p2->u.syment.n_value
-             && offset - (bfd_vma) p2->u.syment.n_value < maxdiff)
+             && offset + sec_vma >= (bfd_vma) p2->u.syment.n_value
+             && offset + sec_vma - (bfd_vma) p2->u.syment.n_value < maxdiff)
            {
              *filename_ptr = (char *) p->u.syment._n._n_n._n_offset;
-             maxdiff = offset - p2->u.syment.n_value;
+             maxdiff = offset + sec_vma - p2->u.syment.n_value;
            }
 
          /* Avoid endless loops on erroneous files by ensuring that
@@ -2254,7 +2272,7 @@ coff_find_nearest_line (abfd, section, symbols, offset, filename_ptr,
            }
          else
            {
-             if (l->u.offset + bfd_get_section_vma (abfd, section) > offset)
+             if (l->u.offset > offset)
                break;
              *line_ptr = l->line_number + line_base - 1;
            }
@@ -2300,3 +2318,71 @@ coff_sizeof_headers (abfd, reloc)
   size += abfd->section_count * bfd_coff_scnhsz (abfd);
   return size;
 }
+
+/* Change the class of a coff symbol held by BFD.  */
+boolean
+bfd_coff_set_symbol_class (abfd, symbol, class)
+     bfd *         abfd;
+     asymbol *     symbol;
+     unsigned int  class;
+{
+  coff_symbol_type * csym;
+
+  csym = coff_symbol_from (abfd, symbol);
+  if (csym == NULL)
+    {
+      bfd_set_error (bfd_error_invalid_operation);
+      return false;
+    }
+  else if (csym->native == NULL)
+    {
+      /* This is an alien symbol which no native coff backend data.
+        We cheat here by creating a fake native entry for it and
+        then filling in the class.  This code is based on that in
+        coff_write_alien_symbol().  */
+      
+      combined_entry_type * native;
+
+      native = (combined_entry_type *) bfd_alloc (abfd, sizeof (* native));
+      if (native == NULL)
+       return false;
+
+      memset (native, 0, sizeof (* native));
+      
+      native->u.syment.n_type   = T_NULL;
+      native->u.syment.n_sclass = class;
+      
+      if (bfd_is_und_section (symbol->section))
+       {
+         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
+       {
+         native->u.syment.n_scnum =
+           symbol->section->output_section->target_index;
+         native->u.syment.n_value = (symbol->value
+                                     + symbol->section->output_offset);
+         if (! obj_pe (abfd))
+           native->u.syment.n_value += symbol->section->output_section->vma;
+         
+         /* Copy the any flags from the the file header into the symbol.
+            FIXME: Why?  */
+         native->u.syment.n_flags = bfd_asymbol_bfd (& csym->symbol)->flags;
+       }
+      
+      csym->native = native;
+    }
+  else
+    {
+      csym->native->u.syment.n_sclass = class;
+    }
+  
+  return true;
+}
+