This is the mail archive of the gdb-patches@sourceware.cygnus.com mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

(patch) hpjyg06: hp-psymtab-read.c etc.


***
This patch needs to be applied along with the next patch ('hpjyg07',
which is for top level include/hp-symtab.h).
***

This patch includes changes to psymtab handling for HP platform (mainly
demand paging of SLT and some Fortran support setups).

- Jimmy Guo, guo@cup.hp.com

ChangeLog:

1999-11-03	Jimmy Guo	<guo@cup.hp.com>

	* hp-psymtab-read.c (DUMPING,QUICK_LOOK_UP): Refine to be 0.
	(hpread_get_textlow): Change return type to CORE_ADDR from
	unsigned long.
	(trans_lang): change HP_LANGUAGE_F77 to HP_LANGUAGE_FORTRAN.
	Declare and initialize default_fortran_main_string to "_main_".
	(hpread_pxdb_needed,hpread_get_header): Use HP_HEADER instead of
	"$HEADER$".
	(scan_procs): 32x64 fix; Fortran demangled name "_MAIN_"
	support; search quick file table for multiple entries fora given
	function, and adjust current file entry and ending addr of function.
	(hpread_quick_traverse): 32x64 fix; use max_LNTT_sym_index if
	there're no globals.
	(string_from_vt): New function, for memory tuning.
	(hpread_symfile_init): Initialize permanent_copy_exists to
	string_from_vt, for memory tuning; initialize
	TYPE_VECTOR_LENGTH(objfile) to 0; use header macros instead of
	literal strings; don't read SLT, will be demand paged in.
	(hpread_build_psymtabs): Change valu, texthigh type to CORE_ADDR;
	(hpread_symtab_finish): Free TYPE_VECTOR(objfile); 
	(initialize_slt_page_table,slt_entry_from_page_table): New
	functions, for SLT demand paging.
	(hpread_get_slt): Demand page SLT.
	(hpread_start_psymtab): Adjust texthigh with offset.
	(hpread_end_psymtab): Don't discard empty psymtabs as all except
	globals are now empty under the new lookup scheme of searching
	minimal symbol table instead and expand the related psymtab if a
	linker symbol is found.

	* hpread.h: Add declarations for demand paging of SLT.
	(SLT_PAGE_COUNT,SLT_ENTRIES_PER_PAGE,SLT_PAGE_NUMBER,SLT_LINE_NUMBER,
	slt_page_frame): Declare.
	(hpread_symfile_info): Add globals_start,slt_page_table,slt_section,
	slt_size; change current_function_value type to CORE_ADDR from
	unsigned int.
	(HP_HEADER,HP_GNTT,HP_LNTT,HP_SLT,HP_VT): Declare.
	(GLOBALS_START,SLT_PAGE_TABLE,SLT_SECTION,SLT_SIZE,INDEX): Declare

	* defs.h (default_main): Declare.

	* symtab.c: Initialize default_main to "main".
	(find_main_psymtab): Replace "main" w/ default_main.

	* blockframe.c (inside_main_func),
	source.c (select_source_symtab): Replace "main" w/ default_main.

Index: gdb/hp-psymtab-read.c
/opt/gnu/bin/diff -r -c -N  /view/guo.wdb.c//CLO/Components/WDB/Src/gnu/gdb/hp-psymtab-read.c gdb/hp-psymtab-read.c
*** /view/guo.wdb.c//CLO/Components/WDB/Src/gnu/gdb/hp-psymtab-read.c	Tue Nov  2 16:31:30 1999
--- gdb/hp-psymtab-read.c	Wed Nov  3 17:55:20 1999
***************
*** 28,37 ****
  
  /* To generate dumping code, uncomment this define.  The dumping
     itself is controlled by routine-local statics called "dumping". */
! /* #define DUMPING         1 */
  
  /* To use the quick look-up tables, uncomment this define. */
! #define QUICK_LOOK_UP      1
  
  /* To call PXDB to process un-processed files, uncomment this define. */
  #define USE_PXDB           1
--- 28,37 ----
  
  /* To generate dumping code, uncomment this define.  The dumping
     itself is controlled by routine-local statics called "dumping". */
! #define DUMPING            0
  
  /* To use the quick look-up tables, uncomment this define. */
! #define QUICK_LOOK_UP      0
  
  /* To call PXDB to process un-processed files, uncomment this define. */
  #define USE_PXDB           1
***************
*** 53,59 ****
  static union dnttentry *hpread_get_gntt
    PARAMS ((int, struct objfile *));
  
! static unsigned long hpread_get_textlow
    PARAMS ((int, int, struct objfile *, int));
  
  static struct partial_symtab *hpread_start_psymtab
--- 53,59 ----
  static union dnttentry *hpread_get_gntt
    PARAMS ((int, struct objfile *));
  
! static CORE_ADDR hpread_get_textlow
    PARAMS ((int, int, struct objfile *, int));
  
  static struct partial_symtab *hpread_start_psymtab
***************
*** 99,112 ****
    else if (in_lang == HP_LANGUAGE_CPLUSPLUS)
      return language_cplus;
  
!   else if (in_lang == HP_LANGUAGE_F77)
      return language_fortran;
  
    else
      return language_unknown;
  }
  
! static char main_string[] = "main";
  
  /* Call PXDB to process our file.
  
--- 99,112 ----
    else if (in_lang == HP_LANGUAGE_CPLUSPLUS)
      return language_cplus;
  
!   else if (in_lang == HP_LANGUAGE_FORTRAN)
      return language_fortran;
  
    else
      return language_unknown;
  }
  
! char default_fortran_main_string[] = "_main_";
  
  /* Call PXDB to process our file.
  
***************
*** 156,169 ****
       bfd *sym_bfd;
  {
    asection *pinfo_section, *debug_section, *header_section;
!   unsigned int do_pxdb;
    char *buf;
    bfd_size_type header_section_size;
  
    unsigned long tmp;
    unsigned int pxdbed;
  
!   header_section = bfd_get_section_by_name (sym_bfd, "$HEADER$");
    if (!header_section)
      {
        return 0;			/* No header at all, can't recover... */
