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: ports/devel/gdb6/files/kvm-fbsd-sparc64.h,v 1.2 2004/08/23 06:34:48 obrien Exp $"); |
23 |
|
24 |
#include "sparc-tdep.h" |
25 |
|
26 |
#define SPARC_INTREG_SIZE 8 |
27 |
|
28 |
static void |
29 |
fetch_kcore_registers (struct pcb *pcbp) |
30 |
{ |
31 |
static struct frame top; |
32 |
CORE_ADDR f_addr; |
33 |
int i; |
34 |
|
35 |
/* Get the register values out of the sys pcb and store them where |
36 |
`read_register' will find them. */ |
37 |
/* |
38 |
* XXX many registers aren't available. |
39 |
* XXX for the non-core case, the registers are stale - they are for |
40 |
* the last context switch to the debugger. |
41 |
* XXX do something with the floating-point registers? |
42 |
*/ |
43 |
regcache_raw_supply (current_regcache, SP_REGNUM, &pcbp->pcb_sp); |
44 |
regcache_raw_supply (current_regcache, PC_REGNUM, &pcbp->pcb_pc); |
45 |
f_addr = extract_unsigned_integer (&pcbp->pcb_sp, SPARC_INTREG_SIZE); |
46 |
/* Load the previous frame by hand (XXX) and supply it. */ |
47 |
read_memory (f_addr + SPOFF, (char *)&top, sizeof (top)); |
48 |
for (i = 0; i < 8; i++) |
49 |
regcache_raw_supply (current_regcache, i + SPARC_L0_REGNUM, &top.fr_local[i]); |
50 |
for (i = 0; i < 8; i++) |
51 |
regcache_raw_supply (current_regcache, i + SPARC_I0_REGNUM, &top.fr_in[i]); |
52 |
} |
53 |
|
54 |
#if __FreeBSD_version >= 500032 |
55 |
CORE_ADDR |
56 |
fbsd_kern_frame_saved_pc (struct frame_info *fi) |
57 |
{ |
58 |
struct minimal_symbol *sym; |
59 |
CORE_ADDR frame, pc_addr, pc; |
60 |
char *buf; |
61 |
|
62 |
buf = alloca (MAX_REGISTER_SIZE); //or use DEPRECATED_MAX_REGISTER_RAW_SIZE |
63 |
/* XXX: duplicates fi->extra_info->bottom. */ |
64 |
frame = (get_next_frame (fi) != NULL) ? get_frame_base (get_next_frame (fi)) : read_sp (); |
65 |
pc_addr = frame + offsetof (struct frame, fr_in[7]); |
66 |
|
67 |
#define READ_PC(pc, a, b) do { \ |
68 |
read_memory (a, b, SPARC_INTREG_SIZE); \ |
69 |
pc = extract_unsigned_integer (b, SPARC_INTREG_SIZE); \ |
70 |
} while (0) |
71 |
|
72 |
READ_PC (pc, pc_addr, buf); |
73 |
|
74 |
sym = lookup_minimal_symbol_by_pc (pc); |
75 |
if (sym != NULL) |
76 |
{ |
77 |
if (strncmp (DEPRECATED_SYMBOL_NAME (sym), "tl0_", 4) == 0 || |
78 |
strcmp (DEPRECATED_SYMBOL_NAME (sym), "btext") == 0 || |
79 |
strcmp (DEPRECATED_SYMBOL_NAME (sym), "mp_startup") == 0 || |
80 |
strcmp (DEPRECATED_SYMBOL_NAME (sym), "fork_trampoline") == 0) |
81 |
{ |
82 |
/* |
83 |
* Ugly kluge: user space addresses aren't separated from kernel |
84 |
* ones by range; if encountering a trap from user space, just |
85 |
* return a 0 to stop the trace. |
86 |
* Do the same for entry points of kernel processes to avoid |
87 |
* printing garbage. |
88 |
*/ |
89 |
pc = 0; |
90 |
} |
91 |
if (strncmp (DEPRECATED_SYMBOL_NAME (sym), "tl1_", 4) == 0) |
92 |
{ |
93 |
pc_addr = get_frame_base (fi) + sizeof (struct frame) + |
94 |
offsetof (struct trapframe, tf_tpc); |
95 |
READ_PC (pc, pc_addr, buf); |
96 |
} |
97 |
} |
98 |
return (pc); |
99 |
} |
100 |
#endif |