Commit | Line | Data |
---|---|---|
2a6d284d MK |
1 | /* Native-dependent code for AMD64. |
2 | ||
3 | Copyright 2003 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, | |
20 | Boston, MA 02111-1307, USA. */ | |
21 | ||
22 | #include "defs.h" | |
23 | #include "gdbarch.h" | |
24 | #include "regcache.h" | |
25 | ||
26 | #include "gdb_assert.h" | |
27 | ||
28 | #include "i386-tdep.h" | |
29 | #include "x86-64-tdep.h" | |
30 | ||
31 | /* The following bits of code help with implementing debugging 32-bit | |
32 | code natively on AMD64. The idea is to define two mappings between | |
33 | the register number as used by GDB and the register set used by the | |
34 | host to represent the general-purpose registers; one for 32-bit | |
35 | code and one for 64-bit code. The mappings are specified by the | |
36 | follwing variables and consist of an array of offsets within the | |
37 | register set indexed by register number, and the number of | |
38 | registers supported by the mapping. We don't need mappings for the | |
39 | floating-point and SSE registers, since the difference between | |
40 | 64-bit and 32-bit variants are negligable. The difference in the | |
41 | number of SSE registers is already handled by the target code. */ | |
42 | ||
43 | /* General-purpose register mapping for native 32-bit code. */ | |
44 | int *amd64_native_gregset32_reg_offset; | |
45 | int amd64_native_gregset32_num_regs = I386_NUM_GREGS; | |
46 | ||
47 | /* General-purpose register mapping for native 64-bit code. */ | |
48 | int *amd64_native_gregset64_reg_offset; | |
49 | int amd64_native_gregset64_num_regs = X86_64_NUM_GREGS; | |
50 | ||
51 | /* Return the offset of REGNUM within the appropriate native | |
52 | general-purpose register set. */ | |
53 | ||
54 | static int | |
55 | amd64_native_gregset_reg_offset (int regnum) | |
56 | { | |
57 | int *reg_offset = amd64_native_gregset64_reg_offset; | |
58 | int num_regs = amd64_native_gregset64_num_regs; | |
59 | ||
60 | gdb_assert (regnum >= 0); | |
61 | ||
62 | if (gdbarch_ptr_bit (current_gdbarch) == 32) | |
63 | { | |
64 | reg_offset = amd64_native_gregset32_reg_offset; | |
65 | num_regs = amd64_native_gregset32_num_regs; | |
66 | } | |
67 | ||
68 | if (num_regs > NUM_REGS) | |
69 | num_regs = NUM_REGS; | |
70 | ||
71 | if (regnum < num_regs && regnum < NUM_REGS) | |
72 | return reg_offset[regnum]; | |
73 | ||
74 | return -1; | |
75 | } | |
76 | ||
77 | /* Return whether the native general-purpose register set supplies | |
78 | register REGNUM. */ | |
79 | ||
80 | int | |
81 | amd64_native_gregset_supplies_p (int regnum) | |
82 | { | |
83 | return (amd64_native_gregset_reg_offset (regnum) != -1); | |
84 | } | |
85 | ||
86 | ||
87 | /* Supply register REGNUM, whose contents are store in BUF, to | |
88 | REGCACHE. If REGNUM is -1, supply all appropriate registers. */ | |
89 | ||
90 | void | |
91 | amd64_supply_native_gregset (struct regcache *regcache, | |
92 | const void *gregs, int regnum) | |
93 | { | |
94 | const char *regs = gregs; | |
95 | int num_regs = amd64_native_gregset64_num_regs; | |
96 | int i; | |
97 | ||
98 | if (gdbarch_ptr_bit (current_gdbarch) == 32) | |
99 | num_regs = amd64_native_gregset32_num_regs; | |
100 | ||
101 | if (num_regs > NUM_REGS) | |
102 | num_regs = NUM_REGS; | |
103 | ||
104 | for (i = 0; i < num_regs; i++) | |
105 | { | |
106 | if (regnum == -1 || regnum == i) | |
107 | { | |
108 | int offset = amd64_native_gregset_reg_offset (i); | |
109 | ||
110 | if (offset != -1) | |
111 | regcache_raw_supply (current_regcache, i, regs + offset); | |
112 | } | |
113 | } | |
114 | } | |
115 | ||
116 | /* Collect register REGNUM from REGCACHE and store its contents in | |
117 | GREGS. If REGNUM is -1, collect and store all appropriate | |
118 | registers. */ | |
119 | ||
120 | void | |
121 | amd64_collect_native_gregset (const struct regcache *regcache, | |
122 | void *gregs, int regnum) | |
123 | { | |
124 | char *regs = gregs; | |
125 | int num_regs = amd64_native_gregset64_num_regs; | |
126 | int i; | |
127 | ||
128 | if (gdbarch_ptr_bit (current_gdbarch) == 32) | |
129 | num_regs = amd64_native_gregset32_num_regs; | |
130 | ||
131 | if (num_regs > NUM_REGS) | |
132 | num_regs = NUM_REGS; | |
133 | ||
134 | for (i = 0; i < num_regs; i++) | |
135 | { | |
136 | if (regnum == -1 || regnum == i) | |
137 | { | |
138 | int offset = amd64_native_gregset_reg_offset (i); | |
139 | ||
140 | if (offset != -1) | |
141 | regcache_raw_collect (current_regcache, i, regs + offset); | |
142 | } | |
143 | } | |
144 | } |