* c-typeprint.c (c_type_print_base): Use `show' of -1 to print
authorPeter Schauer <Peter.Schauer@mytum.de>
Sat, 17 Dec 1994 10:46:32 +0000 (10:46 +0000)
committerPeter Schauer <Peter.Schauer@mytum.de>
Sat, 17 Dec 1994 10:46:32 +0000 (10:46 +0000)
the return type of methods to avoid infinite loops with anonymous
types.
* valops.c (search_struct_field):  Handle anonymous unions.

* sparc-tdep.c (sunos4_skip_trampoline_code):  New function
to correctly handle steps into -g compiled PIC objects in the
main executable.
* config/sparc/tm-sun4os4.h (SKIP_TRAMPOLINE_CODE):
Redefine to use sunos4_skip_trampoline_code.

* dwarfread.c (DWARF_REG_TO_REGNUM):  Provide a default mapping
from DWARF to GDB register numbering.
* dwarfread.c (locval):  Use DWARF_REG_TO_REGNUM to map the
register value.
* config/mips/tm-mipsv4.h (DWARF_REG_TO_REGNUM):  Define.

gdb/ChangeLog
gdb/c-typeprint.c
gdb/config/mips/tm-mipsv4.h
gdb/config/sparc/tm-sun4os4.h
gdb/dwarfread.c
gdb/sparc-tdep.c

index 6ade1bd4aa8a90d7845f690e5be45e25c5546990..0fc5280ffc26047654723b91d8e7a9fba344e49f 100644 (file)
@@ -1,3 +1,26 @@
+Sat Dec 17 02:33:37 1994  Peter Schauer  (pes@regent.e-technik.tu-muenchen.de)
+
+       * c-typeprint.c (c_type_print_base):  Use `show' of -1 to print
+       the return type of methods to avoid infinite loops with anonymous
+       types.
+       * valops.c (search_struct_field):  Handle anonymous unions.
+  
+       * sparc-tdep.c (sunos4_skip_trampoline_code):  New function
+       to correctly handle steps into -g compiled PIC objects in the
+       main executable.
+       * config/sparc/tm-sun4os4.h (SKIP_TRAMPOLINE_CODE):
+       Redefine to use sunos4_skip_trampoline_code.
+
+       * dwarfread.c (DWARF_REG_TO_REGNUM):  Provide a default mapping
+       from DWARF to GDB register numbering.
+       * dwarfread.c (locval):  Use DWARF_REG_TO_REGNUM to map the
+       register value.
+       * config/mips/tm-mipsv4.h (DWARF_REG_TO_REGNUM):  Define.
+
+Fri Dec 16 10:56:29 1994  J.T. Conklin  <jtc@rtl.cygnus.com>
+
+       * Makefile.in (uninstall): transform file names.
+
 Thu Dec 15 16:55:35 1994  Stan Shebs  <shebs@andros.cygnus.com>
 
        * defs.h: Include progress.h.
index ff768ee695bf7e3144739a160939f306138b66d9..01a9a738fdb032727973834b5307b5e50c082ce4 100644 (file)
@@ -1,5 +1,6 @@
 /* Support for printing C and C++ types for GDB, the GNU debugger.
-   Copyright 1986, 1988, 1989, 1991 Free Software Foundation, Inc.
+   Copyright 1986, 1988, 1989, 1991, 1993, 1994
+   Free Software Foundation, Inc.
 
 This file is part of GDB.
 
@@ -692,7 +693,7 @@ c_type_print_base (type, stream, show, level)
                  else if (!is_constructor && !is_full_physname_constructor)
                    {
                      type_print (TYPE_TARGET_TYPE (TYPE_FN_FIELD_TYPE (f, j)),
-                                 "", stream, 0);
+                                 "", stream, -1);
                      fputs_filtered (" ", stream);
                    }
                  if (TYPE_FN_FIELD_STUB (f, j))
index 5fc4e4cddd3c278348592910f0d24b34240b208d..03d398594e43fe4f5c60eb241ad6b44a7173d7ec 100644 (file)
@@ -39,3 +39,6 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
 
 /* Use the alternate method of determining valid frame chains. */
 #define FRAME_CHAIN_VALID_ALTERNATE
