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