Commit | Line | Data |
---|---|---|
e2879ccb MK |
1 | /* Native-dependent code for OpenBSD/amd64. |
2 | ||
0fb0cc75 | 3 | Copyright (C) 2003, 2004, 2007, 2008, 2009 Free Software Foundation, Inc. |
e2879ccb MK |
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 | |
a9762ec7 | 9 | the Free Software Foundation; either version 3 of the License, or |
e2879ccb MK |
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 | |
a9762ec7 | 18 | along with this program. If not, see <http://www.gnu.org/licenses/>. */ |
e2879ccb MK |
19 | |
20 | #include "defs.h" | |
492cf391 MK |
21 | #include "gdbcore.h" |
22 | #include "regcache.h" | |
6a5c78a3 | 23 | #include "target.h" |
e2879ccb MK |
24 | |
25 | #include "gdb_assert.h" | |
26 | ||
85be1ca6 | 27 | #include "amd64-tdep.h" |
e2879ccb MK |
28 | #include "amd64-nat.h" |
29 | ||
30 | /* Mapping between the general-purpose registers in OpenBSD/amd64 | |
31 | `struct reg' format and GDB's register cache layout for | |
32 | OpenBSD/i386. | |
33 | ||
34 | Note that most (if not all) OpenBSD/amd64 registers are 64-bit, | |
35 | while the OpenBSD/i386 registers are all 32-bit, but since we're | |
36 | little-endian we get away with that. */ | |
37 | ||
38 | /* From <machine/reg.h>. */ | |
39 | static int amd64obsd32_r_reg_offset[] = | |
40 | { | |
41 | 14 * 8, /* %eax */ | |
42 | 3 * 8, /* %ecx */ | |
43 | 2 * 8, /* %edx */ | |
44 | 13 * 8, /* %ebx */ | |
45 | 15 * 8, /* %esp */ | |
46 | 12 * 8, /* %ebp */ | |
47 | 1 * 8, /* %esi */ | |
48 | 0 * 8, /* %edi */ | |
49 | 16 * 8, /* %eip */ | |
50 | 17 * 8, /* %eflags */ | |
51 | 18 * 8, /* %cs */ | |
52 | 19 * 8, /* %ss */ | |
53 | 20 * 8, /* %ds */ | |
54 | 21 * 8, /* %es */ | |
55 | 22 * 8, /* %fs */ | |
56 | 23 * 8 /* %gs */ | |
57 | }; | |
58 | \f | |
59 | ||
492cf391 MK |
60 | /* Support for debugging kernel virtual memory images. */ |
61 | ||
62 | #include <sys/types.h> | |
63 | #include <machine/frame.h> | |
64 | #include <machine/pcb.h> | |
65 | ||
66 | #include "bsd-kvm.h" | |
67 | ||
68 | static int | |
69 | amd64obsd_supply_pcb (struct regcache *regcache, struct pcb *pcb) | |
70 | { | |
71 | struct switchframe sf; | |
72 | int regnum; | |
73 | ||
74 | /* The following is true for OpenBSD 3.5: | |
75 | ||
76 | The pcb contains the stack pointer at the point of the context | |
77 | switch in cpu_switch(). At that point we have a stack frame as | |
78 | described by `struct switchframe', which for OpenBSD 3.5 has the | |
79 | following layout: | |
80 | ||
81 | interrupt level | |
82 | %r15 | |
83 | %r14 | |
84 | %r13 | |
85 | %r12 | |
86 | %rbp | |
87 | %rbx | |
88 | return address | |
89 | ||
90 | Together with %rsp in the pcb, this accounts for all callee-saved | |
91 | registers specified by the psABI. From this information we | |
92 | reconstruct the register state as it would look when we just | |
93 | returned from cpu_switch(). | |
94 | ||
95 | For core dumps the pcb is saved by savectx(). In that case the | |
96 | stack frame only contains the return address, and there is no way | |
97 | to recover the other registers. */ | |
98 | ||
99 | /* The stack pointer shouldn't be zero. */ | |
100 | if (pcb->pcb_rsp == 0) | |
101 | return 0; | |
102 | ||
103 | /* Read the stack frame, and check its validity. */ | |
d7a30af7 | 104 | read_memory (pcb->pcb_rsp, (gdb_byte *) &sf, sizeof sf); |
492cf391 MK |
105 | if (sf.sf_rbp == pcb->pcb_rbp) |
106 | { | |
107 | /* Yes, we have a frame that matches cpu_switch(). */ | |
108 | pcb->pcb_rsp += sizeof (struct switchframe); | |
109 | regcache_raw_supply (regcache, 12, &sf.sf_r12); | |
110 | regcache_raw_supply (regcache, 13, &sf.sf_r13); | |
111 | regcache_raw_supply (regcache, 14, &sf.sf_r14); | |
112 | regcache_raw_supply (regcache, 15, &sf.sf_r15); | |
113 | regcache_raw_supply (regcache, AMD64_RBX_REGNUM, &sf.sf_rbx); | |
114 | regcache_raw_supply (regcache, AMD64_RIP_REGNUM, &sf.sf_rip); | |
115 | } | |
116 | else | |
117 | { | |
118 | /* No, the pcb must have been last updated by savectx(). */ | |
119 | pcb->pcb_rsp += 8; | |
120 | regcache_raw_supply (regcache, AMD64_RIP_REGNUM, &sf); | |
121 | } | |
122 | ||
123 | regcache_raw_supply (regcache, AMD64_RSP_REGNUM, &pcb->pcb_rsp); | |
124 | regcache_raw_supply (regcache, AMD64_RBP_REGNUM, &pcb->pcb_rbp); | |
125 | ||
126 | return 1; | |
127 | } | |
128 | \f | |
129 | ||
e2879ccb MK |
130 | /* Provide a prototype to silence -Wmissing-prototypes. */ |
131 | void _initialize_amd64obsd_nat (void); | |
132 | ||
133 | void | |
134 | _initialize_amd64obsd_nat (void) | |
135 | { | |
136 | amd64_native_gregset32_reg_offset = amd64obsd32_r_reg_offset; | |
137 | amd64_native_gregset32_num_regs = ARRAY_SIZE (amd64obsd32_r_reg_offset); | |
138 | amd64_native_gregset64_reg_offset = amd64obsd_r_reg_offset; | |
492cf391 | 139 | |
6a5c78a3 MK |
140 | /* We've got nothing to add to the common *BSD/amd64 target. */ |
141 | add_target (amd64bsd_target ()); | |
142 | ||
492cf391 MK |
143 | /* Support debugging kernel virtual memory images. */ |
144 | bsd_kvm_add_target (amd64obsd_supply_pcb); | |
e2879ccb | 145 | } |