+
+/* Convert a DWARF register number to a gdb REGNUM.  */
+#define DWARF_REG_TO_REGNUM(num) ((num) < 32 ? (num) : (num)+FP0_REGNUM-32)
index 613ed774c1e15747975f80d59c8a63e11506d298..46c20a815a1cd0d5b7f38e02ff5c464a52cff413 100644 (file)
@@ -1,5 +1,5 @@
 /* Macro definitions for GDB for a Sun 4 running sunos 4.
-   Copyright 1989, 1992 Free Software Foundation, Inc.
+   Copyright 1989, 1992, 1994 Free Software Foundation, Inc.
 
 This file is part of GDB.
 
@@ -20,6 +20,13 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
 #include "sparc/tm-sparc.h"
 #include "tm-sunos.h"
 
+/* Redefine SKIP_TRAMPOLINE_CODE to handle PIC compiled modules
+   in main executables.  */
+
+#undef SKIP_TRAMPOLINE_CODE
+#define SKIP_TRAMPOLINE_CODE(pc)  sunos4_skip_trampoline_code (pc)
+extern CORE_ADDR sunos4_skip_trampoline_code PARAMS ((CORE_ADDR));
+
 /* Offsets into jmp_buf.  Not defined by Sun, but at least documented in a
    comment in <machine/setjmp.h>! */
 
index aebe6bffeb3524b42efeaaa9dd516427995c1d37..5afe795cc6d2cd27f863846d0d2deac1e86305f9 100644 (file)
@@ -192,6 +192,11 @@ typedef unsigned int DIE_REF;      /* Reference to a DIE */
 #define CHILL_PRODUCER "GNU Chill "
 #endif
 
+/* Provide a default mapping from a DWARF register number to a gdb REGNUM.  */
+#ifndef DWARF_REG_TO_REGNUM
+#define DWARF_REG_TO_REGNUM(num) (num)
+#endif
+
 /* Flags to target_to_host() that tell whether or not the data object is
    expected to be signed.  Used, for example, when fetching a signed
    integer in the target environment which is used as a signed integer
@@ -2210,8 +2215,10 @@ locval (loc)
            break;
          case OP_REG:
            /* push register (number) */
-           stack[++stacki] = target_to_host (loc, loc_value_size,
-                                             GET_UNSIGNED, current_objfile);
+           stack[++stacki]
+             = DWARF_REG_TO_REGNUM (target_to_host (loc, loc_value_size,
+                                                    GET_UNSIGNED,
+                                                    current_objfile));
            loc += loc_value_size;
            isreg = 1;
            break;
index a0cb2cc11802d3a780fff3cf6fdb2be1f54f36d2..22a0bd2a4563e4f454e73e62e9e4c8816365dd53 100644 (file)
@@ -31,6 +31,30 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
 
 #include "gdbcore.h"
 
+/* Definition of SPARC instruction layouts.  */
+
+union sparc_insn_layout
+{
+  unsigned long int code;
+  struct
+    {
+      unsigned int op:2;
+      unsigned int rd:5;
+      unsigned int op2:3;
+      unsigned int imm22:22;
+    } sethi;
+  struct
+    {
+      unsigned int op:2;
+      unsigned int rd:5;
+      unsigned int op3:6;
+      unsigned int rs1:5;
+      unsigned int i:1;
+      unsigned int simm13:13;
+    } add;
+  int i;
+};
+
 /* From infrun.c */
 extern int stop_after_trap;
 
@@ -129,16 +153,78 @@ single_step (ignore)
     }
 }
 \f