--- 156,169 ----
       bfd *sym_bfd;
  {
    asection *pinfo_section, *debug_section, *header_section;
!   unsigned int do_pxdb = false;
    char *buf;
    bfd_size_type header_section_size;
  
    unsigned long tmp;
    unsigned int pxdbed;
  
!   header_section = bfd_get_section_by_name (sym_bfd, HP_HEADER);
    if (!header_section)
      {
        return 0;			/* No header at all, can't recover... */
***************
*** 516,534 ****
     organized in a separate routine, although it does take lots of arguments. pai/1997-10-08 */
  
  static int
! scan_procs (curr_pd_p, qPD, max_procs, start_adr, end_adr, pst, vt_bits, objfile)
       int *curr_pd_p;		/* pointer to current proc index */
       quick_procedure_entry *qPD;	/* the procedure quick lookup table */
       int max_procs;		/* number of entries in proc. table */
       CORE_ADDR start_adr;	/* beginning of code range for current psymtab */
!      CORE_ADDR end_adr;		/* end of code range for current psymtab */
       struct partial_symtab *pst;	/* current psymtab */
       char *vt_bits;		/* strings table of SOM debug space */
       struct objfile *objfile;	/* current object file */
  {
    union dnttentry *dn_bufp;
    int symbol_count = 0;		/* Total number of symbols in this psymtab */
!   int curr_pd = *curr_pd_p;	/* Convenience variable -- avoid dereferencing pointer all the time */
  
  #ifdef DUMPING
    /* Turn this on for lots of debugging information in this routine */
--- 516,539 ----
     organized in a separate routine, although it does take lots of arguments. pai/1997-10-08 */
  
  static int
! scan_procs (curr_pd_p, qPD, max_procs, start_adr, end_adr_p, pst, vt_bits, objfile, curr_fd_p, qFD, max_files)
       int *curr_pd_p;		/* pointer to current proc index */
       quick_procedure_entry *qPD;	/* the procedure quick lookup table */
       int max_procs;		/* number of entries in proc. table */
       CORE_ADDR start_adr;	/* beginning of code range for current psymtab */
!      CORE_ADDR *end_adr_p;	/* pointer to end of code range for current psymtab */
       struct partial_symtab *pst;	/* current psymtab */
       char *vt_bits;		/* strings table of SOM debug space */
       struct objfile *objfile;	/* current object file */
+      int *curr_fd_p;		/* pointer to current file index */
+      quick_file_entry *qFD;	/* file quick lookup table */
+      int max_files;		/* number of entries in file table */
  {
    union dnttentry *dn_bufp;
    int symbol_count = 0;		/* Total number of symbols in this psymtab */
!   CORE_ADDR end_adr = *end_adr_p;	/* Convenience variables -- avoid dereferencing pointer all the time */
!   int curr_pd = *curr_pd_p;
!   int curr_fd = *curr_fd_p;
  
  #ifdef DUMPING
    /* Turn this on for lots of debugging information in this routine */
***************
*** 538,561 ****
  #ifdef DUMPING
    if (dumping)
      {
!       printf ("Scan_procs called, addresses %x to %x, proc %x\n", start_adr, end_adr, curr_pd);
      }
  #endif
  
    while ((CURR_PROC_START <= end_adr) && (curr_pd < max_procs))
      {
  
        char *rtn_name;		/* mangled name */
        char *rtn_dem_name;	/* qualified demangled name */
-       char *class_name;
-       int class;
  
!       if ((trans_lang ((enum hp_language) qPD[curr_pd].language) == language_cplus) &&
! 	  vt_bits[(long) qPD[curr_pd].sbAlias])		/* not a null string */
  	{
- 	  /* Get mangled name for the procedure, and demangle it */
  	  rtn_name = &vt_bits[(long) qPD[curr_pd].sbAlias];
! 	  rtn_dem_name = cplus_demangle (rtn_name, DMGL_ANSI | DMGL_PARAMS);
  	}
        else
  	{
--- 543,583 ----
  #ifdef DUMPING
    if (dumping)
      {
!       printf ("Scan_procs called, addresses ");
!       print_address_numeric (start_adr, 1, gdb_stdout);
!       printf (" to ");
!       print_address_numeric (end_adr, 1, gdb_stdout);
!       printf (", proc [%d]\n", curr_pd);
      }
  #endif
  
+   /* srikanth, we used to create partial symbols as we iterated over
+      the quick procedure lookup table created by pxdb. We don't do 
+      this anymore. Instead, we will rely on the linker symbol table to
+      locate the symbol, use its address to decide which psymtab would
+      house the partial symbol, were one to exist.
+ 
+      It would be nice if this whole loop could be eliminated. However,
+      there is some Fortran specific processing that goes on here that
+      could not be removed (sigh.) HP compilers provide _MAIN_ as an 
+      alternate name for the (high level) program entry point. So a user 
+      could say b _MAIN_ and expect a breakpoint inserted there. This is 
+      useful since Fortran programs don't have a unique entry point like
+      `main'. Unfortunately, this information is not present in the
+      linker symbol table and must be captured here.
+    */
+ 
    while ((CURR_PROC_START <= end_adr) && (curr_pd < max_procs))
      {
  
        char *rtn_name;		/* mangled name */
        char *rtn_dem_name;	/* qualified demangled name */
  
!       /* Get the alias name if there is one */
!       if (vt_bits[(long) qPD[curr_pd].sbAlias])		/* not a null string */
  	{
  	  rtn_name = &vt_bits[(long) qPD[curr_pd].sbAlias];
! 	  rtn_dem_name = &vt_bits[(long) qPD[curr_pd].sbProc];
  	}
        else
  	{
***************
*** 563,573 ****
  	  rtn_dem_name = NULL;
  	}
  
!       /* Hack to get around HP C/C++ compilers' insistence on providing
!          "_MAIN_" as an alternate name for "main" */
!       if ((strcmp (rtn_name, "_MAIN_") == 0) &&
! 	  (strcmp (&vt_bits[(long) qPD[curr_pd].sbProc], "main") == 0))
! 	rtn_dem_name = rtn_name = main_string;
  
  #ifdef DUMPING
        if (dumping)
--- 585,632 ----
  	  rtn_dem_name = NULL;
  	}
  
!       /* Hack to get around HP compilers' insistence on providing
!        * "_MAIN_" as an alternate name for "main".  
!        */
!       if (strcmp (rtn_name, "_MAIN_") == 0)
! 	{
! 	  /* Set mangled name to "main" and demangled_name to "",
! 	   * except for Fortran, where the mangled name is set to 
! 	   * "_MAIN_" and the demangled name is "" or the program name.
! 	   * We do this for Fortran because "main" is not a special name 
! 	   * and there could be a user subroutine called "main".  If 
! 	   * there is a program name, we want to save it as the user may 
! 	   * reference it to set breakpoints, etc.
! 	   */
! 	  enum language lang =
! 	  trans_lang ((enum hp_language) qPD[curr_pd].language);
! 	  if (lang == language_fortran)
! 	    {
! 	      if (strcmp (rtn_dem_name, default_main) == 0)
! 		rtn_dem_name = NULL;
! 	      default_main = rtn_name = default_fortran_main_string;
! 
! 	    }
! 	  else
! 	    {
! 	      rtn_name = default_main;
! 	      rtn_dem_name = NULL;
! 	    }
! 	  add_psymbol_with_dem_name_to_list (
! 					      rtn_name,
! 					      strlen (rtn_name),
! 					      rtn_dem_name,
! 					      strlen (rtn_dem_name),
! 					      VAR_NAMESPACE,
! 					      LOC_BLOCK,
! 					      &objfile->global_psymbols,
! 					      (qPD[curr_pd].adrStart +	/* Starting address of rtn */
! 					 ANOFFSET (objfile->section_offsets,
! 						   SECT_OFF_TEXT)),
! 					      0,	/* core addr?? */
! 					      lang,
! 					      objfile);
! 	}
  
  #ifdef DUMPING
        if (dumping)
***************
*** 579,624 ****
        /* Check for module-spanning routines. */
        if (CURR_PROC_END > end_adr)
  	{
! 	  TELL_OBJFILE;
! 	  warning ("Procedure \"%s\" [0x%x] spans file or module boundaries.", rtn_name, curr_pd);
  	}
  
-       /* Add this routine symbol to the list in the objfile. 
-          Unfortunately we have to go to the LNTT to determine the
-          correct list to put it on. An alternative (which the
-          code used to do) would be to not check and always throw
-          it on the "static" list. But if we go that route, then
-          symbol_lookup() needs to be tweaked a bit to account
-          for the fact that the function might not be found on
-          the correct list in the psymtab. - RT */
-       dn_bufp = hpread_get_lntt (qPD[curr_pd].isym, objfile);
-       if (dn_bufp->dfunc.global)
- 	add_psymbol_with_dem_name_to_list (rtn_name,
- 					   strlen (rtn_name),
- 					   rtn_dem_name,
- 					   strlen (rtn_dem_name),
- 					   VAR_NAMESPACE,
- 					   LOC_BLOCK,	/* "I am a routine"        */
- 					   &objfile->global_psymbols,
- 					   (qPD[curr_pd].adrStart +	/* Starting address of rtn */
- 				 ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT)),
- 					   0,	/* core addr?? */
- 		      trans_lang ((enum hp_language) qPD[curr_pd].language),
- 					   objfile);
-       else
- 	add_psymbol_with_dem_name_to_list (rtn_name,
- 					   strlen (rtn_name),
- 					   rtn_dem_name,
- 					   strlen (rtn_dem_name),
- 					   VAR_NAMESPACE,
- 					   LOC_BLOCK,	/* "I am a routine"        */
- 					   &objfile->static_psymbols,
- 					   (qPD[curr_pd].adrStart +	/* Starting address of rtn */
- 				 ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT)),
- 					   0,	/* core addr?? */
- 		      trans_lang ((enum hp_language) qPD[curr_pd].language),
- 					   objfile);
- 
        symbol_count++;
        *curr_pd_p = ++curr_pd;	/* bump up count & reflect in caller */
      }				/* loop over procedures */
--- 638,667 ----
        /* Check for module-spanning routines. */
        if (CURR_PROC_END > end_adr)
  	{
! #ifdef DUMPING
! 	  if (dumping)
! 	    {
! 	      printf ("Procedure \"%s\" [%d] spans file or module boundaries.", rtn_name, curr_pd);
! 	      printf ("CURR_PROC_END = 0x%x, end_adr = 0x%x\n", CURR_PROC_END, end_adr);
! 	    }
! #endif
! 	  /* Search through the quick file table for multiple entries for 
! 	   * a given function and adjust the current file entry and the 
! 	   * the ending address of the function.  ipd is the procedure index 
! 	   * of the current file entry in the caller.
! 	   */
! 	  curr_fd = *curr_fd_p;
! 	  while (curr_fd <= max_files
! 		 && qFD[curr_fd].ipd == curr_pd
! 		 && FILE_END (curr_fd) < CURR_PROC_END)
! 	    ++curr_fd;
! 	  if (curr_fd > *curr_fd_p)
! 	    {
! 	      *curr_fd_p = curr_fd;
! 	      *end_adr_p = CURR_PROC_END;
! 	    }
  	}
  
        symbol_count++;
        *curr_pd_p = ++curr_pd;	/* bump up count & reflect in caller */
      }				/* loop over procedures */
***************
*** 671,677 ****
    int curr_md;			/* current module    */
    int start_sym;		/* current psymtab's starting symbol index */
    int end_sym;			/* current psymtab's ending symbol index   */
!   int max_LNTT_sym_index;
    int syms_in_pst;
    B_TYPE *class_entered;
  
--- 714,722 ----
    int curr_md;			/* current module    */
    int start_sym;		/* current psymtab's starting symbol index */
    int end_sym;			/* current psymtab's ending symbol index   */
!   int max_LNTT_sym_index;	/* max index of $LNTT$ subspace;
! 				   it's the index of the combined LNTT
! 				   and GNTT symbols after pxdb has run */
    int syms_in_pst;
    B_TYPE *class_entered;
  
***************
*** 715,723 ****
        for (i = 0; VALID_PROC (i); i++)
  	{
  	  idx = (long) qPD[i].sbProc;
! 	  printf ("%s %x..%x\n", &vt_bits[idx],
! 		  (int) PROC_START (i),
! 		  (int) PROC_END (i));
  	}
      }
  #endif
--- 760,770 ----
        for (i = 0; VALID_PROC (i); i++)
  	{
  	  idx = (long) qPD[i].sbProc;
! 	  printf ("%s ", &vt_bits[idx]);
! 	  print_address_numeric (PROC_START (i), 1, gdb_stdout);
! 	  printf ("..");
! 	  print_address_numeric (PROC_END (i), 1, gdb_stdout);
! 	  printf ("\n");
  	}
      }
  #endif
