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