+/* Call this for each newly created frame.  For SPARC, we need to calculate
+   the bottom of the frame, and do some extra work if the prologue
+   has been generated via the -mflat option to GCC.  In particular,
+   we need to know where the previous fp and the pc have been stashed,
+   since their exact position within the frame may vary.  */
+
+void
+sparc_init_extra_frame_info (fromleaf, fi)
+     int fromleaf;
+     struct frame_info *fi;
+{
+  char *name;
+  CORE_ADDR addr;
+  union sparc_insn_layout x;
+
+  fi->bottom =
+    (fi->next ?
+     (fi->frame == fi->next->frame ? fi->next->bottom : fi->next->frame) :
+     read_register (SP_REGNUM));
+
+  /* Decide whether this is a function with a ``flat register window''
+     frame.  For such functions, the frame pointer is actually in %i7.  */
+  fi->flat = 0;
+  if (find_pc_partial_function (fi->pc, &name, &addr, NULL))
+    {
+      /* See if the function starts with an add (which will be of a
+        negative number if a flat frame) to the sp.  */
+      x.i = read_memory_integer (addr, 4);
+      if (x.add.op == 2 && x.add.rd == 14 && x.add.op3 == 0)
+       {
+         /* Then look for a save of %i7 into the frame.  */
+         x.i = read_memory_integer (addr + 4, 4);
+         if (x.add.op == 3
+             && x.add.rd == 31
+             && x.add.op3 == 4
+             && x.add.rs1 == 14)
+           {
+             /* We definitely have a flat frame now.  */
+             fi->flat = 1;
+             /* Overwrite the frame's address with the value in %i7.  */
+             fi->frame = 
+               (fi->next ?
+                (fi->frame == fi->next->frame ? fi->bottom : fi->frame) :
+                read_register (I7_REGNUM));
+             /* Record where the fp got saved.  */
+             fi->fp_addr = fi->bottom + x.add.simm13;
+             /* Also try to collect where the pc got saved to.  */
+             fi->pc_addr = 0;
+             x.i = read_memory_integer (addr + 12, 4);
+             if (x.add.op == 3
+                 && x.add.rd == 15
+                 && x.add.op3 == 4
+                 && x.add.rs1 == 14)
+               fi->pc_addr = fi->bottom + x.add.simm13;
+           }
+       }
+    }
+}
+
 CORE_ADDR
-sparc_frame_chain (thisframe)
-     FRAME thisframe;
+sparc_frame_chain (frame)
+     struct frame_info *frame;
 {
   char buf[MAX_REGISTER_RAW_SIZE];
   int err;
   CORE_ADDR addr;
 
-  addr = thisframe->frame + FRAME_SAVED_I0 +
-        REGISTER_RAW_SIZE (FP_REGNUM) * (FP_REGNUM - I0_REGNUM);
+  if (frame->flat)
+    addr = frame->fp_addr;
+  else
+    addr = frame->frame + FRAME_SAVED_I0 +
+      REGISTER_RAW_SIZE (FP_REGNUM) * (FP_REGNUM - I0_REGNUM);
   err = target_read_memory (addr, buf, REGISTER_RAW_SIZE (FP_REGNUM));
   if (err)
     return 0;
@@ -157,7 +243,7 @@ sparc_extract_struct_value_address (regbuf)
 
 CORE_ADDR
 sparc_frame_saved_pc (frame)
-     FRAME frame;
+     struct frame_info *frame;
 {
   char buf[MAX_REGISTER_RAW_SIZE];
   CORE_ADDR addr;
@@ -194,39 +280,41 @@ sparc_frame_saved_pc (frame)
                          scbuf, sizeof (scbuf));
       return extract_address (scbuf, sizeof (scbuf));
     }
-  addr = (frame->bottom + FRAME_SAVED_I0 +
-         REGISTER_RAW_SIZE (I7_REGNUM) * (I7_REGNUM - I0_REGNUM));
+  if (frame->flat)
+    addr = frame->pc_addr;
+  else
+    addr = frame->bottom + FRAME_SAVED_I0 +
+      REGISTER_RAW_SIZE (I7_REGNUM) * (I7_REGNUM - I0_REGNUM);
   read_memory (addr, buf, REGISTER_RAW_SIZE (I7_REGNUM));
   return PC_ADJUST (extract_address (buf, REGISTER_RAW_SIZE (I7_REGNUM)));
 }
 