***************
*** 732,740 ****
        for (i = 0; VALID_FILE (i); i++)
  	{
  	  idx = (long) qFD[i].sbFile;
! 	  printf ("%s %x..%x\n", &vt_bits[idx],
! 		  (int) FILE_START (i),
! 		  (int) FILE_END (i));
  	}
      }
  #endif
--- 779,789 ----
        for (i = 0; VALID_FILE (i); i++)
  	{
  	  idx = (long) qFD[i].sbFile;
! 	  printf ("%s ", &vt_bits[idx]);
! 	  print_address_numeric (FILE_START (i), 1, gdb_stdout);
! 	  printf ("..");
! 	  print_address_numeric (FILE_END (i), 1, gdb_stdout);
! 	  printf ("\n");
  	}
      }
  #endif
***************
*** 837,843 ****
    while (VALID_CURR_FILE || VALID_CURR_MODULE)
      {
  
!       char *mod_name_string;
        char *full_name_string;
  
        /* First check for modules like "version.c", which have no code
--- 886,892 ----
    while (VALID_CURR_FILE || VALID_CURR_MODULE)
      {
  
!       char *mod_name_string = NULL;
        char *full_name_string;
  
        /* First check for modules like "version.c", which have no code
***************
*** 888,895 ****
  		(CURR_MODULE_END == 0) || (CURR_MODULE_END == -1)))
  	{
  	  TELL_OBJFILE;
! 	  warning ("Module \"%s\" [0x%x] has non-standard addresses.  It starts at 0x%x, ends at 0x%x, and will be skipped.",
! 		   mod_name_string, curr_md, start_adr, end_adr);
  	  /* On to next module */
  	  curr_md++;
  	}
--- 937,949 ----
  		(CURR_MODULE_END == 0) || (CURR_MODULE_END == -1)))
  	{
  	  TELL_OBJFILE;
! 	  warning_begin ();
! 	  fprintf_filtered ("Module \"%s\" [0x%x] has non-standard addresses.  It starts at ",
! 			    mod_name_string, curr_md);
! 	  print_address_numeric (start_adr, 1, gdb_stderr);
! 	  fprintf_filtered (gdb_stderr, ", ends at ");
! 	  print_address_numeric (end_adr, 1, gdb_stderr);
! 	  fprintf_filtered (gdb_stderr, ", and will be skipped.\n");
  	  /* On to next module */
  	  curr_md++;
  	}
