1 |
/* Kernel core dump functions below target vector, for GDB on FreeBSD/AMD64. |
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-amd64.h,v 1.2 2004/08/23 06:34:48 obrien Exp $"); |
23 |
|
24 |
#include "amd64-tdep.h" |
25 |
|
26 |
static CORE_ADDR |
27 |
ksym_maxuseraddr (void) |
28 |
{ |
29 |
static CORE_ADDR maxuseraddr; |
30 |
struct minimal_symbol *sym; |
31 |
|
32 |
if (maxuseraddr == 0) |
33 |
{ |
34 |
sym = lookup_minimal_symbol ("PTmap", NULL, NULL); |
35 |
if (sym == NULL) { |
36 |
maxuseraddr = VM_MAXUSER_ADDRESS; |
37 |
} else { |
38 |
maxuseraddr = SYMBOL_VALUE_ADDRESS (sym); |
39 |
} |
40 |
} |
41 |
return maxuseraddr; |
42 |
} |
43 |
|
44 |
|
45 |
/* Symbol names of kernel entry points. Use special frames. */ |
46 |
#define KSYM_TRAP "calltrap" |
47 |
#define KSYM_INTR "Xintr" |
48 |
#define KSYM_FASTINTR "Xfastintr" |
49 |
#define KSYM_OLDSYSCALL "Xlcall_syscall" |
50 |
#define KSYM_SYSCALL "Xint0x80_syscall" |
51 |
|
52 |
/* The following is FreeBSD-specific hackery to decode special frames |
53 |
and elide the assembly-language stub. This could be made faster by |
54 |
defining a frame_type field in the machine-dependent frame information, |
55 |
but we don't think that's too important right now. */ |
56 |
enum frametype { tf_normal, tf_trap, tf_interrupt, tf_syscall }; |
57 |
|
58 |
#if __FreeBSD_version >= 500032 |
59 |
CORE_ADDR |
60 |
fbsd_kern_frame_saved_pc (struct frame_info *fi) |
61 |
{ |
62 |
struct minimal_symbol *sym; |
63 |
CORE_ADDR this_saved_pc; |
64 |
enum frametype frametype; |
65 |
|
66 |
this_saved_pc = read_memory_integer (get_frame_base (fi) + 4, 4); |
67 |
sym = lookup_minimal_symbol_by_pc (this_saved_pc); |
68 |
frametype = tf_normal; |
69 |
if (sym != NULL) |
70 |
{ |
71 |
if (strcmp (DEPRECATED_SYMBOL_NAME (sym), KSYM_TRAP) == 0) |
72 |
frametype = tf_trap; |
73 |
else |
74 |
if (strncmp (DEPRECATED_SYMBOL_NAME (sym), KSYM_INTR, |
75 |
strlen (KSYM_INTR)) == 0 || strncmp (DEPRECATED_SYMBOL_NAME(sym), |
76 |
KSYM_FASTINTR, strlen (KSYM_FASTINTR)) == 0) |
77 |
frametype = tf_interrupt; |
78 |
else |
79 |
if (strcmp (DEPRECATED_SYMBOL_NAME (sym), KSYM_SYSCALL) == 0 || |
80 |
strcmp (DEPRECATED_SYMBOL_NAME (sym), KSYM_OLDSYSCALL) == 0) |
81 |
frametype = tf_syscall; |
82 |
} |
83 |
|
84 |
switch (frametype) |
85 |
{ |
86 |
default: |
87 |
case tf_normal: |
88 |
return (this_saved_pc); |
89 |
#define oEIP offsetof (struct trapframe, tf_rip) |
90 |
|
91 |
case tf_trap: |
92 |
return (read_memory_integer (get_frame_base (fi) + 8 + oEIP, 4)); |
93 |
|
94 |
case tf_interrupt: |
95 |
return (read_memory_integer (get_frame_base (fi) + 12 + oEIP, 4)); |
96 |
|
97 |
case tf_syscall: |
98 |
return (read_memory_integer (get_frame_base (fi) + 8 + oEIP, 4)); |
99 |
#undef oEIP |
100 |
} |
101 |
} |
102 |
#endif |
103 |
|
104 |
static void |
105 |
fetch_kcore_registers (struct pcb *pcb) |
106 |
{ |
107 |
int i; |
108 |
int noreg; |
109 |
|
110 |
/* Get the register values out of the sys pcb and store them where |
111 |
`read_register' will find them. */ |
112 |
/* |
113 |
* XXX many registers aren't available. |
114 |
* XXX for the non-core case, the registers are stale - they are for |
115 |
* the last context switch to the debugger. |
116 |
* XXX gcc's register numbers aren't all #defined in tm-amd64.h. |
117 |
*/ |
118 |
noreg = 0; |
119 |
for (i = 0; i < 3; ++i) /* eax,ecx,edx */ |
120 |
regcache_raw_supply (current_regcache, i, (char *)&noreg); |
121 |
|
122 |
/* DEO:XXX use SP_REGNUM and PC_REGNUM -- this is GDB_MULTI_ARCH */ |
123 |
regcache_raw_supply (current_regcache, 3, (char *) &pcb->pcb_rbx); |
124 |
regcache_raw_supply (current_regcache, SP_REGNUM, (char *) &pcb->pcb_rsp); |
125 |
regcache_raw_supply (current_regcache, AMD64_RBP_REGNUM, (char *) &pcb->pcb_rbp); |
126 |
regcache_raw_supply (current_regcache, PC_REGNUM, (char *) &pcb->pcb_rip); |
127 |
|
128 |
for (i = 9; i < 14; ++i) /* rflags, cs, ss, ds, es, fs */ |
129 |
regcache_raw_supply (current_regcache, i, (char *) &noreg); |
130 |
regcache_raw_supply (current_regcache, 15, (char *) &pcb->pcb_gs); |
131 |
|
132 |
/* XXX 80387 registers? */ |
133 |
} |