-/*
- * Since an individual frame in the frame cache is defined by two
- * arguments (a frame pointer and a stack pointer), we need two
- * arguments to get info for an arbitrary stack frame.  This routine
- * takes two arguments and makes the cached frames look as if these
- * two arguments defined a frame on the cache.  This allows the rest
- * of info frame to extract the important arguments without
- * difficulty. 
- */
-FRAME
+/* Since an individual frame in the frame cache is defined by two
+   arguments (a frame pointer and a stack pointer), we need two
+   arguments to get info for an arbitrary stack frame.  This routine
+   takes two arguments and makes the cached frames look as if these
+   two arguments defined a frame on the cache.  This allows the rest
+   of info frame to extract the important arguments without
+   difficulty.  */
+
+struct frame_info *
 setup_arbitrary_frame (argc, argv)
      int argc;
-     FRAME_ADDR *argv;
+     CORE_ADDR *argv;
 {
-  FRAME fid;
+  struct frame_info *frame;
 
   if (argc != 2)
     error ("Sparc frame specifications require two arguments: fp and sp");
 
-  fid = create_new_frame (argv[0], 0);
+  frame = create_new_frame (argv[0], 0);
 
-  if (!fid)
-    fatal ("internal: create_new_frame returned invalid frame id");
+  if (!frame)
+    fatal ("internal: create_new_frame returned invalid frame");
   
-  fid->bottom = argv[1];
-  fid->pc = FRAME_SAVED_PC (fid);
-  return fid;
+  frame->bottom = argv[1];
+  frame->pc = FRAME_SAVED_PC (frame);
+  return frame;
 }
 
 /* Given a pc value, skip it forward past the function prologue by
@@ -237,34 +325,16 @@ setup_arbitrary_frame (argc, argv)
 
    This routine should be more specific in its actions; making sure
    that it uses the same register in the initial prologue section.  */
+
 CORE_ADDR 
 skip_prologue (start_pc, frameless_p)
      CORE_ADDR start_pc;
      int frameless_p;
 {
-  union
-    {
-      unsigned long int code;
-      struct
-       {
-         unsigned int op:2;
-         unsigned int rd:5;
-         unsigned int op2:3;
-         unsigned int imm22:22;
-       } sethi;
-      struct
-       {
-         unsigned int op:2;
-         unsigned int rd:5;
-         unsigned int op3:6;
-         unsigned int rs1:5;
-         unsigned int i:1;
-         unsigned int simm13:13;
-       } add;
-      int i;
-    } x;
+  union sparc_insn_layout x;
   int dest = -1;
   CORE_ADDR pc = start_pc;
+  int is_flat = 0;
 
   x.i = read_memory_integer (pc, 4);
 
@@ -298,33 +368,50 @@ skip_prologue (start_pc, frameless_p)
        return pc;                      /* return before doing more work */
       x.i = read_memory_integer (pc, 4);
     }
-  else
+  else if (x.add.op == 2 && x.add.rd == 14 && x.add.op3 == 0)
     {
-      /* Without a save instruction, it's not a prologue.  */
-      return start_pc;
+      pc += 4;
+      if (frameless_p)                 /* If the add is all we care about, */
+       return pc;                      /* return before doing more work */
+      /* FIXME test that the following instructions are the right ones
+         for a flat frame */
+      x.i = read_memory_integer (pc, 4);
+      pc += 4;
+      x.i = read_memory_integer (pc, 4);
+      pc += 4;
+      x.i = read_memory_integer (pc, 4);
     }
+  else
+    /* Without a save or add instruction, it's not a prologue.  */
+    return start_pc;
 
   /* Now we need to recognize stores into the frame from the input
      registers.  This recognizes all non alternate stores of input
      register, into a location offset from the frame pointer.  */