***************
*** 914,920 ****
  	         are in between file or module ranges for some reason (probably
  	         indicates a compiler bug */
  
! 	      if (CURR_PROC_START < start_adr)
  		{
  		  TELL_OBJFILE;
  		  warning ("Found procedure \"%s\" [0x%x] that is not in any file or module.",
--- 968,974 ----
  	         are in between file or module ranges for some reason (probably
  	         indicates a compiler bug */
  
! 	      if (VALID_CURR_PROC && (CURR_PROC_START < start_adr))
  		{
  		  TELL_OBJFILE;
  		  warning ("Found procedure \"%s\" [0x%x] that is not in any file or module.",
***************
*** 931,937 ****
  	      if (VALID_FILE (curr_fd + 1) && (FILE_START (curr_fd + 1) <= end_adr))
  		{
  		  TELL_OBJFILE;
! 		  warning ("File \"%s\" [0x%x] has ending address after starting address of next file; adjusting ending address down.",
  			   full_name_string, curr_fd);
  		  end_adr = FILE_START (curr_fd + 1) - 1;	/* Is -4 (or -8 for 64-bit) better? */
  		}
--- 985,991 ----
  	      if (VALID_FILE (curr_fd + 1) && (FILE_START (curr_fd + 1) <= end_adr))
  		{
  		  TELL_OBJFILE;
! 		  warning ("File \"%s\" [%d] has ending address after starting address of next file; adjusting ending address down.",
  			   full_name_string, curr_fd);
  		  end_adr = FILE_START (curr_fd + 1) - 1;	/* Is -4 (or -8 for 64-bit) better? */
  		}
***************
*** 947,954 ****
  #ifdef DUMPING
  	      if (dumping)
  		{
! 		  printf ("Make new psymtab for file %s (%x to %x).\n",
! 			  full_name_string, start_adr, end_adr);
  		}
  #endif
  	      /* Create the basic psymtab, connecting it in the list
--- 1001,1012 ----
  #ifdef DUMPING
  	      if (dumping)
  		{
! 		  printf ("Make new psymtab for file %s [%d] (",
! 			  full_name_string, curr_fd);
! 		  print_address_numeric (start_adr, 1, gdb_stdout);
! 		  printf (" to ");
! 		  print_address_numeric (end_adr, 1, gdb_stdout);
! 		  printf (").\n");
  		}
  #endif
  	      /* Create the basic psymtab, connecting it in the list
***************
*** 976,982 ****
  	         file, based on the starting addresses. */
  
  	      syms_in_pst = scan_procs (&curr_pd, qPD, pxdb_header_p->pd_entries,
! 					start_adr, end_adr, pst, vt_bits, objfile);
  
  	      /* Get ending symbol offset */
  
--- 1034,1042 ----
  	         file, based on the starting addresses. */
  
  	      syms_in_pst = scan_procs (&curr_pd, qPD, pxdb_header_p->pd_entries,
! 					start_adr, &end_adr, pst, vt_bits,
! 					objfile, &curr_fd, qFD,
! 					pxdb_header_p->fd_entries);
  
  	      /* Get ending symbol offset */
  
***************
*** 1013,1024 ****
  
  	      /* Couldn't find procedure, file, or module, use globals as default */
  	      if (!end_sym)
! 		end_sym = pxdb_header_p->globals;
  
  #ifdef DUMPING
  	      if (dumping)
  		{
! 		  printf ("File psymtab indices: %x to %x\n", start_sym, end_sym);
  		}
  #endif
  
--- 1073,1087 ----
  
  	      /* Couldn't find procedure, file, or module, use globals as default */
  	      if (!end_sym)
! 		/* if there are no globals, use max_LNTT_sym_index */
! 		end_sym = max_LNTT_sym_index - 1 == pxdb_header_p->globals ?
! 		  max_LNTT_sym_index : pxdb_header_p->globals;
  
  #ifdef DUMPING
  	      if (dumping)
  		{
! 		  printf ("File psymtab indices: 0x%x to 0x%x\n",
! 			  start_sym, end_sym);
  		}
  #endif
  
***************
*** 1036,1048 ****
  	      record_pst_syms (start_sym, end_sym);
  
  	      if (NULL == pst)
! 		warning ("No symbols in psymtab for file \"%s\" [0x%x].", full_name_string, curr_fd);
  
  #ifdef DUMPING
  	      if (dumping)
  		{
! 		  printf ("Made new psymtab for file %s (%x to %x), sym %x to %x.\n",
! 			  full_name_string, start_adr, end_adr, CURR_FILE_ISYM, end_sym);
  		}
  #endif
  	      /* Prepare for the next psymtab. */
--- 1099,1114 ----
  	      record_pst_syms (start_sym, end_sym);
  
  	      if (NULL == pst)
! 		warning ("No symbols in psymtab for file \"%s\" [%d].", full_name_string, curr_fd);
  
  #ifdef DUMPING
  	      if (dumping)
  		{
! 		  printf ("Made new psymtab for file %s [%d] (", full_name_string, curr_fd);
! 		  print_address_numeric (start_adr, 1, gdb_stdout);
! 		  printf (" to ");
! 		  print_address_numeric (end_adr, 1, gdb_stdout);
! 		  printf ("), sym 0x%x to 0x%x.\n", CURR_FILE_ISYM, end_sym);
  		}
  #endif
  	      /* Prepare for the next psymtab. */
***************
*** 1100,1106 ****
  			printf ("Maybe skipping file %s which overlaps with module %s\n",
  				&vt_bits[(long) qFD[curr_fd].sbFile], mod_name_string);
  #endif
! 		      if (CURR_FILE_END > end_adr)
  			{
  			  TELL_OBJFILE;
  			  warning ("File \"%s\" [0x%x] crosses end of module \"%s\".",
--- 1166,1177 ----
  			printf ("Maybe skipping file %s which overlaps with module %s\n",
  				&vt_bits[(long) qFD[curr_fd].sbFile], mod_name_string);
  #endif
! 		      /* The following warning is not valid for f90 programs
! 		         where each function is enclosed in a module;
! 		         consequently there may be several modules within
! 		         a file */
! 		      if ((CURR_FILE_END > end_adr) &&
! 			  (qMD[curr_md].language != HP_LANGUAGE_FORTRAN))
  			{
  			  TELL_OBJFILE;
  			  warning ("File \"%s\" [0x%x] crosses end of module \"%s\".",
***************
*** 1162,1171 ****
  	         are in between file or module ranges for some reason (probably
  	         indicates a compiler bug */
  
! 	      if (CURR_PROC_START < start_adr)
  		{
  		  TELL_OBJFILE;
! 		  warning ("Found procedure \"%s\" [0x%x] that is not in any file or module.",
  			   &vt_bits[(long) qPD[curr_pd].sbProc], curr_pd);
  		  start_adr = CURR_PROC_START;
  		  if (CURR_PROC_ISYM < start_sym)
--- 1233,1242 ----
  	         are in between file or module ranges for some reason (probably
  	         indicates a compiler bug */
  
! 	      if (VALID_CURR_PROC && (CURR_PROC_START < start_adr))
  		{
  		  TELL_OBJFILE;
! 		  warning ("Found procedure \"%s\" [%d] that is not in any file or module.",
  			   &vt_bits[(long) qPD[curr_pd].sbProc], curr_pd);
  		  start_adr = CURR_PROC_START;
  		  if (CURR_PROC_ISYM < start_sym)
***************
*** 1175,1182 ****
  #ifdef DUMPING
  	      if (dumping)
  		{
! 		  printf ("Make new psymtab for module %s (%x to %x), using file %s\n",
! 		     mod_name_string, start_adr, end_adr, full_name_string);
  		}
  #endif
  	      /* Create the basic psymtab, connecting it in the list
--- 1246,1256 ----
  #ifdef DUMPING
  	      if (dumping)
  		{
! 		  printf ("Make new psymtab for module %s (", mod_name_string);
! 		  print_address_numeric (start_adr, 1, gdb_stdout);
! 		  printf (" to ");
! 		  print_address_numeric (end_adr, 1, gdb_stdout);
! 		  printf ("), using file %s\n", full_name_string);
  		}
  #endif
  	      /* Create the basic psymtab, connecting it in the list
***************
*** 1203,1219 ****
  	      /* Scan the procedure descriptors for procedures in the current
  	         module, based on the starting addresses. */
  
! 	      syms_in_pst = scan_procs (&curr_pd, qPD, pxdb_header_p->pd_entries,
! 					start_adr, end_adr, pst, vt_bits, objfile);
  
  	      /* Get ending symbol offset */
  
  	      end_sym = 0;
  	      /* First check for starting index before previous psymtab */
  	      if (pst_syms_count && start_sym < pst_syms_array[pst_syms_count - 1].end)
  		{
  		  end_sym = find_next_pst_start (start_sym);
  		}
  	      /* Look for next start index of a file or module, or procedure */
  	      if (!end_sym)
  		{
--- 1277,1303 ----
  	      /* Scan the procedure descriptors for procedures in the current
  	         module, based on the starting addresses. */
  
! 	      syms_in_pst = scan_procs (&curr_pd, qPD,
! 					pxdb_header_p->pd_entries,
! 					start_adr, &end_adr, pst, vt_bits,
! 					objfile, &curr_fd, qFD,
! 					pxdb_header_p->fd_entries);
  
  	      /* Get ending symbol offset */
  
  	      end_sym = 0;
  	      /* First check for starting index before previous psymtab */
+ 	      /* RM: aCC/pxdb seems to incorrectly emit debug info that
+ 	         includes LNTT entries from files outside the current modules
+ 	         address ranges within the current modules LNTT entries.
+ 	         Disabling the check below works around this, but causes
+ 	         certain CTTI functionality to break. Take your pick. */
+ #if 1
  	      if (pst_syms_count && start_sym < pst_syms_array[pst_syms_count - 1].end)
  		{
  		  end_sym = find_next_pst_start (start_sym);
  		}
+ #endif
  	      /* Look for next start index of a file or module, or procedure */
  	      if (!end_sym)
  		{
***************
*** 1246,1252 ****
  #ifdef DUMPING
  	      if (dumping)
  		{
! 		  printf ("Module psymtab indices: %x to %x\n", start_sym, end_sym);
  		}
  #endif
  
--- 1330,1337 ----
  #ifdef DUMPING
  	      if (dumping)
  		{
! 		  printf ("Module psymtab indices: 0x%x to 0x%x\n",
! 			  start_sym, end_sym);
  		}
  #endif
  
***************
*** 1264,1276 ****
  	      record_pst_syms (start_sym, end_sym);
  
  	      if (NULL == pst)
! 		warning ("No symbols in psymtab for module \"%s\" [0x%x].", mod_name_string, curr_md);
  
  #ifdef DUMPING
  	      if (dumping)
  		{
! 		  printf ("Made new psymtab for module %s (%x to %x), sym %x to %x.\n",
! 			  mod_name_string, start_adr, end_adr, CURR_MODULE_ISYM, end_sym);
  		}
  #endif
  
--- 1349,1364 ----
  	      record_pst_syms (start_sym, end_sym);
  
  	      if (NULL == pst)
! 		warning ("No symbols in psymtab for module \"%s\" [%d].", mod_name_string, curr_md);
  
  #ifdef DUMPING
  	      if (dumping)
  		{
! 		  printf ("Made new psymtab for module %s (", mod_name_string);
! 		  print_address_numeric (start_adr, 1, gdb_stdout);
! 		  printf (" to ");
! 		  print_address_numeric (end_adr, 1, gdb_stdout);
! 		  printf ("), sym %x to %x.\n", CURR_MODULE_ISYM, end_sym);
  		}
  #endif
  
***************
*** 1292,1303 ****
        start_adr = CURR_PROC_START;
        end_adr = qPD[pxdb_header_p->pd_entries - 1].adrEnd;
        TELL_OBJFILE;
!       warning ("Found functions beyond end of all files and modules [0x%x].", curr_pd);
  #ifdef DUMPING
        if (dumping)
  	{
! 	  printf ("Orphan functions at end, PD %d and beyond (%x to %x)\n",
! 		  curr_pd, start_adr, end_adr);
  	}
  #endif
        pst = hpread_start_psymtab (objfile,
--- 1380,1394 ----
        start_adr = CURR_PROC_START;
        end_adr = qPD[pxdb_header_p->pd_entries - 1].adrEnd;
        TELL_OBJFILE;
!       warning ("Found functions beyond end of all files and modules [%d].", curr_pd);
  #ifdef DUMPING
        if (dumping)
  	{
! 	  printf ("Orphan functions at end, PD %d and beyond (", curr_pd);
! 	  print_address_numeric (start_adr, 1, gdb_stdout);
! 	  printf (" to ");
! 	  print_address_numeric (end_adr, 1, gdb_stdout);
! 	  printf (")\n");
  	}
  #endif
        pst = hpread_start_psymtab (objfile,
***************
*** 1309,1315 ****
  				  static_syms);
  
        scan_procs (&curr_pd, qPD, pxdb_header_p->pd_entries,
! 		  start_adr, end_adr, pst, vt_bits, objfile);
  
        pst = hpread_end_psymtab (pst,
  				NULL,	/* psymtab_include_list */
--- 1400,1407 ----
  				  static_syms);
  
        scan_procs (&curr_pd, qPD, pxdb_header_p->pd_entries,
! 		  start_adr, &end_adr, pst, vt_bits, objfile,
! 		  &curr_fd, qFD, pxdb_header_p->fd_entries);
  
        pst = hpread_end_psymtab (pst,
  				NULL,	/* psymtab_include_list */
***************
*** 1365,1371 ****
    static int dumping = 0;
  #endif
  
!   header_section = bfd_get_section_by_name (objfile->obfd, "$HEADER$");
    if (!header_section)
      {
        /* We don't have either PINFO or DEBUG sections.  But
--- 1457,1463 ----
    static int dumping = 0;
  #endif
  
!   header_section = bfd_get_section_by_name (objfile->obfd, HP_HEADER);
    if (!header_section)
      {
        /* We don't have either PINFO or DEBUG sections.  But
***************
*** 1460,1465 ****
--- 1552,1574 ----
  #endif /* QUICK_LOOK_UP */
  
  
+ /* Given a string say whether it points to VT */
+ static boolean
+ string_from_vt (objfile, string)
+      struct objfile *objfile;
+      char *string;
+ {
+   /* don't touch with a barge pole if it ain't kosher */
+   if (!string || !objfile)
+     return 0;
+ 
+   if ((string >= VT (objfile)) &&
+       (string <= (VT (objfile) + VT_SIZE (objfile))))
+     return 1;
+ 
+   return 0;
+ }
+ 
  /* Initialization for reading native HP C debug symbols from OBJFILE.
  
     Its only purpose in life is to set up the symbol reader's private
***************
*** 1479,1484 ****
--- 1588,1599 ----
  {
    asection *vt_section, *slt_section, *lntt_section, *gntt_section;
  
+   extern boolean (*permanent_copy_exists)
+     PARAMS ((struct objfile * objfile,
+ 	     char *string));
+ 
+   permanent_copy_exists = string_from_vt;
+ 
    /* Allocate struct to keep track of the symfile */
    objfile->sym_private = (PTR)
      xmmalloc (objfile->md, sizeof (struct hpread_symfile_info));
***************
*** 1486,1494 ****
  
    /* We haven't read in any types yet.  */
    TYPE_VECTOR (objfile) = 0;
  
    /* Read in data from the $GNTT$ subspace.  */
!   gntt_section = bfd_get_section_by_name (objfile->obfd, "$GNTT$");
    if (!gntt_section)
      return;
  
--- 1601,1611 ----
  
    /* We haven't read in any types yet.  */
    TYPE_VECTOR (objfile) = 0;
+   TYPE_VECTOR_LENGTH (objfile) = 0;
  
+   /* RM: We'll read in the DOOM specific stuff later */
    /* Read in data from the $GNTT$ subspace.  */
!   gntt_section = bfd_get_section_by_name (objfile->obfd, HP_GNTT);
    if (!gntt_section)
      return;
  
***************
*** 1510,1516 ****
       code, and save startup time.  At the moment this data is
       still used, though.  We'd need a way to tell hp-symtab-read.c
       whether or not to load the LNTT. */
!   lntt_section = bfd_get_section_by_name (objfile->obfd, "$LNTT$");
    if (!lntt_section)
      return;
  
--- 1627,1633 ----
       code, and save startup time.  At the moment this data is
       still used, though.  We'd need a way to tell hp-symtab-read.c
       whether or not to load the LNTT. */
!   lntt_section = bfd_get_section_by_name (objfile->obfd, HP_LNTT);
    if (!lntt_section)
      return;
  
***************
*** 1524,1546 ****
    LNTT_SYMCOUNT (objfile)
      = bfd_section_size (objfile->obfd, lntt_section)
      / sizeof (struct dntt_type_block);
  
!   /* Read in data from the $SLT$ subspace.  $SLT$ contains information
!      on source line numbers.  */
!   slt_section = bfd_get_section_by_name (objfile->obfd, "$SLT$");
!   if (!slt_section)
!     return;
! 
!   SLT (objfile) =
!     obstack_alloc (&objfile->symbol_obstack,
! 		   bfd_section_size (objfile->obfd, slt_section));
! 
!   bfd_get_section_contents (objfile->obfd, slt_section, SLT (objfile),
! 			  0, bfd_section_size (objfile->obfd, slt_section));
  
    /* Read in data from the $VT$ subspace.  $VT$ contains things like
       names and constants.  Keep track of the number of symbols in the VT.  */
!   vt_section = bfd_get_section_by_name (objfile->obfd, "$VT$");
    if (!vt_section)
      return;
  
--- 1641,1656 ----
    LNTT_SYMCOUNT (objfile)
      = bfd_section_size (objfile->obfd, lntt_section)
      / sizeof (struct dntt_type_block);
+   GLOBALS_START (objfile) = 0;
  
!   /* srikanth, 990421, don't read in the slt right now. It is quite likely the 
!      user may never set a breakpoint in this load module. If the slt is needed
!      we will page it in on demand. */
!   SLT (objfile) = 0;
  
    /* Read in data from the $VT$ subspace.  $VT$ contains things like
       names and constants.  Keep track of the number of symbols in the VT.  */
!   vt_section = bfd_get_section_by_name (objfile->obfd, HP_VT);
    if (!vt_section)
      return;
  
***************
*** 1576,1582 ****
       struct objfile *objfile;
       int mainline;
  {
- 
  #ifdef DUMPING
    /* Turn this on to get debugging output. */
    static int dumping = 0;
--- 1686,1691 ----
***************
*** 1590,1598 ****
    int scan_start = 0;
  
    union dnttentry *dn_bufp;
!   unsigned long valu;
    char *p;
!   int texthigh = 0;
    int have_name = 0;
  
    /* Current partial symtab */
--- 1699,1707 ----
    int scan_start = 0;
  
    union dnttentry *dn_bufp;
!   CORE_ADDR valu;
    char *p;
!   CORE_ADDR texthigh = 0;
    int have_name = 0;
  
    /* Current partial symtab */
***************
*** 1628,1634 ****
--- 1737,1747 ----
      (struct partial_symtab **) alloca (dependencies_allocated *
  				       sizeof (struct partial_symtab *));
  
+   /* RM: actually this has already been inserted into the cleanup
+      chain in syms_from_objfile */
+ #if 0
    old_chain = make_cleanup ((make_cleanup_func) free_objfile, objfile);
+ #endif
  
    last_source_file = 0;
  
***************
*** 1671,1677 ****
--- 1784,1792 ----
  							  VT (objfile),
  							  &pxdb_header);
  
+ #if 0
  	discard_cleanups (old_chain);
+ #endif
  
  	/* Set up to scan the global section of the LNTT.
  
***************
*** 1685,1699 ****
  	   done below. */
  	if (found_modules_in_program)
  	  scan_start = pxdb_header.globals;
        }
  #ifdef DUMPING
      else
        {
  	if (dumping)
! 	  printf ("\nGoing on to old method for %s\n", objfile->name);
        }
  #endif
!   }
  #endif /* QUICK_LOOK_UP */
  
    /* Make two passes, one over the GNTT symbols, the other for the
--- 1800,1817 ----
  	   done below. */
  	if (found_modules_in_program)
  	  scan_start = pxdb_header.globals;
+ 	else
+ 	  scan_start = 0;
        }
  #ifdef DUMPING
      else
        {
  	if (dumping)
! 	  printf ("\nGoing on to old method for %s\n",
! 		  objfile->name);
        }
  #endif
!   }				/* End of new method code */
  #endif /* QUICK_LOOK_UP */
  
    /* Make two passes, one over the GNTT symbols, the other for the
***************
*** 1868,1875 ****
  	    case DNTT_TYPE_ENTRY:
  	      /* The beginning of a function.  DNTT_TYPE_ENTRY may also denote
  	         a secondary entry point.  */
! 	      valu = dn_bufp->dfunc.hiaddr + ANOFFSET (objfile->section_offsets,
! 						       SECT_OFF_TEXT);
  	      if (valu > texthigh)
  		texthigh = valu;
  	      valu = dn_bufp->dfunc.lowaddr +
--- 1986,1993 ----
  	    case DNTT_TYPE_ENTRY:
  	      /* The beginning of a function.  DNTT_TYPE_ENTRY may also denote
  	         a secondary entry point.  */
! 	      valu = dn_bufp->dfunc.hiaddr +
! 		ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT);
  	      if (valu > texthigh)
  		texthigh = valu;
  	      valu = dn_bufp->dfunc.lowaddr +
***************
*** 1889,1896 ****
  	      continue;
  
  	    case DNTT_TYPE_DOC_FUNCTION:
! 	      valu = dn_bufp->ddocfunc.hiaddr + ANOFFSET (objfile->section_offsets,
! 							  SECT_OFF_TEXT);
  	      if (valu > texthigh)
  		texthigh = valu;
  	      valu = dn_bufp->ddocfunc.lowaddr +
--- 2007,2014 ----
  	      continue;
  
  	    case DNTT_TYPE_DOC_FUNCTION:
! 	      valu = dn_bufp->ddocfunc.hiaddr +
! 		ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT);
  	      if (valu > texthigh)
  		texthigh = valu;
  	      valu = dn_bufp->ddocfunc.lowaddr +
***************
*** 2088,2094 ****
--- 2206,2214 ----
  			  0, dependency_list, dependencies_used);
      }
  
+ #if 0
    discard_cleanups (old_chain);
+ #endif
  }
  
  /* Perform any local cleanups required when we are done with a particular
***************
*** 2102,2107 ****
--- 2222,2230 ----
  {
    if (objfile->sym_private != NULL)
      {
+       /* srikanth, 990311, JAGaa80452, don't forget to forget ... */
+       if (TYPE_VECTOR (objfile))
+ 	mfree (objfile->md, TYPE_VECTOR (objfile));
        mfree (objfile->md, objfile->sym_private);
      }
  }
***************
*** 2129,2140 ****
      &(GNTT (objfile)[(index * sizeof (struct dntt_type_block))]);
  }
  
  union sltentry *
  hpread_get_slt (index, objfile)
       int index;
       struct objfile *objfile;
  {
!   return (union sltentry *) &(SLT (objfile)[index * sizeof (union sltentry)]);
  }
  
  /* Get the low address associated with some symbol (typically the start
--- 2252,2381 ----
      &(GNTT (objfile)[(index * sizeof (struct dntt_type_block))]);
  }
  
+ static void
+ initialize_slt_page_table (objfile)
+      struct objfile *objfile;
+ {
+ 
+   int i;
+   slt_page_frame *page_table;
+   asection *slt_section;
+ 
+   SLT_PAGE_TABLE (objfile) =
+     page_table = (slt_page_frame *)
+     obstack_alloc (&objfile->symbol_obstack,
+ 		   SLT_PAGE_COUNT * sizeof (slt_page_frame));
+ 
+   /* allocate the pages upfront, it is no biggie */
+ 
+   for (i = 0; i < SLT_PAGE_COUNT; i++)
+     {
+       page_table[i].page = (union sltentry *)
+ 	obstack_alloc (&objfile->symbol_obstack,
+ 		       SLT_ENTRIES_PER_PAGE * sizeof (union sltentry));
+       page_table[i].page_number = -1;
+     }
+ 
+   SLT_SECTION (objfile) = slt_section =
+     bfd_get_section_by_name (objfile->obfd, HP_SLT);
+ 
+   SLT_SIZE (objfile) = bfd_section_size (objfile->obfd, slt_section);
+ 
+ }
+ 
+ static union sltentry *
+ slt_entry_from_page_table (index, objfile)
+      int index;
+      struct objfile *objfile;
+ {
+   int i, j;
+ 
+   slt_page_frame *page_table;
+   slt_page_frame this_page_frame, last_page_frame;
+   asection *slt_section;
+   int bytes_to_skip, bytes_to_read;
+ 
+   int page_number;
+   int line_number;
+ 
+   /* do we have the page table set up ? */
+ 
+   if (SLT_PAGE_TABLE (objfile) == 0)
+     initialize_slt_page_table (objfile);
+ 
+   page_table = SLT_PAGE_TABLE (objfile);
+ 
+   page_number = SLT_PAGE_NUMBER (index);
+   line_number = SLT_LINE_NUMBER (index);
+ 
+   if (page_table[0].page_number == page_number)		/* common case */
+     return &page_table[0].page[line_number];
+ 
+   /* Do we have the desired page in memory ?  As we scan the list of pages
+      left to right, looking for the page of interest, we will bubble the page
+      frames away from the beginning i.e., the "most recently used" slot. This
+      would create a vacuum in the very first slot. When we find the page we
+      are looking for, we will move that page to this slot. Alternately, if the
+      page is not in memory and we have to page it in from disk, we will use
+      this slot as the destination. This guarentees that the list is sorted on
+      a MRU basis at all times.
+    */
+ 
+   last_page_frame = page_table[0];
+ 
+   for (i = 1; i < SLT_PAGE_COUNT; i++)
+     {
+       this_page_frame = page_table[i];
+       page_table[i] = last_page_frame;
+ 
+       if (page_number == this_page_frame.page_number)
+ 	{
+ 	  page_table[0] = this_page_frame;	/* Make this MRU */
+ 	  return &this_page_frame.page[line_number];
+ 	}
+ 
+       last_page_frame = this_page_frame;
+     }
+ 
+   /* Page fault. At this point, `last_page_frame' points to the least recently
+      used page. Discard its contents by paging in the new data on top of it.
+      Make the new page the most recently used one ...
+    */
+ 
+   page_table[0] = last_page_frame;
+ 
+   bytes_to_skip = page_number *
+     SLT_ENTRIES_PER_PAGE * sizeof (union sltentry);
+ 
+   bytes_to_read = SLT_ENTRIES_PER_PAGE * sizeof (union sltentry);
+ 
+   slt_section = SLT_SECTION (objfile);
+ 
+   /* last page needs special handling */
+ 
+   if (bytes_to_skip + bytes_to_read > SLT_SIZE (objfile))
+     bytes_to_read = SLT_SIZE (objfile) - bytes_to_skip;
+ 
+   bfd_get_section_contents (objfile->obfd,
+ 			    slt_section,
+ 			    page_table[0].page,
+ 			    bytes_to_skip,
+ 			    bytes_to_read);
+ 
+   page_table[0].page_number = page_number;
+ 
+   return &page_table[0].page[line_number];	/* unwrap the toffee */
+ }
+ 
  union sltentry *
  hpread_get_slt (index, objfile)
       int index;
       struct objfile *objfile;
  {
!   if (SLT (objfile))		/* doom mode */
!     return (union sltentry *) &(SLT (objfile)[index * sizeof (union sltentry)]);
! 
!   return slt_entry_from_page_table (index, objfile);
  }
  
  /* Get the low address associated with some symbol (typically the start
***************
*** 2142,2155 ****
     stored as part of the DNTT_TYPE_MODULE or DNTT_TYPE_SRCFILE symbol we must infer it from
     the existance of DNTT_TYPE_FUNCTION symbols.  */
  
! static unsigned long
  hpread_get_textlow (global, index, objfile, symcount)
       int global;
       int index;
       struct objfile *objfile;
       int symcount;
  {
!   union dnttentry *dn_bufp;
    struct minimal_symbol *msymbol;
  
    /* Look for a DNTT_TYPE_FUNCTION symbol.  */
--- 2383,2396 ----
     stored as part of the DNTT_TYPE_MODULE or DNTT_TYPE_SRCFILE symbol we must infer it from
     the existance of DNTT_TYPE_FUNCTION symbols.  */
  
! static CORE_ADDR
  hpread_get_textlow (global, index, objfile, symcount)
       int global;
       int index;
       struct objfile *objfile;
       int symcount;
  {
!   union dnttentry *dn_bufp = NULL;
    struct minimal_symbol *msymbol;
  
    /* Look for a DNTT_TYPE_FUNCTION symbol.  */
***************
*** 2215,2220 ****
--- 2456,2462 ----
  			filename, textlow, global_syms, static_syms);
  
    result->textlow += offset;
+   result->texthigh += offset;
    result->read_symtab_private = (char *)
      obstack_alloc (&objfile->psymbol_obstack, sizeof (struct symloc));
    LDSYMOFF (result) = ldsymoff;
***************
*** 2328,2355 ****
       This happens in VxWorks.  */
    free_named_symtabs (pst->filename);
  
!   if (num_includes == 0
!       && number_dependencies == 0
!       && pst->n_global_syms == 0
!       && pst->n_static_syms == 0)
!     {
!       /* Throw away this psymtab, it's empty.  We can't deallocate it, since
!          it is on the obstack, but we can forget to chain it on the list. 
!          Empty psymtabs happen as a result of header files which don't have
!          any symbols in them.  There can be a lot of them.  But this check
!          is wrong, in that a psymtab with N_SLINE entries but nothing else
!          is not empty, but we don't realize that.  Fixing that without slowing
!          things down might be tricky.
!          It's also wrong if we're using the quick look-up tables, as
!          we can get empty psymtabs from modules with no routines in
!          them. */
! 
!       discard_psymtab (pst);
! 
!       /* Indicate that psymtab was thrown away.  */
!       pst = (struct partial_symtab *) NULL;
! 
!     }
    return pst;
  }
  
--- 2570,2581 ----
       This happens in VxWorks.  */
    free_named_symtabs (pst->filename);
  
!   /* srikanth, 990609, we used to check for and discard empty psymtabs here.
!      We can't do this anymore, as currently all psymtabs (except for "globals")
!      are empty. The lookup scheme has been changed to search the minimal symbol
!      table instead and if a linker symbol is found, use its address to decide
!      which psymtab to expand. The textlow and texthigh addresses of a psymtab
!      envelop the functions contained ... */
    return pst;
  }
  
Index: gdb/hpread.h
/opt/gnu/bin/diff -r -c -N  /view/guo.wdb.c//CLO/Components/WDB/Src/gnu/gdb/hpread.h gdb/hpread.h
*** /view/guo.wdb.c//CLO/Components/WDB/Src/gnu/gdb/hpread.h	Wed Nov  3 13:17:36 1999
--- gdb/hpread.h	Wed Nov  3 17:55:20 1999
***************
*** 40,45 ****
--- 40,83 ----
  #include "gdbtypes.h"
  #include "demangle.h"
  
+ /* srikanth, 990422, demand paging of SLT...
+ 
+    A paging scheme to load on demand selected parts of SLT and cache the 
+    contents for future references. Under this scheme, there could be upto
+    SLT_PAGE_COUNT number of pages per load module and each could hold upto
+    SLT_ENTRIES_PER_PAGE number of entries. 
+ 
+    When we have allocated SLT_PAGE_COUNT number of pages, we reclaim a page
+    frame by discarding its cached contents. Eviction is on a "least recently 
+    used" basis. 
+ 
+    Parameters for this paging scheme were chosen such that each page would be 
+    8 kilo bytes in size (1024 entries * 8 bytes per entry) and there would be 
+    an upper bound of ~50 kilo bytes (6 pages) of SLT space per load module.
+ 
+    While this may look small, see that more pages is not necessarily better 
+    since the SLT is consulted only during the expansion of a function. By its
+    very nature, accesses to SLT are highly serialized, localized and in bursts.
+    Further more, once gdb metabolizes the contents of an SLT page, all further
+    lookups are to the internalized form. Thus having served its life's mission 
+    a page begins languishing in memory and hence is a good candidate for 
+    replacement.
+ 
+    All allocation is from the symbol_obstack.
+  */
+ 
+ #define SLT_PAGE_COUNT  6
+ #define SLT_ENTRIES_PER_PAGE  1024	/* this must be a power of two */
+ #define SLT_PAGE_NUMBER(index)  ((index) >> 10)
+ #define SLT_LINE_NUMBER(index)  ((index) &  0x000003ff)
+ 
+ typedef struct slt_page_frame
+   {
+     int page_number;
+     union sltentry *page;	/* actual goodies */
+   }
+ slt_page_frame;
+ 
  /* Private information attached to an objfile which we use to find
     and internalize the HP C debug symbols within that objfile.  */
  
***************
*** 50,55 ****
--- 88,98 ----
      char *lntt;
      char *slt;
      char *vt;
+     unsigned int globals_start;
+ 
+     slt_page_frame *slt_page_table;
+     asection *slt_section;
+     int slt_size;
  
      /* We keep the size of the $VT$ section for range checking.  */
      unsigned int vt_size;
***************
*** 71,79 ****
  
      /* Keep track of the current function's address.  We may need to look
         up something based on this address.  */
!     unsigned int current_function_value;
    };
  
  /* Accessor macros to get at the fields.  */
  #define HPUX_SYMFILE_INFO(o) \
    ((struct hpread_symfile_info *)((o)->sym_private))
--- 114,128 ----
  
      /* Keep track of the current function's address.  We may need to look
         up something based on this address.  */
!     CORE_ADDR current_function_value;
    };
  
+ #define HP_HEADER "$HEADER$"
+ #define HP_GNTT   "$GNTT$"
+ #define HP_LNTT   "$LNTT$"
+ #define HP_SLT    "$SLT$"
+ #define HP_VT     "$VT$"
+ 
  /* Accessor macros to get at the fields.  */
  #define HPUX_SYMFILE_INFO(o) \
    ((struct hpread_symfile_info *)((o)->sym_private))
***************
*** 84,94 ****
--- 133,155 ----
  #define VT_SIZE(o)              (HPUX_SYMFILE_INFO(o)->vt_size)
  #define LNTT_SYMCOUNT(o)        (HPUX_SYMFILE_INFO(o)->lntt_symcount)
  #define GNTT_SYMCOUNT(o)        (HPUX_SYMFILE_INFO(o)->gntt_symcount)
+ #define GLOBALS_START(o)        (HPUX_SYMFILE_INFO(o)->globals_start)
  #define TYPE_VECTOR(o)          (HPUX_SYMFILE_INFO(o)->type_vector)
  #define TYPE_VECTOR_LENGTH(o)   (HPUX_SYMFILE_INFO(o)->type_vector_length)
  #define SL_INDEX(o)             (HPUX_SYMFILE_INFO(o)->sl_index)
  #define WITHIN_FUNCTION(o)      (HPUX_SYMFILE_INFO(o)->within_function)
  #define CURRENT_FUNCTION_VALUE(o) (HPUX_SYMFILE_INFO(o)->current_function_value)
+ #define SLT_PAGE_TABLE(o)       (HPUX_SYMFILE_INFO(o)->slt_page_table)
+ #define SLT_SECTION(o)          (HPUX_SYMFILE_INFO(o)->slt_section)
+ #define SLT_SIZE(o)             (HPUX_SYMFILE_INFO(o)->slt_size)
+ 
+ /* For DOOM, we combine the GNTT and LNTT into one large table. But we
+  *  need to fixup GNTT indices before using them
+  */
+ 
+ #define INDEX(o, dp)  (dp.global  ?                                     \
+                        GLOBALS_START(o) + dp.index :                    \
+                        dp.index)
  
  /* Given the native debug symbol SYM, set NAMEP to the name associated
     with the debug symbol.  Note we may be called with a debug symbol which
***************
*** 138,143 ****
--- 199,212 ----
  extern struct complaint string_table_offset_complaint;
  extern struct complaint lbrac_unmatched_complaint;
  extern struct complaint lbrac_mismatch_complaint;
+ 
+ /* The SLT is demand paged. This means that 
+ 
+    (a) you cannot do arithmetic on the return value of hpread_get_slt()
+    (b) you cannot store it for future use. It might evaporate.
+    (c) you cannot write onto SLT. Currently only doom mode needs to do this.
+    But demand paging is not applicable for SLT's from doomed .o files.
+  */
  
  extern union sltentry *hpread_get_slt
    PARAMS ((int, struct objfile *));
Index: gdb/defs.h
/opt/gnu/bin/diff -r -c -N  /view/guo.wdb.c//CLO/Components/WDB/Src/gnu/gdb/defs.h gdb/defs.h
*** /view/guo.wdb.c//CLO/Components/WDB/Src/gnu/gdb/defs.h	Wed Nov  3 13:23:31 1999
--- gdb/defs.h	Wed Nov  3 13:24:23 1999
***************
*** 1252,1255 ****
--- 1252,1258 ----
  #define ISATTY(FP)	(isatty (fileno (FP)))
  #endif
  
+ /* Default string for "main" to allow other possible defaults */
+ extern char * default_main;
+ 
  #endif /* #ifndef DEFS_H */
Index: gdb/symtab.c
/opt/gnu/bin/diff -r -c -N  /view/guo.wdb.c//CLO/Components/WDB/Src/gnu/gdb/symtab.c gdb/symtab.c
*** /view/guo.wdb.c//CLO/Components/WDB/Src/gnu/gdb/symtab.c	Wed Nov  3 13:36:34 1999
--- gdb/symtab.c	Wed Nov  3 17:55:21 1999
***************
*** 127,132 ****
--- 127,134 ----
  
  char no_symtab_msg[] = "No symbol table is loaded.  Use the \"file\" command.";
  
+ char *default_main = "main";
+ 
  /* While the C++ support is still in flux, issue a possibly helpful hint on
     using the new command completion feature on single quoted demangled C++
     symbols.  Remove when loose ends are cleaned up.   FIXME -fnf */
***************
*** 1172,1178 ****
  
    ALL_PSYMTABS (objfile, pst)
    {
!     if (lookup_partial_symbol (pst, "main", 1, VAR_NAMESPACE))
        {
  	return (pst);
        }
--- 1174,1180 ----
  
    ALL_PSYMTABS (objfile, pst)
    {
!     if (lookup_partial_symbol (pst, default_main, 1, VAR_NAMESPACE))
        {
  	return (pst);
        }
***************
*** 1312,1329 ****
  	         ?!? Is checking the current pc correct?  Is this routine
  	         ever called to look up a symbol from another context?
  
! 		 FIXME: No, it's not correct.  If someone sets a
! 		 conditional breakpoint at an address, then the
! 		 breakpoint's `struct expression' should refer to the
! 		 `struct symbol' appropriate for the breakpoint's
! 		 address, which may not be the PC.
! 
! 		 Even if it were never called from another context,
! 		 it's totally bizarre for lookup_symbol's behavior to
! 		 depend on the value of the inferior's current PC.  We
! 		 should pass in the appropriate PC as well as the
! 		 block.  The interface to lookup_symbol should change
! 		 to require the caller to provide a PC.  */
  
  	      if (SYMBOL_ALIASES (sym))
  		sym = find_active_alias (sym, read_pc ());
--- 1314,1331 ----
  	         ?!? Is checking the current pc correct?  Is this routine
  	         ever called to look up a symbol from another context?
  
! 	         FIXME: No, it's not correct.  If someone sets a
! 	         conditional breakpoint at an address, then the
! 	         breakpoint's `struct expression' should refer to the
! 	         `struct symbol' appropriate for the breakpoint's
! 	         address, which may not be the PC.
! 
! 	         Even if it were never called from another context,
! 	         it's totally bizarre for lookup_symbol's behavior to
! 	         depend on the value of the inferior's current PC.  We
! 	         should pass in the appropriate PC as well as the
! 	         block.  The interface to lookup_symbol should change
! 	         to require the caller to provide a PC.  */
  
  	      if (SYMBOL_ALIASES (sym))
  		sym = find_active_alias (sym, read_pc ());
***************
*** 4497,4504 ****
        {
  	/* If interrupted, then quit. */
  	QUIT;
!         /* This will cause the symbol table to be read if it has not yet been */
!         s = PSYMTAB_TO_SYMTAB (ps);
        }
  
      for (psym = objfile->static_psymbols.list + ps->statics_offset;
--- 4499,4506 ----
        {
  	/* If interrupted, then quit. */
  	QUIT;
! 	/* This will cause the symbol table to be read if it has not yet been */
! 	s = PSYMTAB_TO_SYMTAB (ps);
        }
  
      for (psym = objfile->static_psymbols.list + ps->statics_offset;
***************
*** 4507,4514 ****
  	 psym++)
        {
  	QUIT;
!         /* This will cause the symbol table to be read if it has not yet been */
!         s = PSYMTAB_TO_SYMTAB (ps);
        }
    }
  
--- 4509,4516 ----
  	 psym++)
        {
  	QUIT;
! 	/* This will cause the symbol table to be read if it has not yet been */
! 	s = PSYMTAB_TO_SYMTAB (ps);
        }
    }
  
Index: gdb/blockframe.c
/opt/gnu/bin/diff -r -c -N  /view/guo.wdb.c//CLO/Components/WDB/Src/gnu/gdb/blockframe.c gdb/blockframe.c
*** /view/guo.wdb.c//CLO/Components/WDB/Src/gnu/gdb/blockframe.c	Wed Nov  3 13:36:11 1999
--- gdb/blockframe.c	Wed Nov  3 13:38:32 1999
***************
*** 127,133 ****
      {
        struct symbol *mainsym;
  
!       mainsym = lookup_symbol ("main", NULL, VAR_NAMESPACE, NULL, NULL);
        if (mainsym && SYMBOL_CLASS (mainsym) == LOC_BLOCK)
  	{
  	  symfile_objfile->ei.main_func_lowpc =
--- 127,133 ----
      {
        struct symbol *mainsym;
  
!       mainsym = lookup_symbol (default_main, NULL, VAR_NAMESPACE, NULL, NULL);
        if (mainsym && SYMBOL_CLASS (mainsym) == LOC_BLOCK)
  	{
  	  symfile_objfile->ei.main_func_lowpc =
Index: gdb/source.c
/opt/gnu/bin/diff -r -c -N  /view/guo.wdb.c//CLO/Components/WDB/Src/gnu/gdb/source.c gdb/source.c
*** /view/guo.wdb.c//CLO/Components/WDB/Src/gnu/gdb/source.c	Wed Nov  3 13:36:13 1999
--- gdb/source.c	Wed Nov  3 17:55:21 1999
***************
*** 148,156 ****
  
    /* Make the default place to list be the function `main'
       if one exists.  */
!   if (lookup_symbol ("main", 0, VAR_NAMESPACE, 0, NULL))
      {
!       sals = decode_line_spec ("main", 1);
        sal = sals.sals[0];
        free (sals.sals);
        current_source_symtab = sal.symtab;
--- 148,156 ----
  
    /* Make the default place to list be the function `main'
       if one exists.  */
!   if (lookup_symbol (default_main, 0, VAR_NAMESPACE, 0, NULL))
      {
!       sals = decode_line_spec (default_main, 1);
        sal = sals.sals[0];
        free (sals.sals);
        current_source_symtab = sal.symtab;
***************
*** 1011,1027 ****
    current_source_line = line;
    first_line_listed = line;
  
!       /* Only prints "No such file or directory" once */
!       if ((s != last_source_visited) || (!last_source_error))
! 	{
! 	  last_source_visited = s;
! 	  desc = open_source_file (s);
! 	}
!       else
! 	{
! 	  desc = last_source_error;
! 	  noerror = 1;
! 	}
  
    if (desc < 0)
      {
--- 1011,1027 ----
    current_source_line = line;
    first_line_listed = line;
  
!   /* Only prints "No such file or directory" once */
!   if ((s != last_source_visited) || (!last_source_error))
!     {
!       last_source_visited = s;
!       desc = open_source_file (s);
!     }
!   else
!     {
!       desc = last_source_error;
!       noerror = 1;
!     }
  
    if (desc < 0)
      {
***************
*** 1308,1314 ****
      {
        int first_line = sal.line - lines_to_list / 2;
  
!       if (first_line < 1) first_line = 1;
  
        print_source_lines (sal.symtab, first_line, first_line + lines_to_list,
  			  0);
--- 1308,1315 ----
      {
        int first_line = sal.line - lines_to_list / 2;
  
!       if (first_line < 1)
! 	first_line = 1;
  
        print_source_lines (sal.symtab, first_line, first_line + lines_to_list,
  			  0);


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]