* gdbint.texinfo: Bring the HTML `top' menu into sync with the
[binutils-gdb.git] / binutils / rdcoff.c
index 9f7660b278e95699a6d809810d93d9b4110f2fb1..058289567f801501eac9f09f78494566529f5538 100644 (file)
@@ -1,5 +1,5 @@
 /* stabs.c -- Parse COFF debugging information
-   Copyright (C) 1996 Free Software Foundation, Inc.
+   Copyright 1996, 2000 Free Software Foundation, Inc.
    Written by Ian Lance Taylor <ian@cygnus.com>.
 
    This file is part of GNU Binutils.
@@ -99,6 +99,7 @@ static debug_type parse_coff_enum_type
 static boolean parse_coff_symbol
   PARAMS ((bfd *, struct coff_types *, asymbol *, long,
           struct internal_syment *, PTR, debug_type, boolean));
+static boolean external_coff_symbol_p PARAMS ((int sym_class));
 \f
 /* Return the slot for a type.  */
 
@@ -199,6 +200,11 @@ parse_coff_type (abfd, symbols, types, coff_symno, ntype, pauxent, useaux,
                                                              NULL, dhandle),
                                        0, n - 1, false);
        }
+      else
+       {
+         non_fatal (_("parse_coff_type: Bad type code 0x%x"), ntype);
+         return DEBUG_TYPE_NULL;
+       }
 
       return type;
     }
@@ -414,8 +420,8 @@ parse_coff_struct_type (abfd, symbols, types, ntype, pauxent, dhandle)
 
       if (! bfd_coff_get_syment (abfd, sym, &syment))
        {
-         fprintf (stderr, "%s: bfd_coff_get_syment failed: %s\n",
-                  program_name, bfd_errmsg (bfd_get_error ()));
+         non_fatal (_("bfd_coff_get_syment failed: %s"),
+                    bfd_errmsg (bfd_get_error ()));
          return DEBUG_TYPE_NULL;
        }
 
@@ -430,8 +436,8 @@ parse_coff_struct_type (abfd, symbols, types, ntype, pauxent, dhandle)
        {
          if (! bfd_coff_get_auxent (abfd, sym, 0, &auxent))
            {
-             fprintf (stderr, "%s: bfd_coff_get_auxent failed: %s\n",
-                      program_name, bfd_errmsg (bfd_get_error ()));
+             non_fatal (_("bfd_coff_get_auxent failed: %s"),
+                        bfd_errmsg (bfd_get_error ()));
              return DEBUG_TYPE_NULL;
            }
          psubaux = &auxent;
@@ -492,7 +498,7 @@ static debug_type
 parse_coff_enum_type (abfd, symbols, types, pauxent, dhandle)
      bfd *abfd;
      struct coff_symbols *symbols;
-     struct coff_types *types;
+     struct coff_types *types ATTRIBUTE_UNUSED;
      union internal_auxent *pauxent;
      PTR dhandle;
 {
@@ -522,8 +528,8 @@ parse_coff_enum_type (abfd, symbols, types, pauxent, dhandle)
 
       if (! bfd_coff_get_syment (abfd, sym, &syment))
        {
-         fprintf (stderr, "%s: bfd_coff_get_syment failed: %s\n",
-                  program_name, bfd_errmsg (bfd_get_error ()));
+         non_fatal (_("bfd_coff_get_syment failed: %s"),
+                    bfd_errmsg (bfd_get_error ()));
          return DEBUG_TYPE_NULL;
        }
 
@@ -563,7 +569,7 @@ parse_coff_enum_type (abfd, symbols, types, pauxent, dhandle)
 static boolean
 parse_coff_symbol (abfd, types, sym, coff_symno, psyment, dhandle, type,
                   within_function)
-     bfd *abfd;
+     bfd *abfd ATTRIBUTE_UNUSED;
      struct coff_types *types;
      asymbol *sym;
      long coff_symno;
@@ -583,6 +589,7 @@ parse_coff_symbol (abfd, types, sym, coff_symno, psyment, dhandle, type,
        return false;
       break;
 
+    case C_WEAKEXT:
     case C_EXT:
       if (! debug_record_variable (dhandle, bfd_asymbol_name (sym), type,
                                   DEBUG_GLOBAL, bfd_asymbol_value (sym)))
@@ -651,6 +658,23 @@ parse_coff_symbol (abfd, types, sym, coff_symno, psyment, dhandle, type,
   return true;                            
 }
 
+/* Determine if a symbol has external visibility.  */
+
+static boolean
+external_coff_symbol_p (sym_class)
+     int sym_class;
+{
+  switch (sym_class)
+    {
+      case C_EXT:
+      case C_WEAKEXT:
+        return true;
+    default:
+      break;
+    }
+  return false;         
+}
+
 /* This is the main routine.  It looks through all the symbols and
    handles them.  */
 
@@ -668,6 +692,7 @@ parse_coff (abfd, syms, symcount, dhandle)
   const char *fnname;
   int fnclass;
   int fntype;
+  bfd_vma fnend;
   alent *linenos;
   boolean within_function;
   long this_coff_symno;
@@ -685,6 +710,7 @@ parse_coff (abfd, syms, symcount, dhandle)
   fnname = NULL;
   fnclass = 0;
   fntype = 0;
+  fnend = 0;
   linenos = NULL;
   within_function = false;
 
@@ -701,8 +727,8 @@ parse_coff (abfd, syms, symcount, dhandle)
 
       if (! bfd_coff_get_syment (abfd, sym, &syment))
        {
-         fprintf (stderr, "%s: bfd_coff_get_syment failed: %s\n",
-                  program_name, bfd_errmsg (bfd_get_error ()));
+         non_fatal (_("bfd_coff_get_syment failed: %s"),
+                    bfd_errmsg (bfd_get_error ()));
          return false;
        }
 
@@ -721,8 +747,8 @@ parse_coff (abfd, syms, symcount, dhandle)
        {
          if (! bfd_coff_get_auxent (abfd, sym, 0, &auxent))
            {
-             fprintf (stderr, "%s: bfd_coff_get_auxent failed: %s\n",
-                      program_name, bfd_errmsg (bfd_get_error ()));
+             non_fatal (_("bfd_coff_get_auxent failed: %s"),
+                        bfd_errmsg (bfd_get_error ()));
              return false;
            }
          paux = &auxent;
@@ -760,12 +786,17 @@ parse_coff (abfd, syms, symcount, dhandle)
          if (syment.n_type == T_NULL)
            break;
          /* Fall through.  */
+       case C_WEAKEXT:
        case C_EXT:
          if (ISFCN (syment.n_type))
            {
              fnname = name;
              fnclass = syment.n_sclass;
              fntype = syment.n_type;
+             if (syment.n_numaux > 0)
+               fnend = bfd_asymbol_value (sym) + auxent.x_sym.x_misc.x_fsize;
+             else
+               fnend = 0;
              linenos = BFD_SEND (abfd, _get_lineno, (abfd, sym));
              break;
            }
@@ -783,8 +814,8 @@ parse_coff (abfd, syms, symcount, dhandle)
            {
              if (fnname == NULL)
                {
-                 fprintf (stderr, "%s: %ld: .bf without preceding function\n",
-                          program_name, this_coff_symno);
+                 non_fatal (_("%ld: .bf without preceding function"),
+                            this_coff_symno);
                  return false;
                }
 
@@ -794,7 +825,7 @@ parse_coff (abfd, syms, symcount, dhandle)
                return false;
 
              if (! debug_record_function (dhandle, fnname, type,
-                                          fnclass == C_EXT,
+                                          external_coff_symbol_p (fnclass),
                                           bfd_asymbol_value (sym)))
                return false;
 
@@ -833,14 +864,16 @@ parse_coff (abfd, syms, symcount, dhandle)
            {
              if (! within_function)
                {
-                 fprintf (stderr, "%s: %ld: unexpected .ef\n",
-                          program_name, this_coff_symno);
+                 non_fatal (_("%ld: unexpected .ef\n"), this_coff_symno);
                  return false;
                }
 
-             if (! debug_end_function (dhandle, bfd_asymbol_value (sym)))
+             if (bfd_asymbol_value (sym) > fnend)
+               fnend = bfd_asymbol_value (sym);
+             if (! debug_end_function (dhandle, fnend))
                return false;
 
+             fnend = 0;
              within_function = false;
            }
          break;