-  while (x.add.op == 3
-        && (x.add.op3 & 0x3c) == 4 /* Store, non-alternate.  */
-        && (x.add.rd & 0x18) == 0x18 /* Input register.  */
-        && x.add.i             /* Immediate mode.  */
-        && x.add.rs1 == 30     /* Off of frame pointer.  */
-        /* Into reserved stack space.  */
-        && x.add.simm13 >= 0x44
-        && x.add.simm13 < 0x5b)
+  while ((x.add.op == 3
+         && (x.add.op3 & 0x3c) == 4 /* Store, non-alternate.  */
+         && (x.add.rd & 0x18) == 0x18 /* Input register.  */
+         && x.add.i            /* Immediate mode.  */
+         && x.add.rs1 == 30    /* Off of frame pointer.  */
+         /* Into reserved stack space.  */
+         && x.add.simm13 >= 0x44
+         && x.add.simm13 < 0x5b)
+        || (is_flat
+            && x.add.op == 3
+            && x.add.op3 == 4
+            && x.add.rs1 == 14
+            ))
     {
       pc += 4;
       x.i = read_memory_integer (pc, 4);
     }
+
   return pc;
 }
 
 /* Check instruction at ADDR to see if it is an annulled branch.
    All other instructions will go to NPC or will trap.
-   Set *TARGET if we find a canidate branch; set to zero if not. */
+   Set *TARGET if we find a candidate branch; set to zero if not. */
    
 branch_type
 isannulled (instruction, addr, target)
@@ -395,10 +482,9 @@ sparc_frame_find_saved_regs (fi, saved_regs_addr)
      struct frame_saved_regs *saved_regs_addr;
 {
   register int regnum;
-  FRAME_ADDR frame = FRAME_FP(fi);
-  FRAME fid = FRAME_INFO_ID (fi);
+  CORE_ADDR frame_addr = FRAME_FP (fi);
 
-  if (!fid)
+  if (!fi)
     fatal ("Bad frame info struct in FRAME_FIND_SAVED_REGS");
 
   memset (saved_regs_addr, 0, sizeof (*saved_regs_addr));
@@ -410,38 +496,59 @@ sparc_frame_find_saved_regs (fi, saved_regs_addr)
       /* Dummy frame.  All but the window regs are in there somewhere. */
       for (regnum = G1_REGNUM; regnum < G1_REGNUM+7; regnum++)
        saved_regs_addr->regs[regnum] =
-         frame + (regnum - G0_REGNUM) * 4 - 0xa0;
+         frame_addr + (regnum - G0_REGNUM) * 4 - 0xa0;
       for (regnum = I0_REGNUM; regnum < I0_REGNUM+8; regnum++)
        saved_regs_addr->regs[regnum] =
-         frame + (regnum - I0_REGNUM) * 4 - 0xc0;
+         frame_addr + (regnum - I0_REGNUM) * 4 - 0xc0;
       for (regnum = FP0_REGNUM; regnum < FP0_REGNUM + 32; regnum++)
        saved_regs_addr->regs[regnum] =
-         frame + (regnum - FP0_REGNUM) * 4 - 0x80;
+         frame_addr + (regnum - FP0_REGNUM) * 4 - 0x80;
       for (regnum = Y_REGNUM; regnum < NUM_REGS; regnum++)
        saved_regs_addr->regs[regnum] =
-         frame + (regnum - Y_REGNUM) * 4 - 0xe0;
-      frame = fi->bottom ?
+         frame_addr + (regnum - Y_REGNUM) * 4 - 0xe0;
+      frame_addr = fi->bottom ?
        fi->bottom : read_register (SP_REGNUM);
     }
