scsi: pvscsi: check command descriptor ring buffer size (CVE-2016-4952)
[qemu.git] / target-sparc / gdbstub.c
1 /*
2 * SPARC gdb server stub
3 *
4 * Copyright (c) 2003-2005 Fabrice Bellard
5 * Copyright (c) 2013 SUSE LINUX Products GmbH
6 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2 of the License, or (at your option) any later version.
11 *
12 * This library 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 GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
19 */
20 #include "qemu/osdep.h"
21 #include "qemu-common.h"
22 #include "cpu.h"
23 #include "exec/gdbstub.h"
24
25 #ifdef TARGET_ABI32
26 #define gdb_get_rega(buf, val) gdb_get_reg32(buf, val)
27 #else
28 #define gdb_get_rega(buf, val) gdb_get_regl(buf, val)
29 #endif
30
31 int sparc_cpu_gdb_read_register(CPUState *cs, uint8_t *mem_buf, int n)
32 {
33 SPARCCPU *cpu = SPARC_CPU(cs);
34 CPUSPARCState *env = &cpu->env;
35
36 if (n < 8) {
37 /* g0..g7 */
38 return gdb_get_rega(mem_buf, env->gregs[n]);
39 }
40 if (n < 32) {
41 /* register window */
42 return gdb_get_rega(mem_buf, env->regwptr[n - 8]);
43 }
44 #if defined(TARGET_ABI32) || !defined(TARGET_SPARC64)
45 if (n < 64) {
46 /* fprs */
47 if (n & 1) {
48 return gdb_get_reg32(mem_buf, env->fpr[(n - 32) / 2].l.lower);
49 } else {
50 return gdb_get_reg32(mem_buf, env->fpr[(n - 32) / 2].l.upper);
51 }
52 }
53 /* Y, PSR, WIM, TBR, PC, NPC, FPSR, CPSR */
54 switch (n) {
55 case 64:
56 return gdb_get_rega(mem_buf, env->y);
57 case 65:
58 return gdb_get_rega(mem_buf, cpu_get_psr(env));
59 case 66:
60 return gdb_get_rega(mem_buf, env->wim);
61 case 67:
62 return gdb_get_rega(mem_buf, env->tbr);
63 case 68:
64 return gdb_get_rega(mem_buf, env->pc);
65 case 69:
66 return gdb_get_rega(mem_buf, env->npc);
67 case 70:
68 return gdb_get_rega(mem_buf, env->fsr);
69 case 71:
70 return gdb_get_rega(mem_buf, 0); /* csr */
71 default:
72 return gdb_get_rega(mem_buf, 0);
73 }
74 #else
75 if (n < 64) {
76 /* f0-f31 */
77 if (n & 1) {
78 return gdb_get_reg32(mem_buf, env->fpr[(n - 32) / 2].l.lower);
79 } else {
80 return gdb_get_reg32(mem_buf, env->fpr[(n - 32) / 2].l.upper);
81 }
82 }
83 if (n < 80) {
84 /* f32-f62 (double width, even numbers only) */
85 return gdb_get_reg64(mem_buf, env->fpr[(n - 32) / 2].ll);
86 }
87 switch (n) {
88 case 80:
89 return gdb_get_regl(mem_buf, env->pc);
90 case 81:
91 return gdb_get_regl(mem_buf, env->npc);
92 case 82:
93 return gdb_get_regl(mem_buf, (cpu_get_ccr(env) << 32) |
94 ((env->asi & 0xff) << 24) |
95 ((env->pstate & 0xfff) << 8) |
96 cpu_get_cwp64(env));
97 case 83:
98 return gdb_get_regl(mem_buf, env->fsr);
99 case 84:
100 return gdb_get_regl(mem_buf, env->fprs);
101 case 85:
102 return gdb_get_regl(mem_buf, env->y);
103 }
104 #endif
105 return 0;
106 }
107
108 int sparc_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n)
109 {
110 SPARCCPU *cpu = SPARC_CPU(cs);
111 CPUSPARCState *env = &cpu->env;
112 #if defined(TARGET_ABI32)
113 abi_ulong tmp;
114
115 tmp = ldl_p(mem_buf);
116 #else
117 target_ulong tmp;
118
119 tmp = ldtul_p(mem_buf);
120 #endif
121
122 if (n < 8) {
123 /* g0..g7 */
124 env->gregs[n] = tmp;
125 } else if (n < 32) {
126 /* register window */
127 env->regwptr[n - 8] = tmp;
128 }
129 #if defined(TARGET_ABI32) || !defined(TARGET_SPARC64)
130 else if (n < 64) {
131 /* fprs */
132 /* f0-f31 */
133 if (n & 1) {
134 env->fpr[(n - 32) / 2].l.lower = tmp;
135 } else {
136 env->fpr[(n - 32) / 2].l.upper = tmp;
137 }
138 } else {
139 /* Y, PSR, WIM, TBR, PC, NPC, FPSR, CPSR */
140 switch (n) {
141 case 64:
142 env->y = tmp;
143 break;
144 case 65:
145 cpu_put_psr(env, tmp);
146 break;
147 case 66:
148 env->wim = tmp;
149 break;
150 case 67:
151 env->tbr = tmp;
152 break;
153 case 68:
154 env->pc = tmp;
155 break;
156 case 69:
157 env->npc = tmp;
158 break;
159 case 70:
160 env->fsr = tmp;
161 break;
162 default:
163 return 0;
164 }
165 }
166 return 4;
167 #else
168 else if (n < 64) {
169 /* f0-f31 */
170 tmp = ldl_p(mem_buf);
171 if (n & 1) {
172 env->fpr[(n - 32) / 2].l.lower = tmp;
173 } else {
174 env->fpr[(n - 32) / 2].l.upper = tmp;
175 }
176 return 4;
177 } else if (n < 80) {
178 /* f32-f62 (double width, even numbers only) */
179 env->fpr[(n - 32) / 2].ll = tmp;
180 } else {
181 switch (n) {
182 case 80:
183 env->pc = tmp;
184 break;
185 case 81:
186 env->npc = tmp;
187 break;
188 case 82:
189 cpu_put_ccr(env, tmp >> 32);
190 env->asi = (tmp >> 24) & 0xff;
191 env->pstate = (tmp >> 8) & 0xfff;
192 cpu_put_cwp64(env, tmp & 0xff);
193 break;
194 case 83:
195 env->fsr = tmp;
196 break;
197 case 84:
198 env->fprs = tmp;
199 break;
200 case 85:
201 env->y = tmp;
202 break;
203 default:
204 return 0;
205 }
206 }
207 return 8;
208 #endif
209 }