Commit | Line | Data |
---|---|---|
e2879ccb MK |
1 | /* Native-dependent code for OpenBSD/amd64. |
2 | ||
42a4f53d | 3 | Copyright (C) 2003-2019 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" | |
4de283e4 TT |
21 | #include "gdbcore.h" |
22 | #include "regcache.h" | |
23 | #include "target.h" | |
e2879ccb | 24 | |
4de283e4 | 25 | #include "amd64-tdep.h" |
f6ac5f3d | 26 | #include "amd64-bsd-nat.h" |
e2879ccb | 27 | #include "amd64-nat.h" |
874a80af | 28 | #include "obsd-nat.h" |
e2879ccb MK |
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); | |
73e1c03f SM |
109 | regcache->raw_supply (12, &sf.sf_r12); |
110 | regcache->raw_supply (13, &sf.sf_r13); | |
111 | regcache->raw_supply (14, &sf.sf_r14); | |
112 | regcache->raw_supply (15, &sf.sf_r15); | |
113 | regcache->raw_supply (AMD64_RBX_REGNUM, &sf.sf_rbx); | |
114 | regcache->raw_supply (AMD64_RIP_REGNUM, &sf.sf_rip); | |
492cf391 MK |
115 | } |
116 | else | |
117 | { | |
118 | /* No, the pcb must have been last updated by savectx(). */ | |
119 | pcb->pcb_rsp += 8; | |
73e1c03f | 120 | regcache->raw_supply (AMD64_RIP_REGNUM, &sf); |
492cf391 MK |
121 | } |
122 | ||
73e1c03f SM |
123 | regcache->raw_supply (AMD64_RSP_REGNUM, &pcb->pcb_rsp); |
124 | regcache->raw_supply (AMD64_RBP_REGNUM, &pcb->pcb_rbp); | |
492cf391 MK |
125 | |
126 | return 1; | |
127 | } | |
e2879ccb | 128 | |
f6ac5f3d PA |
129 | static amd64_bsd_nat_target<obsd_nat_target> the_amd64_obsd_nat_target; |
130 | ||
e2879ccb MK |
131 | void |
132 | _initialize_amd64obsd_nat (void) | |
133 | { | |
134 | amd64_native_gregset32_reg_offset = amd64obsd32_r_reg_offset; | |
135 | amd64_native_gregset32_num_regs = ARRAY_SIZE (amd64obsd32_r_reg_offset); | |
136 | amd64_native_gregset64_reg_offset = amd64obsd_r_reg_offset; | |
492cf391 | 137 | |
d9f719f1 | 138 | add_inf_child_target (&the_amd64_obsd_nat_target); |
6a5c78a3 | 139 | |
492cf391 MK |
140 | /* Support debugging kernel virtual memory images. */ |
141 | bsd_kvm_add_target (amd64obsd_supply_pcb); | |
e2879ccb | 142 | } |