Isolate STABS readers' use of the `textlow' and `texthigh' fields
[deliverable/binutils-gdb.git] / gdb / dbxread.c
index 0452e5b24006db5fb20e8726e1ca0c38b0cc23ef..75a1ba70f5e7518b460c43a27166792614e7bc7b 100644 (file)
@@ -46,7 +46,6 @@
 #include "gdb_stat.h"
 #include "symtab.h"
 #include "breakpoint.h"
-#include "command.h"
 #include "target.h"
 #include "gdbcore.h"           /* for bfd stuff */
 #include "libaout.h"           /* FIXME Secret internal BFD stuff for a.out */
@@ -58,6 +57,7 @@
 #include "demangle.h"
 #include "language.h"          /* Needed inside partial-stab.h */
 #include "complaints.h"
+#include "cp-abi.h"
 
 #include "aout/aout64.h"
 #include "aout/stab_gnu.h"     /* We always use GNU stabs, not native, now */
 
 struct symloc
   {
+    /* The start (inclusive) and end (exclusive) addresses for this
+       partial symtab's text.  STABS doesn't reliably give us nice
+       start and end addresses for each function.  Instead, we are
+       told the addresses of various boundary points, and we have to
+       gather those together to build ranges.  These are our running
+       best guess as to the range of text addresses for this psymtab.  */
+    CORE_ADDR textlow, texthigh;
 
     /* Offset within the file symbol table of first local symbol for this
        file.  */
@@ -105,6 +112,8 @@ struct symloc
 #define LDSYMOFF(p) (((struct symloc *)((p)->read_symtab_private))->ldsymoff)
 #define LDSYMLEN(p) (((struct symloc *)((p)->read_symtab_private))->ldsymlen)
 #define SYMLOC(p) ((struct symloc *)((p)->read_symtab_private))
+#define TEXTLOW(p) (SYMLOC(p)->textlow)
+#define TEXTHIGH(p) (SYMLOC(p)->texthigh)
 #define SYMBOL_SIZE(p) (SYMLOC(p)->symbol_size)
 #define SYMBOL_OFFSET(p) (SYMLOC(p)->symbol_offset)
 #define STRING_OFFSET(p) (SYMLOC(p)->string_offset)
@@ -270,10 +279,6 @@ extern void _initialize_dbxread (void);
 
 static void process_now (struct objfile *);
 
-static void free_header_files (void);
-
-static void init_header_files (void);
-
 static void read_ofile_symtab (struct partial_symtab *);
 
 static void dbx_psymtab_to_symtab (struct partial_symtab *);
@@ -319,7 +324,7 @@ static struct partial_symtab *start_psymtab (struct objfile *, char *,
 
 /* Free up old header file tables */
 
-static void
+void
 free_header_files (void)
 {
   if (this_object_header_files)
@@ -332,7 +337,7 @@ free_header_files (void)
 
 /* Allocate new header file tables */
 
-static void
+void
 init_header_files (void)
 {
   n_allocated_this_object_header_files = 10;
@@ -515,7 +520,7 @@ record_minimal_symbol (char *name, CORE_ADDR address, int type,
        char *tempstring = name;
        if (tempstring[0] == bfd_get_symbol_leading_char (objfile->obfd))
          ++tempstring;
-       if (VTBL_PREFIX_P ((tempstring)))
+       if (is_vtable_name (tempstring))
          ms_type = mst_data;
       }
       section = SECT_OFF_DATA (objfile);
@@ -582,8 +587,8 @@ dbx_symfile_read (struct objfile *objfile, int mainline)
 
   /* If we are reinitializing, or if we have never loaded syms yet, init */
   if (mainline
-      || objfile->global_psymbols.size == 0
-      || objfile->static_psymbols.size == 0)
+      || (objfile->global_psymbols.size == 0
+         &&  objfile->static_psymbols.size == 0))
     init_psymbol_list (objfile, DBX_SYMCOUNT (objfile));
 
   symbol_size = DBX_SYMBOL_SIZE (objfile);
@@ -603,6 +608,19 @@ dbx_symfile_read (struct objfile *objfile, int mainline)
 
   read_dbx_dynamic_symtab (objfile);
 
+  /* Take the text ranges the STABS partial symbol scanner computed
+     for each of the psymtabs and convert it into the canonical form
+     for psymtabs.  */
+  {
+    struct partial_symtab *p;
+
+    ALL_OBJFILE_PSYMTABS (objfile, p)
+      {
+        p->textlow = TEXTLOW (p);
+        p->texthigh = TEXTHIGH (p);
+      }
+  }
+
   /* Install any minimal symbols that have been collected as the current
      minimal symbols for this objfile. */
 
@@ -704,7 +722,7 @@ dbx_symfile_init (struct objfile *objfile)
        perror_with_name (name);
 
       memset ((PTR) size_temp, 0, sizeof (size_temp));
-      val = bfd_read ((PTR) size_temp, sizeof (size_temp), 1, sym_bfd);
+      val = bfd_bread ((PTR) size_temp, sizeof (size_temp), sym_bfd);
       if (val < 0)
        {
          perror_with_name (name);
@@ -743,8 +761,9 @@ dbx_symfile_init (struct objfile *objfile)
          val = bfd_seek (sym_bfd, STRING_TABLE_OFFSET, SEEK_SET);
          if (val < 0)
            perror_with_name (name);
-         val = bfd_read (DBX_STRINGTAB (objfile), DBX_STRINGTAB_SIZE (objfile), 1,
-                         sym_bfd);
+         val = bfd_bread (DBX_STRINGTAB (objfile),
+                          DBX_STRINGTAB_SIZE (objfile),
+                          sym_bfd);
          if (val != DBX_STRINGTAB_SIZE (objfile))
            perror_with_name (name);
        }
@@ -935,7 +954,7 @@ fill_symbuf (bfd *sym_bfd)
        count = sizeof (symbuf);
     }
 
-  nbytes = bfd_read ((PTR) symbuf, count, 1, sym_bfd);
+  nbytes = bfd_bread ((PTR) symbuf, count, sym_bfd);
   if (nbytes < 0)
     perror_with_name (bfd_get_filename (sym_bfd));
   else if (nbytes == 0)
@@ -946,22 +965,15 @@ fill_symbuf (bfd *sym_bfd)
   symbuf_read += nbytes;
 }
 
-#define SWAP_SYMBOL(symp, abfd) \
-  { \
-    (symp)->n_strx = bfd_h_get_32(abfd,                        \
-                               (unsigned char *)&(symp)->n_strx);      \
-    (symp)->n_desc = bfd_h_get_16 (abfd,                       \
-                               (unsigned char *)&(symp)->n_desc);      \
-    (symp)->n_value = bfd_h_get_32 (abfd,                      \
-                               (unsigned char *)&(symp)->n_value);     \
-  }
-
 #define INTERNALIZE_SYMBOL(intern, extern, abfd)                       \
   {                                                                    \
     (intern).n_type = bfd_h_get_8 (abfd, (extern)->e_type);            \
     (intern).n_strx = bfd_h_get_32 (abfd, (extern)->e_strx);           \
     (intern).n_desc = bfd_h_get_16 (abfd, (extern)->e_desc);           \
-    (intern).n_value = bfd_h_get_32 (abfd, (extern)->e_value);         \
+    if (bfd_get_sign_extend_vma (abfd))                                        \
+      (intern).n_value = bfd_h_get_signed_32 (abfd, (extern)->e_value);        \
+    else                                                               \
+      (intern).n_value = bfd_h_get_32 (abfd, (extern)->e_value);       \
   }
 
 /* Invariant: The symbol pointed to by symbuf_idx is the first one
@@ -1351,7 +1363,7 @@ read_dbx_symtab (struct objfile *objfile)
 
       end_psymtab (pst, psymtab_include_list, includes_used,
                   symnum * symbol_size,
-                  text_end > pst->texthigh ? text_end : pst->texthigh,
+                  text_end > TEXTHIGH (pst) ? text_end : TEXTHIGH (pst),
                   dependency_list, dependencies_used, textlow_not_set);
     }
 
@@ -1377,6 +1389,8 @@ start_psymtab (struct objfile *objfile, char *filename, CORE_ADDR textlow,
 
   result->read_symtab_private = (char *)
     obstack_alloc (&objfile->psymbol_obstack, sizeof (struct symloc));
+  TEXTLOW (result) = result->textlow;
+  TEXTHIGH (result) = result->texthigh;
   LDSYMOFF (result) = ldsymoff;
   result->read_symtab = dbx_psymtab_to_symtab;
   SYMBOL_SIZE (result) = symbol_size;
@@ -1412,7 +1426,7 @@ end_psymtab (struct partial_symtab *pst, char **include_list, int num_includes,
 
   if (capping_symbol_offset != -1)
     LDSYMLEN (pst) = capping_symbol_offset - LDSYMOFF (pst);
-  pst->texthigh = capping_text;
+  TEXTHIGH (pst) = capping_text;
 
 #ifdef SOFUN_ADDRESS_MAYBE_MISSING
   /* Under Solaris, the N_SO symbols always have a value of 0,
@@ -1430,7 +1444,7 @@ end_psymtab (struct partial_symtab *pst, char **include_list, int num_includes,
      a reliable texthigh by taking the address plus size of the
      last function in the file.  */
 
-  if (pst->texthigh == 0 && last_function_name)
+  if (TEXTHIGH (pst) == 0 && last_function_name)
     {
       char *p;
       int n;
@@ -1456,14 +1470,14 @@ end_psymtab (struct partial_symtab *pst, char **include_list, int num_includes,
        }
 
       if (minsym)
-       pst->texthigh = SYMBOL_VALUE_ADDRESS (minsym) + MSYMBOL_SIZE (minsym);
+       TEXTHIGH (pst) = SYMBOL_VALUE_ADDRESS (minsym) + MSYMBOL_SIZE (minsym);
 
       last_function_name = NULL;
     }
 
   /* this test will be true if the last .o file is only data */
   if (textlow_not_set)
-    pst->textlow = pst->texthigh;
+    TEXTLOW (pst) = TEXTHIGH (pst);
   else
     {
       struct partial_symtab *p1;
@@ -1476,12 +1490,12 @@ end_psymtab (struct partial_symtab *pst, char **include_list, int num_includes,
 
       ALL_OBJFILE_PSYMTABS (objfile, p1)
       {
-       if (p1->texthigh == 0 && p1->textlow != 0 && p1 != pst)
+       if (TEXTHIGH (p1) == 0 && TEXTLOW (p1) != 0 && p1 != pst)
          {
-           p1->texthigh = pst->textlow;
+           TEXTHIGH (p1) = TEXTLOW (pst);
            /* if this file has only data, then make textlow match texthigh */
-           if (p1->textlow == 0)
-             p1->textlow = p1->texthigh;
+           if (TEXTLOW (p1) == 0)
+             TEXTLOW (p1) = TEXTHIGH (p1);
          }
       }
     }
@@ -1518,8 +1532,8 @@ end_psymtab (struct partial_symtab *pst, char **include_list, int num_includes,
                                sizeof (struct symloc));
       LDSYMOFF (subpst) =
        LDSYMLEN (subpst) =
-       subpst->textlow =
-       subpst->texthigh = 0;
+       TEXTLOW (subpst) =
+       TEXTHIGH (subpst) = 0;
 
       /* We could save slight bits of space by only making one of these,
          shared by the entire set of include files.  FIXME-someday.  */
@@ -1687,8 +1701,8 @@ read_ofile_symtab (struct partial_symtab *pst)
   objfile = pst->objfile;
   sym_offset = LDSYMOFF (pst);
   sym_size = LDSYMLEN (pst);
-  text_offset = pst->textlow;
-  text_size = pst->texthigh - pst->textlow;
+  text_offset = TEXTLOW (pst);
+  text_size = TEXTHIGH (pst) - TEXTLOW (pst);
   /* This cannot be simply objfile->section_offsets because of
      elfstab_offset_sections() which initializes the psymtab section
      offsets information in a special way, and that is different from
@@ -1833,13 +1847,13 @@ read_ofile_symtab (struct partial_symtab *pst)
 
   /* In a Solaris elf file, this variable, which comes from the
      value of the N_SO symbol, will still be 0.  Luckily, text_offset,
-     which comes from pst->textlow is correct. */
+     which comes from TEXTLOW (pst) is correct. */
   if (last_source_start_addr == 0)
     last_source_start_addr = text_offset;
 
   /* In reordered executables last_source_start_addr may not be the
      lower bound for this symtab, instead use text_offset which comes
-     from pst->textlow which is correct.  */
+     from TEXTLOW (pst) which is correct.  */
   if (last_source_start_addr > text_offset)
     last_source_start_addr = text_offset;
 
@@ -2277,8 +2291,18 @@ process_one_symbol (int type, int desc, CORE_ADDR valu, char *name,
                 from N_FUN symbols.  */
              if (type == N_FUN
                  && valu == ANOFFSET (section_offsets, SECT_OFF_TEXT (objfile)))
-               valu = 
-                 find_stab_function_addr (name, last_source_file, objfile);
+               {
+                 CORE_ADDR minsym_valu = 
+                   find_stab_function_addr (name, last_source_file, objfile);
+
+                 /* find_stab_function_addr will return 0 if the minimal
+                    symbol wasn't found.  (Unfortunately, this might also
+                    be a valid address.)  Anyway, if it *does* return 0,
+                    it is likely that the value was set correctly to begin
+                    with... */
+                 if (minsym_valu != 0)
+                   valu = minsym_valu;
+               }
 #endif
 
 #ifdef SUN_FIXED_LBRAC_BUG
@@ -2390,13 +2414,25 @@ process_one_symbol (int type, int desc, CORE_ADDR valu, char *name,
        }
       break;
 
+    case N_MAIN:               /* Name of main routine.  */
+      /* FIXME: If one has a symbol file with N_MAIN and then replaces
+        it with a symbol file with "main" and without N_MAIN.  I'm
+        not sure exactly what rule to follow but probably something
+        like: N_MAIN takes precedence over "main" no matter what
+        objfile it is in; If there is more than one N_MAIN, choose
+        the one in the symfile_objfile; If there is more than one
+        N_MAIN within a given objfile, complain() and choose
+        arbitrarily. (kingdon) */
+      if (name != NULL)
+       set_main_name (name);
+      break;
+
       /* The following symbol types can be ignored.  */
     case N_OBJ:                /* Solaris 2:  Object file dir and name */
       /*   N_UNDF:                   Solaris 2:  file separator mark */
       /*   N_UNDF: -- we will never encounter it, since we only process one
          file's symbols at once.  */
     case N_ENDM:               /* Solaris 2:  End of module */
-    case N_MAIN:               /* Name of main routine.  */
     case N_ALIAS:              /* SunPro F77: alias name, ignore for now.  */
       break;
     }
@@ -2490,7 +2526,7 @@ coffstab_build_psymtabs (struct objfile *objfile, int mainline,
   val = bfd_seek (sym_bfd, stabstroffset, SEEK_SET);
   if (val < 0)
     perror_with_name (name);
-  val = bfd_read (DBX_STRINGTAB (objfile), stabstrsize, 1, sym_bfd);
+  val = bfd_bread (DBX_STRINGTAB (objfile), stabstrsize, sym_bfd);
   if (val != stabstrsize)
     perror_with_name (name);
 
@@ -2586,7 +2622,7 @@ elfstab_build_psymtabs (struct objfile *objfile, int mainline,
   val = bfd_seek (sym_bfd, stabstroffset, SEEK_SET);
   if (val < 0)
     perror_with_name (name);
-  val = bfd_read (DBX_STRINGTAB (objfile), stabstrsize, 1, sym_bfd);
+  val = bfd_bread (DBX_STRINGTAB (objfile), stabstrsize, sym_bfd);
   if (val != stabstrsize)
     perror_with_name (name);
 
This page took 0.029406 seconds and 4 git commands to generate.