arm-get-next-pcs.c revision 1.1.1.6 1 1.1 christos /* Common code for ARM software single stepping support.
2 1.1 christos
3 1.1.1.6 christos Copyright (C) 1988-2024 Free Software Foundation, Inc.
4 1.1 christos
5 1.1 christos This file is part of GDB.
6 1.1 christos
7 1.1 christos This program is free software; you can redistribute it and/or modify
8 1.1 christos it under the terms of the GNU General Public License as published by
9 1.1 christos the Free Software Foundation; either version 3 of the License, or
10 1.1 christos (at your option) any later version.
11 1.1 christos
12 1.1 christos This program is distributed in the hope that it will be useful,
13 1.1 christos but WITHOUT ANY WARRANTY; without even the implied warranty of
14 1.1 christos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 1.1 christos GNU General Public License for more details.
16 1.1 christos
17 1.1 christos You should have received a copy of the GNU General Public License
18 1.1 christos along with this program. If not, see <http://www.gnu.org/licenses/>. */
19 1.1 christos
20 1.1.1.4 christos #include "gdbsupport/gdb_vecs.h"
21 1.1.1.4 christos #include "gdbsupport/common-regcache.h"
22 1.1 christos #include "arm.h"
23 1.1 christos #include "arm-get-next-pcs.h"
24 1.1.1.4 christos #include "count-one-bits.h"
25 1.1 christos
26 1.1 christos /* See arm-get-next-pcs.h. */
27 1.1 christos
28 1.1 christos void
29 1.1 christos arm_get_next_pcs_ctor (struct arm_get_next_pcs *self,
30 1.1 christos struct arm_get_next_pcs_ops *ops,
31 1.1 christos int byte_order,
32 1.1 christos int byte_order_for_code,
33 1.1 christos int has_thumb2_breakpoint,
34 1.1.1.6 christos reg_buffer_common *regcache)
35 1.1 christos {
36 1.1 christos self->ops = ops;
37 1.1 christos self->byte_order = byte_order;
38 1.1 christos self->byte_order_for_code = byte_order_for_code;
39 1.1 christos self->has_thumb2_breakpoint = has_thumb2_breakpoint;
40 1.1 christos self->regcache = regcache;
41 1.1 christos }
42 1.1 christos
43 1.1 christos /* Checks for an atomic sequence of instructions beginning with a LDREX{,B,H,D}
44 1.1 christos instruction and ending with a STREX{,B,H,D} instruction. If such a sequence
45 1.1 christos is found, attempt to step through it. The end of the sequence address is
46 1.1 christos added to the next_pcs list. */
47 1.1 christos
48 1.1.1.3 christos static std::vector<CORE_ADDR>
49 1.1 christos thumb_deal_with_atomic_sequence_raw (struct arm_get_next_pcs *self)
50 1.1 christos {
51 1.1 christos int byte_order_for_code = self->byte_order_for_code;
52 1.1.1.3 christos CORE_ADDR breaks[2] = {CORE_ADDR_MAX, CORE_ADDR_MAX};
53 1.1 christos CORE_ADDR pc = regcache_read_pc (self->regcache);
54 1.1 christos CORE_ADDR loc = pc;
55 1.1 christos unsigned short insn1, insn2;
56 1.1 christos int insn_count;
57 1.1 christos int index;
58 1.1 christos int last_breakpoint = 0; /* Defaults to 0 (no breakpoints placed). */
59 1.1 christos const int atomic_sequence_length = 16; /* Instruction sequence length. */
60 1.1 christos ULONGEST status, itstate;
61 1.1 christos
62 1.1 christos /* We currently do not support atomic sequences within an IT block. */
63 1.1 christos status = regcache_raw_get_unsigned (self->regcache, ARM_PS_REGNUM);
64 1.1 christos itstate = ((status >> 8) & 0xfc) | ((status >> 25) & 0x3);
65 1.1 christos if (itstate & 0x0f)
66 1.1.1.3 christos return {};
67 1.1 christos
68 1.1 christos /* Assume all atomic sequences start with a ldrex{,b,h,d} instruction. */
69 1.1 christos insn1 = self->ops->read_mem_uint (loc, 2, byte_order_for_code);
70 1.1 christos
71 1.1 christos loc += 2;
72 1.1 christos if (thumb_insn_size (insn1) != 4)
73 1.1.1.3 christos return {};
74 1.1 christos
75 1.1 christos insn2 = self->ops->read_mem_uint (loc, 2, byte_order_for_code);
76 1.1 christos
77 1.1 christos loc += 2;
78 1.1 christos if (!((insn1 & 0xfff0) == 0xe850
79 1.1.1.5 christos || ((insn1 & 0xfff0) == 0xe8d0 && (insn2 & 0x00c0) == 0x0040)))
80 1.1.1.3 christos return {};
81 1.1 christos
82 1.1 christos /* Assume that no atomic sequence is longer than "atomic_sequence_length"
83 1.1 christos instructions. */
84 1.1 christos for (insn_count = 0; insn_count < atomic_sequence_length; ++insn_count)
85 1.1 christos {
86 1.1 christos insn1 = self->ops->read_mem_uint (loc, 2,byte_order_for_code);
87 1.1 christos loc += 2;
88 1.1 christos
89 1.1 christos if (thumb_insn_size (insn1) != 4)
90 1.1 christos {
91 1.1 christos /* Assume that there is at most one conditional branch in the
92 1.1 christos atomic sequence. If a conditional branch is found, put a
93 1.1 christos breakpoint in its destination address. */
94 1.1 christos if ((insn1 & 0xf000) == 0xd000 && bits (insn1, 8, 11) != 0x0f)
95 1.1 christos {
96 1.1 christos if (last_breakpoint > 0)
97 1.1.1.3 christos return {}; /* More than one conditional branch found,
98 1.1.1.3 christos fallback to the standard code. */
99 1.1 christos
100 1.1 christos breaks[1] = loc + 2 + (sbits (insn1, 0, 7) << 1);
101 1.1 christos last_breakpoint++;
102 1.1 christos }
103 1.1 christos
104 1.1 christos /* We do not support atomic sequences that use any *other*
105 1.1 christos instructions but conditional branches to change the PC.
106 1.1 christos Fall back to standard code to avoid losing control of
107 1.1 christos execution. */
108 1.1 christos else if (thumb_instruction_changes_pc (insn1))
109 1.1.1.3 christos return {};
110 1.1 christos }
111 1.1 christos else
112 1.1 christos {
113 1.1 christos insn2 = self->ops->read_mem_uint (loc, 2, byte_order_for_code);
114 1.1 christos
115 1.1 christos loc += 2;
116 1.1 christos
117 1.1 christos /* Assume that there is at most one conditional branch in the
118 1.1 christos atomic sequence. If a conditional branch is found, put a
119 1.1 christos breakpoint in its destination address. */
120 1.1 christos if ((insn1 & 0xf800) == 0xf000
121 1.1 christos && (insn2 & 0xd000) == 0x8000
122 1.1 christos && (insn1 & 0x0380) != 0x0380)
123 1.1 christos {
124 1.1 christos int sign, j1, j2, imm1, imm2;
125 1.1 christos unsigned int offset;
126 1.1 christos
127 1.1 christos sign = sbits (insn1, 10, 10);
128 1.1 christos imm1 = bits (insn1, 0, 5);
129 1.1 christos imm2 = bits (insn2, 0, 10);
130 1.1 christos j1 = bit (insn2, 13);
131 1.1 christos j2 = bit (insn2, 11);
132 1.1 christos
133 1.1 christos offset = (sign << 20) + (j2 << 19) + (j1 << 18);
134 1.1 christos offset += (imm1 << 12) + (imm2 << 1);
135 1.1 christos
136 1.1 christos if (last_breakpoint > 0)
137 1.1.1.3 christos return {}; /* More than one conditional branch found,
138 1.1.1.3 christos fallback to the standard code. */
139 1.1 christos
140 1.1 christos breaks[1] = loc + offset;
141 1.1 christos last_breakpoint++;
142 1.1 christos }
143 1.1 christos
144 1.1 christos /* We do not support atomic sequences that use any *other*
145 1.1 christos instructions but conditional branches to change the PC.
146 1.1 christos Fall back to standard code to avoid losing control of
147 1.1 christos execution. */
148 1.1 christos else if (thumb2_instruction_changes_pc (insn1, insn2))
149 1.1.1.3 christos return {};
150 1.1 christos
151 1.1 christos /* If we find a strex{,b,h,d}, we're done. */
152 1.1 christos if ((insn1 & 0xfff0) == 0xe840
153 1.1 christos || ((insn1 & 0xfff0) == 0xe8c0 && (insn2 & 0x00c0) == 0x0040))
154 1.1 christos break;
155 1.1 christos }
156 1.1 christos }
157 1.1 christos
158 1.1 christos /* If we didn't find the strex{,b,h,d}, we cannot handle the sequence. */
159 1.1 christos if (insn_count == atomic_sequence_length)
160 1.1.1.3 christos return {};
161 1.1 christos
162 1.1 christos /* Insert a breakpoint right after the end of the atomic sequence. */
163 1.1 christos breaks[0] = loc;
164 1.1 christos
165 1.1 christos /* Check for duplicated breakpoints. Check also for a breakpoint
166 1.1 christos placed (branch instruction's destination) anywhere in sequence. */
167 1.1 christos if (last_breakpoint
168 1.1 christos && (breaks[1] == breaks[0]
169 1.1 christos || (breaks[1] >= pc && breaks[1] < loc)))
170 1.1 christos last_breakpoint = 0;
171 1.1 christos
172 1.1.1.3 christos std::vector<CORE_ADDR> next_pcs;
173 1.1.1.3 christos
174 1.1 christos /* Adds the breakpoints to the list to be inserted. */
175 1.1 christos for (index = 0; index <= last_breakpoint; index++)
176 1.1.1.3 christos next_pcs.push_back (MAKE_THUMB_ADDR (breaks[index]));
177 1.1 christos
178 1.1 christos return next_pcs;
179 1.1 christos }
180 1.1 christos
181 1.1 christos /* Checks for an atomic sequence of instructions beginning with a LDREX{,B,H,D}
182 1.1 christos instruction and ending with a STREX{,B,H,D} instruction. If such a sequence
183 1.1 christos is found, attempt to step through it. The end of the sequence address is
184 1.1 christos added to the next_pcs list. */
185 1.1 christos
186 1.1.1.3 christos static std::vector<CORE_ADDR>
187 1.1 christos arm_deal_with_atomic_sequence_raw (struct arm_get_next_pcs *self)
188 1.1 christos {
189 1.1 christos int byte_order_for_code = self->byte_order_for_code;
190 1.1.1.3 christos CORE_ADDR breaks[2] = {CORE_ADDR_MAX, CORE_ADDR_MAX};
191 1.1 christos CORE_ADDR pc = regcache_read_pc (self->regcache);
192 1.1 christos CORE_ADDR loc = pc;
193 1.1 christos unsigned int insn;
194 1.1 christos int insn_count;
195 1.1 christos int index;
196 1.1 christos int last_breakpoint = 0; /* Defaults to 0 (no breakpoints placed). */
197 1.1 christos const int atomic_sequence_length = 16; /* Instruction sequence length. */
198 1.1 christos
199 1.1 christos /* Assume all atomic sequences start with a ldrex{,b,h,d} instruction.
200 1.1 christos Note that we do not currently support conditionally executed atomic
201 1.1 christos instructions. */
202 1.1 christos insn = self->ops->read_mem_uint (loc, 4, byte_order_for_code);
203 1.1 christos
204 1.1 christos loc += 4;
205 1.1 christos if ((insn & 0xff9000f0) != 0xe1900090)
206 1.1.1.3 christos return {};
207 1.1 christos
208 1.1 christos /* Assume that no atomic sequence is longer than "atomic_sequence_length"
209 1.1 christos instructions. */
210 1.1 christos for (insn_count = 0; insn_count < atomic_sequence_length; ++insn_count)
211 1.1 christos {
212 1.1 christos insn = self->ops->read_mem_uint (loc, 4, byte_order_for_code);
213 1.1 christos
214 1.1 christos loc += 4;
215 1.1 christos
216 1.1 christos /* Assume that there is at most one conditional branch in the atomic
217 1.1.1.5 christos sequence. If a conditional branch is found, put a breakpoint in
218 1.1.1.5 christos its destination address. */
219 1.1 christos if (bits (insn, 24, 27) == 0xa)
220 1.1 christos {
221 1.1.1.5 christos if (last_breakpoint > 0)
222 1.1.1.5 christos return {}; /* More than one conditional branch found, fallback
223 1.1.1.3 christos to the standard single-step code. */
224 1.1 christos
225 1.1 christos breaks[1] = BranchDest (loc - 4, insn);
226 1.1 christos last_breakpoint++;
227 1.1.1.5 christos }
228 1.1 christos
229 1.1 christos /* We do not support atomic sequences that use any *other* instructions
230 1.1.1.5 christos but conditional branches to change the PC. Fall back to standard
231 1.1 christos code to avoid losing control of execution. */
232 1.1 christos else if (arm_instruction_changes_pc (insn))
233 1.1.1.3 christos return {};
234 1.1 christos
235 1.1 christos /* If we find a strex{,b,h,d}, we're done. */
236 1.1 christos if ((insn & 0xff9000f0) == 0xe1800090)
237 1.1 christos break;
238 1.1 christos }
239 1.1 christos
240 1.1 christos /* If we didn't find the strex{,b,h,d}, we cannot handle the sequence. */
241 1.1 christos if (insn_count == atomic_sequence_length)
242 1.1.1.3 christos return {};
243 1.1 christos
244 1.1 christos /* Insert a breakpoint right after the end of the atomic sequence. */
245 1.1 christos breaks[0] = loc;
246 1.1 christos
247 1.1 christos /* Check for duplicated breakpoints. Check also for a breakpoint
248 1.1 christos placed (branch instruction's destination) anywhere in sequence. */
249 1.1 christos if (last_breakpoint
250 1.1 christos && (breaks[1] == breaks[0]
251 1.1 christos || (breaks[1] >= pc && breaks[1] < loc)))
252 1.1 christos last_breakpoint = 0;
253 1.1 christos
254 1.1.1.3 christos std::vector<CORE_ADDR> next_pcs;
255 1.1.1.3 christos
256 1.1 christos /* Adds the breakpoints to the list to be inserted. */
257 1.1 christos for (index = 0; index <= last_breakpoint; index++)
258 1.1.1.3 christos next_pcs.push_back (breaks[index]);
259 1.1 christos
260 1.1 christos return next_pcs;
261 1.1 christos }
262 1.1 christos
263 1.1 christos /* Find the next possible PCs for thumb mode. */
264 1.1 christos
265 1.1.1.3 christos static std::vector<CORE_ADDR>
266 1.1 christos thumb_get_next_pcs_raw (struct arm_get_next_pcs *self)
267 1.1 christos {
268 1.1 christos int byte_order = self->byte_order;
269 1.1 christos int byte_order_for_code = self->byte_order_for_code;
270 1.1.1.6 christos reg_buffer_common *regcache = self->regcache;
271 1.1 christos CORE_ADDR pc = regcache_read_pc (self->regcache);
272 1.1 christos unsigned long pc_val = ((unsigned long) pc) + 4; /* PC after prefetch */
273 1.1 christos unsigned short inst1;
274 1.1 christos CORE_ADDR nextpc = pc + 2; /* Default is next instruction. */
275 1.1 christos ULONGEST status, itstate;
276 1.1.1.3 christos std::vector<CORE_ADDR> next_pcs;
277 1.1 christos
278 1.1 christos nextpc = MAKE_THUMB_ADDR (nextpc);
279 1.1 christos pc_val = MAKE_THUMB_ADDR (pc_val);
280 1.1 christos
281 1.1 christos inst1 = self->ops->read_mem_uint (pc, 2, byte_order_for_code);
282 1.1 christos
283 1.1 christos /* Thumb-2 conditional execution support. There are eight bits in
284 1.1 christos the CPSR which describe conditional execution state. Once
285 1.1 christos reconstructed (they're in a funny order), the low five bits
286 1.1 christos describe the low bit of the condition for each instruction and
287 1.1 christos how many instructions remain. The high three bits describe the
288 1.1 christos base condition. One of the low four bits will be set if an IT
289 1.1 christos block is active. These bits read as zero on earlier
290 1.1 christos processors. */
291 1.1 christos status = regcache_raw_get_unsigned (regcache, ARM_PS_REGNUM);
292 1.1 christos itstate = ((status >> 8) & 0xfc) | ((status >> 25) & 0x3);
293 1.1 christos
294 1.1 christos /* If-Then handling. On GNU/Linux, where this routine is used, we
295 1.1 christos use an undefined instruction as a breakpoint. Unlike BKPT, IT
296 1.1 christos can disable execution of the undefined instruction. So we might
297 1.1 christos miss the breakpoint if we set it on a skipped conditional
298 1.1 christos instruction. Because conditional instructions can change the
299 1.1 christos flags, affecting the execution of further instructions, we may
300 1.1 christos need to set two breakpoints. */
301 1.1 christos
302 1.1 christos if (self->has_thumb2_breakpoint)
303 1.1 christos {
304 1.1 christos if ((inst1 & 0xff00) == 0xbf00 && (inst1 & 0x000f) != 0)
305 1.1 christos {
306 1.1 christos /* An IT instruction. Because this instruction does not
307 1.1 christos modify the flags, we can accurately predict the next
308 1.1 christos executed instruction. */
309 1.1 christos itstate = inst1 & 0x00ff;
310 1.1 christos pc += thumb_insn_size (inst1);
311 1.1 christos
312 1.1 christos while (itstate != 0 && ! condition_true (itstate >> 4, status))
313 1.1 christos {
314 1.1 christos inst1 = self->ops->read_mem_uint (pc, 2,byte_order_for_code);
315 1.1 christos pc += thumb_insn_size (inst1);
316 1.1 christos itstate = thumb_advance_itstate (itstate);
317 1.1 christos }
318 1.1 christos
319 1.1.1.3 christos next_pcs.push_back (MAKE_THUMB_ADDR (pc));
320 1.1 christos return next_pcs;
321 1.1 christos }
322 1.1 christos else if (itstate != 0)
323 1.1 christos {
324 1.1 christos /* We are in a conditional block. Check the condition. */
325 1.1 christos if (! condition_true (itstate >> 4, status))
326 1.1 christos {
327 1.1 christos /* Advance to the next executed instruction. */
328 1.1 christos pc += thumb_insn_size (inst1);
329 1.1 christos itstate = thumb_advance_itstate (itstate);
330 1.1 christos
331 1.1 christos while (itstate != 0 && ! condition_true (itstate >> 4, status))
332 1.1 christos {
333 1.1 christos inst1 = self->ops->read_mem_uint (pc, 2, byte_order_for_code);
334 1.1 christos
335 1.1 christos pc += thumb_insn_size (inst1);
336 1.1 christos itstate = thumb_advance_itstate (itstate);
337 1.1 christos }
338 1.1 christos
339 1.1.1.3 christos next_pcs.push_back (MAKE_THUMB_ADDR (pc));
340 1.1 christos return next_pcs;
341 1.1 christos }
342 1.1 christos else if ((itstate & 0x0f) == 0x08)
343 1.1 christos {
344 1.1 christos /* This is the last instruction of the conditional
345 1.1 christos block, and it is executed. We can handle it normally
346 1.1 christos because the following instruction is not conditional,
347 1.1 christos and we must handle it normally because it is
348 1.1 christos permitted to branch. Fall through. */
349 1.1 christos }
350 1.1 christos else
351 1.1 christos {
352 1.1 christos int cond_negated;
353 1.1 christos
354 1.1 christos /* There are conditional instructions after this one.
355 1.1 christos If this instruction modifies the flags, then we can
356 1.1 christos not predict what the next executed instruction will
357 1.1 christos be. Fortunately, this instruction is architecturally
358 1.1 christos forbidden to branch; we know it will fall through.
359 1.1 christos Start by skipping past it. */
360 1.1 christos pc += thumb_insn_size (inst1);
361 1.1 christos itstate = thumb_advance_itstate (itstate);
362 1.1 christos
363 1.1 christos /* Set a breakpoint on the following instruction. */
364 1.1 christos gdb_assert ((itstate & 0x0f) != 0);
365 1.1.1.3 christos next_pcs.push_back (MAKE_THUMB_ADDR (pc));
366 1.1 christos
367 1.1 christos cond_negated = (itstate >> 4) & 1;
368 1.1 christos
369 1.1 christos /* Skip all following instructions with the same
370 1.1 christos condition. If there is a later instruction in the IT
371 1.1 christos block with the opposite condition, set the other
372 1.1 christos breakpoint there. If not, then set a breakpoint on
373 1.1 christos the instruction after the IT block. */
374 1.1 christos do
375 1.1 christos {
376 1.1 christos inst1 = self->ops->read_mem_uint (pc, 2, byte_order_for_code);
377 1.1 christos pc += thumb_insn_size (inst1);
378 1.1 christos itstate = thumb_advance_itstate (itstate);
379 1.1 christos }
380 1.1 christos while (itstate != 0 && ((itstate >> 4) & 1) == cond_negated);
381 1.1 christos
382 1.1.1.3 christos next_pcs.push_back (MAKE_THUMB_ADDR (pc));
383 1.1 christos
384 1.1 christos return next_pcs;
385 1.1 christos }
386 1.1 christos }
387 1.1 christos }
388 1.1 christos else if (itstate & 0x0f)
389 1.1 christos {
390 1.1 christos /* We are in a conditional block. Check the condition. */
391 1.1 christos int cond = itstate >> 4;
392 1.1 christos
393 1.1 christos if (! condition_true (cond, status))
394 1.1 christos {
395 1.1 christos /* Advance to the next instruction. All the 32-bit
396 1.1 christos instructions share a common prefix. */
397 1.1.1.3 christos next_pcs.push_back (MAKE_THUMB_ADDR (pc + thumb_insn_size (inst1)));
398 1.1 christos }
399 1.1 christos
400 1.1 christos return next_pcs;
401 1.1 christos
402 1.1 christos /* Otherwise, handle the instruction normally. */
403 1.1 christos }
404 1.1 christos
405 1.1 christos if ((inst1 & 0xff00) == 0xbd00) /* pop {rlist, pc} */
406 1.1 christos {
407 1.1 christos CORE_ADDR sp;
408 1.1 christos
409 1.1 christos /* Fetch the saved PC from the stack. It's stored above
410 1.1.1.5 christos all of the other registers. */
411 1.1.1.4 christos unsigned long offset
412 1.1.1.4 christos = count_one_bits (bits (inst1, 0, 7)) * ARM_INT_REGISTER_SIZE;
413 1.1 christos sp = regcache_raw_get_unsigned (regcache, ARM_SP_REGNUM);
414 1.1 christos nextpc = self->ops->read_mem_uint (sp + offset, 4, byte_order);
415 1.1 christos }
416 1.1 christos else if ((inst1 & 0xf000) == 0xd000) /* conditional branch */
417 1.1 christos {
418 1.1 christos unsigned long cond = bits (inst1, 8, 11);
419 1.1 christos if (cond == 0x0f) /* 0x0f = SWI */
420 1.1 christos {
421 1.1 christos nextpc = self->ops->syscall_next_pc (self);
422 1.1 christos }
423 1.1 christos else if (cond != 0x0f && condition_true (cond, status))
424 1.1 christos nextpc = pc_val + (sbits (inst1, 0, 7) << 1);
425 1.1 christos }
426 1.1 christos else if ((inst1 & 0xf800) == 0xe000) /* unconditional branch */
427 1.1 christos {
428 1.1 christos nextpc = pc_val + (sbits (inst1, 0, 10) << 1);
429 1.1 christos }
430 1.1 christos else if (thumb_insn_size (inst1) == 4) /* 32-bit instruction */
431 1.1 christos {
432 1.1 christos unsigned short inst2;
433 1.1 christos inst2 = self->ops->read_mem_uint (pc + 2, 2, byte_order_for_code);
434 1.1 christos
435 1.1 christos /* Default to the next instruction. */
436 1.1 christos nextpc = pc + 4;
437 1.1 christos nextpc = MAKE_THUMB_ADDR (nextpc);
438 1.1 christos
439 1.1 christos if ((inst1 & 0xf800) == 0xf000 && (inst2 & 0x8000) == 0x8000)
440 1.1 christos {
441 1.1 christos /* Branches and miscellaneous control instructions. */
442 1.1 christos
443 1.1 christos if ((inst2 & 0x1000) != 0 || (inst2 & 0xd001) == 0xc000)
444 1.1 christos {
445 1.1 christos /* B, BL, BLX. */
446 1.1 christos int j1, j2, imm1, imm2;
447 1.1 christos
448 1.1 christos imm1 = sbits (inst1, 0, 10);
449 1.1 christos imm2 = bits (inst2, 0, 10);
450 1.1 christos j1 = bit (inst2, 13);
451 1.1 christos j2 = bit (inst2, 11);
452 1.1 christos
453 1.1.1.3 christos unsigned long offset = ((imm1 << 12) + (imm2 << 1));
454 1.1 christos offset ^= ((!j2) << 22) | ((!j1) << 23);
455 1.1 christos
456 1.1 christos nextpc = pc_val + offset;
457 1.1 christos /* For BLX make sure to clear the low bits. */
458 1.1 christos if (bit (inst2, 12) == 0)
459 1.1 christos nextpc = nextpc & 0xfffffffc;
460 1.1 christos }
461 1.1 christos else if (inst1 == 0xf3de && (inst2 & 0xff00) == 0x3f00)
462 1.1 christos {
463 1.1 christos /* SUBS PC, LR, #imm8. */
464 1.1 christos nextpc = regcache_raw_get_unsigned (regcache, ARM_LR_REGNUM);
465 1.1 christos nextpc -= inst2 & 0x00ff;
466 1.1 christos }
467 1.1 christos else if ((inst2 & 0xd000) == 0x8000 && (inst1 & 0x0380) != 0x0380)
468 1.1 christos {
469 1.1 christos /* Conditional branch. */
470 1.1 christos if (condition_true (bits (inst1, 6, 9), status))
471 1.1 christos {
472 1.1 christos int sign, j1, j2, imm1, imm2;
473 1.1 christos
474 1.1 christos sign = sbits (inst1, 10, 10);
475 1.1 christos imm1 = bits (inst1, 0, 5);
476 1.1 christos imm2 = bits (inst2, 0, 10);
477 1.1 christos j1 = bit (inst2, 13);
478 1.1 christos j2 = bit (inst2, 11);
479 1.1 christos
480 1.1.1.3 christos unsigned long offset
481 1.1.1.3 christos = (sign << 20) + (j2 << 19) + (j1 << 18);
482 1.1 christos offset += (imm1 << 12) + (imm2 << 1);
483 1.1 christos
484 1.1 christos nextpc = pc_val + offset;
485 1.1 christos }
486 1.1 christos }
487 1.1 christos }
488 1.1 christos else if ((inst1 & 0xfe50) == 0xe810)
489 1.1 christos {
490 1.1 christos /* Load multiple or RFE. */
491 1.1 christos int rn, offset, load_pc = 1;
492 1.1 christos
493 1.1 christos rn = bits (inst1, 0, 3);
494 1.1 christos if (bit (inst1, 7) && !bit (inst1, 8))
495 1.1 christos {
496 1.1 christos /* LDMIA or POP */
497 1.1 christos if (!bit (inst2, 15))
498 1.1 christos load_pc = 0;
499 1.1.1.4 christos offset = count_one_bits (inst2) * 4 - 4;
500 1.1 christos }
501 1.1 christos else if (!bit (inst1, 7) && bit (inst1, 8))
502 1.1 christos {
503 1.1 christos /* LDMDB */
504 1.1 christos if (!bit (inst2, 15))
505 1.1 christos load_pc = 0;
506 1.1 christos offset = -4;
507 1.1 christos }
508 1.1 christos else if (bit (inst1, 7) && bit (inst1, 8))
509 1.1 christos {
510 1.1 christos /* RFEIA */
511 1.1 christos offset = 0;
512 1.1 christos }
513 1.1 christos else if (!bit (inst1, 7) && !bit (inst1, 8))
514 1.1 christos {
515 1.1 christos /* RFEDB */
516 1.1 christos offset = -8;
517 1.1 christos }
518 1.1 christos else
519 1.1 christos load_pc = 0;
520 1.1 christos
521 1.1 christos if (load_pc)
522 1.1 christos {
523 1.1 christos CORE_ADDR addr = regcache_raw_get_unsigned (regcache, rn);
524 1.1 christos nextpc = self->ops->read_mem_uint (addr + offset, 4, byte_order);
525 1.1 christos }
526 1.1 christos }
527 1.1 christos else if ((inst1 & 0xffef) == 0xea4f && (inst2 & 0xfff0) == 0x0f00)
528 1.1 christos {
529 1.1 christos /* MOV PC or MOVS PC. */
530 1.1 christos nextpc = regcache_raw_get_unsigned (regcache, bits (inst2, 0, 3));
531 1.1 christos nextpc = MAKE_THUMB_ADDR (nextpc);
532 1.1 christos }
533 1.1 christos else if ((inst1 & 0xff70) == 0xf850 && (inst2 & 0xf000) == 0xf000)
534 1.1 christos {
535 1.1 christos /* LDR PC. */
536 1.1 christos CORE_ADDR base;
537 1.1 christos int rn, load_pc = 1;
538 1.1 christos
539 1.1 christos rn = bits (inst1, 0, 3);
540 1.1 christos base = regcache_raw_get_unsigned (regcache, rn);
541 1.1 christos if (rn == ARM_PC_REGNUM)
542 1.1 christos {
543 1.1 christos base = (base + 4) & ~(CORE_ADDR) 0x3;
544 1.1 christos if (bit (inst1, 7))
545 1.1 christos base += bits (inst2, 0, 11);
546 1.1 christos else
547 1.1 christos base -= bits (inst2, 0, 11);
548 1.1 christos }
549 1.1 christos else if (bit (inst1, 7))
550 1.1 christos base += bits (inst2, 0, 11);
551 1.1 christos else if (bit (inst2, 11))
552 1.1 christos {
553 1.1 christos if (bit (inst2, 10))
554 1.1 christos {
555 1.1 christos if (bit (inst2, 9))
556 1.1 christos base += bits (inst2, 0, 7);
557 1.1 christos else
558 1.1 christos base -= bits (inst2, 0, 7);
559 1.1 christos }
560 1.1 christos }
561 1.1 christos else if ((inst2 & 0x0fc0) == 0x0000)
562 1.1 christos {
563 1.1 christos int shift = bits (inst2, 4, 5), rm = bits (inst2, 0, 3);
564 1.1 christos base += regcache_raw_get_unsigned (regcache, rm) << shift;
565 1.1 christos }
566 1.1 christos else
567 1.1 christos /* Reserved. */
568 1.1 christos load_pc = 0;
569 1.1 christos
570 1.1 christos if (load_pc)
571 1.1 christos nextpc
572 1.1 christos = self->ops->read_mem_uint (base, 4, byte_order);
573 1.1 christos }
574 1.1 christos else if ((inst1 & 0xfff0) == 0xe8d0 && (inst2 & 0xfff0) == 0xf000)
575 1.1 christos {
576 1.1 christos /* TBB. */
577 1.1 christos CORE_ADDR tbl_reg, table, offset, length;
578 1.1 christos
579 1.1 christos tbl_reg = bits (inst1, 0, 3);
580 1.1 christos if (tbl_reg == 0x0f)
581 1.1 christos table = pc + 4; /* Regcache copy of PC isn't right yet. */
582 1.1 christos else
583 1.1 christos table = regcache_raw_get_unsigned (regcache, tbl_reg);
584 1.1 christos
585 1.1 christos offset = regcache_raw_get_unsigned (regcache, bits (inst2, 0, 3));
586 1.1 christos length = 2 * self->ops->read_mem_uint (table + offset, 1, byte_order);
587 1.1 christos nextpc = pc_val + length;
588 1.1 christos }
589 1.1 christos else if ((inst1 & 0xfff0) == 0xe8d0 && (inst2 & 0xfff0) == 0xf010)
590 1.1 christos {
591 1.1 christos /* TBH. */
592 1.1 christos CORE_ADDR tbl_reg, table, offset, length;
593 1.1 christos
594 1.1 christos tbl_reg = bits (inst1, 0, 3);
595 1.1 christos if (tbl_reg == 0x0f)
596 1.1 christos table = pc + 4; /* Regcache copy of PC isn't right yet. */
597 1.1 christos else
598 1.1 christos table = regcache_raw_get_unsigned (regcache, tbl_reg);
599 1.1 christos
600 1.1 christos offset = 2 * regcache_raw_get_unsigned (regcache, bits (inst2, 0, 3));
601 1.1 christos length = 2 * self->ops->read_mem_uint (table + offset, 2, byte_order);
602 1.1 christos nextpc = pc_val + length;
603 1.1 christos }
604 1.1 christos }
605 1.1 christos else if ((inst1 & 0xff00) == 0x4700) /* bx REG, blx REG */
606 1.1 christos {
607 1.1 christos if (bits (inst1, 3, 6) == 0x0f)
608 1.1 christos nextpc = UNMAKE_THUMB_ADDR (pc_val);
609 1.1 christos else
610 1.1 christos nextpc = regcache_raw_get_unsigned (regcache, bits (inst1, 3, 6));
611 1.1 christos }
612 1.1 christos else if ((inst1 & 0xff87) == 0x4687) /* mov pc, REG */
613 1.1 christos {
614 1.1 christos if (bits (inst1, 3, 6) == 0x0f)
615 1.1 christos nextpc = pc_val;
616 1.1 christos else
617 1.1 christos nextpc = regcache_raw_get_unsigned (regcache, bits (inst1, 3, 6));
618 1.1 christos
619 1.1 christos nextpc = MAKE_THUMB_ADDR (nextpc);
620 1.1 christos }
621 1.1 christos else if ((inst1 & 0xf500) == 0xb100)
622 1.1 christos {
623 1.1 christos /* CBNZ or CBZ. */
624 1.1 christos int imm = (bit (inst1, 9) << 6) + (bits (inst1, 3, 7) << 1);
625 1.1 christos ULONGEST reg = regcache_raw_get_unsigned (regcache, bits (inst1, 0, 2));
626 1.1 christos
627 1.1 christos if (bit (inst1, 11) && reg != 0)
628 1.1 christos nextpc = pc_val + imm;
629 1.1 christos else if (!bit (inst1, 11) && reg == 0)
630 1.1 christos nextpc = pc_val + imm;
631 1.1 christos }
632 1.1 christos
633 1.1.1.3 christos next_pcs.push_back (nextpc);
634 1.1 christos
635 1.1 christos return next_pcs;
636 1.1 christos }
637 1.1 christos
638 1.1 christos /* Get the raw next possible addresses. PC in next_pcs is the current program
639 1.1 christos counter, which is assumed to be executing in ARM mode.
640 1.1 christos
641 1.1 christos The values returned have the execution state of the next instruction
642 1.1 christos encoded in it. Use IS_THUMB_ADDR () to see whether the instruction is
643 1.1 christos in Thumb-State, and gdbarch_addr_bits_remove () to get the plain memory
644 1.1 christos address in GDB and arm_addr_bits_remove in GDBServer. */
645 1.1 christos
646 1.1.1.3 christos static std::vector<CORE_ADDR>
647 1.1 christos arm_get_next_pcs_raw (struct arm_get_next_pcs *self)
648 1.1 christos {
649 1.1 christos int byte_order = self->byte_order;
650 1.1 christos int byte_order_for_code = self->byte_order_for_code;
651 1.1 christos unsigned long pc_val;
652 1.1 christos unsigned long this_instr = 0;
653 1.1 christos unsigned long status;
654 1.1 christos CORE_ADDR nextpc;
655 1.1.1.6 christos reg_buffer_common *regcache = self->regcache;
656 1.1.1.6 christos CORE_ADDR pc = regcache_read_pc (regcache);
657 1.1.1.3 christos std::vector<CORE_ADDR> next_pcs;
658 1.1 christos
659 1.1 christos pc_val = (unsigned long) pc;
660 1.1 christos this_instr = self->ops->read_mem_uint (pc, 4, byte_order_for_code);
661 1.1 christos
662 1.1 christos status = regcache_raw_get_unsigned (regcache, ARM_PS_REGNUM);
663 1.1 christos nextpc = (CORE_ADDR) (pc_val + 4); /* Default case */
664 1.1 christos
665 1.1 christos if (bits (this_instr, 28, 31) == INST_NV)
666 1.1 christos switch (bits (this_instr, 24, 27))
667 1.1 christos {
668 1.1 christos case 0xa:
669 1.1 christos case 0xb:
670 1.1 christos {
671 1.1 christos /* Branch with Link and change to Thumb. */
672 1.1 christos nextpc = BranchDest (pc, this_instr);
673 1.1 christos nextpc |= bit (this_instr, 24) << 1;
674 1.1 christos nextpc = MAKE_THUMB_ADDR (nextpc);
675 1.1 christos break;
676 1.1 christos }
677 1.1 christos case 0xc:
678 1.1 christos case 0xd:
679 1.1 christos case 0xe:
680 1.1 christos /* Coprocessor register transfer. */
681 1.1.1.5 christos if (bits (this_instr, 12, 15) == 15)
682 1.1 christos error (_("Invalid update to pc in instruction"));
683 1.1 christos break;
684 1.1 christos }
685 1.1 christos else if (condition_true (bits (this_instr, 28, 31), status))
686 1.1 christos {
687 1.1 christos switch (bits (this_instr, 24, 27))
688 1.1 christos {
689 1.1 christos case 0x0:
690 1.1 christos case 0x1: /* data processing */
691 1.1 christos case 0x2:
692 1.1 christos case 0x3:
693 1.1 christos {
694 1.1 christos unsigned long operand1, operand2, result = 0;
695 1.1 christos unsigned long rn;
696 1.1 christos int c;
697 1.1 christos
698 1.1 christos if (bits (this_instr, 12, 15) != 15)
699 1.1 christos break;
700 1.1 christos
701 1.1 christos if (bits (this_instr, 22, 25) == 0
702 1.1 christos && bits (this_instr, 4, 7) == 9) /* multiply */
703 1.1 christos error (_("Invalid update to pc in instruction"));
704 1.1 christos
705 1.1 christos /* BX <reg>, BLX <reg> */
706 1.1 christos if (bits (this_instr, 4, 27) == 0x12fff1
707 1.1 christos || bits (this_instr, 4, 27) == 0x12fff3)
708 1.1 christos {
709 1.1 christos rn = bits (this_instr, 0, 3);
710 1.1 christos nextpc = ((rn == ARM_PC_REGNUM)
711 1.1 christos ? (pc_val + 8)
712 1.1 christos : regcache_raw_get_unsigned (regcache, rn));
713 1.1 christos
714 1.1.1.3 christos next_pcs.push_back (nextpc);
715 1.1 christos return next_pcs;
716 1.1 christos }
717 1.1 christos
718 1.1 christos /* Multiply into PC. */
719 1.1 christos c = (status & FLAG_C) ? 1 : 0;
720 1.1 christos rn = bits (this_instr, 16, 19);
721 1.1 christos operand1 = ((rn == ARM_PC_REGNUM)
722 1.1 christos ? (pc_val + 8)
723 1.1 christos : regcache_raw_get_unsigned (regcache, rn));
724 1.1 christos
725 1.1 christos if (bit (this_instr, 25))
726 1.1 christos {
727 1.1 christos unsigned long immval = bits (this_instr, 0, 7);
728 1.1 christos unsigned long rotate = 2 * bits (this_instr, 8, 11);
729 1.1 christos operand2 = ((immval >> rotate) | (immval << (32 - rotate)))
730 1.1 christos & 0xffffffff;
731 1.1 christos }
732 1.1 christos else /* operand 2 is a shifted register. */
733 1.1 christos operand2 = shifted_reg_val (regcache, this_instr, c,
734 1.1 christos pc_val, status);
735 1.1 christos
736 1.1 christos switch (bits (this_instr, 21, 24))
737 1.1 christos {
738 1.1 christos case 0x0: /*and */
739 1.1 christos result = operand1 & operand2;
740 1.1 christos break;
741 1.1 christos
742 1.1 christos case 0x1: /*eor */
743 1.1 christos result = operand1 ^ operand2;
744 1.1 christos break;
745 1.1 christos
746 1.1 christos case 0x2: /*sub */
747 1.1 christos result = operand1 - operand2;
748 1.1 christos break;
749 1.1 christos
750 1.1 christos case 0x3: /*rsb */
751 1.1 christos result = operand2 - operand1;
752 1.1 christos break;
753 1.1 christos
754 1.1 christos case 0x4: /*add */
755 1.1 christos result = operand1 + operand2;
756 1.1 christos break;
757 1.1 christos
758 1.1 christos case 0x5: /*adc */
759 1.1 christos result = operand1 + operand2 + c;
760 1.1 christos break;
761 1.1 christos
762 1.1 christos case 0x6: /*sbc */
763 1.1 christos result = operand1 - operand2 + c;
764 1.1 christos break;
765 1.1 christos
766 1.1 christos case 0x7: /*rsc */
767 1.1 christos result = operand2 - operand1 + c;
768 1.1 christos break;
769 1.1 christos
770 1.1 christos case 0x8:
771 1.1 christos case 0x9:
772 1.1 christos case 0xa:
773 1.1 christos case 0xb: /* tst, teq, cmp, cmn */
774 1.1 christos result = (unsigned long) nextpc;
775 1.1 christos break;
776 1.1 christos
777 1.1 christos case 0xc: /*orr */
778 1.1 christos result = operand1 | operand2;
779 1.1 christos break;
780 1.1 christos
781 1.1 christos case 0xd: /*mov */
782 1.1 christos /* Always step into a function. */
783 1.1 christos result = operand2;
784 1.1 christos break;
785 1.1 christos
786 1.1 christos case 0xe: /*bic */
787 1.1 christos result = operand1 & ~operand2;
788 1.1 christos break;
789 1.1 christos
790 1.1 christos case 0xf: /*mvn */
791 1.1 christos result = ~operand2;
792 1.1 christos break;
793 1.1 christos }
794 1.1 christos nextpc = self->ops->addr_bits_remove (self, result);
795 1.1 christos break;
796 1.1 christos }
797 1.1 christos
798 1.1 christos case 0x4:
799 1.1 christos case 0x5: /* data transfer */
800 1.1 christos case 0x6:
801 1.1 christos case 0x7:
802 1.1 christos if (bits (this_instr, 25, 27) == 0x3 && bit (this_instr, 4) == 1)
803 1.1 christos {
804 1.1 christos /* Media instructions and architecturally undefined
805 1.1 christos instructions. */
806 1.1 christos break;
807 1.1 christos }
808 1.1 christos
809 1.1 christos if (bit (this_instr, 20))
810 1.1 christos {
811 1.1 christos /* load */
812 1.1 christos if (bits (this_instr, 12, 15) == 15)
813 1.1 christos {
814 1.1 christos /* rd == pc */
815 1.1 christos unsigned long rn;
816 1.1 christos unsigned long base;
817 1.1 christos
818 1.1 christos if (bit (this_instr, 22))
819 1.1 christos error (_("Invalid update to pc in instruction"));
820 1.1 christos
821 1.1 christos /* byte write to PC */
822 1.1 christos rn = bits (this_instr, 16, 19);
823 1.1 christos base = ((rn == ARM_PC_REGNUM)
824 1.1 christos ? (pc_val + 8)
825 1.1 christos : regcache_raw_get_unsigned (regcache, rn));
826 1.1 christos
827 1.1 christos if (bit (this_instr, 24))
828 1.1 christos {
829 1.1 christos /* pre-indexed */
830 1.1 christos int c = (status & FLAG_C) ? 1 : 0;
831 1.1 christos unsigned long offset =
832 1.1 christos (bit (this_instr, 25)
833 1.1 christos ? shifted_reg_val (regcache, this_instr, c,
834 1.1 christos pc_val, status)
835 1.1 christos : bits (this_instr, 0, 11));
836 1.1 christos
837 1.1 christos if (bit (this_instr, 23))
838 1.1 christos base += offset;
839 1.1 christos else
840 1.1 christos base -= offset;
841 1.1 christos }
842 1.1 christos nextpc
843 1.1 christos = (CORE_ADDR) self->ops->read_mem_uint ((CORE_ADDR) base,
844 1.1 christos 4, byte_order);
845 1.1 christos }
846 1.1 christos }
847 1.1 christos break;
848 1.1 christos
849 1.1 christos case 0x8:
850 1.1 christos case 0x9: /* block transfer */
851 1.1 christos if (bit (this_instr, 20))
852 1.1 christos {
853 1.1 christos /* LDM */
854 1.1 christos if (bit (this_instr, 15))
855 1.1 christos {
856 1.1 christos /* loading pc */
857 1.1 christos int offset = 0;
858 1.1 christos CORE_ADDR rn_val_offset = 0;
859 1.1 christos unsigned long rn_val
860 1.1 christos = regcache_raw_get_unsigned (regcache,
861 1.1 christos bits (this_instr, 16, 19));
862 1.1 christos
863 1.1 christos if (bit (this_instr, 23))
864 1.1 christos {
865 1.1 christos /* up */
866 1.1 christos unsigned long reglist = bits (this_instr, 0, 14);
867 1.1.1.4 christos offset = count_one_bits_l (reglist) * 4;
868 1.1 christos if (bit (this_instr, 24)) /* pre */
869 1.1 christos offset += 4;
870 1.1 christos }
871 1.1 christos else if (bit (this_instr, 24))
872 1.1 christos offset = -4;
873 1.1 christos
874 1.1 christos rn_val_offset = rn_val + offset;
875 1.1 christos nextpc = (CORE_ADDR) self->ops->read_mem_uint (rn_val_offset,
876 1.1 christos 4, byte_order);
877 1.1 christos }
878 1.1 christos }
879 1.1 christos break;
880 1.1 christos
881 1.1 christos case 0xb: /* branch & link */
882 1.1 christos case 0xa: /* branch */
883 1.1 christos {
884 1.1 christos nextpc = BranchDest (pc, this_instr);
885 1.1 christos break;
886 1.1 christos }
887 1.1 christos
888 1.1 christos case 0xc:
889 1.1 christos case 0xd:
890 1.1 christos case 0xe: /* coproc ops */
891 1.1 christos break;
892 1.1 christos case 0xf: /* SWI */
893 1.1 christos {
894 1.1 christos nextpc = self->ops->syscall_next_pc (self);
895 1.1 christos }
896 1.1 christos break;
897 1.1 christos
898 1.1 christos default:
899 1.1 christos error (_("Bad bit-field extraction"));
900 1.1 christos return next_pcs;
901 1.1 christos }
902 1.1 christos }
903 1.1 christos
904 1.1.1.3 christos next_pcs.push_back (nextpc);
905 1.1.1.3 christos
906 1.1 christos return next_pcs;
907 1.1 christos }
908 1.1 christos
909 1.1 christos /* See arm-get-next-pcs.h. */
910 1.1 christos
911 1.1.1.3 christos std::vector<CORE_ADDR>
912 1.1 christos arm_get_next_pcs (struct arm_get_next_pcs *self)
913 1.1 christos {
914 1.1.1.3 christos std::vector<CORE_ADDR> next_pcs;
915 1.1 christos
916 1.1 christos if (self->ops->is_thumb (self))
917 1.1 christos {
918 1.1 christos next_pcs = thumb_deal_with_atomic_sequence_raw (self);
919 1.1.1.3 christos if (next_pcs.empty ())
920 1.1 christos next_pcs = thumb_get_next_pcs_raw (self);
921 1.1 christos }
922 1.1 christos else
923 1.1 christos {
924 1.1 christos next_pcs = arm_deal_with_atomic_sequence_raw (self);
925 1.1.1.3 christos if (next_pcs.empty ())
926 1.1 christos next_pcs = arm_get_next_pcs_raw (self);
927 1.1 christos }
928 1.1 christos
929 1.1 christos if (self->ops->fixup != NULL)
930 1.1 christos {
931 1.1.1.3 christos for (CORE_ADDR &pc_ref : next_pcs)
932 1.1.1.3 christos pc_ref = self->ops->fixup (self, pc_ref);
933 1.1 christos }
934 1.1.1.3 christos
935 1.1 christos return next_pcs;
936 1.1 christos }
937