]> CyberLeo.Net >> Repos - FreeBSD/releng/8.1.git/blob - gnu/usr.bin/binutils/gdb/kvm-fbsd-sparc64.h
Copy stable/8 to releng/8.1 in preparation for 8.1-RC1.
[FreeBSD/releng/8.1.git] / gnu / usr.bin / binutils / gdb / kvm-fbsd-sparc64.h
1 /* Kernel core dump functions below target vector, for GDB on FreeBSD/sparc64.
2    Copyright 1986, 1987, 1989, 1991, 1992, 1993, 1994, 1995
3    Free Software Foundation, Inc.
4
5 This file is part of GDB.
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 */
21
22 __FBSDID("$FreeBSD$");
23
24 #define SPARC_INTREG_SIZE       8
25
26 static void
27 fetch_kcore_registers (struct pcb *pcbp)
28 {
29   static struct frame top;
30   CORE_ADDR f_addr;
31   int i;
32
33   /* Get the register values out of the sys pcb and store them where
34      `read_register' will find them.  */
35   /*
36    * XXX many registers aren't available.
37    * XXX for the non-core case, the registers are stale - they are for
38    *     the last context switch to the debugger.
39    * XXX do something with the floating-point registers?
40    */
41   supply_register (SP_REGNUM, (char *)&pcbp->pcb_ufp);
42   supply_register (PC_REGNUM, (char *)&pcbp->pcb_pc);
43   f_addr = extract_address (&pcbp->pcb_ufp, SPARC_INTREG_SIZE);
44   /* Load the previous frame by hand (XXX) and supply it. */
45   read_memory (f_addr + SPOFF, (char *)&top, sizeof (top));
46   for (i = 0; i < 8; i++)
47     supply_register (i + L0_REGNUM, (char *)&top.fr_local[i]);
48   for (i = 0; i < 8; i++)
49     supply_register (i + I0_REGNUM, (char *)&top.fr_in[i]);
50 }
51
52 CORE_ADDR
53 fbsd_kern_frame_saved_pc (struct frame_info *fi)
54 {
55   struct minimal_symbol *sym;
56   CORE_ADDR frame, pc_addr, pc;
57   char *buf;
58
59   buf = alloca (MAX_REGISTER_RAW_SIZE);
60   /* XXX: duplicates fi->extra_info->bottom. */
61   frame = (fi->next != NULL) ? fi->next->frame : read_sp ();
62   pc_addr = frame + offsetof (struct frame, fr_in[7]);
63
64 #define READ_PC(pc, a, b) do { \
65   read_memory (a, b, SPARC_INTREG_SIZE); \
66   pc = extract_address (b, SPARC_INTREG_SIZE); \
67 } while (0)
68
69   READ_PC (pc, pc_addr, buf);
70
71   sym = lookup_minimal_symbol_by_pc (pc);
72   if (sym != NULL)
73     {
74       if (strncmp (SYMBOL_NAME (sym), "tl0_", 4) == 0 ||
75           strcmp (SYMBOL_NAME (sym), "btext") == 0 ||
76           strcmp (SYMBOL_NAME (sym), "mp_startup") == 0 ||
77           strcmp (SYMBOL_NAME (sym), "fork_trampoline") == 0)
78         {
79           /*
80            * Ugly kluge: user space addresses aren't separated from kernel
81            * ones by range; if encountering a trap from user space, just
82            * return a 0 to stop the trace.
83            * Do the same for entry points of kernel processes to avoid
84            * printing garbage.
85            */
86           pc = 0;
87         }
88       if (strncmp (SYMBOL_NAME (sym), "tl1_", 4) == 0)
89         {
90           pc_addr = fi->frame + sizeof (struct frame) +
91             offsetof (struct trapframe, tf_tpc);
92           READ_PC (pc, pc_addr, buf);
93         }
94     }
95   return (pc);
96 }