From 2b5a8d9c47f77cebff48c49d5b9025ac8baf88c5 Mon Sep 17 00:00:00 2001
From: Per Bothner <per@bothner.com>
Date: Sun, 1 Mar 1992 01:04:13 +0000
Subject: [PATCH] More changes, mostly from IBM, for the rs6000.  See
 ChangeLog.

---
 gdb/buildsym.c       | 34 ++++++++++++++++++++-----------
 gdb/config/rs6000.mh |  5 +++++
 gdb/objfiles.c       |  4 ++--
 gdb/rs6000-tdep.c    |  3 ---
 gdb/rs6000-xdep.c    | 48 +++++++++++++++++++++++++++++++++++---------
 gdb/tm-rs6000.h      | 48 +++++++++++++++++++++++++++++++++++++++++---
 gdb/xcoffread.c      | 40 ++++++++++++++++++++++++++++--------
 7 files changed, 144 insertions(+), 38 deletions(-)

diff --git a/gdb/buildsym.c b/gdb/buildsym.c
index d71bdd04814..eab5e2880bb 100644
--- a/gdb/buildsym.c
+++ b/gdb/buildsym.c
@@ -48,7 +48,7 @@ patch_block_stabs PARAMS ((struct pending *, struct pending_stabs *,
 static void
 read_huge_number PARAMS ((char **, int, long *, int *));
 
-static struct type *
+struct type *
 dbx_alloc_type PARAMS ((int [2], struct objfile *));
 
 static int
@@ -243,7 +243,7 @@ dbx_lookup_type (typenums)
    TYPENUMS may be (-1, -1) to return a new type object that is not
    put into the type vector, and so may not be referred to by number. */
 
-static struct type *
+struct type *
 dbx_alloc_type (typenums, objfile)
      int typenums[2];
      struct objfile *objfile;
@@ -676,7 +676,6 @@ start_symtab (name, dirname, start_addr)
   file_symbols = 0;
   global_symbols = 0;
   global_stabs = 0;		/* AIX COFF */
-  file_stabs = 0;		/* AIX COFF */
   within_function = 0;
 
   /* Context stack is initially empty.  Allocate first one with room for
@@ -817,13 +816,6 @@ end_symtab (end_addr, sort_pending, sort_linevec, objfile)
      file_symbols is still good).  */
   cleanup_undefined_types ();
 
-  /* Hooks for xcoffread.c */
-  if (file_stabs) {
-    patch_block_stabs (file_symbols, file_stabs, objfile);
-    free (file_stabs);
-    file_stabs = 0;
-  }
-
   if (global_stabs) {
     patch_block_stabs (global_symbols, global_stabs, objfile);
     free (global_stabs);
@@ -887,6 +879,15 @@ end_symtab (end_addr, sort_pending, sort_linevec, objfile)
 	symtab->dirname = subfile->dirname;
 	symtab->free_code = free_linetable;
 	symtab->free_ptr = 0;
+
+#if 0 /* defined(IBM6000) */
+	/* In case we need to duplicate symbol tables (to represent include
+	   files), and in case our system needs relocation, we want to
+	   relocate the main symbol table node only (for the main file,
+	   not for the include files). */
+
+	symtab->nonreloc = TRUE;
+#endif
       }
       if (subfile->line_vector)
 	free (subfile->line_vector);
@@ -895,6 +896,13 @@ end_symtab (end_addr, sort_pending, sort_linevec, objfile)
       free (subfile);
     }
 
+#if 0 /* defined(IBM6000) */
+  /* all include symbol tables are non-relocatable, except the main source
+     file's. */
+  if (symtab_list)
+    symtab_list->nonreloc = FALSE;
+#endif
+
   if (type_vector)
     free ((char *) type_vector);
   type_vector = 0;
@@ -1941,14 +1949,16 @@ read_type (pp, objfile)
 
     case 's':
       type = dbx_alloc_type (typenums, objfile);
-      TYPE_NAME (type) = type_synonym_name;
+      if (!TYPE_NAME (type))
+        TYPE_NAME (type) = type_synonym_name;
       type_synonym_name = 0;
       type = read_struct_type (pp, type, objfile);
       break;
 
     case 'u':
       type = dbx_alloc_type (typenums, objfile);
-      TYPE_NAME (type) = type_synonym_name;
+      if (!TYPE_NAME (type))
+	TYPE_NAME (type) = type_synonym_name;
       type_synonym_name = 0;
       type = read_struct_type (pp, type, objfile);
       TYPE_CODE (type) = TYPE_CODE_UNION;
diff --git a/gdb/config/rs6000.mh b/gdb/config/rs6000.mh
index 6f644b5f64b..cd80d89532b 100644
--- a/gdb/config/rs6000.mh
+++ b/gdb/config/rs6000.mh
@@ -20,3 +20,8 @@
 XDEPFILES= xcoffexec.o infptrace.o rs6000-xdep.o
 XM_FILE= xm-rs6000.h
 XM_CFLAGS = -bnodelcsect
+
+# Because of shared libraries, we risk ending up with *two*
+# versions of malloc if we use GNU malloc ...
+GNU_MALLOC =
+MALLOC_CFLAGS = -DNO_MALLOC_CHECK
diff --git a/gdb/objfiles.c b/gdb/objfiles.c
index 53ac034b16a..1bba838c40c 100644
--- a/gdb/objfiles.c
+++ b/gdb/objfiles.c
@@ -64,8 +64,8 @@ allocate_objfile (abfd, filename, dumpable)
     {
       objfile = (struct objfile *) xmalloc (sizeof (struct objfile));
       (void) memset (objfile, 0, sizeof (struct objfile));
-      objfile -> malloc = malloc;
-      objfile -> realloc = realloc;
+      objfile -> malloc = xmalloc;
+      objfile -> realloc = xrealloc;
       objfile -> xmalloc = xmalloc;
       objfile -> xrealloc = xrealloc;
       objfile -> free = free;
diff --git a/gdb/rs6000-tdep.c b/gdb/rs6000-tdep.c
index e90222fbdc8..468414a5a87 100644
--- a/gdb/rs6000-tdep.c
+++ b/gdb/rs6000-tdep.c
@@ -507,9 +507,6 @@ function_frame_info (pc, frameless, offset, saved_gpr, saved_fpr)
   *offset = 0;
   *saved_gpr = *saved_fpr = -1;
 
-  if (!inferior_pid)
-    return;
-
   op  = read_memory_integer (pc, 4);
   if (op == 0x7c0802a6) {		/* mflr r0 */
     pc += 4;
diff --git a/gdb/rs6000-xdep.c b/gdb/rs6000-xdep.c
index 6a5543a3fcd..7f14dfa9093 100644
--- a/gdb/rs6000-xdep.c
+++ b/gdb/rs6000-xdep.c
@@ -60,30 +60,58 @@ static int special_regs[] = {
 /* Nonzero if we just simulated a single step break. */
 extern int one_stepped;
 
+extern char register_valid[];
+
 
 void
 fetch_inferior_registers (regno)
-     int regno;
+  int regno;
 {
   int ii;
   extern char registers[];
 
-  /* read 32 general purpose registers. */
+  if (regno < 0) {			/* for all registers */
 
-  for (ii=0; ii < 32; ++ii)
-    *(int*)&registers[REGISTER_BYTE (ii)] = 
+    /* read 32 general purpose registers. */
+
+    for (ii=0; ii < 32; ++ii)
+      *(int*)&registers[REGISTER_BYTE (ii)] = 
 	ptrace (PT_READ_GPR, inferior_pid, ii, 0, 0);
 
-  /* read general purpose floating point registers. */
+    /* read general purpose floating point registers. */
 
-  for (ii=0; ii < 32; ++ii)
-    ptrace (PT_READ_FPR, inferior_pid, 
+    for (ii=0; ii < 32; ++ii)
+      ptrace (PT_READ_FPR, inferior_pid, 
 	(int*)&registers [REGISTER_BYTE (FP0_REGNUM+ii)], FPR0+ii, 0);
 
-  /* read special registers. */
-  for (ii=0; ii <= LAST_SP_REGNUM-FIRST_SP_REGNUM; ++ii)
-    *(int*)&registers[REGISTER_BYTE (FIRST_SP_REGNUM+ii)] = 
+    /* read special registers. */
+    for (ii=0; ii <= LAST_SP_REGNUM-FIRST_SP_REGNUM; ++ii)
+      *(int*)&registers[REGISTER_BYTE (FIRST_SP_REGNUM+ii)] = 
 	ptrace (PT_READ_GPR, inferior_pid, special_regs[ii], 0, 0);
+
+    registers_fetched ();
+    return;
+  }
+
+  /* else an individual register is addressed. */
+
+  else if (regno < FP0_REGNUM) {		/* a GPR */
+    *(int*)&registers[REGISTER_BYTE (regno)] =
+	ptrace (PT_READ_GPR, inferior_pid, regno, 0, 0);
+  }
+  else if (regno <= FPLAST_REGNUM) {		/* a FPR */
+    ptrace (PT_READ_FPR, inferior_pid,
+	(int*)&registers [REGISTER_BYTE (regno)], (regno-FP0_REGNUM+FPR0), 0);
+  }
+  else if (regno <= LAST_SP_REGNUM) {		/* a special register */
+    *(int*)&registers[REGISTER_BYTE (regno)] =
+	ptrace (PT_READ_GPR, inferior_pid,
+		special_regs[regno-FIRST_SP_REGNUM], 0, 0);
+  }
+  else
+    fprintf (stderr, "gdb error: register no %d not implemented.\n", regno);
+
+  register_valid [regno] = 1;
 }
 
 /* Store our register values back into the inferior.
diff --git a/gdb/tm-rs6000.h b/gdb/tm-rs6000.h
index 07ec07bbdae..ce4f212e63d 100644
--- a/gdb/tm-rs6000.h
+++ b/gdb/tm-rs6000.h
@@ -148,9 +148,12 @@ extern int aix_loadInfoTextIndex;
    some instructions.  */
 
 extern char registers[];
+extern char register_valid [];
 
 #define	SAVED_PC_AFTER_CALL(frame)	\
-	(*(int*)&registers[REGISTER_BYTE (LR_REGNUM)])
+	(register_valid [LR_REGNUM] ? 	\
+	  (*(int*)&registers[REGISTER_BYTE (LR_REGNUM)]) :	\
+	  read_register (LR_REGNUM))
 
 /*#define SAVED_PC_AFTER_CALL(frame)	saved_pc_after_call(frame) */
 
@@ -451,9 +454,48 @@ extern unsigned int rs6000_struct_return_address;
    This includes special registers such as pc and fp saved in special
    ways in the stack frame.  sp is even more special:
    the address we return for it IS the sp for the next frame.  */
+/* In the following implementation for RS6000, we did *not* save sp. I am
+   not sure if it will be needed. The following macro takes care of gpr's
+   and fpr's only. */
+
+#define FRAME_FIND_SAVED_REGS(FRAME_INFO, FRAME_SAVED_REGS)		\
+{									\
+  int frameless, offset, saved_gpr, saved_fpr, ii, frame_addr, func_start;	\
+										\
+  /* find the start of the function and collect info about its frame. */	\
+										\
+  func_start = get_pc_function_start ((FRAME_INFO)->pc) + FUNCTION_START_OFFSET;\
+  function_frame_info (func_start, &frameless, &offset, &saved_gpr, &saved_fpr);\
+  bzero (&(FRAME_SAVED_REGS), sizeof (FRAME_SAVED_REGS));			\
+										\
+  /* if there were any saved registers, figure out parent's stack pointer. */	\
+  frame_addr = 0;								\
+  if (saved_fpr >= 0 || saved_gpr >= 0) {					\
+    if ((FRAME_INFO)->prev && (FRAME_INFO)->prev->frame)			\
+      frame_addr = (FRAME_INFO)->prev->frame;					\
+    else									\
+      frame_addr = read_memory_integer ((FRAME_INFO)->frame, 4);		\
+  }										\
+										\
+  /* if != -1, saved_fpr is the smallest number of saved_fpr. All fpr's		\
+     from saved_fpr to fp31 are saved right underneath caller stack pointer,	\
+     starting from fp31 first. */						\
+										\
+  if (saved_fpr >= 0) {								\
+    for (ii=31; ii >= saved_fpr; --ii) 						\
+      (FRAME_SAVED_REGS).regs [FP0_REGNUM + ii] = frame_addr - ((32 - ii) * 8);	\
+    frame_addr -= (32 - saved_fpr) * 8;						\
+  }										\
+										\
+  /* if != -1, saved_gpr is the smallest number of saved_gpr. All gpr's		\
+     from saved_gpr to gpr31 are saved right under saved fprs, starting		\
+     from r31 first. */								\
+										\
+  if (saved_gpr >= 0)								\
+    for (ii=31; ii >= saved_gpr; --ii)						\
+      (FRAME_SAVED_REGS).regs [ii] = frame_addr - ((32 - ii) * 4);		\
+}
 
-#define FRAME_FIND_SAVED_REGS(frame_info, frame_saved_regs)		\
-	printf ("FIXMEmgo! FRAME_FIND_SAVED_REGS() not implemented!\n")
 
 /* Things needed for making the inferior call functions.  */
 
diff --git a/gdb/xcoffread.c b/gdb/xcoffread.c
index 4d66f5171c4..2b1986d5604 100644
--- a/gdb/xcoffread.c
+++ b/gdb/xcoffread.c
@@ -1427,11 +1427,14 @@ function_entry_point:
 	/* Between a function symbol and `.bf', there always will be a function
 	   stab. We save function type when processing that stab. */
 
-	if (fcn_type_saved == NULL)
-	  fatal ("Unknown function type");
-
-	SYMBOL_TYPE (new->name) = fcn_type_saved;
-	fcn_type_saved = NULL;
+	if (fcn_type_saved == NULL) {
+	  printf ("Unknown function type: symbol 0x%x\n", cs->c_symnum);
+	  SYMBOL_TYPE (new->name) = lookup_function_type (builtin_type_int);
+	}
+	else {
+	  SYMBOL_TYPE (new->name) = fcn_type_saved;
+	  fcn_type_saved = NULL;
+	}
       }
       else if (strcmp (cs->c_name, ".ef") == 0) {
 
@@ -1599,16 +1602,36 @@ process_xcoff_symbol (cs, objfile)
 
     case C_DECL:      			/* a type decleration?? */
 	qq =  (char*) strchr (name, ':');
+	/* skip if there is no ':' or a nameless construct */
 	if (!qq)			/* skip if there is no ':' */
 	  return NULL;
 
 	struct_and_type_combined = (qq[1] == 'T' && qq[2] == 't');
 	pp = qq + (struct_and_type_combined ? 3 : 2);
+
+
+	/* To handle GNU C++ typename abbreviation, we need to be able to fill
+	   in a type's name as soon as space for that type is allocated. */
+
+	if (struct_and_type_combined && name != qq) {
+
+	   int typenums[2];
+	   struct type *tmp_type;
+	   char *tmp_pp = pp;
+
+	   read_type_number (&tmp_pp, typenums);
+	   tmp_type = dbx_alloc_type (typenums);
+
+	   if (tmp_type && !TYPE_NAME (tmp_type))
+	     TYPE_NAME (tmp_type) = SYMBOL_NAME (sym) =
+				obsavestring (name, qq-name);
+	}
 	ttype = SYMBOL_TYPE (sym) = read_type (&pp, objfile);
 
 	/* read_type() will return null if type (or tag) definition was
 	   unnnecessarily duplicated. Also, if the symbol doesn't have a name,
 	   there is no need to keep it in symbol table. */
+	/* The above argument no longer valid. read_type() never returns NULL. */
 
 	if (!ttype || name == qq)
 	  return NULL;
@@ -1623,11 +1646,12 @@ process_xcoff_symbol (cs, objfile)
 	}
 
 	SYMBOL_CLASS (sym) = LOC_TYPEDEF;
-	SYMBOL_NAME (sym) = obsavestring (name, qq-name, &objfile->symbol_obstack);
+	if (!SYMBOL_NAME (sym))
+	  SYMBOL_NAME (sym) =
+	    obsavestring (name, qq-name, &objfile->symbol_obstack);
 
 	if (struct_and_type_combined)
-	  TYPE_NAME (ttype) = SYMBOL_NAME (sym);
-	  
+	  ;
 	else if  (SYMBOL_NAMESPACE (sym) == STRUCT_NAMESPACE)
 	    TYPE_NAME (ttype) = concat (
 		TYPE_CODE (ttype) == TYPE_CODE_UNION ? "union " :