+  else if (fi->flat)
+    {
+      /* Flat register window frame.  */
+      saved_regs_addr->regs[RP_REGNUM] = fi->pc_addr;
+      saved_regs_addr->regs[I7_REGNUM] = fi->fp_addr;
+      frame_addr = fi->bottom ? fi->bottom : read_register (SP_REGNUM);
+    }
   else
     {
       /* Normal frame.  Just Local and In registers */
-      frame = fi->bottom ?
+      frame_addr = fi->bottom ?
        fi->bottom : read_register (SP_REGNUM);
-      for (regnum = L0_REGNUM; regnum < L0_REGNUM+16; regnum++)
+      for (regnum = L0_REGNUM; regnum < L0_REGNUM+8; regnum++)
        saved_regs_addr->regs[regnum] =
-         frame + (regnum - L0_REGNUM) * REGISTER_RAW_SIZE (L0_REGNUM);
+         (frame_addr + (regnum - L0_REGNUM) * REGISTER_RAW_SIZE (L0_REGNUM)
+          + FRAME_SAVED_L0);
+      for (regnum = I0_REGNUM; regnum < I0_REGNUM+8; regnum++)
+       saved_regs_addr->regs[regnum] =
+         (frame_addr + (regnum - I0_REGNUM) * REGISTER_RAW_SIZE (I0_REGNUM)
+          + FRAME_SAVED_I0);
     }
   if (fi->next)
     {
-      /* Pull off either the next frame pointer or the stack pointer */
-      FRAME_ADDR next_next_frame =
-       (fi->next->bottom ?
-        fi->next->bottom :
-        read_register (SP_REGNUM));
-      for (regnum = O0_REGNUM; regnum < O0_REGNUM+8; regnum++)
-       saved_regs_addr->regs[regnum] =
-         next_next_frame + regnum * REGISTER_RAW_SIZE (O0_REGNUM);
+      if (fi->flat)
+       {
+         saved_regs_addr->regs[O7_REGNUM] = fi->pc_addr;
+       }
+      else
+       {
+         /* Pull off either the next frame pointer or the stack pointer */
+         CORE_ADDR next_next_frame_addr =
+           (fi->next->bottom ?
+            fi->next->bottom :
+            read_register (SP_REGNUM));
+         for (regnum = O0_REGNUM; regnum < O0_REGNUM+8; regnum++)
+           saved_regs_addr->regs[regnum] =
+             (next_next_frame_addr
+              + (regnum - O0_REGNUM) * REGISTER_RAW_SIZE (O0_REGNUM)
+              + FRAME_SAVED_I0);
+       }
     }
   /* Otherwise, whatever we would get from ptrace(GETREGS) is accurate */
   saved_regs_addr->regs[SP_REGNUM] = FRAME_FP (fi);
@@ -505,14 +612,13 @@ sparc_push_dummy_frame ()
 void
 sparc_pop_frame ()
 {
-  register FRAME frame = get_current_frame ();
+  register struct frame_info *frame = get_current_frame ();
   register CORE_ADDR pc;
   struct frame_saved_regs fsr;
-  struct frame_info *fi;
   char raw_buffer[REGISTER_BYTES];
+  int regnum;
 
-  fi = get_frame_info (frame);
-  get_frame_saved_regs (fi, &fsr);
+  get_frame_saved_regs (frame, &fsr);
   if (fsr.regs[FP0_REGNUM])
     {
       read_memory (fsr.regs[FP0_REGNUM], raw_buffer, 32 * 4);
@@ -533,7 +639,22 @@ sparc_pop_frame ()
       read_memory (fsr.regs[G1_REGNUM], raw_buffer, 7 * 4);
       write_register_bytes (REGISTER_BYTE (G1_REGNUM), raw_buffer, 7 * 4);
     }
-  if (fsr.regs[I0_REGNUM])
+
+  if (frame->flat)
+    {
+      /* Each register might or might not have been saved, need to test
+        individually.  */
+      for (regnum = L0_REGNUM; regnum < L0_REGNUM + 8; ++regnum)
+       if (fsr.regs[regnum])
+         write_register (regnum, read_memory_integer (fsr.regs[regnum], 4));
+      for (regnum = I0_REGNUM; regnum < I0_REGNUM + 8; ++regnum)
+       if (fsr.regs[regnum])
+         write_register (regnum, read_memory_integer (fsr.regs[regnum], 4));
+      for (regnum = O0_REGNUM; regnum < O0_REGNUM + 8; ++regnum)
+       if (fsr.regs[regnum])
+         write_register (regnum, read_memory_integer (fsr.regs[regnum], 4));
+    }
+  else if (fsr.regs[I0_REGNUM])
     {
       CORE_ADDR sp;
 
@@ -569,6 +690,12 @@ sparc_pop_frame ()
        write_register (NPC_REGNUM,
                        read_memory_integer (fsr.regs[NPC_REGNUM], 4));
     }
+  else if (frame->flat && frame->pc_addr)
+    {
+      pc = PC_ADJUST ((CORE_ADDR) read_memory_integer (frame->pc_addr, 4));
+      write_register (PC_REGNUM,  pc);
+      write_register (NPC_REGNUM, pc + 4);
+    }
   else if (fsr.regs[I7_REGNUM])
     {
       /* Return address in %i7 -- adjust it, then restore PC and NPC from it */
@@ -598,6 +725,48 @@ sparc_pc_adjust(pc)
   else
     return pc+8;
 }
+
+/* If pc is in a shared library trampoline, return its target.
+   The SunOs 4.x linker rewrites the jump table entries for PIC
+   compiled modules in the main executable to bypass the dynamic linker
+   with jumps of the form
+       sethi %hi(addr),%g1
+       jmp %g1+%lo(addr)
+   and removes the corresponding jump table relocation entry in the
+   dynamic relocations.
+   find_solib_trampoline_target relies on the presence of the jump
+   table relocation entry, so we have to detect these jump instructions
+   by hand.  */
+
+CORE_ADDR
+sunos4_skip_trampoline_code (pc)
+     CORE_ADDR pc;
+{
+  unsigned long insn1;
+  char buf[4];
+  int err;
+
+  err = target_read_memory (pc, buf, 4);
+  insn1 = extract_unsigned_integer (buf, 4);
+  if (err == 0 && (insn1 & 0xffc00000) == 0x03000000)
+    {
+      unsigned long insn2;
+
+      err = target_read_memory (pc + 4, buf, 4);
+      insn2 = extract_unsigned_integer (buf, 4);
+      if (err == 0 && (insn2 & 0xffffe000) == 0x81c06000)
+       {
+         CORE_ADDR target_pc = (insn1 & 0x3fffff) << 10;
+         int delta = insn2 & 0x1fff;
+
+         /* Sign extend the displacement.  */
+         if (delta & 0x1000)
+           delta |= ~0x1fff;
+         return target_pc + delta;
+       }
+    }
+  return find_solib_trampoline_target (pc);
+}
 \f
 #ifdef USE_PROC_FS     /* Target dependent support for /proc */
 
@@ -637,7 +806,6 @@ sparc_pc_adjust(pc)
 
  */
 
-
 /*  Given a pointer to a general register set in /proc format (gregset_t *),
     unpack the register contents and supply them as gdb's idea of the current
     register values. */
@@ -761,17 +929,17 @@ int regno;
    This routine returns true on success */
 
 int
-get_longjmp_target(pc)
+get_longjmp_target (pc)
      CORE_ADDR *pc;
 {
   CORE_ADDR jb_addr;
 #define LONGJMP_TARGET_SIZE 4
   char buf[LONGJMP_TARGET_SIZE];
 
-  jb_addr = read_register(O0_REGNUM);
+  jb_addr = read_register (O0_REGNUM);
 
-  if (target_read_memory(jb_addr + JB_PC * JB_ELEMENT_SIZE, buf,
-                        LONGJMP_TARGET_SIZE))
+  if (target_read_memory (jb_addr + JB_PC * JB_ELEMENT_SIZE, buf,
+                         LONGJMP_TARGET_SIZE))
     return 0;
 
   *pc = extract_address (buf, LONGJMP_TARGET_SIZE);