1b725ae77Skettenis /* Common target dependent code for GDB on ARM systems.
2b725ae77Skettenis Copyright 1988, 1989, 1991, 1992, 1993, 1995, 1996, 1998, 1999, 2000,
3b725ae77Skettenis 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
4e93f7393Sniklas
5e93f7393Sniklas This file is part of GDB.
6e93f7393Sniklas
7e93f7393Sniklas This program is free software; you can redistribute it and/or modify
8e93f7393Sniklas it under the terms of the GNU General Public License as published by
9e93f7393Sniklas the Free Software Foundation; either version 2 of the License, or
10e93f7393Sniklas (at your option) any later version.
11e93f7393Sniklas
12e93f7393Sniklas This program is distributed in the hope that it will be useful,
13e93f7393Sniklas but WITHOUT ANY WARRANTY; without even the implied warranty of
14e93f7393Sniklas MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15e93f7393Sniklas GNU General Public License for more details.
16e93f7393Sniklas
17e93f7393Sniklas You should have received a copy of the GNU General Public License
18e93f7393Sniklas along with this program; if not, write to the Free Software
19b725ae77Skettenis Foundation, Inc., 59 Temple Place - Suite 330,
20b725ae77Skettenis Boston, MA 02111-1307, USA. */
21b725ae77Skettenis
22b725ae77Skettenis #include <ctype.h> /* XXX for isupper () */
23e93f7393Sniklas
24e93f7393Sniklas #include "defs.h"
25e93f7393Sniklas #include "frame.h"
26e93f7393Sniklas #include "inferior.h"
27e93f7393Sniklas #include "gdbcmd.h"
28e93f7393Sniklas #include "gdbcore.h"
29b725ae77Skettenis #include "gdb_string.h"
30b725ae77Skettenis #include "dis-asm.h" /* For register styles. */
31b725ae77Skettenis #include "regcache.h"
32b725ae77Skettenis #include "doublest.h"
33b725ae77Skettenis #include "value.h"
34b725ae77Skettenis #include "arch-utils.h"
35b725ae77Skettenis #include "osabi.h"
36b725ae77Skettenis #include "frame-unwind.h"
37b725ae77Skettenis #include "frame-base.h"
38b725ae77Skettenis #include "trad-frame.h"
39b725ae77Skettenis
40b725ae77Skettenis #include "arm-tdep.h"
41b725ae77Skettenis #include "gdb/sim-arm.h"
42b725ae77Skettenis
43b725ae77Skettenis #include "elf-bfd.h"
44b725ae77Skettenis #include "coff/internal.h"
45b725ae77Skettenis #include "elf/arm.h"
46b725ae77Skettenis
47b725ae77Skettenis #include "gdb_assert.h"
48b725ae77Skettenis
49b725ae77Skettenis static int arm_debug;
50b725ae77Skettenis
51b725ae77Skettenis /* Each OS has a different mechanism for accessing the various
52b725ae77Skettenis registers stored in the sigcontext structure.
53b725ae77Skettenis
54b725ae77Skettenis SIGCONTEXT_REGISTER_ADDRESS should be defined to the name (or
55b725ae77Skettenis function pointer) which may be used to determine the addresses
56b725ae77Skettenis of the various saved registers in the sigcontext structure.
57b725ae77Skettenis
58b725ae77Skettenis For the ARM target, there are three parameters to this function.
59b725ae77Skettenis The first is the pc value of the frame under consideration, the
60b725ae77Skettenis second the stack pointer of this frame, and the last is the
61b725ae77Skettenis register number to fetch.
62b725ae77Skettenis
63b725ae77Skettenis If the tm.h file does not define this macro, then it's assumed that
64b725ae77Skettenis no mechanism is needed and we define SIGCONTEXT_REGISTER_ADDRESS to
65b725ae77Skettenis be 0.
66b725ae77Skettenis
67b725ae77Skettenis When it comes time to multi-arching this code, see the identically
68b725ae77Skettenis named machinery in ia64-tdep.c for an example of how it could be
69b725ae77Skettenis done. It should not be necessary to modify the code below where
70b725ae77Skettenis this macro is used. */
71b725ae77Skettenis
72b725ae77Skettenis #ifdef SIGCONTEXT_REGISTER_ADDRESS
73b725ae77Skettenis #ifndef SIGCONTEXT_REGISTER_ADDRESS_P
74b725ae77Skettenis #define SIGCONTEXT_REGISTER_ADDRESS_P() 1
75b725ae77Skettenis #endif
76b725ae77Skettenis #else
77b725ae77Skettenis #define SIGCONTEXT_REGISTER_ADDRESS(SP,PC,REG) 0
78b725ae77Skettenis #define SIGCONTEXT_REGISTER_ADDRESS_P() 0
79b725ae77Skettenis #endif
80b725ae77Skettenis
81b725ae77Skettenis /* Macros for setting and testing a bit in a minimal symbol that marks
82b725ae77Skettenis it as Thumb function. The MSB of the minimal symbol's "info" field
83b725ae77Skettenis is used for this purpose.
84b725ae77Skettenis
85b725ae77Skettenis MSYMBOL_SET_SPECIAL Actually sets the "special" bit.
86b725ae77Skettenis MSYMBOL_IS_SPECIAL Tests the "special" bit in a minimal symbol. */
87b725ae77Skettenis
88b725ae77Skettenis #define MSYMBOL_SET_SPECIAL(msym) \
89b725ae77Skettenis MSYMBOL_INFO (msym) = (char *) (((long) MSYMBOL_INFO (msym)) \
90b725ae77Skettenis | 0x80000000)
91b725ae77Skettenis
92b725ae77Skettenis #define MSYMBOL_IS_SPECIAL(msym) \
93b725ae77Skettenis (((long) MSYMBOL_INFO (msym) & 0x80000000) != 0)
94b725ae77Skettenis
95b725ae77Skettenis /* The list of available "set arm ..." and "show arm ..." commands. */
96b725ae77Skettenis static struct cmd_list_element *setarmcmdlist = NULL;
97b725ae77Skettenis static struct cmd_list_element *showarmcmdlist = NULL;
98b725ae77Skettenis
99b725ae77Skettenis /* The type of floating-point to use. Keep this in sync with enum
100b725ae77Skettenis arm_float_model, and the help string in _initialize_arm_tdep. */
101b725ae77Skettenis static const char *fp_model_strings[] =
102b725ae77Skettenis {
103b725ae77Skettenis "auto",
104b725ae77Skettenis "softfpa",
105b725ae77Skettenis "fpa",
106b725ae77Skettenis "softvfp",
107b725ae77Skettenis "vfp"
108b725ae77Skettenis };
109b725ae77Skettenis
110b725ae77Skettenis /* A variable that can be configured by the user. */
111b725ae77Skettenis static enum arm_float_model arm_fp_model = ARM_FLOAT_AUTO;
112b725ae77Skettenis static const char *current_fp_model = "auto";
113b725ae77Skettenis
114b725ae77Skettenis /* Number of different reg name sets (options). */
115b725ae77Skettenis static int num_disassembly_options;
116b725ae77Skettenis
117b725ae77Skettenis /* We have more registers than the disassembler as gdb can print the value
118b725ae77Skettenis of special registers as well.
119b725ae77Skettenis The general register names are overwritten by whatever is being used by
120b725ae77Skettenis the disassembler at the moment. We also adjust the case of cpsr and fps. */
121b725ae77Skettenis
122b725ae77Skettenis /* Initial value: Register names used in ARM's ISA documentation. */
123b725ae77Skettenis static char * arm_register_name_strings[] =
124b725ae77Skettenis {"r0", "r1", "r2", "r3", /* 0 1 2 3 */
125b725ae77Skettenis "r4", "r5", "r6", "r7", /* 4 5 6 7 */
126b725ae77Skettenis "r8", "r9", "r10", "r11", /* 8 9 10 11 */
127b725ae77Skettenis "r12", "sp", "lr", "pc", /* 12 13 14 15 */
128b725ae77Skettenis "f0", "f1", "f2", "f3", /* 16 17 18 19 */
129b725ae77Skettenis "f4", "f5", "f6", "f7", /* 20 21 22 23 */
130b725ae77Skettenis "fps", "cpsr" }; /* 24 25 */
131b725ae77Skettenis static char **arm_register_names = arm_register_name_strings;
132b725ae77Skettenis
133b725ae77Skettenis /* Valid register name styles. */
134b725ae77Skettenis static const char **valid_disassembly_styles;
135b725ae77Skettenis
136b725ae77Skettenis /* Disassembly style to use. Default to "std" register names. */
137b725ae77Skettenis static const char *disassembly_style;
138b725ae77Skettenis /* Index to that option in the opcodes table. */
139b725ae77Skettenis static int current_option;
140b725ae77Skettenis
141b725ae77Skettenis /* This is used to keep the bfd arch_info in sync with the disassembly
142b725ae77Skettenis style. */
143b725ae77Skettenis static void set_disassembly_style_sfunc(char *, int,
144b725ae77Skettenis struct cmd_list_element *);
145b725ae77Skettenis static void set_disassembly_style (void);
146b725ae77Skettenis
147b725ae77Skettenis static void convert_from_extended (const struct floatformat *, const void *,
148b725ae77Skettenis void *);
149b725ae77Skettenis static void convert_to_extended (const struct floatformat *, void *,
150b725ae77Skettenis const void *);
151b725ae77Skettenis
152b725ae77Skettenis struct arm_prologue_cache
153b725ae77Skettenis {
154b725ae77Skettenis /* The stack pointer at the time this frame was created; i.e. the
155b725ae77Skettenis caller's stack pointer when this function was called. It is used
156b725ae77Skettenis to identify this frame. */
157b725ae77Skettenis CORE_ADDR prev_sp;
158b725ae77Skettenis
159b725ae77Skettenis /* The frame base for this frame is just prev_sp + frame offset -
160b725ae77Skettenis frame size. FRAMESIZE is the size of this stack frame, and
161b725ae77Skettenis FRAMEOFFSET if the initial offset from the stack pointer (this
162b725ae77Skettenis frame's stack pointer, not PREV_SP) to the frame base. */
163b725ae77Skettenis
164b725ae77Skettenis int framesize;
165b725ae77Skettenis int frameoffset;
166b725ae77Skettenis
167b725ae77Skettenis /* The register used to hold the frame pointer for this frame. */
168b725ae77Skettenis int framereg;
169b725ae77Skettenis
170b725ae77Skettenis /* Saved register offsets. */
171b725ae77Skettenis struct trad_frame_saved_reg *saved_regs;
172b725ae77Skettenis };
173b725ae77Skettenis
174b725ae77Skettenis /* Addresses for calling Thumb functions have the bit 0 set.
175b725ae77Skettenis Here are some macros to test, set, or clear bit 0 of addresses. */
176b725ae77Skettenis #define IS_THUMB_ADDR(addr) ((addr) & 1)
177b725ae77Skettenis #define MAKE_THUMB_ADDR(addr) ((addr) | 1)
178b725ae77Skettenis #define UNMAKE_THUMB_ADDR(addr) ((addr) & ~1)
179e93f7393Sniklas
180e93f7393Sniklas /* Set to true if the 32-bit mode is in use. */
181e93f7393Sniklas
182e93f7393Sniklas int arm_apcs_32 = 1;
183e93f7393Sniklas
184b725ae77Skettenis /* Flag set by arm_fix_call_dummy that tells whether the target
185b725ae77Skettenis function is a Thumb function. This flag is checked by
186b725ae77Skettenis arm_push_arguments. FIXME: Change the PUSH_ARGUMENTS macro (and
187b725ae77Skettenis its use in valops.c) to pass the function address as an additional
188b725ae77Skettenis parameter. */
189b725ae77Skettenis
190b725ae77Skettenis static int target_is_thumb;
191b725ae77Skettenis
192b725ae77Skettenis /* Flag set by arm_fix_call_dummy that tells whether the calling
193b725ae77Skettenis function is a Thumb function. This flag is checked by
194*63addd46Skettenis arm_pc_is_thumb. */
195b725ae77Skettenis
196b725ae77Skettenis static int caller_is_thumb;
197b725ae77Skettenis
198b725ae77Skettenis /* Determine if the program counter specified in MEMADDR is in a Thumb
199b725ae77Skettenis function. */
200b725ae77Skettenis
201b725ae77Skettenis int
arm_pc_is_thumb(CORE_ADDR memaddr)202b725ae77Skettenis arm_pc_is_thumb (CORE_ADDR memaddr)
203e93f7393Sniklas {
204b725ae77Skettenis struct minimal_symbol *sym;
205b725ae77Skettenis
206b725ae77Skettenis /* If bit 0 of the address is set, assume this is a Thumb address. */
207b725ae77Skettenis if (IS_THUMB_ADDR (memaddr))
208b725ae77Skettenis return 1;
209b725ae77Skettenis
210b725ae77Skettenis /* Thumb functions have a "special" bit set in minimal symbols. */
211b725ae77Skettenis sym = lookup_minimal_symbol_by_pc (memaddr);
212b725ae77Skettenis if (sym)
213b725ae77Skettenis {
214b725ae77Skettenis return (MSYMBOL_IS_SPECIAL (sym));
215b725ae77Skettenis }
216b725ae77Skettenis else
217b725ae77Skettenis {
218b725ae77Skettenis return 0;
219b725ae77Skettenis }
220e93f7393Sniklas }
221e93f7393Sniklas
222b725ae77Skettenis /* Determine if the program counter specified in MEMADDR is in a call
223b725ae77Skettenis dummy being called from a Thumb function. */
224b725ae77Skettenis
225b725ae77Skettenis int
arm_pc_is_thumb_dummy(CORE_ADDR memaddr)226b725ae77Skettenis arm_pc_is_thumb_dummy (CORE_ADDR memaddr)
227e93f7393Sniklas {
228b725ae77Skettenis CORE_ADDR sp = read_sp ();
229b725ae77Skettenis
230b725ae77Skettenis /* FIXME: Until we switch for the new call dummy macros, this heuristic
231b725ae77Skettenis is the best we can do. We are trying to determine if the pc is on
232b725ae77Skettenis the stack, which (hopefully) will only happen in a call dummy.
233b725ae77Skettenis We hope the current stack pointer is not so far alway from the dummy
234b725ae77Skettenis frame location (true if we have not pushed large data structures or
235b725ae77Skettenis gone too many levels deep) and that our 1024 is not enough to consider
236b725ae77Skettenis code regions as part of the stack (true for most practical purposes). */
237*63addd46Skettenis if (deprecated_pc_in_call_dummy (memaddr))
238b725ae77Skettenis return caller_is_thumb;
239b725ae77Skettenis else
240b725ae77Skettenis return 0;
241e93f7393Sniklas }
242e93f7393Sniklas
243b725ae77Skettenis /* Remove useless bits from addresses in a running program. */
244b725ae77Skettenis static CORE_ADDR
arm_addr_bits_remove(CORE_ADDR val)245b725ae77Skettenis arm_addr_bits_remove (CORE_ADDR val)
246b725ae77Skettenis {
247b725ae77Skettenis if (arm_apcs_32)
248b725ae77Skettenis return (val & (arm_pc_is_thumb (val) ? 0xfffffffe : 0xfffffffc));
249b725ae77Skettenis else
250b725ae77Skettenis return (val & 0x03fffffc);
251b725ae77Skettenis }
252b725ae77Skettenis
253b725ae77Skettenis /* When reading symbols, we need to zap the low bit of the address,
254b725ae77Skettenis which may be set to 1 for Thumb functions. */
255b725ae77Skettenis static CORE_ADDR
arm_smash_text_address(CORE_ADDR val)256b725ae77Skettenis arm_smash_text_address (CORE_ADDR val)
257b725ae77Skettenis {
258b725ae77Skettenis return val & ~1;
259b725ae77Skettenis }
260b725ae77Skettenis
261b725ae77Skettenis /* Immediately after a function call, return the saved pc. Can't
262b725ae77Skettenis always go through the frames for this because on some machines the
263b725ae77Skettenis new frame is not set up until the new function executes some
264b725ae77Skettenis instructions. */
265b725ae77Skettenis
266b725ae77Skettenis static CORE_ADDR
arm_saved_pc_after_call(struct frame_info * frame)267b725ae77Skettenis arm_saved_pc_after_call (struct frame_info *frame)
268b725ae77Skettenis {
269b725ae77Skettenis return ADDR_BITS_REMOVE (read_register (ARM_LR_REGNUM));
270b725ae77Skettenis }
271b725ae77Skettenis
272b725ae77Skettenis /* A typical Thumb prologue looks like this:
273b725ae77Skettenis push {r7, lr}
274b725ae77Skettenis add sp, sp, #-28
275b725ae77Skettenis add r7, sp, #12
276b725ae77Skettenis Sometimes the latter instruction may be replaced by:
277b725ae77Skettenis mov r7, sp
278b725ae77Skettenis
279b725ae77Skettenis or like this:
280b725ae77Skettenis push {r7, lr}
281b725ae77Skettenis mov r7, sp
282b725ae77Skettenis sub sp, #12
283b725ae77Skettenis
284b725ae77Skettenis or, on tpcs, like this:
285b725ae77Skettenis sub sp,#16
286b725ae77Skettenis push {r7, lr}
287b725ae77Skettenis (many instructions)
288b725ae77Skettenis mov r7, sp
289b725ae77Skettenis sub sp, #12
290b725ae77Skettenis
291b725ae77Skettenis There is always one instruction of three classes:
292b725ae77Skettenis 1 - push
293b725ae77Skettenis 2 - setting of r7
294b725ae77Skettenis 3 - adjusting of sp
295b725ae77Skettenis
296b725ae77Skettenis When we have found at least one of each class we are done with the prolog.
297b725ae77Skettenis Note that the "sub sp, #NN" before the push does not count.
298b725ae77Skettenis */
299b725ae77Skettenis
300b725ae77Skettenis static CORE_ADDR
thumb_skip_prologue(CORE_ADDR pc,CORE_ADDR func_end)301b725ae77Skettenis thumb_skip_prologue (CORE_ADDR pc, CORE_ADDR func_end)
302b725ae77Skettenis {
303b725ae77Skettenis CORE_ADDR current_pc;
304b725ae77Skettenis /* findmask:
305b725ae77Skettenis bit 0 - push { rlist }
306b725ae77Skettenis bit 1 - mov r7, sp OR add r7, sp, #imm (setting of r7)
307b725ae77Skettenis bit 2 - sub sp, #simm OR add sp, #simm (adjusting of sp)
308b725ae77Skettenis */
309b725ae77Skettenis int findmask = 0;
310b725ae77Skettenis
311b725ae77Skettenis for (current_pc = pc;
312b725ae77Skettenis current_pc + 2 < func_end && current_pc < pc + 40;
313b725ae77Skettenis current_pc += 2)
314b725ae77Skettenis {
315b725ae77Skettenis unsigned short insn = read_memory_unsigned_integer (current_pc, 2);
316b725ae77Skettenis
317b725ae77Skettenis if ((insn & 0xfe00) == 0xb400) /* push { rlist } */
318b725ae77Skettenis {
319b725ae77Skettenis findmask |= 1; /* push found */
320b725ae77Skettenis }
321b725ae77Skettenis else if ((insn & 0xff00) == 0xb000) /* add sp, #simm OR
322b725ae77Skettenis sub sp, #simm */
323b725ae77Skettenis {
324b725ae77Skettenis if ((findmask & 1) == 0) /* before push ? */
325b725ae77Skettenis continue;
326b725ae77Skettenis else
327b725ae77Skettenis findmask |= 4; /* add/sub sp found */
328b725ae77Skettenis }
329b725ae77Skettenis else if ((insn & 0xff00) == 0xaf00) /* add r7, sp, #imm */
330b725ae77Skettenis {
331b725ae77Skettenis findmask |= 2; /* setting of r7 found */
332b725ae77Skettenis }
333b725ae77Skettenis else if (insn == 0x466f) /* mov r7, sp */
334b725ae77Skettenis {
335b725ae77Skettenis findmask |= 2; /* setting of r7 found */
336b725ae77Skettenis }
337b725ae77Skettenis else if (findmask == (4+2+1))
338b725ae77Skettenis {
339b725ae77Skettenis /* We have found one of each type of prologue instruction */
340b725ae77Skettenis break;
341b725ae77Skettenis }
342b725ae77Skettenis else
343b725ae77Skettenis /* Something in the prolog that we don't care about or some
344b725ae77Skettenis instruction from outside the prolog scheduled here for
345b725ae77Skettenis optimization. */
346b725ae77Skettenis continue;
347b725ae77Skettenis }
348b725ae77Skettenis
349b725ae77Skettenis return current_pc;
350b725ae77Skettenis }
351b725ae77Skettenis
352b725ae77Skettenis /* Advance the PC across any function entry prologue instructions to
353b725ae77Skettenis reach some "real" code.
354b725ae77Skettenis
355b725ae77Skettenis The APCS (ARM Procedure Call Standard) defines the following
356b725ae77Skettenis prologue:
357e93f7393Sniklas
358e93f7393Sniklas mov ip, sp
359e93f7393Sniklas [stmfd sp!, {a1,a2,a3,a4}]
360e93f7393Sniklas stmfd sp!, {...,fp,ip,lr,pc}
361e93f7393Sniklas [stfe f7, [sp, #-12]!]
362e93f7393Sniklas [stfe f6, [sp, #-12]!]
363e93f7393Sniklas [stfe f5, [sp, #-12]!]
364e93f7393Sniklas [stfe f4, [sp, #-12]!]
365b725ae77Skettenis sub fp, ip, #nn @@ nn == 20 or 4 depending on second insn */
366e93f7393Sniklas
367b725ae77Skettenis static CORE_ADDR
arm_skip_prologue(CORE_ADDR pc)368b725ae77Skettenis arm_skip_prologue (CORE_ADDR pc)
369e93f7393Sniklas {
370e93f7393Sniklas unsigned long inst;
371b725ae77Skettenis CORE_ADDR skip_pc;
372b725ae77Skettenis CORE_ADDR func_addr, func_end = 0;
373b725ae77Skettenis char *func_name;
374b725ae77Skettenis struct symtab_and_line sal;
375e93f7393Sniklas
376b725ae77Skettenis /* If we're in a dummy frame, don't even try to skip the prologue. */
377*63addd46Skettenis if (deprecated_pc_in_call_dummy (pc))
378e93f7393Sniklas return pc;
379e93f7393Sniklas
380b725ae77Skettenis /* See what the symbol table says. */
381b725ae77Skettenis
382b725ae77Skettenis if (find_pc_partial_function (pc, &func_name, &func_addr, &func_end))
383e93f7393Sniklas {
384b725ae77Skettenis struct symbol *sym;
385b725ae77Skettenis
386b725ae77Skettenis /* Found a function. */
387b725ae77Skettenis sym = lookup_symbol (func_name, NULL, VAR_DOMAIN, NULL, NULL);
388b725ae77Skettenis if (sym && SYMBOL_LANGUAGE (sym) != language_asm)
389b725ae77Skettenis {
390b725ae77Skettenis /* Don't use this trick for assembly source files. */
391b725ae77Skettenis sal = find_pc_line (func_addr, 0);
392b725ae77Skettenis if ((sal.line != 0) && (sal.end < func_end))
393b725ae77Skettenis return sal.end;
394b725ae77Skettenis }
395e93f7393Sniklas }
396e93f7393Sniklas
397b725ae77Skettenis /* Check if this is Thumb code. */
398b725ae77Skettenis if (arm_pc_is_thumb (pc))
399b725ae77Skettenis return thumb_skip_prologue (pc, func_end);
400e93f7393Sniklas
401b725ae77Skettenis /* Can't find the prologue end in the symbol table, try it the hard way
402b725ae77Skettenis by disassembling the instructions. */
403b725ae77Skettenis
404b725ae77Skettenis /* Like arm_scan_prologue, stop no later than pc + 64. */
405b725ae77Skettenis if (func_end == 0 || func_end > pc + 64)
406b725ae77Skettenis func_end = pc + 64;
407b725ae77Skettenis
408b725ae77Skettenis for (skip_pc = pc; skip_pc < func_end; skip_pc += 4)
409b725ae77Skettenis {
410e93f7393Sniklas inst = read_memory_integer (skip_pc, 4);
411e93f7393Sniklas
412b725ae77Skettenis /* "mov ip, sp" is no longer a required part of the prologue. */
413b725ae77Skettenis if (inst == 0xe1a0c00d) /* mov ip, sp */
414b725ae77Skettenis continue;
415b725ae77Skettenis
416b725ae77Skettenis if ((inst & 0xfffff000) == 0xe28dc000) /* add ip, sp #n */
417b725ae77Skettenis continue;
418b725ae77Skettenis
419b725ae77Skettenis if ((inst & 0xfffff000) == 0xe24dc000) /* sub ip, sp #n */
420b725ae77Skettenis continue;
421b725ae77Skettenis
422b725ae77Skettenis /* Some prologues begin with "str lr, [sp, #-4]!". */
423b725ae77Skettenis if (inst == 0xe52de004) /* str lr, [sp, #-4]! */
424b725ae77Skettenis continue;
425b725ae77Skettenis
426b725ae77Skettenis if ((inst & 0xfffffff0) == 0xe92d0000) /* stmfd sp!,{a1,a2,a3,a4} */
427b725ae77Skettenis continue;
428b725ae77Skettenis
429b725ae77Skettenis if ((inst & 0xfffff800) == 0xe92dd800) /* stmfd sp!,{fp,ip,lr,pc} */
430b725ae77Skettenis continue;
431b725ae77Skettenis
432e93f7393Sniklas /* Any insns after this point may float into the code, if it makes
433b725ae77Skettenis for better instruction scheduling, so we skip them only if we
434b725ae77Skettenis find them, but still consider the function to be frame-ful. */
435e93f7393Sniklas
436b725ae77Skettenis /* We may have either one sfmfd instruction here, or several stfe
437b725ae77Skettenis insns, depending on the version of floating point code we
438b725ae77Skettenis support. */
439e93f7393Sniklas if ((inst & 0xffbf0fff) == 0xec2d0200) /* sfmfd fn, <cnt>, [sp]! */
440b725ae77Skettenis continue;
441b725ae77Skettenis
442b725ae77Skettenis if ((inst & 0xffff8fff) == 0xed6d0103) /* stfe fn, [sp, #-12]! */
443b725ae77Skettenis continue;
444b725ae77Skettenis
445b725ae77Skettenis if ((inst & 0xfffff000) == 0xe24cb000) /* sub fp, ip, #nn */
446b725ae77Skettenis continue;
447b725ae77Skettenis
448b725ae77Skettenis if ((inst & 0xfffff000) == 0xe24dd000) /* sub sp, sp, #nn */
449b725ae77Skettenis continue;
450b725ae77Skettenis
451b725ae77Skettenis if ((inst & 0xffffc000) == 0xe54b0000 || /* strb r(0123),[r11,#-nn] */
452b725ae77Skettenis (inst & 0xffffc0f0) == 0xe14b00b0 || /* strh r(0123),[r11,#-nn] */
453b725ae77Skettenis (inst & 0xffffc000) == 0xe50b0000) /* str r(0123),[r11,#-nn] */
454b725ae77Skettenis continue;
455b725ae77Skettenis
456b725ae77Skettenis if ((inst & 0xffffc000) == 0xe5cd0000 || /* strb r(0123),[sp,#nn] */
457b725ae77Skettenis (inst & 0xffffc0f0) == 0xe1cd00b0 || /* strh r(0123),[sp,#nn] */
458b725ae77Skettenis (inst & 0xffffc000) == 0xe58d0000) /* str r(0123),[sp,#nn] */
459b725ae77Skettenis continue;
460b725ae77Skettenis
461b725ae77Skettenis /* Un-recognized instruction; stop scanning. */
462b725ae77Skettenis break;
463b725ae77Skettenis }
464b725ae77Skettenis
465b725ae77Skettenis return skip_pc; /* End of prologue */
466b725ae77Skettenis }
467b725ae77Skettenis
468b725ae77Skettenis /* *INDENT-OFF* */
469b725ae77Skettenis /* Function: thumb_scan_prologue (helper function for arm_scan_prologue)
470b725ae77Skettenis This function decodes a Thumb function prologue to determine:
471b725ae77Skettenis 1) the size of the stack frame
472b725ae77Skettenis 2) which registers are saved on it
473b725ae77Skettenis 3) the offsets of saved regs
474b725ae77Skettenis 4) the offset from the stack pointer to the frame pointer
475b725ae77Skettenis
476b725ae77Skettenis A typical Thumb function prologue would create this stack frame
477b725ae77Skettenis (offsets relative to FP)
478b725ae77Skettenis old SP -> 24 stack parameters
479b725ae77Skettenis 20 LR
480b725ae77Skettenis 16 R7
481b725ae77Skettenis R7 -> 0 local variables (16 bytes)
482b725ae77Skettenis SP -> -12 additional stack space (12 bytes)
483b725ae77Skettenis The frame size would thus be 36 bytes, and the frame offset would be
484b725ae77Skettenis 12 bytes. The frame register is R7.
485b725ae77Skettenis
486b725ae77Skettenis The comments for thumb_skip_prolog() describe the algorithm we use
487b725ae77Skettenis to detect the end of the prolog. */
488b725ae77Skettenis /* *INDENT-ON* */
489b725ae77Skettenis
490b725ae77Skettenis static void
thumb_scan_prologue(CORE_ADDR prev_pc,struct arm_prologue_cache * cache)491b725ae77Skettenis thumb_scan_prologue (CORE_ADDR prev_pc, struct arm_prologue_cache *cache)
492e93f7393Sniklas {
493b725ae77Skettenis CORE_ADDR prologue_start;
494b725ae77Skettenis CORE_ADDR prologue_end;
495b725ae77Skettenis CORE_ADDR current_pc;
496b725ae77Skettenis /* Which register has been copied to register n? */
497b725ae77Skettenis int saved_reg[16];
498b725ae77Skettenis /* findmask:
499b725ae77Skettenis bit 0 - push { rlist }
500b725ae77Skettenis bit 1 - mov r7, sp OR add r7, sp, #imm (setting of r7)
501b725ae77Skettenis bit 2 - sub sp, #simm OR add sp, #simm (adjusting of sp)
502b725ae77Skettenis */
503b725ae77Skettenis int findmask = 0;
504b725ae77Skettenis int i;
505b725ae77Skettenis
506b725ae77Skettenis if (find_pc_partial_function (prev_pc, NULL, &prologue_start, &prologue_end))
507b725ae77Skettenis {
508b725ae77Skettenis struct symtab_and_line sal = find_pc_line (prologue_start, 0);
509b725ae77Skettenis
510b725ae77Skettenis if (sal.line == 0) /* no line info, use current PC */
511b725ae77Skettenis prologue_end = prev_pc;
512b725ae77Skettenis else if (sal.end < prologue_end) /* next line begins after fn end */
513b725ae77Skettenis prologue_end = sal.end; /* (probably means no prologue) */
514b725ae77Skettenis }
515b725ae77Skettenis else
516b725ae77Skettenis /* We're in the boondocks: allow for
517b725ae77Skettenis 16 pushes, an add, and "mv fp,sp". */
518b725ae77Skettenis prologue_end = prologue_start + 40;
519b725ae77Skettenis
520b725ae77Skettenis prologue_end = min (prologue_end, prev_pc);
521b725ae77Skettenis
522b725ae77Skettenis /* Initialize the saved register map. When register H is copied to
523b725ae77Skettenis register L, we will put H in saved_reg[L]. */
524b725ae77Skettenis for (i = 0; i < 16; i++)
525b725ae77Skettenis saved_reg[i] = i;
526b725ae77Skettenis
527b725ae77Skettenis /* Search the prologue looking for instructions that set up the
528b725ae77Skettenis frame pointer, adjust the stack pointer, and save registers.
529b725ae77Skettenis Do this until all basic prolog instructions are found. */
530b725ae77Skettenis
531b725ae77Skettenis cache->framesize = 0;
532b725ae77Skettenis for (current_pc = prologue_start;
533b725ae77Skettenis (current_pc < prologue_end) && ((findmask & 7) != 7);
534b725ae77Skettenis current_pc += 2)
535b725ae77Skettenis {
536b725ae77Skettenis unsigned short insn;
537b725ae77Skettenis int regno;
538b725ae77Skettenis int offset;
539b725ae77Skettenis
540b725ae77Skettenis insn = read_memory_unsigned_integer (current_pc, 2);
541b725ae77Skettenis
542b725ae77Skettenis if ((insn & 0xfe00) == 0xb400) /* push { rlist } */
543b725ae77Skettenis {
544b725ae77Skettenis int mask;
545b725ae77Skettenis findmask |= 1; /* push found */
546b725ae77Skettenis /* Bits 0-7 contain a mask for registers R0-R7. Bit 8 says
547b725ae77Skettenis whether to save LR (R14). */
548b725ae77Skettenis mask = (insn & 0xff) | ((insn & 0x100) << 6);
549b725ae77Skettenis
550b725ae77Skettenis /* Calculate offsets of saved R0-R7 and LR. */
551b725ae77Skettenis for (regno = ARM_LR_REGNUM; regno >= 0; regno--)
552b725ae77Skettenis if (mask & (1 << regno))
553b725ae77Skettenis {
554b725ae77Skettenis cache->framesize += 4;
555b725ae77Skettenis cache->saved_regs[saved_reg[regno]].addr = -cache->framesize;
556b725ae77Skettenis /* Reset saved register map. */
557b725ae77Skettenis saved_reg[regno] = regno;
558b725ae77Skettenis }
559b725ae77Skettenis }
560b725ae77Skettenis else if ((insn & 0xff00) == 0xb000) /* add sp, #simm OR
561b725ae77Skettenis sub sp, #simm */
562b725ae77Skettenis {
563b725ae77Skettenis if ((findmask & 1) == 0) /* before push? */
564b725ae77Skettenis continue;
565b725ae77Skettenis else
566b725ae77Skettenis findmask |= 4; /* add/sub sp found */
567b725ae77Skettenis
568b725ae77Skettenis offset = (insn & 0x7f) << 2; /* get scaled offset */
569b725ae77Skettenis if (insn & 0x80) /* is it signed? (==subtracting) */
570b725ae77Skettenis {
571b725ae77Skettenis cache->frameoffset += offset;
572b725ae77Skettenis offset = -offset;
573b725ae77Skettenis }
574b725ae77Skettenis cache->framesize -= offset;
575b725ae77Skettenis }
576b725ae77Skettenis else if ((insn & 0xff00) == 0xaf00) /* add r7, sp, #imm */
577b725ae77Skettenis {
578b725ae77Skettenis findmask |= 2; /* setting of r7 found */
579b725ae77Skettenis cache->framereg = THUMB_FP_REGNUM;
580b725ae77Skettenis /* get scaled offset */
581b725ae77Skettenis cache->frameoffset = (insn & 0xff) << 2;
582b725ae77Skettenis }
583b725ae77Skettenis else if (insn == 0x466f) /* mov r7, sp */
584b725ae77Skettenis {
585b725ae77Skettenis findmask |= 2; /* setting of r7 found */
586b725ae77Skettenis cache->framereg = THUMB_FP_REGNUM;
587b725ae77Skettenis cache->frameoffset = 0;
588b725ae77Skettenis saved_reg[THUMB_FP_REGNUM] = ARM_SP_REGNUM;
589b725ae77Skettenis }
590b725ae77Skettenis else if ((insn & 0xffc0) == 0x4640) /* mov r0-r7, r8-r15 */
591b725ae77Skettenis {
592b725ae77Skettenis int lo_reg = insn & 7; /* dest. register (r0-r7) */
593b725ae77Skettenis int hi_reg = ((insn >> 3) & 7) + 8; /* source register (r8-15) */
594b725ae77Skettenis saved_reg[lo_reg] = hi_reg; /* remember hi reg was saved */
595b725ae77Skettenis }
596b725ae77Skettenis else
597b725ae77Skettenis /* Something in the prolog that we don't care about or some
598b725ae77Skettenis instruction from outside the prolog scheduled here for
599b725ae77Skettenis optimization. */
600b725ae77Skettenis continue;
601b725ae77Skettenis }
602b725ae77Skettenis }
603b725ae77Skettenis
604b725ae77Skettenis /* This function decodes an ARM function prologue to determine:
605b725ae77Skettenis 1) the size of the stack frame
606b725ae77Skettenis 2) which registers are saved on it
607b725ae77Skettenis 3) the offsets of saved regs
608b725ae77Skettenis 4) the offset from the stack pointer to the frame pointer
609b725ae77Skettenis This information is stored in the "extra" fields of the frame_info.
610b725ae77Skettenis
611b725ae77Skettenis There are two basic forms for the ARM prologue. The fixed argument
612b725ae77Skettenis function call will look like:
613b725ae77Skettenis
614b725ae77Skettenis mov ip, sp
615b725ae77Skettenis stmfd sp!, {fp, ip, lr, pc}
616b725ae77Skettenis sub fp, ip, #4
617b725ae77Skettenis [sub sp, sp, #4]
618b725ae77Skettenis
619b725ae77Skettenis Which would create this stack frame (offsets relative to FP):
620b725ae77Skettenis IP -> 4 (caller's stack)
621b725ae77Skettenis FP -> 0 PC (points to address of stmfd instruction + 8 in callee)
622b725ae77Skettenis -4 LR (return address in caller)
623b725ae77Skettenis -8 IP (copy of caller's SP)
624b725ae77Skettenis -12 FP (caller's FP)
625b725ae77Skettenis SP -> -28 Local variables
626b725ae77Skettenis
627b725ae77Skettenis The frame size would thus be 32 bytes, and the frame offset would be
628b725ae77Skettenis 28 bytes. The stmfd call can also save any of the vN registers it
629b725ae77Skettenis plans to use, which increases the frame size accordingly.
630b725ae77Skettenis
631b725ae77Skettenis Note: The stored PC is 8 off of the STMFD instruction that stored it
632b725ae77Skettenis because the ARM Store instructions always store PC + 8 when you read
633b725ae77Skettenis the PC register.
634b725ae77Skettenis
635b725ae77Skettenis A variable argument function call will look like:
636b725ae77Skettenis
637b725ae77Skettenis mov ip, sp
638b725ae77Skettenis stmfd sp!, {a1, a2, a3, a4}
639b725ae77Skettenis stmfd sp!, {fp, ip, lr, pc}
640b725ae77Skettenis sub fp, ip, #20
641b725ae77Skettenis
642b725ae77Skettenis Which would create this stack frame (offsets relative to FP):
643b725ae77Skettenis IP -> 20 (caller's stack)
644b725ae77Skettenis 16 A4
645b725ae77Skettenis 12 A3
646b725ae77Skettenis 8 A2
647b725ae77Skettenis 4 A1
648b725ae77Skettenis FP -> 0 PC (points to address of stmfd instruction + 8 in callee)
649b725ae77Skettenis -4 LR (return address in caller)
650b725ae77Skettenis -8 IP (copy of caller's SP)
651b725ae77Skettenis -12 FP (caller's FP)
652b725ae77Skettenis SP -> -28 Local variables
653b725ae77Skettenis
654b725ae77Skettenis The frame size would thus be 48 bytes, and the frame offset would be
655b725ae77Skettenis 28 bytes.
656b725ae77Skettenis
657b725ae77Skettenis There is another potential complication, which is that the optimizer
658b725ae77Skettenis will try to separate the store of fp in the "stmfd" instruction from
659b725ae77Skettenis the "sub fp, ip, #NN" instruction. Almost anything can be there, so
660b725ae77Skettenis we just key on the stmfd, and then scan for the "sub fp, ip, #NN"...
661b725ae77Skettenis
662b725ae77Skettenis Also, note, the original version of the ARM toolchain claimed that there
663b725ae77Skettenis should be an
664b725ae77Skettenis
665b725ae77Skettenis instruction at the end of the prologue. I have never seen GCC produce
666b725ae77Skettenis this, and the ARM docs don't mention it. We still test for it below in
667b725ae77Skettenis case it happens...
668b725ae77Skettenis
669b725ae77Skettenis */
670b725ae77Skettenis
671b725ae77Skettenis static void
arm_scan_prologue(struct frame_info * next_frame,struct arm_prologue_cache * cache)672b725ae77Skettenis arm_scan_prologue (struct frame_info *next_frame, struct arm_prologue_cache *cache)
673b725ae77Skettenis {
674b725ae77Skettenis int regno, sp_offset, fp_offset, ip_offset;
675b725ae77Skettenis CORE_ADDR prologue_start, prologue_end, current_pc;
676b725ae77Skettenis CORE_ADDR prev_pc = frame_pc_unwind (next_frame);
677b725ae77Skettenis
678b725ae77Skettenis /* Assume there is no frame until proven otherwise. */
679b725ae77Skettenis cache->framereg = ARM_SP_REGNUM;
680b725ae77Skettenis cache->framesize = 0;
681b725ae77Skettenis cache->frameoffset = 0;
682b725ae77Skettenis
683b725ae77Skettenis /* Check for Thumb prologue. */
684b725ae77Skettenis if (arm_pc_is_thumb (prev_pc))
685b725ae77Skettenis {
686b725ae77Skettenis thumb_scan_prologue (prev_pc, cache);
687b725ae77Skettenis return;
688b725ae77Skettenis }
689b725ae77Skettenis
690b725ae77Skettenis /* Find the function prologue. If we can't find the function in
691b725ae77Skettenis the symbol table, peek in the stack frame to find the PC. */
692b725ae77Skettenis if (find_pc_partial_function (prev_pc, NULL, &prologue_start, &prologue_end))
693b725ae77Skettenis {
694b725ae77Skettenis /* One way to find the end of the prologue (which works well
695b725ae77Skettenis for unoptimized code) is to do the following:
696b725ae77Skettenis
697b725ae77Skettenis struct symtab_and_line sal = find_pc_line (prologue_start, 0);
698b725ae77Skettenis
699b725ae77Skettenis if (sal.line == 0)
700b725ae77Skettenis prologue_end = prev_pc;
701b725ae77Skettenis else if (sal.end < prologue_end)
702b725ae77Skettenis prologue_end = sal.end;
703b725ae77Skettenis
704b725ae77Skettenis This mechanism is very accurate so long as the optimizer
705b725ae77Skettenis doesn't move any instructions from the function body into the
706b725ae77Skettenis prologue. If this happens, sal.end will be the last
707b725ae77Skettenis instruction in the first hunk of prologue code just before
708b725ae77Skettenis the first instruction that the scheduler has moved from
709b725ae77Skettenis the body to the prologue.
710b725ae77Skettenis
711b725ae77Skettenis In order to make sure that we scan all of the prologue
712b725ae77Skettenis instructions, we use a slightly less accurate mechanism which
713b725ae77Skettenis may scan more than necessary. To help compensate for this
714b725ae77Skettenis lack of accuracy, the prologue scanning loop below contains
715b725ae77Skettenis several clauses which'll cause the loop to terminate early if
716b725ae77Skettenis an implausible prologue instruction is encountered.
717b725ae77Skettenis
718b725ae77Skettenis The expression
719b725ae77Skettenis
720b725ae77Skettenis prologue_start + 64
721b725ae77Skettenis
722b725ae77Skettenis is a suitable endpoint since it accounts for the largest
723b725ae77Skettenis possible prologue plus up to five instructions inserted by
724b725ae77Skettenis the scheduler. */
725b725ae77Skettenis
726b725ae77Skettenis if (prologue_end > prologue_start + 64)
727b725ae77Skettenis {
728b725ae77Skettenis prologue_end = prologue_start + 64; /* See above. */
729b725ae77Skettenis }
730e93f7393Sniklas }
731e93f7393Sniklas else
732e93f7393Sniklas {
733b725ae77Skettenis /* We have no symbol information. Our only option is to assume this
734b725ae77Skettenis function has a standard stack frame and the normal frame register.
735b725ae77Skettenis Then, we can find the value of our frame pointer on entrance to
736b725ae77Skettenis the callee (or at the present moment if this is the innermost frame).
737b725ae77Skettenis The value stored there should be the address of the stmfd + 8. */
738b725ae77Skettenis CORE_ADDR frame_loc;
739b725ae77Skettenis LONGEST return_value;
740b725ae77Skettenis
741b725ae77Skettenis frame_loc = frame_unwind_register_unsigned (next_frame, ARM_FP_REGNUM);
742b725ae77Skettenis if (!safe_read_memory_integer (frame_loc, 4, &return_value))
743b725ae77Skettenis return;
744b725ae77Skettenis else
745e93f7393Sniklas {
746b725ae77Skettenis prologue_start = ADDR_BITS_REMOVE (return_value) - 8;
747b725ae77Skettenis prologue_end = prologue_start + 64; /* See above. */
748e93f7393Sniklas }
749e93f7393Sniklas }
750e93f7393Sniklas
751b725ae77Skettenis if (prev_pc < prologue_end)
752b725ae77Skettenis prologue_end = prev_pc;
753e93f7393Sniklas
754b725ae77Skettenis /* Now search the prologue looking for instructions that set up the
755b725ae77Skettenis frame pointer, adjust the stack pointer, and save registers.
756b725ae77Skettenis
757b725ae77Skettenis Be careful, however, and if it doesn't look like a prologue,
758b725ae77Skettenis don't try to scan it. If, for instance, a frameless function
759b725ae77Skettenis begins with stmfd sp!, then we will tell ourselves there is
760b725ae77Skettenis a frame, which will confuse stack traceback, as well as "finish"
761b725ae77Skettenis and other operations that rely on a knowledge of the stack
762b725ae77Skettenis traceback.
763b725ae77Skettenis
764b725ae77Skettenis In the APCS, the prologue should start with "mov ip, sp" so
765b725ae77Skettenis if we don't see this as the first insn, we will stop.
766b725ae77Skettenis
767b725ae77Skettenis [Note: This doesn't seem to be true any longer, so it's now an
768b725ae77Skettenis optional part of the prologue. - Kevin Buettner, 2001-11-20]
769b725ae77Skettenis
770b725ae77Skettenis [Note further: The "mov ip,sp" only seems to be missing in
771b725ae77Skettenis frameless functions at optimization level "-O2" or above,
772b725ae77Skettenis in which case it is often (but not always) replaced by
773b725ae77Skettenis "str lr, [sp, #-4]!". - Michael Snyder, 2002-04-23] */
774b725ae77Skettenis
775b725ae77Skettenis sp_offset = fp_offset = ip_offset = 0;
776b725ae77Skettenis
777b725ae77Skettenis for (current_pc = prologue_start;
778b725ae77Skettenis current_pc < prologue_end;
779b725ae77Skettenis current_pc += 4)
780b725ae77Skettenis {
781b725ae77Skettenis unsigned int insn = read_memory_unsigned_integer (current_pc, 4);
782b725ae77Skettenis
783b725ae77Skettenis if (insn == 0xe1a0c00d) /* mov ip, sp */
784b725ae77Skettenis {
785b725ae77Skettenis ip_offset = 0;
786b725ae77Skettenis continue;
787b725ae77Skettenis }
788b725ae77Skettenis else if ((insn & 0xfffff000) == 0xe28dc000) /* add ip, sp #n */
789b725ae77Skettenis {
790b725ae77Skettenis unsigned imm = insn & 0xff; /* immediate value */
791b725ae77Skettenis unsigned rot = (insn & 0xf00) >> 7; /* rotate amount */
792b725ae77Skettenis imm = (imm >> rot) | (imm << (32 - rot));
793b725ae77Skettenis ip_offset = imm;
794b725ae77Skettenis continue;
795b725ae77Skettenis }
796b725ae77Skettenis else if ((insn & 0xfffff000) == 0xe24dc000) /* sub ip, sp #n */
797b725ae77Skettenis {
798b725ae77Skettenis unsigned imm = insn & 0xff; /* immediate value */
799b725ae77Skettenis unsigned rot = (insn & 0xf00) >> 7; /* rotate amount */
800b725ae77Skettenis imm = (imm >> rot) | (imm << (32 - rot));
801b725ae77Skettenis ip_offset = -imm;
802b725ae77Skettenis continue;
803b725ae77Skettenis }
804b725ae77Skettenis else if (insn == 0xe52de004) /* str lr, [sp, #-4]! */
805b725ae77Skettenis {
806b725ae77Skettenis sp_offset -= 4;
807b725ae77Skettenis cache->saved_regs[ARM_LR_REGNUM].addr = sp_offset;
808b725ae77Skettenis continue;
809b725ae77Skettenis }
810b725ae77Skettenis else if ((insn & 0xffff0000) == 0xe92d0000)
811b725ae77Skettenis /* stmfd sp!, {..., fp, ip, lr, pc}
812b725ae77Skettenis or
813b725ae77Skettenis stmfd sp!, {a1, a2, a3, a4} */
814b725ae77Skettenis {
815b725ae77Skettenis int mask = insn & 0xffff;
816b725ae77Skettenis
817b725ae77Skettenis /* Calculate offsets of saved registers. */
818b725ae77Skettenis for (regno = ARM_PC_REGNUM; regno >= 0; regno--)
819b725ae77Skettenis if (mask & (1 << regno))
820b725ae77Skettenis {
821b725ae77Skettenis sp_offset -= 4;
822b725ae77Skettenis cache->saved_regs[regno].addr = sp_offset;
823b725ae77Skettenis }
824b725ae77Skettenis }
825b725ae77Skettenis else if ((insn & 0xffffc000) == 0xe54b0000 || /* strb rx,[r11,#-n] */
826b725ae77Skettenis (insn & 0xffffc0f0) == 0xe14b00b0 || /* strh rx,[r11,#-n] */
827b725ae77Skettenis (insn & 0xffffc000) == 0xe50b0000) /* str rx,[r11,#-n] */
828b725ae77Skettenis {
829b725ae77Skettenis /* No need to add this to saved_regs -- it's just an arg reg. */
830b725ae77Skettenis continue;
831b725ae77Skettenis }
832b725ae77Skettenis else if ((insn & 0xffffc000) == 0xe5cd0000 || /* strb rx,[sp,#n] */
833b725ae77Skettenis (insn & 0xffffc0f0) == 0xe1cd00b0 || /* strh rx,[sp,#n] */
834b725ae77Skettenis (insn & 0xffffc000) == 0xe58d0000) /* str rx,[sp,#n] */
835b725ae77Skettenis {
836b725ae77Skettenis /* No need to add this to saved_regs -- it's just an arg reg. */
837b725ae77Skettenis continue;
838b725ae77Skettenis }
839b725ae77Skettenis else if ((insn & 0xfffff000) == 0xe24cb000) /* sub fp, ip #n */
840b725ae77Skettenis {
841b725ae77Skettenis unsigned imm = insn & 0xff; /* immediate value */
842b725ae77Skettenis unsigned rot = (insn & 0xf00) >> 7; /* rotate amount */
843b725ae77Skettenis imm = (imm >> rot) | (imm << (32 - rot));
844b725ae77Skettenis fp_offset = -imm + ip_offset;
845b725ae77Skettenis cache->framereg = ARM_FP_REGNUM;
846b725ae77Skettenis }
847b725ae77Skettenis else if ((insn & 0xfffff000) == 0xe24dd000) /* sub sp, sp #n */
848b725ae77Skettenis {
849b725ae77Skettenis unsigned imm = insn & 0xff; /* immediate value */
850b725ae77Skettenis unsigned rot = (insn & 0xf00) >> 7; /* rotate amount */
851b725ae77Skettenis imm = (imm >> rot) | (imm << (32 - rot));
852b725ae77Skettenis sp_offset -= imm;
853b725ae77Skettenis }
854b725ae77Skettenis else if ((insn & 0xffff7fff) == 0xed6d0103) /* stfe f?, [sp, -#c]! */
855b725ae77Skettenis {
856b725ae77Skettenis sp_offset -= 12;
857b725ae77Skettenis regno = ARM_F0_REGNUM + ((insn >> 12) & 0x07);
858b725ae77Skettenis cache->saved_regs[regno].addr = sp_offset;
859b725ae77Skettenis }
860b725ae77Skettenis else if ((insn & 0xffbf0fff) == 0xec2d0200) /* sfmfd f0, 4, [sp!] */
861b725ae77Skettenis {
862b725ae77Skettenis int n_saved_fp_regs;
863b725ae77Skettenis unsigned int fp_start_reg, fp_bound_reg;
864b725ae77Skettenis
865b725ae77Skettenis if ((insn & 0x800) == 0x800) /* N0 is set */
866b725ae77Skettenis {
867b725ae77Skettenis if ((insn & 0x40000) == 0x40000) /* N1 is set */
868b725ae77Skettenis n_saved_fp_regs = 3;
869b725ae77Skettenis else
870b725ae77Skettenis n_saved_fp_regs = 1;
871b725ae77Skettenis }
872b725ae77Skettenis else
873b725ae77Skettenis {
874b725ae77Skettenis if ((insn & 0x40000) == 0x40000) /* N1 is set */
875b725ae77Skettenis n_saved_fp_regs = 2;
876b725ae77Skettenis else
877b725ae77Skettenis n_saved_fp_regs = 4;
878e93f7393Sniklas }
879e93f7393Sniklas
880b725ae77Skettenis fp_start_reg = ARM_F0_REGNUM + ((insn >> 12) & 0x7);
881b725ae77Skettenis fp_bound_reg = fp_start_reg + n_saved_fp_regs;
882b725ae77Skettenis for (; fp_start_reg < fp_bound_reg; fp_start_reg++)
883e93f7393Sniklas {
884b725ae77Skettenis sp_offset -= 12;
885b725ae77Skettenis cache->saved_regs[fp_start_reg++].addr = sp_offset;
886e93f7393Sniklas }
887e93f7393Sniklas }
888b725ae77Skettenis else if ((insn & 0xf0000000) != 0xe0000000)
889b725ae77Skettenis break; /* Condition not true, exit early */
890b725ae77Skettenis else if ((insn & 0xfe200000) == 0xe8200000) /* ldm? */
891b725ae77Skettenis break; /* Don't scan past a block load */
892b725ae77Skettenis else
893b725ae77Skettenis /* The optimizer might shove anything into the prologue,
894b725ae77Skettenis so we just skip what we don't recognize. */
895b725ae77Skettenis continue;
896e93f7393Sniklas }
897e93f7393Sniklas
898b725ae77Skettenis /* The frame size is just the negative of the offset (from the
899b725ae77Skettenis original SP) of the last thing thing we pushed on the stack.
900b725ae77Skettenis The frame offset is [new FP] - [new SP]. */
901b725ae77Skettenis cache->framesize = -sp_offset;
902b725ae77Skettenis if (cache->framereg == ARM_FP_REGNUM)
903b725ae77Skettenis cache->frameoffset = fp_offset - sp_offset;
904b725ae77Skettenis else
905b725ae77Skettenis cache->frameoffset = 0;
906e93f7393Sniklas }
907e93f7393Sniklas
908b725ae77Skettenis static struct arm_prologue_cache *
arm_make_prologue_cache(struct frame_info * next_frame)909b725ae77Skettenis arm_make_prologue_cache (struct frame_info *next_frame)
910e93f7393Sniklas {
911b725ae77Skettenis int reg;
912b725ae77Skettenis struct arm_prologue_cache *cache;
913b725ae77Skettenis CORE_ADDR unwound_fp;
914e93f7393Sniklas
915b725ae77Skettenis cache = frame_obstack_zalloc (sizeof (struct arm_prologue_cache));
916b725ae77Skettenis cache->saved_regs = trad_frame_alloc_saved_regs (next_frame);
917b725ae77Skettenis
918b725ae77Skettenis arm_scan_prologue (next_frame, cache);
919b725ae77Skettenis
920b725ae77Skettenis unwound_fp = frame_unwind_register_unsigned (next_frame, cache->framereg);
921b725ae77Skettenis if (unwound_fp == 0)
922b725ae77Skettenis return cache;
923b725ae77Skettenis
924b725ae77Skettenis cache->prev_sp = unwound_fp + cache->framesize - cache->frameoffset;
925b725ae77Skettenis
926b725ae77Skettenis /* Calculate actual addresses of saved registers using offsets
927b725ae77Skettenis determined by arm_scan_prologue. */
928b725ae77Skettenis for (reg = 0; reg < NUM_REGS; reg++)
929b725ae77Skettenis if (trad_frame_addr_p (cache->saved_regs, reg))
930b725ae77Skettenis cache->saved_regs[reg].addr += cache->prev_sp;
931b725ae77Skettenis
932b725ae77Skettenis return cache;
933e93f7393Sniklas }
934b725ae77Skettenis
935b725ae77Skettenis /* Our frame ID for a normal frame is the current function's starting PC
936b725ae77Skettenis and the caller's SP when we were called. */
937b725ae77Skettenis
938b725ae77Skettenis static void
arm_prologue_this_id(struct frame_info * next_frame,void ** this_cache,struct frame_id * this_id)939b725ae77Skettenis arm_prologue_this_id (struct frame_info *next_frame,
940b725ae77Skettenis void **this_cache,
941b725ae77Skettenis struct frame_id *this_id)
942b725ae77Skettenis {
943b725ae77Skettenis struct arm_prologue_cache *cache;
944b725ae77Skettenis struct frame_id id;
945b725ae77Skettenis CORE_ADDR func;
946b725ae77Skettenis
947b725ae77Skettenis if (*this_cache == NULL)
948b725ae77Skettenis *this_cache = arm_make_prologue_cache (next_frame);
949b725ae77Skettenis cache = *this_cache;
950b725ae77Skettenis
951b725ae77Skettenis func = frame_func_unwind (next_frame);
952b725ae77Skettenis
953b725ae77Skettenis /* This is meant to halt the backtrace at "_start". Make sure we
954b725ae77Skettenis don't halt it at a generic dummy frame. */
955b725ae77Skettenis if (func <= LOWEST_PC)
956b725ae77Skettenis return;
957b725ae77Skettenis
958b725ae77Skettenis /* If we've hit a wall, stop. */
959b725ae77Skettenis if (cache->prev_sp == 0)
960b725ae77Skettenis return;
961b725ae77Skettenis
962b725ae77Skettenis id = frame_id_build (cache->prev_sp, func);
963b725ae77Skettenis *this_id = id;
964e93f7393Sniklas }
965e93f7393Sniklas
966e93f7393Sniklas static void
arm_prologue_prev_register(struct frame_info * next_frame,void ** this_cache,int prev_regnum,int * optimized,enum lval_type * lvalp,CORE_ADDR * addrp,int * realnump,void * valuep)967b725ae77Skettenis arm_prologue_prev_register (struct frame_info *next_frame,
968b725ae77Skettenis void **this_cache,
969b725ae77Skettenis int prev_regnum,
970b725ae77Skettenis int *optimized,
971b725ae77Skettenis enum lval_type *lvalp,
972b725ae77Skettenis CORE_ADDR *addrp,
973b725ae77Skettenis int *realnump,
974b725ae77Skettenis void *valuep)
975e93f7393Sniklas {
976b725ae77Skettenis struct arm_prologue_cache *cache;
977b725ae77Skettenis
978b725ae77Skettenis if (*this_cache == NULL)
979b725ae77Skettenis *this_cache = arm_make_prologue_cache (next_frame);
980b725ae77Skettenis cache = *this_cache;
981b725ae77Skettenis
982b725ae77Skettenis /* If we are asked to unwind the PC, then we need to return the LR
983b725ae77Skettenis instead. The saved value of PC points into this frame's
984b725ae77Skettenis prologue, not the next frame's resume location. */
985b725ae77Skettenis if (prev_regnum == ARM_PC_REGNUM)
986b725ae77Skettenis prev_regnum = ARM_LR_REGNUM;
987b725ae77Skettenis
988b725ae77Skettenis /* SP is generally not saved to the stack, but this frame is
989b725ae77Skettenis identified by NEXT_FRAME's stack pointer at the time of the call.
990b725ae77Skettenis The value was already reconstructed into PREV_SP. */
991b725ae77Skettenis if (prev_regnum == ARM_SP_REGNUM)
992b725ae77Skettenis {
993b725ae77Skettenis *lvalp = not_lval;
994b725ae77Skettenis if (valuep)
995b725ae77Skettenis store_unsigned_integer (valuep, 4, cache->prev_sp);
996b725ae77Skettenis return;
997b725ae77Skettenis }
998b725ae77Skettenis
999*63addd46Skettenis trad_frame_get_prev_register (next_frame, cache->saved_regs, prev_regnum,
1000b725ae77Skettenis optimized, lvalp, addrp, realnump, valuep);
1001b725ae77Skettenis }
1002b725ae77Skettenis
1003b725ae77Skettenis struct frame_unwind arm_prologue_unwind = {
1004b725ae77Skettenis NORMAL_FRAME,
1005b725ae77Skettenis arm_prologue_this_id,
1006b725ae77Skettenis arm_prologue_prev_register
1007b725ae77Skettenis };
1008b725ae77Skettenis
1009b725ae77Skettenis static const struct frame_unwind *
arm_prologue_unwind_sniffer(struct frame_info * next_frame)1010b725ae77Skettenis arm_prologue_unwind_sniffer (struct frame_info *next_frame)
1011b725ae77Skettenis {
1012b725ae77Skettenis return &arm_prologue_unwind;
1013b725ae77Skettenis }
1014b725ae77Skettenis
1015b725ae77Skettenis static CORE_ADDR
arm_normal_frame_base(struct frame_info * next_frame,void ** this_cache)1016b725ae77Skettenis arm_normal_frame_base (struct frame_info *next_frame, void **this_cache)
1017b725ae77Skettenis {
1018b725ae77Skettenis struct arm_prologue_cache *cache;
1019b725ae77Skettenis
1020b725ae77Skettenis if (*this_cache == NULL)
1021b725ae77Skettenis *this_cache = arm_make_prologue_cache (next_frame);
1022b725ae77Skettenis cache = *this_cache;
1023b725ae77Skettenis
1024b725ae77Skettenis return cache->prev_sp + cache->frameoffset - cache->framesize;
1025b725ae77Skettenis }
1026b725ae77Skettenis
1027b725ae77Skettenis struct frame_base arm_normal_base = {
1028b725ae77Skettenis &arm_prologue_unwind,
1029b725ae77Skettenis arm_normal_frame_base,
1030b725ae77Skettenis arm_normal_frame_base,
1031b725ae77Skettenis arm_normal_frame_base
1032b725ae77Skettenis };
1033b725ae77Skettenis
1034b725ae77Skettenis static struct arm_prologue_cache *
arm_make_sigtramp_cache(struct frame_info * next_frame)1035b725ae77Skettenis arm_make_sigtramp_cache (struct frame_info *next_frame)
1036b725ae77Skettenis {
1037b725ae77Skettenis struct arm_prologue_cache *cache;
1038b725ae77Skettenis int reg;
1039b725ae77Skettenis
1040b725ae77Skettenis cache = frame_obstack_zalloc (sizeof (struct arm_prologue_cache));
1041b725ae77Skettenis
1042b725ae77Skettenis cache->prev_sp = frame_unwind_register_unsigned (next_frame, ARM_SP_REGNUM);
1043b725ae77Skettenis
1044b725ae77Skettenis cache->saved_regs = trad_frame_alloc_saved_regs (next_frame);
1045b725ae77Skettenis
1046b725ae77Skettenis for (reg = 0; reg < NUM_REGS; reg++)
1047b725ae77Skettenis cache->saved_regs[reg].addr
1048b725ae77Skettenis = SIGCONTEXT_REGISTER_ADDRESS (cache->prev_sp,
1049b725ae77Skettenis frame_pc_unwind (next_frame), reg);
1050b725ae77Skettenis
1051b725ae77Skettenis /* FIXME: What about thumb mode? */
1052b725ae77Skettenis cache->framereg = ARM_SP_REGNUM;
1053b725ae77Skettenis cache->prev_sp
1054b725ae77Skettenis = read_memory_integer (cache->saved_regs[cache->framereg].addr,
1055b725ae77Skettenis register_size (current_gdbarch, cache->framereg));
1056b725ae77Skettenis
1057b725ae77Skettenis return cache;
1058b725ae77Skettenis }
1059b725ae77Skettenis
1060b725ae77Skettenis static void
arm_sigtramp_this_id(struct frame_info * next_frame,void ** this_cache,struct frame_id * this_id)1061b725ae77Skettenis arm_sigtramp_this_id (struct frame_info *next_frame,
1062b725ae77Skettenis void **this_cache,
1063b725ae77Skettenis struct frame_id *this_id)
1064b725ae77Skettenis {
1065b725ae77Skettenis struct arm_prologue_cache *cache;
1066b725ae77Skettenis
1067b725ae77Skettenis if (*this_cache == NULL)
1068b725ae77Skettenis *this_cache = arm_make_sigtramp_cache (next_frame);
1069b725ae77Skettenis cache = *this_cache;
1070b725ae77Skettenis
1071b725ae77Skettenis /* FIXME drow/2003-07-07: This isn't right if we single-step within
1072b725ae77Skettenis the sigtramp frame; the PC should be the beginning of the trampoline. */
1073b725ae77Skettenis *this_id = frame_id_build (cache->prev_sp, frame_pc_unwind (next_frame));
1074b725ae77Skettenis }
1075b725ae77Skettenis
1076b725ae77Skettenis static void
arm_sigtramp_prev_register(struct frame_info * next_frame,void ** this_cache,int prev_regnum,int * optimized,enum lval_type * lvalp,CORE_ADDR * addrp,int * realnump,void * valuep)1077b725ae77Skettenis arm_sigtramp_prev_register (struct frame_info *next_frame,
1078b725ae77Skettenis void **this_cache,
1079b725ae77Skettenis int prev_regnum,
1080b725ae77Skettenis int *optimized,
1081b725ae77Skettenis enum lval_type *lvalp,
1082b725ae77Skettenis CORE_ADDR *addrp,
1083b725ae77Skettenis int *realnump,
1084b725ae77Skettenis void *valuep)
1085b725ae77Skettenis {
1086b725ae77Skettenis struct arm_prologue_cache *cache;
1087b725ae77Skettenis
1088b725ae77Skettenis if (*this_cache == NULL)
1089b725ae77Skettenis *this_cache = arm_make_sigtramp_cache (next_frame);
1090b725ae77Skettenis cache = *this_cache;
1091b725ae77Skettenis
1092*63addd46Skettenis trad_frame_get_prev_register (next_frame, cache->saved_regs, prev_regnum,
1093b725ae77Skettenis optimized, lvalp, addrp, realnump, valuep);
1094b725ae77Skettenis }
1095b725ae77Skettenis
1096b725ae77Skettenis struct frame_unwind arm_sigtramp_unwind = {
1097b725ae77Skettenis SIGTRAMP_FRAME,
1098b725ae77Skettenis arm_sigtramp_this_id,
1099b725ae77Skettenis arm_sigtramp_prev_register
1100b725ae77Skettenis };
1101b725ae77Skettenis
1102b725ae77Skettenis static const struct frame_unwind *
arm_sigtramp_unwind_sniffer(struct frame_info * next_frame)1103b725ae77Skettenis arm_sigtramp_unwind_sniffer (struct frame_info *next_frame)
1104b725ae77Skettenis {
1105b725ae77Skettenis if (SIGCONTEXT_REGISTER_ADDRESS_P ()
1106*63addd46Skettenis && legacy_pc_in_sigtramp (frame_pc_unwind (next_frame), (char *) 0))
1107b725ae77Skettenis return &arm_sigtramp_unwind;
1108b725ae77Skettenis
1109b725ae77Skettenis return NULL;
1110b725ae77Skettenis }
1111b725ae77Skettenis
1112b725ae77Skettenis /* Assuming NEXT_FRAME->prev is a dummy, return the frame ID of that
1113b725ae77Skettenis dummy frame. The frame ID's base needs to match the TOS value
1114b725ae77Skettenis saved by save_dummy_frame_tos() and returned from
1115b725ae77Skettenis arm_push_dummy_call, and the PC needs to match the dummy frame's
1116b725ae77Skettenis breakpoint. */
1117b725ae77Skettenis
1118b725ae77Skettenis static struct frame_id
arm_unwind_dummy_id(struct gdbarch * gdbarch,struct frame_info * next_frame)1119b725ae77Skettenis arm_unwind_dummy_id (struct gdbarch *gdbarch, struct frame_info *next_frame)
1120b725ae77Skettenis {
1121b725ae77Skettenis return frame_id_build (frame_unwind_register_unsigned (next_frame, ARM_SP_REGNUM),
1122b725ae77Skettenis frame_pc_unwind (next_frame));
1123b725ae77Skettenis }
1124b725ae77Skettenis
1125b725ae77Skettenis /* Given THIS_FRAME, find the previous frame's resume PC (which will
1126b725ae77Skettenis be used to construct the previous frame's ID, after looking up the
1127b725ae77Skettenis containing function). */
1128b725ae77Skettenis
1129b725ae77Skettenis static CORE_ADDR
arm_unwind_pc(struct gdbarch * gdbarch,struct frame_info * this_frame)1130b725ae77Skettenis arm_unwind_pc (struct gdbarch *gdbarch, struct frame_info *this_frame)
1131b725ae77Skettenis {
1132b725ae77Skettenis CORE_ADDR pc;
1133b725ae77Skettenis pc = frame_unwind_register_unsigned (this_frame, ARM_PC_REGNUM);
1134b725ae77Skettenis return IS_THUMB_ADDR (pc) ? UNMAKE_THUMB_ADDR (pc) : pc;
1135b725ae77Skettenis }
1136b725ae77Skettenis
1137b725ae77Skettenis static CORE_ADDR
arm_unwind_sp(struct gdbarch * gdbarch,struct frame_info * this_frame)1138b725ae77Skettenis arm_unwind_sp (struct gdbarch *gdbarch, struct frame_info *this_frame)
1139b725ae77Skettenis {
1140b725ae77Skettenis return frame_unwind_register_unsigned (this_frame, ARM_SP_REGNUM);
1141b725ae77Skettenis }
1142b725ae77Skettenis
1143b725ae77Skettenis /* When arguments must be pushed onto the stack, they go on in reverse
1144b725ae77Skettenis order. The code below implements a FILO (stack) to do this. */
1145b725ae77Skettenis
1146b725ae77Skettenis struct stack_item
1147b725ae77Skettenis {
1148b725ae77Skettenis int len;
1149b725ae77Skettenis struct stack_item *prev;
1150b725ae77Skettenis void *data;
1151b725ae77Skettenis };
1152b725ae77Skettenis
1153b725ae77Skettenis static struct stack_item *
push_stack_item(struct stack_item * prev,void * contents,int len)1154b725ae77Skettenis push_stack_item (struct stack_item *prev, void *contents, int len)
1155b725ae77Skettenis {
1156b725ae77Skettenis struct stack_item *si;
1157b725ae77Skettenis si = xmalloc (sizeof (struct stack_item));
1158b725ae77Skettenis si->data = xmalloc (len);
1159b725ae77Skettenis si->len = len;
1160b725ae77Skettenis si->prev = prev;
1161b725ae77Skettenis memcpy (si->data, contents, len);
1162b725ae77Skettenis return si;
1163b725ae77Skettenis }
1164b725ae77Skettenis
1165b725ae77Skettenis static struct stack_item *
pop_stack_item(struct stack_item * si)1166b725ae77Skettenis pop_stack_item (struct stack_item *si)
1167b725ae77Skettenis {
1168b725ae77Skettenis struct stack_item *dead = si;
1169b725ae77Skettenis si = si->prev;
1170b725ae77Skettenis xfree (dead->data);
1171b725ae77Skettenis xfree (dead);
1172b725ae77Skettenis return si;
1173b725ae77Skettenis }
1174b725ae77Skettenis
1175b725ae77Skettenis /* We currently only support passing parameters in integer registers. This
1176b725ae77Skettenis conforms with GCC's default model. Several other variants exist and
1177b725ae77Skettenis we should probably support some of them based on the selected ABI. */
1178b725ae77Skettenis
1179b725ae77Skettenis static CORE_ADDR
arm_push_dummy_call(struct gdbarch * gdbarch,struct value * function,struct regcache * regcache,CORE_ADDR bp_addr,int nargs,struct value ** args,CORE_ADDR sp,int struct_return,CORE_ADDR struct_addr)1180*63addd46Skettenis arm_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
1181b725ae77Skettenis struct regcache *regcache, CORE_ADDR bp_addr, int nargs,
1182b725ae77Skettenis struct value **args, CORE_ADDR sp, int struct_return,
1183b725ae77Skettenis CORE_ADDR struct_addr)
1184b725ae77Skettenis {
1185b725ae77Skettenis int argnum;
1186b725ae77Skettenis int argreg;
1187b725ae77Skettenis int nstack;
1188b725ae77Skettenis struct stack_item *si = NULL;
1189b725ae77Skettenis
1190b725ae77Skettenis /* Set the return address. For the ARM, the return breakpoint is
1191b725ae77Skettenis always at BP_ADDR. */
1192b725ae77Skettenis /* XXX Fix for Thumb. */
1193b725ae77Skettenis regcache_cooked_write_unsigned (regcache, ARM_LR_REGNUM, bp_addr);
1194b725ae77Skettenis
1195b725ae77Skettenis /* Walk through the list of args and determine how large a temporary
1196b725ae77Skettenis stack is required. Need to take care here as structs may be
1197b725ae77Skettenis passed on the stack, and we have to to push them. */
1198b725ae77Skettenis nstack = 0;
1199b725ae77Skettenis
1200b725ae77Skettenis argreg = ARM_A1_REGNUM;
1201b725ae77Skettenis nstack = 0;
1202b725ae77Skettenis
1203b725ae77Skettenis /* Some platforms require a double-word aligned stack. Make sure sp
1204b725ae77Skettenis is correctly aligned before we start. We always do this even if
1205b725ae77Skettenis it isn't really needed -- it can never hurt things. */
1206b725ae77Skettenis sp &= ~(CORE_ADDR)(2 * DEPRECATED_REGISTER_SIZE - 1);
1207b725ae77Skettenis
1208b725ae77Skettenis /* The struct_return pointer occupies the first parameter
1209b725ae77Skettenis passing register. */
1210b725ae77Skettenis if (struct_return)
1211b725ae77Skettenis {
1212b725ae77Skettenis if (arm_debug)
1213b725ae77Skettenis fprintf_unfiltered (gdb_stdlog, "struct return in %s = 0x%s\n",
1214b725ae77Skettenis REGISTER_NAME (argreg), paddr (struct_addr));
1215b725ae77Skettenis regcache_cooked_write_unsigned (regcache, argreg, struct_addr);
1216b725ae77Skettenis argreg++;
1217b725ae77Skettenis }
1218b725ae77Skettenis
1219b725ae77Skettenis for (argnum = 0; argnum < nargs; argnum++)
1220b725ae77Skettenis {
1221b725ae77Skettenis int len;
1222b725ae77Skettenis struct type *arg_type;
1223b725ae77Skettenis struct type *target_type;
1224b725ae77Skettenis enum type_code typecode;
1225b725ae77Skettenis char *val;
1226b725ae77Skettenis
1227b725ae77Skettenis arg_type = check_typedef (VALUE_TYPE (args[argnum]));
1228b725ae77Skettenis len = TYPE_LENGTH (arg_type);
1229b725ae77Skettenis target_type = TYPE_TARGET_TYPE (arg_type);
1230b725ae77Skettenis typecode = TYPE_CODE (arg_type);
1231b725ae77Skettenis val = VALUE_CONTENTS (args[argnum]);
1232b725ae77Skettenis
1233b725ae77Skettenis /* If the argument is a pointer to a function, and it is a
1234b725ae77Skettenis Thumb function, create a LOCAL copy of the value and set
1235b725ae77Skettenis the THUMB bit in it. */
1236b725ae77Skettenis if (TYPE_CODE_PTR == typecode
1237b725ae77Skettenis && target_type != NULL
1238b725ae77Skettenis && TYPE_CODE_FUNC == TYPE_CODE (target_type))
1239b725ae77Skettenis {
1240b725ae77Skettenis CORE_ADDR regval = extract_unsigned_integer (val, len);
1241b725ae77Skettenis if (arm_pc_is_thumb (regval))
1242b725ae77Skettenis {
1243b725ae77Skettenis val = alloca (len);
1244b725ae77Skettenis store_unsigned_integer (val, len, MAKE_THUMB_ADDR (regval));
1245b725ae77Skettenis }
1246b725ae77Skettenis }
1247b725ae77Skettenis
1248b725ae77Skettenis /* Copy the argument to general registers or the stack in
1249b725ae77Skettenis register-sized pieces. Large arguments are split between
1250b725ae77Skettenis registers and stack. */
1251b725ae77Skettenis while (len > 0)
1252b725ae77Skettenis {
1253b725ae77Skettenis int partial_len = len < DEPRECATED_REGISTER_SIZE ? len : DEPRECATED_REGISTER_SIZE;
1254b725ae77Skettenis
1255b725ae77Skettenis if (argreg <= ARM_LAST_ARG_REGNUM)
1256b725ae77Skettenis {
1257b725ae77Skettenis /* The argument is being passed in a general purpose
1258b725ae77Skettenis register. */
1259b725ae77Skettenis CORE_ADDR regval = extract_unsigned_integer (val, partial_len);
1260b725ae77Skettenis if (arm_debug)
1261b725ae77Skettenis fprintf_unfiltered (gdb_stdlog, "arg %d in %s = 0x%s\n",
1262b725ae77Skettenis argnum, REGISTER_NAME (argreg),
1263b725ae77Skettenis phex (regval, DEPRECATED_REGISTER_SIZE));
1264b725ae77Skettenis regcache_cooked_write_unsigned (regcache, argreg, regval);
1265b725ae77Skettenis argreg++;
1266b725ae77Skettenis }
1267b725ae77Skettenis else
1268b725ae77Skettenis {
1269b725ae77Skettenis /* Push the arguments onto the stack. */
1270b725ae77Skettenis if (arm_debug)
1271b725ae77Skettenis fprintf_unfiltered (gdb_stdlog, "arg %d @ sp + %d\n",
1272b725ae77Skettenis argnum, nstack);
1273b725ae77Skettenis si = push_stack_item (si, val, DEPRECATED_REGISTER_SIZE);
1274b725ae77Skettenis nstack += DEPRECATED_REGISTER_SIZE;
1275b725ae77Skettenis }
1276b725ae77Skettenis
1277b725ae77Skettenis len -= partial_len;
1278b725ae77Skettenis val += partial_len;
1279b725ae77Skettenis }
1280b725ae77Skettenis }
1281b725ae77Skettenis /* If we have an odd number of words to push, then decrement the stack
1282b725ae77Skettenis by one word now, so first stack argument will be dword aligned. */
1283b725ae77Skettenis if (nstack & 4)
1284b725ae77Skettenis sp -= 4;
1285b725ae77Skettenis
1286b725ae77Skettenis while (si)
1287b725ae77Skettenis {
1288b725ae77Skettenis sp -= si->len;
1289b725ae77Skettenis write_memory (sp, si->data, si->len);
1290b725ae77Skettenis si = pop_stack_item (si);
1291b725ae77Skettenis }
1292b725ae77Skettenis
1293b725ae77Skettenis /* Finally, update teh SP register. */
1294b725ae77Skettenis regcache_cooked_write_unsigned (regcache, ARM_SP_REGNUM, sp);
1295b725ae77Skettenis
1296b725ae77Skettenis return sp;
1297b725ae77Skettenis }
1298b725ae77Skettenis
1299b725ae77Skettenis static void
print_fpu_flags(int flags)1300b725ae77Skettenis print_fpu_flags (int flags)
1301b725ae77Skettenis {
1302b725ae77Skettenis if (flags & (1 << 0))
1303b725ae77Skettenis fputs ("IVO ", stdout);
1304b725ae77Skettenis if (flags & (1 << 1))
1305b725ae77Skettenis fputs ("DVZ ", stdout);
1306b725ae77Skettenis if (flags & (1 << 2))
1307b725ae77Skettenis fputs ("OFL ", stdout);
1308b725ae77Skettenis if (flags & (1 << 3))
1309b725ae77Skettenis fputs ("UFL ", stdout);
1310b725ae77Skettenis if (flags & (1 << 4))
1311b725ae77Skettenis fputs ("INX ", stdout);
1312e93f7393Sniklas putchar ('\n');
1313e93f7393Sniklas }
1314e93f7393Sniklas
1315b725ae77Skettenis /* Print interesting information about the floating point processor
1316b725ae77Skettenis (if present) or emulator. */
1317b725ae77Skettenis static void
arm_print_float_info(struct gdbarch * gdbarch,struct ui_file * file,struct frame_info * frame,const char * args)1318b725ae77Skettenis arm_print_float_info (struct gdbarch *gdbarch, struct ui_file *file,
1319b725ae77Skettenis struct frame_info *frame, const char *args)
1320e93f7393Sniklas {
1321b725ae77Skettenis unsigned long status = read_register (ARM_FPS_REGNUM);
1322e93f7393Sniklas int type;
1323e93f7393Sniklas
1324e93f7393Sniklas type = (status >> 24) & 127;
1325e93f7393Sniklas printf ("%s FPU type %d\n",
1326e93f7393Sniklas (status & (1 << 31)) ? "Hardware" : "Software",
1327e93f7393Sniklas type);
1328e93f7393Sniklas fputs ("mask: ", stdout);
1329e93f7393Sniklas print_fpu_flags (status >> 16);
1330e93f7393Sniklas fputs ("flags: ", stdout);
1331e93f7393Sniklas print_fpu_flags (status);
1332e93f7393Sniklas }
1333e93f7393Sniklas
1334b725ae77Skettenis /* Return the GDB type object for the "standard" data type of data in
1335b725ae77Skettenis register N. */
1336b725ae77Skettenis
1337b725ae77Skettenis static struct type *
arm_register_type(struct gdbarch * gdbarch,int regnum)1338b725ae77Skettenis arm_register_type (struct gdbarch *gdbarch, int regnum)
1339b725ae77Skettenis {
1340b725ae77Skettenis if (regnum >= ARM_F0_REGNUM && regnum < ARM_F0_REGNUM + NUM_FREGS)
1341b725ae77Skettenis {
1342b725ae77Skettenis if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
1343b725ae77Skettenis return builtin_type_arm_ext_big;
1344b725ae77Skettenis else
1345b725ae77Skettenis return builtin_type_arm_ext_littlebyte_bigword;
1346b725ae77Skettenis }
1347b725ae77Skettenis else
1348b725ae77Skettenis return builtin_type_int32;
1349b725ae77Skettenis }
1350b725ae77Skettenis
1351b725ae77Skettenis /* Index within `registers' of the first byte of the space for
1352b725ae77Skettenis register N. */
1353b725ae77Skettenis
1354b725ae77Skettenis static int
arm_register_byte(int regnum)1355b725ae77Skettenis arm_register_byte (int regnum)
1356b725ae77Skettenis {
1357b725ae77Skettenis if (regnum < ARM_F0_REGNUM)
1358b725ae77Skettenis return regnum * INT_REGISTER_SIZE;
1359b725ae77Skettenis else if (regnum < ARM_PS_REGNUM)
1360b725ae77Skettenis return (NUM_GREGS * INT_REGISTER_SIZE
1361b725ae77Skettenis + (regnum - ARM_F0_REGNUM) * FP_REGISTER_SIZE);
1362b725ae77Skettenis else
1363b725ae77Skettenis return (NUM_GREGS * INT_REGISTER_SIZE
1364b725ae77Skettenis + NUM_FREGS * FP_REGISTER_SIZE
1365b725ae77Skettenis + (regnum - ARM_FPS_REGNUM) * STATUS_REGISTER_SIZE);
1366b725ae77Skettenis }
1367b725ae77Skettenis
1368b725ae77Skettenis /* Map GDB internal REGNUM onto the Arm simulator register numbers. */
1369b725ae77Skettenis static int
arm_register_sim_regno(int regnum)1370b725ae77Skettenis arm_register_sim_regno (int regnum)
1371b725ae77Skettenis {
1372b725ae77Skettenis int reg = regnum;
1373b725ae77Skettenis gdb_assert (reg >= 0 && reg < NUM_REGS);
1374b725ae77Skettenis
1375b725ae77Skettenis if (reg < NUM_GREGS)
1376b725ae77Skettenis return SIM_ARM_R0_REGNUM + reg;
1377b725ae77Skettenis reg -= NUM_GREGS;
1378b725ae77Skettenis
1379b725ae77Skettenis if (reg < NUM_FREGS)
1380b725ae77Skettenis return SIM_ARM_FP0_REGNUM + reg;
1381b725ae77Skettenis reg -= NUM_FREGS;
1382b725ae77Skettenis
1383b725ae77Skettenis if (reg < NUM_SREGS)
1384b725ae77Skettenis return SIM_ARM_FPS_REGNUM + reg;
1385b725ae77Skettenis reg -= NUM_SREGS;
1386b725ae77Skettenis
1387b725ae77Skettenis internal_error (__FILE__, __LINE__, "Bad REGNUM %d", regnum);
1388b725ae77Skettenis }
1389b725ae77Skettenis
1390b725ae77Skettenis /* NOTE: cagney/2001-08-20: Both convert_from_extended() and
1391b725ae77Skettenis convert_to_extended() use floatformat_arm_ext_littlebyte_bigword.
1392b725ae77Skettenis It is thought that this is is the floating-point register format on
1393b725ae77Skettenis little-endian systems. */
1394b725ae77Skettenis
1395e93f7393Sniklas static void
convert_from_extended(const struct floatformat * fmt,const void * ptr,void * dbl)1396b725ae77Skettenis convert_from_extended (const struct floatformat *fmt, const void *ptr,
1397b725ae77Skettenis void *dbl)
1398e93f7393Sniklas {
1399b725ae77Skettenis DOUBLEST d;
1400b725ae77Skettenis if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
1401b725ae77Skettenis floatformat_to_doublest (&floatformat_arm_ext_big, ptr, &d);
1402b725ae77Skettenis else
1403b725ae77Skettenis floatformat_to_doublest (&floatformat_arm_ext_littlebyte_bigword,
1404b725ae77Skettenis ptr, &d);
1405b725ae77Skettenis floatformat_from_doublest (fmt, &d, dbl);
1406e93f7393Sniklas }
1407e93f7393Sniklas
1408b725ae77Skettenis static void
convert_to_extended(const struct floatformat * fmt,void * dbl,const void * ptr)1409b725ae77Skettenis convert_to_extended (const struct floatformat *fmt, void *dbl, const void *ptr)
1410e93f7393Sniklas {
1411b725ae77Skettenis DOUBLEST d;
1412b725ae77Skettenis floatformat_to_doublest (fmt, ptr, &d);
1413b725ae77Skettenis if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
1414b725ae77Skettenis floatformat_from_doublest (&floatformat_arm_ext_big, &d, dbl);
1415b725ae77Skettenis else
1416b725ae77Skettenis floatformat_from_doublest (&floatformat_arm_ext_littlebyte_bigword,
1417b725ae77Skettenis &d, dbl);
1418e93f7393Sniklas }
1419e93f7393Sniklas
1420b725ae77Skettenis static int
condition_true(unsigned long cond,unsigned long status_reg)1421b725ae77Skettenis condition_true (unsigned long cond, unsigned long status_reg)
1422e93f7393Sniklas {
1423e93f7393Sniklas if (cond == INST_AL || cond == INST_NV)
1424b725ae77Skettenis return 1;
1425e93f7393Sniklas
1426e93f7393Sniklas switch (cond)
1427e93f7393Sniklas {
1428e93f7393Sniklas case INST_EQ:
1429e93f7393Sniklas return ((status_reg & FLAG_Z) != 0);
1430b725ae77Skettenis case INST_NE:
1431b725ae77Skettenis return ((status_reg & FLAG_Z) == 0);
1432e93f7393Sniklas case INST_CS:
1433e93f7393Sniklas return ((status_reg & FLAG_C) != 0);
1434b725ae77Skettenis case INST_CC:
1435b725ae77Skettenis return ((status_reg & FLAG_C) == 0);
1436e93f7393Sniklas case INST_MI:
1437e93f7393Sniklas return ((status_reg & FLAG_N) != 0);
1438b725ae77Skettenis case INST_PL:
1439b725ae77Skettenis return ((status_reg & FLAG_N) == 0);
1440e93f7393Sniklas case INST_VS:
1441e93f7393Sniklas return ((status_reg & FLAG_V) != 0);
1442b725ae77Skettenis case INST_VC:
1443b725ae77Skettenis return ((status_reg & FLAG_V) == 0);
1444e93f7393Sniklas case INST_HI:
1445b725ae77Skettenis return ((status_reg & (FLAG_C | FLAG_Z)) == FLAG_C);
1446e93f7393Sniklas case INST_LS:
1447b725ae77Skettenis return ((status_reg & (FLAG_C | FLAG_Z)) != FLAG_C);
1448e93f7393Sniklas case INST_GE:
1449e93f7393Sniklas return (((status_reg & FLAG_N) == 0) == ((status_reg & FLAG_V) == 0));
1450b725ae77Skettenis case INST_LT:
1451b725ae77Skettenis return (((status_reg & FLAG_N) == 0) != ((status_reg & FLAG_V) == 0));
1452e93f7393Sniklas case INST_GT:
1453e93f7393Sniklas return (((status_reg & FLAG_Z) == 0) &&
1454e93f7393Sniklas (((status_reg & FLAG_N) == 0) == ((status_reg & FLAG_V) == 0)));
1455b725ae77Skettenis case INST_LE:
1456b725ae77Skettenis return (((status_reg & FLAG_Z) != 0) ||
1457b725ae77Skettenis (((status_reg & FLAG_N) == 0) != ((status_reg & FLAG_V) == 0)));
1458e93f7393Sniklas }
1459b725ae77Skettenis return 1;
1460e93f7393Sniklas }
1461e93f7393Sniklas
1462b725ae77Skettenis /* Support routines for single stepping. Calculate the next PC value. */
1463e93f7393Sniklas #define submask(x) ((1L << ((x) + 1)) - 1)
1464b725ae77Skettenis #define bit(obj,st) (((obj) >> (st)) & 1)
1465b725ae77Skettenis #define bits(obj,st,fn) (((obj) >> (st)) & submask ((fn) - (st)))
1466e93f7393Sniklas #define sbits(obj,st,fn) \
1467e93f7393Sniklas ((long) (bits(obj,st,fn) | ((long) bit(obj,fn) * ~ submask (fn - st))))
1468e93f7393Sniklas #define BranchDest(addr,instr) \
1469e93f7393Sniklas ((CORE_ADDR) (((long) (addr)) + 8 + (sbits (instr, 0, 23) << 2)))
1470e93f7393Sniklas #define ARM_PC_32 1
1471e93f7393Sniklas
1472e93f7393Sniklas static unsigned long
shifted_reg_val(unsigned long inst,int carry,unsigned long pc_val,unsigned long status_reg)1473b725ae77Skettenis shifted_reg_val (unsigned long inst, int carry, unsigned long pc_val,
1474b725ae77Skettenis unsigned long status_reg)
1475e93f7393Sniklas {
1476e93f7393Sniklas unsigned long res, shift;
1477e93f7393Sniklas int rm = bits (inst, 0, 3);
1478e93f7393Sniklas unsigned long shifttype = bits (inst, 5, 6);
1479e93f7393Sniklas
1480e93f7393Sniklas if (bit (inst, 4))
1481e93f7393Sniklas {
1482e93f7393Sniklas int rs = bits (inst, 8, 11);
1483e93f7393Sniklas shift = (rs == 15 ? pc_val + 8 : read_register (rs)) & 0xFF;
1484e93f7393Sniklas }
1485e93f7393Sniklas else
1486e93f7393Sniklas shift = bits (inst, 7, 11);
1487e93f7393Sniklas
1488e93f7393Sniklas res = (rm == 15
1489b725ae77Skettenis ? ((pc_val | (ARM_PC_32 ? 0 : status_reg))
1490e93f7393Sniklas + (bit (inst, 4) ? 12 : 8))
1491e93f7393Sniklas : read_register (rm));
1492e93f7393Sniklas
1493e93f7393Sniklas switch (shifttype)
1494e93f7393Sniklas {
1495e93f7393Sniklas case 0: /* LSL */
1496e93f7393Sniklas res = shift >= 32 ? 0 : res << shift;
1497e93f7393Sniklas break;
1498e93f7393Sniklas
1499e93f7393Sniklas case 1: /* LSR */
1500e93f7393Sniklas res = shift >= 32 ? 0 : res >> shift;
1501e93f7393Sniklas break;
1502e93f7393Sniklas
1503e93f7393Sniklas case 2: /* ASR */
1504b725ae77Skettenis if (shift >= 32)
1505b725ae77Skettenis shift = 31;
1506e93f7393Sniklas res = ((res & 0x80000000L)
1507e93f7393Sniklas ? ~((~res) >> shift) : res >> shift);
1508e93f7393Sniklas break;
1509e93f7393Sniklas
1510e93f7393Sniklas case 3: /* ROR/RRX */
1511e93f7393Sniklas shift &= 31;
1512e93f7393Sniklas if (shift == 0)
1513e93f7393Sniklas res = (res >> 1) | (carry ? 0x80000000L : 0);
1514e93f7393Sniklas else
1515e93f7393Sniklas res = (res >> shift) | (res << (32 - shift));
1516e93f7393Sniklas break;
1517e93f7393Sniklas }
1518e93f7393Sniklas
1519e93f7393Sniklas return res & 0xffffffff;
1520e93f7393Sniklas }
1521e93f7393Sniklas
1522b725ae77Skettenis /* Return number of 1-bits in VAL. */
1523b725ae77Skettenis
1524b725ae77Skettenis static int
bitcount(unsigned long val)1525b725ae77Skettenis bitcount (unsigned long val)
1526b725ae77Skettenis {
1527b725ae77Skettenis int nbits;
1528b725ae77Skettenis for (nbits = 0; val != 0; nbits++)
1529b725ae77Skettenis val &= val - 1; /* delete rightmost 1-bit in val */
1530b725ae77Skettenis return nbits;
1531b725ae77Skettenis }
1532e93f7393Sniklas
1533e93f7393Sniklas CORE_ADDR
thumb_get_next_pc(CORE_ADDR pc)1534b725ae77Skettenis thumb_get_next_pc (CORE_ADDR pc)
1535e93f7393Sniklas {
1536b725ae77Skettenis unsigned long pc_val = ((unsigned long) pc) + 4; /* PC after prefetch */
1537b725ae77Skettenis unsigned short inst1 = read_memory_integer (pc, 2);
1538b725ae77Skettenis CORE_ADDR nextpc = pc + 2; /* default is next instruction */
1539b725ae77Skettenis unsigned long offset;
1540e93f7393Sniklas
1541b725ae77Skettenis if ((inst1 & 0xff00) == 0xbd00) /* pop {rlist, pc} */
1542b725ae77Skettenis {
1543b725ae77Skettenis CORE_ADDR sp;
1544b725ae77Skettenis
1545b725ae77Skettenis /* Fetch the saved PC from the stack. It's stored above
1546b725ae77Skettenis all of the other registers. */
1547b725ae77Skettenis offset = bitcount (bits (inst1, 0, 7)) * DEPRECATED_REGISTER_SIZE;
1548b725ae77Skettenis sp = read_register (ARM_SP_REGNUM);
1549b725ae77Skettenis nextpc = (CORE_ADDR) read_memory_integer (sp + offset, 4);
1550b725ae77Skettenis nextpc = ADDR_BITS_REMOVE (nextpc);
1551b725ae77Skettenis if (nextpc == pc)
1552b725ae77Skettenis error ("Infinite loop detected");
1553b725ae77Skettenis }
1554b725ae77Skettenis else if ((inst1 & 0xf000) == 0xd000) /* conditional branch */
1555b725ae77Skettenis {
1556b725ae77Skettenis unsigned long status = read_register (ARM_PS_REGNUM);
1557b725ae77Skettenis unsigned long cond = bits (inst1, 8, 11);
1558b725ae77Skettenis if (cond != 0x0f && condition_true (cond, status)) /* 0x0f = SWI */
1559b725ae77Skettenis nextpc = pc_val + (sbits (inst1, 0, 7) << 1);
1560b725ae77Skettenis }
1561b725ae77Skettenis else if ((inst1 & 0xf800) == 0xe000) /* unconditional branch */
1562b725ae77Skettenis {
1563b725ae77Skettenis nextpc = pc_val + (sbits (inst1, 0, 10) << 1);
1564b725ae77Skettenis }
1565b725ae77Skettenis else if ((inst1 & 0xf800) == 0xf000) /* long branch with link, and blx */
1566b725ae77Skettenis {
1567b725ae77Skettenis unsigned short inst2 = read_memory_integer (pc + 2, 2);
1568b725ae77Skettenis offset = (sbits (inst1, 0, 10) << 12) + (bits (inst2, 0, 10) << 1);
1569b725ae77Skettenis nextpc = pc_val + offset;
1570b725ae77Skettenis /* For BLX make sure to clear the low bits. */
1571b725ae77Skettenis if (bits (inst2, 11, 12) == 1)
1572b725ae77Skettenis nextpc = nextpc & 0xfffffffc;
1573b725ae77Skettenis }
1574b725ae77Skettenis else if ((inst1 & 0xff00) == 0x4700) /* bx REG, blx REG */
1575b725ae77Skettenis {
1576b725ae77Skettenis if (bits (inst1, 3, 6) == 0x0f)
1577b725ae77Skettenis nextpc = pc_val;
1578b725ae77Skettenis else
1579b725ae77Skettenis nextpc = read_register (bits (inst1, 3, 6));
1580b725ae77Skettenis
1581b725ae77Skettenis nextpc = ADDR_BITS_REMOVE (nextpc);
1582b725ae77Skettenis if (nextpc == pc)
1583b725ae77Skettenis error ("Infinite loop detected");
1584b725ae77Skettenis }
1585b725ae77Skettenis
1586b725ae77Skettenis return nextpc;
1587b725ae77Skettenis }
1588b725ae77Skettenis
1589b725ae77Skettenis CORE_ADDR
arm_get_next_pc(CORE_ADDR pc)1590b725ae77Skettenis arm_get_next_pc (CORE_ADDR pc)
1591b725ae77Skettenis {
1592b725ae77Skettenis unsigned long pc_val;
1593b725ae77Skettenis unsigned long this_instr;
1594b725ae77Skettenis unsigned long status;
1595b725ae77Skettenis CORE_ADDR nextpc;
1596b725ae77Skettenis
1597b725ae77Skettenis if (arm_pc_is_thumb (pc))
1598b725ae77Skettenis return thumb_get_next_pc (pc);
1599b725ae77Skettenis
1600b725ae77Skettenis pc_val = (unsigned long) pc;
1601b725ae77Skettenis this_instr = read_memory_integer (pc, 4);
1602b725ae77Skettenis status = read_register (ARM_PS_REGNUM);
1603b725ae77Skettenis nextpc = (CORE_ADDR) (pc_val + 4); /* Default case */
1604b725ae77Skettenis
1605b725ae77Skettenis if (condition_true (bits (this_instr, 28, 31), status))
1606e93f7393Sniklas {
1607e93f7393Sniklas switch (bits (this_instr, 24, 27))
1608e93f7393Sniklas {
1609b725ae77Skettenis case 0x0:
1610b725ae77Skettenis case 0x1: /* data processing */
1611b725ae77Skettenis case 0x2:
1612b725ae77Skettenis case 0x3:
1613e93f7393Sniklas {
1614e93f7393Sniklas unsigned long operand1, operand2, result = 0;
1615e93f7393Sniklas unsigned long rn;
1616e93f7393Sniklas int c;
1617e93f7393Sniklas
1618e93f7393Sniklas if (bits (this_instr, 12, 15) != 15)
1619e93f7393Sniklas break;
1620e93f7393Sniklas
1621e93f7393Sniklas if (bits (this_instr, 22, 25) == 0
1622e93f7393Sniklas && bits (this_instr, 4, 7) == 9) /* multiply */
1623e93f7393Sniklas error ("Illegal update to pc in instruction");
1624e93f7393Sniklas
1625b725ae77Skettenis /* BX <reg>, BLX <reg> */
1626b725ae77Skettenis if (bits (this_instr, 4, 28) == 0x12fff1
1627b725ae77Skettenis || bits (this_instr, 4, 28) == 0x12fff3)
1628b725ae77Skettenis {
1629b725ae77Skettenis rn = bits (this_instr, 0, 3);
1630b725ae77Skettenis result = (rn == 15) ? pc_val + 8 : read_register (rn);
1631b725ae77Skettenis nextpc = (CORE_ADDR) ADDR_BITS_REMOVE (result);
1632b725ae77Skettenis
1633b725ae77Skettenis if (nextpc == pc)
1634b725ae77Skettenis error ("Infinite loop detected");
1635b725ae77Skettenis
1636b725ae77Skettenis return nextpc;
1637b725ae77Skettenis }
1638b725ae77Skettenis
1639e93f7393Sniklas /* Multiply into PC */
1640e93f7393Sniklas c = (status & FLAG_C) ? 1 : 0;
1641e93f7393Sniklas rn = bits (this_instr, 16, 19);
1642e93f7393Sniklas operand1 = (rn == 15) ? pc_val + 8 : read_register (rn);
1643e93f7393Sniklas
1644e93f7393Sniklas if (bit (this_instr, 25))
1645e93f7393Sniklas {
1646e93f7393Sniklas unsigned long immval = bits (this_instr, 0, 7);
1647e93f7393Sniklas unsigned long rotate = 2 * bits (this_instr, 8, 11);
1648b725ae77Skettenis operand2 = ((immval >> rotate) | (immval << (32 - rotate)))
1649b725ae77Skettenis & 0xffffffff;
1650e93f7393Sniklas }
1651e93f7393Sniklas else /* operand 2 is a shifted register */
1652b725ae77Skettenis operand2 = shifted_reg_val (this_instr, c, pc_val, status);
1653e93f7393Sniklas
1654e93f7393Sniklas switch (bits (this_instr, 21, 24))
1655e93f7393Sniklas {
1656e93f7393Sniklas case 0x0: /*and */
1657e93f7393Sniklas result = operand1 & operand2;
1658e93f7393Sniklas break;
1659e93f7393Sniklas
1660e93f7393Sniklas case 0x1: /*eor */
1661e93f7393Sniklas result = operand1 ^ operand2;
1662e93f7393Sniklas break;
1663e93f7393Sniklas
1664e93f7393Sniklas case 0x2: /*sub */
1665e93f7393Sniklas result = operand1 - operand2;
1666e93f7393Sniklas break;
1667e93f7393Sniklas
1668e93f7393Sniklas case 0x3: /*rsb */
1669e93f7393Sniklas result = operand2 - operand1;
1670e93f7393Sniklas break;
1671e93f7393Sniklas
1672e93f7393Sniklas case 0x4: /*add */
1673e93f7393Sniklas result = operand1 + operand2;
1674e93f7393Sniklas break;
1675e93f7393Sniklas
1676e93f7393Sniklas case 0x5: /*adc */
1677e93f7393Sniklas result = operand1 + operand2 + c;
1678e93f7393Sniklas break;
1679e93f7393Sniklas
1680e93f7393Sniklas case 0x6: /*sbc */
1681e93f7393Sniklas result = operand1 - operand2 + c;
1682e93f7393Sniklas break;
1683e93f7393Sniklas
1684e93f7393Sniklas case 0x7: /*rsc */
1685e93f7393Sniklas result = operand2 - operand1 + c;
1686e93f7393Sniklas break;
1687e93f7393Sniklas
1688b725ae77Skettenis case 0x8:
1689b725ae77Skettenis case 0x9:
1690b725ae77Skettenis case 0xa:
1691b725ae77Skettenis case 0xb: /* tst, teq, cmp, cmn */
1692e93f7393Sniklas result = (unsigned long) nextpc;
1693e93f7393Sniklas break;
1694e93f7393Sniklas
1695e93f7393Sniklas case 0xc: /*orr */
1696e93f7393Sniklas result = operand1 | operand2;
1697e93f7393Sniklas break;
1698e93f7393Sniklas
1699e93f7393Sniklas case 0xd: /*mov */
1700e93f7393Sniklas /* Always step into a function. */
1701e93f7393Sniklas result = operand2;
1702e93f7393Sniklas break;
1703e93f7393Sniklas
1704e93f7393Sniklas case 0xe: /*bic */
1705e93f7393Sniklas result = operand1 & ~operand2;
1706e93f7393Sniklas break;
1707e93f7393Sniklas
1708e93f7393Sniklas case 0xf: /*mvn */
1709e93f7393Sniklas result = ~operand2;
1710e93f7393Sniklas break;
1711e93f7393Sniklas }
1712e93f7393Sniklas nextpc = (CORE_ADDR) ADDR_BITS_REMOVE (result);
1713e93f7393Sniklas
1714e93f7393Sniklas if (nextpc == pc)
1715e93f7393Sniklas error ("Infinite loop detected");
1716e93f7393Sniklas break;
1717e93f7393Sniklas }
1718e93f7393Sniklas
1719b725ae77Skettenis case 0x4:
1720b725ae77Skettenis case 0x5: /* data transfer */
1721b725ae77Skettenis case 0x6:
1722b725ae77Skettenis case 0x7:
1723e93f7393Sniklas if (bit (this_instr, 20))
1724e93f7393Sniklas {
1725e93f7393Sniklas /* load */
1726e93f7393Sniklas if (bits (this_instr, 12, 15) == 15)
1727e93f7393Sniklas {
1728e93f7393Sniklas /* rd == pc */
1729e93f7393Sniklas unsigned long rn;
1730e93f7393Sniklas unsigned long base;
1731e93f7393Sniklas
1732e93f7393Sniklas if (bit (this_instr, 22))
1733e93f7393Sniklas error ("Illegal update to pc in instruction");
1734e93f7393Sniklas
1735e93f7393Sniklas /* byte write to PC */
1736e93f7393Sniklas rn = bits (this_instr, 16, 19);
1737e93f7393Sniklas base = (rn == 15) ? pc_val + 8 : read_register (rn);
1738e93f7393Sniklas if (bit (this_instr, 24))
1739e93f7393Sniklas {
1740e93f7393Sniklas /* pre-indexed */
1741e93f7393Sniklas int c = (status & FLAG_C) ? 1 : 0;
1742e93f7393Sniklas unsigned long offset =
1743e93f7393Sniklas (bit (this_instr, 25)
1744b725ae77Skettenis ? shifted_reg_val (this_instr, c, pc_val, status)
1745e93f7393Sniklas : bits (this_instr, 0, 11));
1746e93f7393Sniklas
1747e93f7393Sniklas if (bit (this_instr, 23))
1748e93f7393Sniklas base += offset;
1749e93f7393Sniklas else
1750e93f7393Sniklas base -= offset;
1751e93f7393Sniklas }
1752e93f7393Sniklas nextpc = (CORE_ADDR) read_memory_integer ((CORE_ADDR) base,
1753e93f7393Sniklas 4);
1754e93f7393Sniklas
1755e93f7393Sniklas nextpc = ADDR_BITS_REMOVE (nextpc);
1756e93f7393Sniklas
1757e93f7393Sniklas if (nextpc == pc)
1758e93f7393Sniklas error ("Infinite loop detected");
1759e93f7393Sniklas }
1760e93f7393Sniklas }
1761e93f7393Sniklas break;
1762e93f7393Sniklas
1763b725ae77Skettenis case 0x8:
1764b725ae77Skettenis case 0x9: /* block transfer */
1765e93f7393Sniklas if (bit (this_instr, 20))
1766e93f7393Sniklas {
1767e93f7393Sniklas /* LDM */
1768e93f7393Sniklas if (bit (this_instr, 15))
1769e93f7393Sniklas {
1770e93f7393Sniklas /* loading pc */
1771e93f7393Sniklas int offset = 0;
1772e93f7393Sniklas
1773e93f7393Sniklas if (bit (this_instr, 23))
1774e93f7393Sniklas {
1775e93f7393Sniklas /* up */
1776e93f7393Sniklas unsigned long reglist = bits (this_instr, 0, 14);
1777b725ae77Skettenis offset = bitcount (reglist) * 4;
1778e93f7393Sniklas if (bit (this_instr, 24)) /* pre */
1779e93f7393Sniklas offset += 4;
1780e93f7393Sniklas }
1781e93f7393Sniklas else if (bit (this_instr, 24))
1782e93f7393Sniklas offset = -4;
1783e93f7393Sniklas
1784e93f7393Sniklas {
1785e93f7393Sniklas unsigned long rn_val =
1786e93f7393Sniklas read_register (bits (this_instr, 16, 19));
1787e93f7393Sniklas nextpc =
1788e93f7393Sniklas (CORE_ADDR) read_memory_integer ((CORE_ADDR) (rn_val
1789e93f7393Sniklas + offset),
1790e93f7393Sniklas 4);
1791e93f7393Sniklas }
1792e93f7393Sniklas nextpc = ADDR_BITS_REMOVE (nextpc);
1793e93f7393Sniklas if (nextpc == pc)
1794e93f7393Sniklas error ("Infinite loop detected");
1795e93f7393Sniklas }
1796e93f7393Sniklas }
1797e93f7393Sniklas break;
1798e93f7393Sniklas
1799e93f7393Sniklas case 0xb: /* branch & link */
1800e93f7393Sniklas case 0xa: /* branch */
1801e93f7393Sniklas {
1802e93f7393Sniklas nextpc = BranchDest (pc, this_instr);
1803e93f7393Sniklas
1804b725ae77Skettenis /* BLX */
1805b725ae77Skettenis if (bits (this_instr, 28, 31) == INST_NV)
1806b725ae77Skettenis nextpc |= bit (this_instr, 24) << 1;
1807b725ae77Skettenis
1808e93f7393Sniklas nextpc = ADDR_BITS_REMOVE (nextpc);
1809e93f7393Sniklas if (nextpc == pc)
1810e93f7393Sniklas error ("Infinite loop detected");
1811e93f7393Sniklas break;
1812e93f7393Sniklas }
1813e93f7393Sniklas
1814b725ae77Skettenis case 0xc:
1815b725ae77Skettenis case 0xd:
1816e93f7393Sniklas case 0xe: /* coproc ops */
1817e93f7393Sniklas case 0xf: /* SWI */
1818e93f7393Sniklas break;
1819e93f7393Sniklas
1820e93f7393Sniklas default:
1821b725ae77Skettenis fprintf_filtered (gdb_stderr, "Bad bit-field extraction\n");
1822e93f7393Sniklas return (pc);
1823e93f7393Sniklas }
1824e93f7393Sniklas }
1825e93f7393Sniklas
1826e93f7393Sniklas return nextpc;
1827e93f7393Sniklas }
1828e93f7393Sniklas
1829b725ae77Skettenis /* single_step() is called just before we want to resume the inferior,
1830b725ae77Skettenis if we want to single-step it but there is no hardware or kernel
1831b725ae77Skettenis single-step support. We find the target of the coming instruction
1832b725ae77Skettenis and breakpoint it.
1833b725ae77Skettenis
1834b725ae77Skettenis single_step() is also called just after the inferior stops. If we
1835b725ae77Skettenis had set up a simulated single-step, we undo our damage. */
1836b725ae77Skettenis
1837b725ae77Skettenis static void
arm_software_single_step(enum target_signal sig,int insert_bpt)1838b725ae77Skettenis arm_software_single_step (enum target_signal sig, int insert_bpt)
1839e93f7393Sniklas {
1840b725ae77Skettenis static int next_pc; /* State between setting and unsetting. */
1841b725ae77Skettenis static char break_mem[BREAKPOINT_MAX]; /* Temporary storage for mem@bpt */
1842e93f7393Sniklas
1843b725ae77Skettenis if (insert_bpt)
1844b725ae77Skettenis {
1845b725ae77Skettenis next_pc = arm_get_next_pc (read_register (ARM_PC_REGNUM));
1846b725ae77Skettenis target_insert_breakpoint (next_pc, break_mem);
1847b725ae77Skettenis }
1848b725ae77Skettenis else
1849b725ae77Skettenis target_remove_breakpoint (next_pc, break_mem);
1850b725ae77Skettenis }
1851e93f7393Sniklas
1852b725ae77Skettenis #include "bfd-in2.h"
1853b725ae77Skettenis #include "libcoff.h"
1854e93f7393Sniklas
1855b725ae77Skettenis static int
gdb_print_insn_arm(bfd_vma memaddr,disassemble_info * info)1856b725ae77Skettenis gdb_print_insn_arm (bfd_vma memaddr, disassemble_info *info)
1857b725ae77Skettenis {
1858b725ae77Skettenis if (arm_pc_is_thumb (memaddr))
1859b725ae77Skettenis {
1860b725ae77Skettenis static asymbol *asym;
1861b725ae77Skettenis static combined_entry_type ce;
1862b725ae77Skettenis static struct coff_symbol_struct csym;
1863b725ae77Skettenis static struct bfd fake_bfd;
1864b725ae77Skettenis static bfd_target fake_target;
1865b725ae77Skettenis
1866b725ae77Skettenis if (csym.native == NULL)
1867b725ae77Skettenis {
1868b725ae77Skettenis /* Create a fake symbol vector containing a Thumb symbol.
1869b725ae77Skettenis This is solely so that the code in print_insn_little_arm()
1870b725ae77Skettenis and print_insn_big_arm() in opcodes/arm-dis.c will detect
1871b725ae77Skettenis the presence of a Thumb symbol and switch to decoding
1872b725ae77Skettenis Thumb instructions. */
1873b725ae77Skettenis
1874b725ae77Skettenis fake_target.flavour = bfd_target_coff_flavour;
1875b725ae77Skettenis fake_bfd.xvec = &fake_target;
1876b725ae77Skettenis ce.u.syment.n_sclass = C_THUMBEXTFUNC;
1877b725ae77Skettenis csym.native = &ce;
1878b725ae77Skettenis csym.symbol.the_bfd = &fake_bfd;
1879b725ae77Skettenis csym.symbol.name = "fake";
1880b725ae77Skettenis asym = (asymbol *) & csym;
1881b725ae77Skettenis }
1882b725ae77Skettenis
1883b725ae77Skettenis memaddr = UNMAKE_THUMB_ADDR (memaddr);
1884b725ae77Skettenis info->symbols = &asym;
1885b725ae77Skettenis }
1886b725ae77Skettenis else
1887b725ae77Skettenis info->symbols = NULL;
1888b725ae77Skettenis
1889b725ae77Skettenis if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
1890b725ae77Skettenis return print_insn_big_arm (memaddr, info);
1891b725ae77Skettenis else
1892b725ae77Skettenis return print_insn_little_arm (memaddr, info);
1893b725ae77Skettenis }
1894b725ae77Skettenis
1895b725ae77Skettenis /* The following define instruction sequences that will cause ARM
1896b725ae77Skettenis cpu's to take an undefined instruction trap. These are used to
1897b725ae77Skettenis signal a breakpoint to GDB.
1898b725ae77Skettenis
1899b725ae77Skettenis The newer ARMv4T cpu's are capable of operating in ARM or Thumb
1900b725ae77Skettenis modes. A different instruction is required for each mode. The ARM
1901b725ae77Skettenis cpu's can also be big or little endian. Thus four different
1902b725ae77Skettenis instructions are needed to support all cases.
1903b725ae77Skettenis
1904b725ae77Skettenis Note: ARMv4 defines several new instructions that will take the
1905b725ae77Skettenis undefined instruction trap. ARM7TDMI is nominally ARMv4T, but does
1906b725ae77Skettenis not in fact add the new instructions. The new undefined
1907b725ae77Skettenis instructions in ARMv4 are all instructions that had no defined
1908b725ae77Skettenis behaviour in earlier chips. There is no guarantee that they will
1909b725ae77Skettenis raise an exception, but may be treated as NOP's. In practice, it
1910b725ae77Skettenis may only safe to rely on instructions matching:
1911b725ae77Skettenis
1912b725ae77Skettenis 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1
1913b725ae77Skettenis 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
1914b725ae77Skettenis C C C C 0 1 1 x x x x x x x x x x x x x x x x x x x x 1 x x x x
1915b725ae77Skettenis
1916b725ae77Skettenis Even this may only true if the condition predicate is true. The
1917b725ae77Skettenis following use a condition predicate of ALWAYS so it is always TRUE.
1918b725ae77Skettenis
1919b725ae77Skettenis There are other ways of forcing a breakpoint. GNU/Linux, RISC iX,
1920b725ae77Skettenis and NetBSD all use a software interrupt rather than an undefined
1921b725ae77Skettenis instruction to force a trap. This can be handled by by the
1922b725ae77Skettenis abi-specific code during establishment of the gdbarch vector. */
1923b725ae77Skettenis
1924b725ae77Skettenis
1925b725ae77Skettenis /* NOTE rearnsha 2002-02-18: for now we allow a non-multi-arch gdb to
1926b725ae77Skettenis override these definitions. */
1927b725ae77Skettenis #ifndef ARM_LE_BREAKPOINT
1928b725ae77Skettenis #define ARM_LE_BREAKPOINT {0xFE,0xDE,0xFF,0xE7}
1929b725ae77Skettenis #endif
1930b725ae77Skettenis #ifndef ARM_BE_BREAKPOINT
1931b725ae77Skettenis #define ARM_BE_BREAKPOINT {0xE7,0xFF,0xDE,0xFE}
1932b725ae77Skettenis #endif
1933b725ae77Skettenis #ifndef THUMB_LE_BREAKPOINT
1934b725ae77Skettenis #define THUMB_LE_BREAKPOINT {0xfe,0xdf}
1935b725ae77Skettenis #endif
1936b725ae77Skettenis #ifndef THUMB_BE_BREAKPOINT
1937b725ae77Skettenis #define THUMB_BE_BREAKPOINT {0xdf,0xfe}
1938b725ae77Skettenis #endif
1939b725ae77Skettenis
1940b725ae77Skettenis static const char arm_default_arm_le_breakpoint[] = ARM_LE_BREAKPOINT;
1941b725ae77Skettenis static const char arm_default_arm_be_breakpoint[] = ARM_BE_BREAKPOINT;
1942b725ae77Skettenis static const char arm_default_thumb_le_breakpoint[] = THUMB_LE_BREAKPOINT;
1943b725ae77Skettenis static const char arm_default_thumb_be_breakpoint[] = THUMB_BE_BREAKPOINT;
1944b725ae77Skettenis
1945b725ae77Skettenis /* Determine the type and size of breakpoint to insert at PCPTR. Uses
1946b725ae77Skettenis the program counter value to determine whether a 16-bit or 32-bit
1947b725ae77Skettenis breakpoint should be used. It returns a pointer to a string of
1948b725ae77Skettenis bytes that encode a breakpoint instruction, stores the length of
1949b725ae77Skettenis the string to *lenptr, and adjusts the program counter (if
1950b725ae77Skettenis necessary) to point to the actual memory location where the
1951b725ae77Skettenis breakpoint should be inserted. */
1952b725ae77Skettenis
1953b725ae77Skettenis /* XXX ??? from old tm-arm.h: if we're using RDP, then we're inserting
1954b725ae77Skettenis breakpoints and storing their handles instread of what was in
1955b725ae77Skettenis memory. It is nice that this is the same size as a handle -
1956b725ae77Skettenis otherwise remote-rdp will have to change. */
1957b725ae77Skettenis
1958b725ae77Skettenis static const unsigned char *
arm_breakpoint_from_pc(CORE_ADDR * pcptr,int * lenptr)1959b725ae77Skettenis arm_breakpoint_from_pc (CORE_ADDR *pcptr, int *lenptr)
1960b725ae77Skettenis {
1961b725ae77Skettenis struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
1962b725ae77Skettenis
1963b725ae77Skettenis if (arm_pc_is_thumb (*pcptr) || arm_pc_is_thumb_dummy (*pcptr))
1964b725ae77Skettenis {
1965b725ae77Skettenis *pcptr = UNMAKE_THUMB_ADDR (*pcptr);
1966b725ae77Skettenis *lenptr = tdep->thumb_breakpoint_size;
1967b725ae77Skettenis return tdep->thumb_breakpoint;
1968b725ae77Skettenis }
1969b725ae77Skettenis else
1970b725ae77Skettenis {
1971b725ae77Skettenis *lenptr = tdep->arm_breakpoint_size;
1972b725ae77Skettenis return tdep->arm_breakpoint;
1973b725ae77Skettenis }
1974b725ae77Skettenis }
1975b725ae77Skettenis
1976b725ae77Skettenis /* Extract from an array REGBUF containing the (raw) register state a
1977b725ae77Skettenis function return value of type TYPE, and copy that, in virtual
1978b725ae77Skettenis format, into VALBUF. */
1979b725ae77Skettenis
1980b725ae77Skettenis static void
arm_extract_return_value(struct type * type,struct regcache * regs,void * dst)1981b725ae77Skettenis arm_extract_return_value (struct type *type,
1982b725ae77Skettenis struct regcache *regs,
1983b725ae77Skettenis void *dst)
1984b725ae77Skettenis {
1985b725ae77Skettenis bfd_byte *valbuf = dst;
1986b725ae77Skettenis
1987b725ae77Skettenis if (TYPE_CODE_FLT == TYPE_CODE (type))
1988b725ae77Skettenis {
1989b725ae77Skettenis switch (arm_get_fp_model (current_gdbarch))
1990b725ae77Skettenis {
1991b725ae77Skettenis case ARM_FLOAT_FPA:
1992b725ae77Skettenis {
1993b725ae77Skettenis /* The value is in register F0 in internal format. We need to
1994b725ae77Skettenis extract the raw value and then convert it to the desired
1995b725ae77Skettenis internal type. */
1996b725ae77Skettenis bfd_byte tmpbuf[FP_REGISTER_SIZE];
1997b725ae77Skettenis
1998b725ae77Skettenis regcache_cooked_read (regs, ARM_F0_REGNUM, tmpbuf);
1999b725ae77Skettenis convert_from_extended (floatformat_from_type (type), tmpbuf,
2000b725ae77Skettenis valbuf);
2001b725ae77Skettenis }
2002b725ae77Skettenis break;
2003b725ae77Skettenis
2004b725ae77Skettenis case ARM_FLOAT_SOFT_FPA:
2005b725ae77Skettenis case ARM_FLOAT_SOFT_VFP:
2006b725ae77Skettenis regcache_cooked_read (regs, ARM_A1_REGNUM, valbuf);
2007b725ae77Skettenis if (TYPE_LENGTH (type) > 4)
2008b725ae77Skettenis regcache_cooked_read (regs, ARM_A1_REGNUM + 1,
2009b725ae77Skettenis valbuf + INT_REGISTER_SIZE);
2010b725ae77Skettenis break;
2011b725ae77Skettenis
2012b725ae77Skettenis default:
2013b725ae77Skettenis internal_error
2014b725ae77Skettenis (__FILE__, __LINE__,
2015b725ae77Skettenis "arm_extract_return_value: Floating point model not supported");
2016b725ae77Skettenis break;
2017b725ae77Skettenis }
2018b725ae77Skettenis }
2019b725ae77Skettenis else if (TYPE_CODE (type) == TYPE_CODE_INT
2020b725ae77Skettenis || TYPE_CODE (type) == TYPE_CODE_CHAR
2021b725ae77Skettenis || TYPE_CODE (type) == TYPE_CODE_BOOL
2022b725ae77Skettenis || TYPE_CODE (type) == TYPE_CODE_PTR
2023b725ae77Skettenis || TYPE_CODE (type) == TYPE_CODE_REF
2024b725ae77Skettenis || TYPE_CODE (type) == TYPE_CODE_ENUM)
2025b725ae77Skettenis {
2026b725ae77Skettenis /* If the the type is a plain integer, then the access is
2027b725ae77Skettenis straight-forward. Otherwise we have to play around a bit more. */
2028b725ae77Skettenis int len = TYPE_LENGTH (type);
2029b725ae77Skettenis int regno = ARM_A1_REGNUM;
2030b725ae77Skettenis ULONGEST tmp;
2031b725ae77Skettenis
2032b725ae77Skettenis while (len > 0)
2033b725ae77Skettenis {
2034b725ae77Skettenis /* By using store_unsigned_integer we avoid having to do
2035b725ae77Skettenis anything special for small big-endian values. */
2036b725ae77Skettenis regcache_cooked_read_unsigned (regs, regno++, &tmp);
2037b725ae77Skettenis store_unsigned_integer (valbuf,
2038b725ae77Skettenis (len > INT_REGISTER_SIZE
2039b725ae77Skettenis ? INT_REGISTER_SIZE : len),
2040b725ae77Skettenis tmp);
2041b725ae77Skettenis len -= INT_REGISTER_SIZE;
2042b725ae77Skettenis valbuf += INT_REGISTER_SIZE;
2043b725ae77Skettenis }
2044b725ae77Skettenis }
2045b725ae77Skettenis else
2046b725ae77Skettenis {
2047b725ae77Skettenis /* For a structure or union the behaviour is as if the value had
2048b725ae77Skettenis been stored to word-aligned memory and then loaded into
2049b725ae77Skettenis registers with 32-bit load instruction(s). */
2050b725ae77Skettenis int len = TYPE_LENGTH (type);
2051b725ae77Skettenis int regno = ARM_A1_REGNUM;
2052b725ae77Skettenis bfd_byte tmpbuf[INT_REGISTER_SIZE];
2053b725ae77Skettenis
2054b725ae77Skettenis while (len > 0)
2055b725ae77Skettenis {
2056b725ae77Skettenis regcache_cooked_read (regs, regno++, tmpbuf);
2057b725ae77Skettenis memcpy (valbuf, tmpbuf,
2058b725ae77Skettenis len > INT_REGISTER_SIZE ? INT_REGISTER_SIZE : len);
2059b725ae77Skettenis len -= INT_REGISTER_SIZE;
2060b725ae77Skettenis valbuf += INT_REGISTER_SIZE;
2061b725ae77Skettenis }
2062b725ae77Skettenis }
2063b725ae77Skettenis }
2064b725ae77Skettenis
2065b725ae77Skettenis /* Extract from an array REGBUF containing the (raw) register state
2066b725ae77Skettenis the address in which a function should return its structure value. */
2067b725ae77Skettenis
2068b725ae77Skettenis static CORE_ADDR
arm_extract_struct_value_address(struct regcache * regcache)2069b725ae77Skettenis arm_extract_struct_value_address (struct regcache *regcache)
2070b725ae77Skettenis {
2071b725ae77Skettenis ULONGEST ret;
2072b725ae77Skettenis
2073b725ae77Skettenis regcache_cooked_read_unsigned (regcache, ARM_A1_REGNUM, &ret);
2074b725ae77Skettenis return ret;
2075b725ae77Skettenis }
2076b725ae77Skettenis
2077b725ae77Skettenis /* Will a function return an aggregate type in memory or in a
2078b725ae77Skettenis register? Return 0 if an aggregate type can be returned in a
2079b725ae77Skettenis register, 1 if it must be returned in memory. */
2080b725ae77Skettenis
2081b725ae77Skettenis static int
arm_use_struct_convention(int gcc_p,struct type * type)2082b725ae77Skettenis arm_use_struct_convention (int gcc_p, struct type *type)
2083b725ae77Skettenis {
2084b725ae77Skettenis int nRc;
2085b725ae77Skettenis enum type_code code;
2086b725ae77Skettenis
2087b725ae77Skettenis CHECK_TYPEDEF (type);
2088b725ae77Skettenis
2089b725ae77Skettenis /* In the ARM ABI, "integer" like aggregate types are returned in
2090b725ae77Skettenis registers. For an aggregate type to be integer like, its size
2091b725ae77Skettenis must be less than or equal to DEPRECATED_REGISTER_SIZE and the
2092b725ae77Skettenis offset of each addressable subfield must be zero. Note that bit
2093b725ae77Skettenis fields are not addressable, and all addressable subfields of
2094b725ae77Skettenis unions always start at offset zero.
2095b725ae77Skettenis
2096b725ae77Skettenis This function is based on the behaviour of GCC 2.95.1.
2097b725ae77Skettenis See: gcc/arm.c: arm_return_in_memory() for details.
2098b725ae77Skettenis
2099b725ae77Skettenis Note: All versions of GCC before GCC 2.95.2 do not set up the
2100b725ae77Skettenis parameters correctly for a function returning the following
2101b725ae77Skettenis structure: struct { float f;}; This should be returned in memory,
2102b725ae77Skettenis not a register. Richard Earnshaw sent me a patch, but I do not
2103b725ae77Skettenis know of any way to detect if a function like the above has been
2104b725ae77Skettenis compiled with the correct calling convention. */
2105b725ae77Skettenis
2106b725ae77Skettenis /* All aggregate types that won't fit in a register must be returned
2107b725ae77Skettenis in memory. */
2108b725ae77Skettenis if (TYPE_LENGTH (type) > DEPRECATED_REGISTER_SIZE)
2109b725ae77Skettenis {
2110b725ae77Skettenis return 1;
2111b725ae77Skettenis }
2112b725ae77Skettenis
2113b725ae77Skettenis /* The only aggregate types that can be returned in a register are
2114b725ae77Skettenis structs and unions. Arrays must be returned in memory. */
2115b725ae77Skettenis code = TYPE_CODE (type);
2116b725ae77Skettenis if ((TYPE_CODE_STRUCT != code) && (TYPE_CODE_UNION != code))
2117b725ae77Skettenis {
2118b725ae77Skettenis return 1;
2119b725ae77Skettenis }
2120b725ae77Skettenis
2121b725ae77Skettenis /* Assume all other aggregate types can be returned in a register.
2122b725ae77Skettenis Run a check for structures, unions and arrays. */
2123b725ae77Skettenis nRc = 0;
2124b725ae77Skettenis
2125b725ae77Skettenis if ((TYPE_CODE_STRUCT == code) || (TYPE_CODE_UNION == code))
2126b725ae77Skettenis {
2127b725ae77Skettenis int i;
2128b725ae77Skettenis /* Need to check if this struct/union is "integer" like. For
2129b725ae77Skettenis this to be true, its size must be less than or equal to
2130b725ae77Skettenis DEPRECATED_REGISTER_SIZE and the offset of each addressable
2131b725ae77Skettenis subfield must be zero. Note that bit fields are not
2132b725ae77Skettenis addressable, and unions always start at offset zero. If any
2133b725ae77Skettenis of the subfields is a floating point type, the struct/union
2134b725ae77Skettenis cannot be an integer type. */
2135b725ae77Skettenis
2136b725ae77Skettenis /* For each field in the object, check:
2137b725ae77Skettenis 1) Is it FP? --> yes, nRc = 1;
2138b725ae77Skettenis 2) Is it addressable (bitpos != 0) and
2139b725ae77Skettenis not packed (bitsize == 0)?
2140b725ae77Skettenis --> yes, nRc = 1
2141b725ae77Skettenis */
2142b725ae77Skettenis
2143b725ae77Skettenis for (i = 0; i < TYPE_NFIELDS (type); i++)
2144b725ae77Skettenis {
2145b725ae77Skettenis enum type_code field_type_code;
2146b725ae77Skettenis field_type_code = TYPE_CODE (check_typedef (TYPE_FIELD_TYPE (type, i)));
2147b725ae77Skettenis
2148b725ae77Skettenis /* Is it a floating point type field? */
2149b725ae77Skettenis if (field_type_code == TYPE_CODE_FLT)
2150b725ae77Skettenis {
2151b725ae77Skettenis nRc = 1;
2152b725ae77Skettenis break;
2153b725ae77Skettenis }
2154b725ae77Skettenis
2155b725ae77Skettenis /* If bitpos != 0, then we have to care about it. */
2156b725ae77Skettenis if (TYPE_FIELD_BITPOS (type, i) != 0)
2157b725ae77Skettenis {
2158b725ae77Skettenis /* Bitfields are not addressable. If the field bitsize is
2159b725ae77Skettenis zero, then the field is not packed. Hence it cannot be
2160b725ae77Skettenis a bitfield or any other packed type. */
2161b725ae77Skettenis if (TYPE_FIELD_BITSIZE (type, i) == 0)
2162b725ae77Skettenis {
2163b725ae77Skettenis nRc = 1;
2164b725ae77Skettenis break;
2165b725ae77Skettenis }
2166b725ae77Skettenis }
2167b725ae77Skettenis }
2168b725ae77Skettenis }
2169b725ae77Skettenis
2170b725ae77Skettenis return nRc;
2171b725ae77Skettenis }
2172b725ae77Skettenis
2173b725ae77Skettenis /* Write into appropriate registers a function return value of type
2174b725ae77Skettenis TYPE, given in virtual format. */
2175b725ae77Skettenis
2176b725ae77Skettenis static void
arm_store_return_value(struct type * type,struct regcache * regs,const void * src)2177b725ae77Skettenis arm_store_return_value (struct type *type, struct regcache *regs,
2178b725ae77Skettenis const void *src)
2179b725ae77Skettenis {
2180b725ae77Skettenis const bfd_byte *valbuf = src;
2181b725ae77Skettenis
2182b725ae77Skettenis if (TYPE_CODE (type) == TYPE_CODE_FLT)
2183b725ae77Skettenis {
2184b725ae77Skettenis char buf[MAX_REGISTER_SIZE];
2185b725ae77Skettenis
2186b725ae77Skettenis switch (arm_get_fp_model (current_gdbarch))
2187b725ae77Skettenis {
2188b725ae77Skettenis case ARM_FLOAT_FPA:
2189b725ae77Skettenis
2190b725ae77Skettenis convert_to_extended (floatformat_from_type (type), buf, valbuf);
2191b725ae77Skettenis regcache_cooked_write (regs, ARM_F0_REGNUM, buf);
2192b725ae77Skettenis break;
2193b725ae77Skettenis
2194b725ae77Skettenis case ARM_FLOAT_SOFT_FPA:
2195b725ae77Skettenis case ARM_FLOAT_SOFT_VFP:
2196b725ae77Skettenis regcache_cooked_write (regs, ARM_A1_REGNUM, valbuf);
2197b725ae77Skettenis if (TYPE_LENGTH (type) > 4)
2198b725ae77Skettenis regcache_cooked_write (regs, ARM_A1_REGNUM + 1,
2199b725ae77Skettenis valbuf + INT_REGISTER_SIZE);
2200b725ae77Skettenis break;
2201b725ae77Skettenis
2202b725ae77Skettenis default:
2203b725ae77Skettenis internal_error
2204b725ae77Skettenis (__FILE__, __LINE__,
2205b725ae77Skettenis "arm_store_return_value: Floating point model not supported");
2206b725ae77Skettenis break;
2207b725ae77Skettenis }
2208b725ae77Skettenis }
2209b725ae77Skettenis else if (TYPE_CODE (type) == TYPE_CODE_INT
2210b725ae77Skettenis || TYPE_CODE (type) == TYPE_CODE_CHAR
2211b725ae77Skettenis || TYPE_CODE (type) == TYPE_CODE_BOOL
2212b725ae77Skettenis || TYPE_CODE (type) == TYPE_CODE_PTR
2213b725ae77Skettenis || TYPE_CODE (type) == TYPE_CODE_REF
2214b725ae77Skettenis || TYPE_CODE (type) == TYPE_CODE_ENUM)
2215b725ae77Skettenis {
2216b725ae77Skettenis if (TYPE_LENGTH (type) <= 4)
2217b725ae77Skettenis {
2218b725ae77Skettenis /* Values of one word or less are zero/sign-extended and
2219b725ae77Skettenis returned in r0. */
2220b725ae77Skettenis bfd_byte tmpbuf[INT_REGISTER_SIZE];
2221b725ae77Skettenis LONGEST val = unpack_long (type, valbuf);
2222b725ae77Skettenis
2223b725ae77Skettenis store_signed_integer (tmpbuf, INT_REGISTER_SIZE, val);
2224b725ae77Skettenis regcache_cooked_write (regs, ARM_A1_REGNUM, tmpbuf);
2225b725ae77Skettenis }
2226b725ae77Skettenis else
2227b725ae77Skettenis {
2228b725ae77Skettenis /* Integral values greater than one word are stored in consecutive
2229b725ae77Skettenis registers starting with r0. This will always be a multiple of
2230b725ae77Skettenis the regiser size. */
2231b725ae77Skettenis int len = TYPE_LENGTH (type);
2232b725ae77Skettenis int regno = ARM_A1_REGNUM;
2233b725ae77Skettenis
2234b725ae77Skettenis while (len > 0)
2235b725ae77Skettenis {
2236b725ae77Skettenis regcache_cooked_write (regs, regno++, valbuf);
2237b725ae77Skettenis len -= INT_REGISTER_SIZE;
2238b725ae77Skettenis valbuf += INT_REGISTER_SIZE;
2239b725ae77Skettenis }
2240b725ae77Skettenis }
2241b725ae77Skettenis }
2242b725ae77Skettenis else
2243b725ae77Skettenis {
2244b725ae77Skettenis /* For a structure or union the behaviour is as if the value had
2245b725ae77Skettenis been stored to word-aligned memory and then loaded into
2246b725ae77Skettenis registers with 32-bit load instruction(s). */
2247b725ae77Skettenis int len = TYPE_LENGTH (type);
2248b725ae77Skettenis int regno = ARM_A1_REGNUM;
2249b725ae77Skettenis bfd_byte tmpbuf[INT_REGISTER_SIZE];
2250b725ae77Skettenis
2251b725ae77Skettenis while (len > 0)
2252b725ae77Skettenis {
2253b725ae77Skettenis memcpy (tmpbuf, valbuf,
2254b725ae77Skettenis len > INT_REGISTER_SIZE ? INT_REGISTER_SIZE : len);
2255b725ae77Skettenis regcache_cooked_write (regs, regno++, tmpbuf);
2256b725ae77Skettenis len -= INT_REGISTER_SIZE;
2257b725ae77Skettenis valbuf += INT_REGISTER_SIZE;
2258b725ae77Skettenis }
2259b725ae77Skettenis }
2260b725ae77Skettenis }
2261b725ae77Skettenis
2262b725ae77Skettenis static int
arm_get_longjmp_target(CORE_ADDR * pc)2263b725ae77Skettenis arm_get_longjmp_target (CORE_ADDR *pc)
2264b725ae77Skettenis {
2265b725ae77Skettenis CORE_ADDR jb_addr;
2266b725ae77Skettenis char buf[INT_REGISTER_SIZE];
2267b725ae77Skettenis struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
2268b725ae77Skettenis
2269b725ae77Skettenis jb_addr = read_register (ARM_A1_REGNUM);
2270b725ae77Skettenis
2271b725ae77Skettenis if (target_read_memory (jb_addr + tdep->jb_pc * tdep->jb_elt_size, buf,
2272b725ae77Skettenis INT_REGISTER_SIZE))
2273b725ae77Skettenis return 0;
2274b725ae77Skettenis
2275b725ae77Skettenis *pc = extract_unsigned_integer (buf, INT_REGISTER_SIZE);
2276b725ae77Skettenis return 1;
2277b725ae77Skettenis }
2278b725ae77Skettenis
2279b725ae77Skettenis /* Return non-zero if the PC is inside a thumb call thunk. */
2280b725ae77Skettenis
2281b725ae77Skettenis int
arm_in_call_stub(CORE_ADDR pc,char * name)2282b725ae77Skettenis arm_in_call_stub (CORE_ADDR pc, char *name)
2283b725ae77Skettenis {
2284b725ae77Skettenis CORE_ADDR start_addr;
2285b725ae77Skettenis
2286b725ae77Skettenis /* Find the starting address of the function containing the PC. If
2287b725ae77Skettenis the caller didn't give us a name, look it up at the same time. */
2288b725ae77Skettenis if (0 == find_pc_partial_function (pc, name ? NULL : &name,
2289b725ae77Skettenis &start_addr, NULL))
2290b725ae77Skettenis return 0;
2291b725ae77Skettenis
2292b725ae77Skettenis return strncmp (name, "_call_via_r", 11) == 0;
2293b725ae77Skettenis }
2294b725ae77Skettenis
2295b725ae77Skettenis /* If PC is in a Thumb call or return stub, return the address of the
2296b725ae77Skettenis target PC, which is in a register. The thunk functions are called
2297b725ae77Skettenis _called_via_xx, where x is the register name. The possible names
2298b725ae77Skettenis are r0-r9, sl, fp, ip, sp, and lr. */
2299b725ae77Skettenis
2300b725ae77Skettenis CORE_ADDR
arm_skip_stub(CORE_ADDR pc)2301b725ae77Skettenis arm_skip_stub (CORE_ADDR pc)
2302b725ae77Skettenis {
2303b725ae77Skettenis char *name;
2304b725ae77Skettenis CORE_ADDR start_addr;
2305b725ae77Skettenis
2306b725ae77Skettenis /* Find the starting address and name of the function containing the PC. */
2307b725ae77Skettenis if (find_pc_partial_function (pc, &name, &start_addr, NULL) == 0)
2308b725ae77Skettenis return 0;
2309b725ae77Skettenis
2310b725ae77Skettenis /* Call thunks always start with "_call_via_". */
2311b725ae77Skettenis if (strncmp (name, "_call_via_", 10) == 0)
2312b725ae77Skettenis {
2313b725ae77Skettenis /* Use the name suffix to determine which register contains the
2314b725ae77Skettenis target PC. */
2315b725ae77Skettenis static char *table[15] =
2316b725ae77Skettenis {"r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
2317b725ae77Skettenis "r8", "r9", "sl", "fp", "ip", "sp", "lr"
2318b725ae77Skettenis };
2319b725ae77Skettenis int regno;
2320b725ae77Skettenis
2321b725ae77Skettenis for (regno = 0; regno <= 14; regno++)
2322b725ae77Skettenis if (strcmp (&name[10], table[regno]) == 0)
2323b725ae77Skettenis return read_register (regno);
2324b725ae77Skettenis }
2325b725ae77Skettenis
2326b725ae77Skettenis return 0; /* not a stub */
2327b725ae77Skettenis }
2328b725ae77Skettenis
2329b725ae77Skettenis static void
set_arm_command(char * args,int from_tty)2330b725ae77Skettenis set_arm_command (char *args, int from_tty)
2331b725ae77Skettenis {
2332b725ae77Skettenis printf_unfiltered ("\"set arm\" must be followed by an apporpriate subcommand.\n");
2333b725ae77Skettenis help_list (setarmcmdlist, "set arm ", all_commands, gdb_stdout);
2334b725ae77Skettenis }
2335b725ae77Skettenis
2336b725ae77Skettenis static void
show_arm_command(char * args,int from_tty)2337b725ae77Skettenis show_arm_command (char *args, int from_tty)
2338b725ae77Skettenis {
2339b725ae77Skettenis cmd_show_list (showarmcmdlist, from_tty, "");
2340b725ae77Skettenis }
2341b725ae77Skettenis
2342b725ae77Skettenis enum arm_float_model
arm_get_fp_model(struct gdbarch * gdbarch)2343b725ae77Skettenis arm_get_fp_model (struct gdbarch *gdbarch)
2344b725ae77Skettenis {
2345b725ae77Skettenis if (arm_fp_model == ARM_FLOAT_AUTO)
2346b725ae77Skettenis return gdbarch_tdep (gdbarch)->fp_model;
2347b725ae77Skettenis
2348b725ae77Skettenis return arm_fp_model;
2349b725ae77Skettenis }
2350b725ae77Skettenis
2351b725ae77Skettenis static void
arm_set_fp(struct gdbarch * gdbarch)2352b725ae77Skettenis arm_set_fp (struct gdbarch *gdbarch)
2353b725ae77Skettenis {
2354b725ae77Skettenis enum arm_float_model fp_model = arm_get_fp_model (gdbarch);
2355b725ae77Skettenis
2356b725ae77Skettenis if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_LITTLE
2357b725ae77Skettenis && (fp_model == ARM_FLOAT_SOFT_FPA || fp_model == ARM_FLOAT_FPA))
2358b725ae77Skettenis {
2359b725ae77Skettenis set_gdbarch_double_format (gdbarch,
2360b725ae77Skettenis &floatformat_ieee_double_littlebyte_bigword);
2361b725ae77Skettenis set_gdbarch_long_double_format
2362b725ae77Skettenis (gdbarch, &floatformat_ieee_double_littlebyte_bigword);
2363b725ae77Skettenis }
2364b725ae77Skettenis else
2365b725ae77Skettenis {
2366b725ae77Skettenis set_gdbarch_double_format (gdbarch, &floatformat_ieee_double_little);
2367b725ae77Skettenis set_gdbarch_long_double_format (gdbarch,
2368b725ae77Skettenis &floatformat_ieee_double_little);
2369b725ae77Skettenis }
2370b725ae77Skettenis }
2371b725ae77Skettenis
2372b725ae77Skettenis static void
set_fp_model_sfunc(char * args,int from_tty,struct cmd_list_element * c)2373b725ae77Skettenis set_fp_model_sfunc (char *args, int from_tty,
2374b725ae77Skettenis struct cmd_list_element *c)
2375b725ae77Skettenis {
2376b725ae77Skettenis enum arm_float_model fp_model;
2377b725ae77Skettenis
2378b725ae77Skettenis for (fp_model = ARM_FLOAT_AUTO; fp_model != ARM_FLOAT_LAST; fp_model++)
2379b725ae77Skettenis if (strcmp (current_fp_model, fp_model_strings[fp_model]) == 0)
2380b725ae77Skettenis {
2381b725ae77Skettenis arm_fp_model = fp_model;
2382b725ae77Skettenis break;
2383b725ae77Skettenis }
2384b725ae77Skettenis
2385b725ae77Skettenis if (fp_model == ARM_FLOAT_LAST)
2386b725ae77Skettenis internal_error (__FILE__, __LINE__, "Invalid fp model accepted: %s.",
2387b725ae77Skettenis current_fp_model);
2388b725ae77Skettenis
2389b725ae77Skettenis if (gdbarch_bfd_arch_info (current_gdbarch)->arch == bfd_arch_arm)
2390b725ae77Skettenis arm_set_fp (current_gdbarch);
2391b725ae77Skettenis }
2392b725ae77Skettenis
2393b725ae77Skettenis static void
show_fp_model(char * args,int from_tty,struct cmd_list_element * c)2394b725ae77Skettenis show_fp_model (char *args, int from_tty,
2395b725ae77Skettenis struct cmd_list_element *c)
2396b725ae77Skettenis {
2397b725ae77Skettenis struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
2398b725ae77Skettenis
2399b725ae77Skettenis if (arm_fp_model == ARM_FLOAT_AUTO
2400b725ae77Skettenis && gdbarch_bfd_arch_info (current_gdbarch)->arch == bfd_arch_arm)
2401b725ae77Skettenis printf_filtered (" - the default for the current ABI is \"%s\".\n",
2402b725ae77Skettenis fp_model_strings[tdep->fp_model]);
2403b725ae77Skettenis }
2404b725ae77Skettenis
2405b725ae77Skettenis /* If the user changes the register disassembly style used for info
2406b725ae77Skettenis register and other commands, we have to also switch the style used
2407b725ae77Skettenis in opcodes for disassembly output. This function is run in the "set
2408b725ae77Skettenis arm disassembly" command, and does that. */
2409b725ae77Skettenis
2410b725ae77Skettenis static void
set_disassembly_style_sfunc(char * args,int from_tty,struct cmd_list_element * c)2411b725ae77Skettenis set_disassembly_style_sfunc (char *args, int from_tty,
2412b725ae77Skettenis struct cmd_list_element *c)
2413b725ae77Skettenis {
2414b725ae77Skettenis set_disassembly_style ();
2415b725ae77Skettenis }
2416b725ae77Skettenis
2417b725ae77Skettenis /* Return the ARM register name corresponding to register I. */
2418b725ae77Skettenis static const char *
arm_register_name(int i)2419b725ae77Skettenis arm_register_name (int i)
2420b725ae77Skettenis {
2421b725ae77Skettenis return arm_register_names[i];
2422b725ae77Skettenis }
2423b725ae77Skettenis
2424b725ae77Skettenis static void
set_disassembly_style(void)2425b725ae77Skettenis set_disassembly_style (void)
2426b725ae77Skettenis {
2427b725ae77Skettenis const char *setname, *setdesc, **regnames;
2428b725ae77Skettenis int numregs, j;
2429b725ae77Skettenis
2430b725ae77Skettenis /* Find the style that the user wants in the opcodes table. */
2431b725ae77Skettenis int current = 0;
2432b725ae77Skettenis numregs = get_arm_regnames (current, &setname, &setdesc, ®names);
2433b725ae77Skettenis while ((disassembly_style != setname)
2434b725ae77Skettenis && (current < num_disassembly_options))
2435b725ae77Skettenis get_arm_regnames (++current, &setname, &setdesc, ®names);
2436b725ae77Skettenis current_option = current;
2437b725ae77Skettenis
2438b725ae77Skettenis /* Fill our copy. */
2439b725ae77Skettenis for (j = 0; j < numregs; j++)
2440b725ae77Skettenis arm_register_names[j] = (char *) regnames[j];
2441b725ae77Skettenis
2442b725ae77Skettenis /* Adjust case. */
2443b725ae77Skettenis if (isupper (*regnames[ARM_PC_REGNUM]))
2444b725ae77Skettenis {
2445b725ae77Skettenis arm_register_names[ARM_FPS_REGNUM] = "FPS";
2446b725ae77Skettenis arm_register_names[ARM_PS_REGNUM] = "CPSR";
2447b725ae77Skettenis }
2448b725ae77Skettenis else
2449b725ae77Skettenis {
2450b725ae77Skettenis arm_register_names[ARM_FPS_REGNUM] = "fps";
2451b725ae77Skettenis arm_register_names[ARM_PS_REGNUM] = "cpsr";
2452b725ae77Skettenis }
2453b725ae77Skettenis
2454b725ae77Skettenis /* Synchronize the disassembler. */
2455b725ae77Skettenis set_arm_regname_option (current);
2456b725ae77Skettenis }
2457b725ae77Skettenis
2458b725ae77Skettenis /* arm_othernames implements the "othernames" command. This is deprecated
2459b725ae77Skettenis by the "set arm disassembly" command. */
2460b725ae77Skettenis
2461b725ae77Skettenis static void
arm_othernames(char * names,int n)2462b725ae77Skettenis arm_othernames (char *names, int n)
2463b725ae77Skettenis {
2464b725ae77Skettenis /* Circle through the various flavors. */
2465b725ae77Skettenis current_option = (current_option + 1) % num_disassembly_options;
2466b725ae77Skettenis
2467b725ae77Skettenis disassembly_style = valid_disassembly_styles[current_option];
2468b725ae77Skettenis set_disassembly_style ();
2469b725ae77Skettenis }
2470b725ae77Skettenis
2471b725ae77Skettenis /* Test whether the coff symbol specific value corresponds to a Thumb
2472b725ae77Skettenis function. */
2473b725ae77Skettenis
2474b725ae77Skettenis static int
coff_sym_is_thumb(int val)2475b725ae77Skettenis coff_sym_is_thumb (int val)
2476b725ae77Skettenis {
2477b725ae77Skettenis return (val == C_THUMBEXT ||
2478b725ae77Skettenis val == C_THUMBSTAT ||
2479b725ae77Skettenis val == C_THUMBEXTFUNC ||
2480b725ae77Skettenis val == C_THUMBSTATFUNC ||
2481b725ae77Skettenis val == C_THUMBLABEL);
2482b725ae77Skettenis }
2483b725ae77Skettenis
2484b725ae77Skettenis /* arm_coff_make_msymbol_special()
2485b725ae77Skettenis arm_elf_make_msymbol_special()
2486b725ae77Skettenis
2487b725ae77Skettenis These functions test whether the COFF or ELF symbol corresponds to
2488b725ae77Skettenis an address in thumb code, and set a "special" bit in a minimal
2489b725ae77Skettenis symbol to indicate that it does. */
2490b725ae77Skettenis
2491b725ae77Skettenis static void
arm_elf_make_msymbol_special(asymbol * sym,struct minimal_symbol * msym)2492b725ae77Skettenis arm_elf_make_msymbol_special(asymbol *sym, struct minimal_symbol *msym)
2493b725ae77Skettenis {
2494b725ae77Skettenis /* Thumb symbols are of type STT_LOPROC, (synonymous with
2495b725ae77Skettenis STT_ARM_TFUNC). */
2496b725ae77Skettenis if (ELF_ST_TYPE (((elf_symbol_type *)sym)->internal_elf_sym.st_info)
2497b725ae77Skettenis == STT_LOPROC)
2498b725ae77Skettenis MSYMBOL_SET_SPECIAL (msym);
2499b725ae77Skettenis }
2500b725ae77Skettenis
2501b725ae77Skettenis static void
arm_coff_make_msymbol_special(int val,struct minimal_symbol * msym)2502b725ae77Skettenis arm_coff_make_msymbol_special(int val, struct minimal_symbol *msym)
2503b725ae77Skettenis {
2504b725ae77Skettenis if (coff_sym_is_thumb (val))
2505b725ae77Skettenis MSYMBOL_SET_SPECIAL (msym);
2506b725ae77Skettenis }
2507b725ae77Skettenis
2508b725ae77Skettenis static void
arm_write_pc(CORE_ADDR pc,ptid_t ptid)2509b725ae77Skettenis arm_write_pc (CORE_ADDR pc, ptid_t ptid)
2510b725ae77Skettenis {
2511b725ae77Skettenis write_register_pid (ARM_PC_REGNUM, pc, ptid);
2512b725ae77Skettenis
2513b725ae77Skettenis /* If necessary, set the T bit. */
2514b725ae77Skettenis if (arm_apcs_32)
2515b725ae77Skettenis {
2516b725ae77Skettenis CORE_ADDR val = read_register_pid (ARM_PS_REGNUM, ptid);
2517b725ae77Skettenis if (arm_pc_is_thumb (pc))
2518b725ae77Skettenis write_register_pid (ARM_PS_REGNUM, val | 0x20, ptid);
2519b725ae77Skettenis else
2520b725ae77Skettenis write_register_pid (ARM_PS_REGNUM, val & ~(CORE_ADDR) 0x20, ptid);
2521b725ae77Skettenis }
2522b725ae77Skettenis }
2523b725ae77Skettenis
2524b725ae77Skettenis static enum gdb_osabi
arm_elf_osabi_sniffer(bfd * abfd)2525b725ae77Skettenis arm_elf_osabi_sniffer (bfd *abfd)
2526b725ae77Skettenis {
2527b725ae77Skettenis unsigned int elfosabi, eflags;
2528b725ae77Skettenis enum gdb_osabi osabi = GDB_OSABI_UNKNOWN;
2529b725ae77Skettenis
2530b725ae77Skettenis elfosabi = elf_elfheader (abfd)->e_ident[EI_OSABI];
2531b725ae77Skettenis
2532b725ae77Skettenis switch (elfosabi)
2533b725ae77Skettenis {
2534b725ae77Skettenis case ELFOSABI_NONE:
2535b725ae77Skettenis /* When elfosabi is ELFOSABI_NONE (0), then the ELF structures in the
2536b725ae77Skettenis file are conforming to the base specification for that machine
2537b725ae77Skettenis (there are no OS-specific extensions). In order to determine the
2538b725ae77Skettenis real OS in use we must look for OS notes that have been added. */
2539b725ae77Skettenis bfd_map_over_sections (abfd,
2540b725ae77Skettenis generic_elf_osabi_sniff_abi_tag_sections,
2541b725ae77Skettenis &osabi);
2542b725ae77Skettenis if (osabi == GDB_OSABI_UNKNOWN)
2543b725ae77Skettenis {
2544b725ae77Skettenis /* Existing ARM tools don't set this field, so look at the EI_FLAGS
2545b725ae77Skettenis field for more information. */
2546b725ae77Skettenis eflags = EF_ARM_EABI_VERSION(elf_elfheader(abfd)->e_flags);
2547b725ae77Skettenis switch (eflags)
2548b725ae77Skettenis {
2549b725ae77Skettenis case EF_ARM_EABI_VER1:
2550b725ae77Skettenis osabi = GDB_OSABI_ARM_EABI_V1;
2551b725ae77Skettenis break;
2552b725ae77Skettenis
2553b725ae77Skettenis case EF_ARM_EABI_VER2:
2554b725ae77Skettenis osabi = GDB_OSABI_ARM_EABI_V2;
2555b725ae77Skettenis break;
2556b725ae77Skettenis
2557b725ae77Skettenis case EF_ARM_EABI_UNKNOWN:
2558b725ae77Skettenis /* Assume GNU tools. */
2559b725ae77Skettenis osabi = GDB_OSABI_ARM_APCS;
2560b725ae77Skettenis break;
2561b725ae77Skettenis
2562b725ae77Skettenis default:
2563b725ae77Skettenis internal_error (__FILE__, __LINE__,
2564b725ae77Skettenis "arm_elf_osabi_sniffer: Unknown ARM EABI "
2565b725ae77Skettenis "version 0x%x", eflags);
2566b725ae77Skettenis }
2567b725ae77Skettenis }
2568b725ae77Skettenis break;
2569b725ae77Skettenis
2570b725ae77Skettenis case ELFOSABI_ARM:
2571b725ae77Skettenis /* GNU tools use this value. Check note sections in this case,
2572b725ae77Skettenis as well. */
2573b725ae77Skettenis bfd_map_over_sections (abfd,
2574b725ae77Skettenis generic_elf_osabi_sniff_abi_tag_sections,
2575b725ae77Skettenis &osabi);
2576b725ae77Skettenis if (osabi == GDB_OSABI_UNKNOWN)
2577b725ae77Skettenis {
2578b725ae77Skettenis /* Assume APCS ABI. */
2579b725ae77Skettenis osabi = GDB_OSABI_ARM_APCS;
2580b725ae77Skettenis }
2581b725ae77Skettenis break;
2582b725ae77Skettenis
2583b725ae77Skettenis case ELFOSABI_FREEBSD:
2584b725ae77Skettenis osabi = GDB_OSABI_FREEBSD_ELF;
2585b725ae77Skettenis break;
2586b725ae77Skettenis
2587b725ae77Skettenis case ELFOSABI_NETBSD:
2588b725ae77Skettenis osabi = GDB_OSABI_NETBSD_ELF;
2589b725ae77Skettenis break;
2590b725ae77Skettenis
2591b725ae77Skettenis case ELFOSABI_LINUX:
2592b725ae77Skettenis osabi = GDB_OSABI_LINUX;
2593b725ae77Skettenis break;
2594b725ae77Skettenis }
2595b725ae77Skettenis
2596b725ae77Skettenis return osabi;
2597b725ae77Skettenis }
2598b725ae77Skettenis
2599b725ae77Skettenis
2600b725ae77Skettenis /* Initialize the current architecture based on INFO. If possible,
2601b725ae77Skettenis re-use an architecture from ARCHES, which is a list of
2602b725ae77Skettenis architectures already created during this debugging session.
2603b725ae77Skettenis
2604b725ae77Skettenis Called e.g. at program startup, when reading a core file, and when
2605b725ae77Skettenis reading a binary file. */
2606b725ae77Skettenis
2607b725ae77Skettenis static struct gdbarch *
arm_gdbarch_init(struct gdbarch_info info,struct gdbarch_list * arches)2608b725ae77Skettenis arm_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
2609b725ae77Skettenis {
2610b725ae77Skettenis struct gdbarch_tdep *tdep;
2611b725ae77Skettenis struct gdbarch *gdbarch;
2612b725ae77Skettenis
2613b725ae77Skettenis /* Try to deterimine the ABI of the object we are loading. */
2614b725ae77Skettenis
2615b725ae77Skettenis if (info.abfd != NULL && info.osabi == GDB_OSABI_UNKNOWN)
2616b725ae77Skettenis {
2617b725ae77Skettenis switch (bfd_get_flavour (info.abfd))
2618b725ae77Skettenis {
2619b725ae77Skettenis case bfd_target_aout_flavour:
2620b725ae77Skettenis /* Assume it's an old APCS-style ABI. */
2621b725ae77Skettenis info.osabi = GDB_OSABI_ARM_APCS;
2622b725ae77Skettenis break;
2623b725ae77Skettenis
2624b725ae77Skettenis case bfd_target_coff_flavour:
2625b725ae77Skettenis /* Assume it's an old APCS-style ABI. */
2626b725ae77Skettenis /* XXX WinCE? */
2627b725ae77Skettenis info.osabi = GDB_OSABI_ARM_APCS;
2628b725ae77Skettenis break;
2629b725ae77Skettenis
2630b725ae77Skettenis default:
2631b725ae77Skettenis /* Leave it as "unknown". */
2632b725ae77Skettenis break;
2633b725ae77Skettenis }
2634b725ae77Skettenis }
2635b725ae77Skettenis
2636b725ae77Skettenis /* If there is already a candidate, use it. */
2637b725ae77Skettenis arches = gdbarch_list_lookup_by_info (arches, &info);
2638b725ae77Skettenis if (arches != NULL)
2639b725ae77Skettenis return arches->gdbarch;
2640b725ae77Skettenis
2641b725ae77Skettenis tdep = xmalloc (sizeof (struct gdbarch_tdep));
2642b725ae77Skettenis gdbarch = gdbarch_alloc (&info, tdep);
2643b725ae77Skettenis
2644b725ae77Skettenis /* We used to default to FPA for generic ARM, but almost nobody uses that
2645b725ae77Skettenis now, and we now provide a way for the user to force the model. So
2646b725ae77Skettenis default to the most useful variant. */
2647b725ae77Skettenis tdep->fp_model = ARM_FLOAT_SOFT_FPA;
2648b725ae77Skettenis
2649b725ae77Skettenis /* Breakpoints. */
2650b725ae77Skettenis switch (info.byte_order)
2651b725ae77Skettenis {
2652b725ae77Skettenis case BFD_ENDIAN_BIG:
2653b725ae77Skettenis tdep->arm_breakpoint = arm_default_arm_be_breakpoint;
2654b725ae77Skettenis tdep->arm_breakpoint_size = sizeof (arm_default_arm_be_breakpoint);
2655b725ae77Skettenis tdep->thumb_breakpoint = arm_default_thumb_be_breakpoint;
2656b725ae77Skettenis tdep->thumb_breakpoint_size = sizeof (arm_default_thumb_be_breakpoint);
2657b725ae77Skettenis
2658b725ae77Skettenis break;
2659b725ae77Skettenis
2660b725ae77Skettenis case BFD_ENDIAN_LITTLE:
2661b725ae77Skettenis tdep->arm_breakpoint = arm_default_arm_le_breakpoint;
2662b725ae77Skettenis tdep->arm_breakpoint_size = sizeof (arm_default_arm_le_breakpoint);
2663b725ae77Skettenis tdep->thumb_breakpoint = arm_default_thumb_le_breakpoint;
2664b725ae77Skettenis tdep->thumb_breakpoint_size = sizeof (arm_default_thumb_le_breakpoint);
2665b725ae77Skettenis
2666b725ae77Skettenis break;
2667b725ae77Skettenis
2668b725ae77Skettenis default:
2669b725ae77Skettenis internal_error (__FILE__, __LINE__,
2670b725ae77Skettenis "arm_gdbarch_init: bad byte order for float format");
2671b725ae77Skettenis }
2672b725ae77Skettenis
2673b725ae77Skettenis /* On ARM targets char defaults to unsigned. */
2674b725ae77Skettenis set_gdbarch_char_signed (gdbarch, 0);
2675b725ae77Skettenis
2676b725ae77Skettenis /* This should be low enough for everything. */
2677b725ae77Skettenis tdep->lowest_pc = 0x20;
2678b725ae77Skettenis tdep->jb_pc = -1; /* Longjump support not enabled by default. */
2679b725ae77Skettenis
2680b725ae77Skettenis set_gdbarch_push_dummy_call (gdbarch, arm_push_dummy_call);
2681b725ae77Skettenis
2682b725ae77Skettenis set_gdbarch_write_pc (gdbarch, arm_write_pc);
2683b725ae77Skettenis
2684b725ae77Skettenis /* Frame handling. */
2685b725ae77Skettenis set_gdbarch_unwind_dummy_id (gdbarch, arm_unwind_dummy_id);
2686b725ae77Skettenis set_gdbarch_unwind_pc (gdbarch, arm_unwind_pc);
2687b725ae77Skettenis set_gdbarch_unwind_sp (gdbarch, arm_unwind_sp);
2688b725ae77Skettenis
2689b725ae77Skettenis frame_base_set_default (gdbarch, &arm_normal_base);
2690b725ae77Skettenis
2691b725ae77Skettenis /* Address manipulation. */
2692b725ae77Skettenis set_gdbarch_smash_text_address (gdbarch, arm_smash_text_address);
2693b725ae77Skettenis set_gdbarch_addr_bits_remove (gdbarch, arm_addr_bits_remove);
2694b725ae77Skettenis
2695b725ae77Skettenis /* Advance PC across function entry code. */
2696b725ae77Skettenis set_gdbarch_skip_prologue (gdbarch, arm_skip_prologue);
2697b725ae77Skettenis
2698b725ae77Skettenis /* Get the PC when a frame might not be available. */
2699b725ae77Skettenis set_gdbarch_deprecated_saved_pc_after_call (gdbarch, arm_saved_pc_after_call);
2700b725ae77Skettenis
2701b725ae77Skettenis /* The stack grows downward. */
2702b725ae77Skettenis set_gdbarch_inner_than (gdbarch, core_addr_lessthan);
2703b725ae77Skettenis
2704b725ae77Skettenis /* Breakpoint manipulation. */
2705b725ae77Skettenis set_gdbarch_breakpoint_from_pc (gdbarch, arm_breakpoint_from_pc);
2706b725ae77Skettenis
2707b725ae77Skettenis /* Information about registers, etc. */
2708b725ae77Skettenis set_gdbarch_print_float_info (gdbarch, arm_print_float_info);
2709b725ae77Skettenis set_gdbarch_deprecated_fp_regnum (gdbarch, ARM_FP_REGNUM); /* ??? */
2710b725ae77Skettenis set_gdbarch_sp_regnum (gdbarch, ARM_SP_REGNUM);
2711b725ae77Skettenis set_gdbarch_pc_regnum (gdbarch, ARM_PC_REGNUM);
2712b725ae77Skettenis set_gdbarch_deprecated_register_byte (gdbarch, arm_register_byte);
2713b725ae77Skettenis set_gdbarch_num_regs (gdbarch, NUM_GREGS + NUM_FREGS + NUM_SREGS);
2714b725ae77Skettenis set_gdbarch_register_type (gdbarch, arm_register_type);
2715b725ae77Skettenis
2716b725ae77Skettenis /* Internal <-> external register number maps. */
2717b725ae77Skettenis set_gdbarch_register_sim_regno (gdbarch, arm_register_sim_regno);
2718b725ae77Skettenis
2719b725ae77Skettenis /* Integer registers are 4 bytes. */
2720b725ae77Skettenis set_gdbarch_deprecated_register_size (gdbarch, 4);
2721b725ae77Skettenis set_gdbarch_register_name (gdbarch, arm_register_name);
2722b725ae77Skettenis
2723b725ae77Skettenis /* Returning results. */
2724b725ae77Skettenis set_gdbarch_extract_return_value (gdbarch, arm_extract_return_value);
2725b725ae77Skettenis set_gdbarch_store_return_value (gdbarch, arm_store_return_value);
2726*63addd46Skettenis set_gdbarch_deprecated_use_struct_convention (gdbarch, arm_use_struct_convention);
2727b725ae77Skettenis set_gdbarch_deprecated_extract_struct_value_address (gdbarch, arm_extract_struct_value_address);
2728b725ae77Skettenis
2729b725ae77Skettenis /* Single stepping. */
2730b725ae77Skettenis /* XXX For an RDI target we should ask the target if it can single-step. */
2731b725ae77Skettenis set_gdbarch_software_single_step (gdbarch, arm_software_single_step);
2732b725ae77Skettenis
2733b725ae77Skettenis /* Disassembly. */
2734b725ae77Skettenis set_gdbarch_print_insn (gdbarch, gdb_print_insn_arm);
2735b725ae77Skettenis
2736b725ae77Skettenis /* Minsymbol frobbing. */
2737b725ae77Skettenis set_gdbarch_elf_make_msymbol_special (gdbarch, arm_elf_make_msymbol_special);
2738b725ae77Skettenis set_gdbarch_coff_make_msymbol_special (gdbarch,
2739b725ae77Skettenis arm_coff_make_msymbol_special);
2740b725ae77Skettenis
2741b725ae77Skettenis /* Hook in the ABI-specific overrides, if they have been registered. */
2742b725ae77Skettenis gdbarch_init_osabi (info, gdbarch);
2743b725ae77Skettenis
2744b725ae77Skettenis /* Add some default predicates. */
2745b725ae77Skettenis frame_unwind_append_sniffer (gdbarch, arm_sigtramp_unwind_sniffer);
2746b725ae77Skettenis frame_unwind_append_sniffer (gdbarch, arm_prologue_unwind_sniffer);
2747b725ae77Skettenis
2748b725ae77Skettenis /* Now we have tuned the configuration, set a few final things,
2749b725ae77Skettenis based on what the OS ABI has told us. */
2750b725ae77Skettenis
2751b725ae77Skettenis if (tdep->jb_pc >= 0)
2752b725ae77Skettenis set_gdbarch_get_longjmp_target (gdbarch, arm_get_longjmp_target);
2753b725ae77Skettenis
2754b725ae77Skettenis /* Floating point sizes and format. */
2755b725ae77Skettenis switch (info.byte_order)
2756b725ae77Skettenis {
2757b725ae77Skettenis case BFD_ENDIAN_BIG:
2758b725ae77Skettenis set_gdbarch_float_format (gdbarch, &floatformat_ieee_single_big);
2759b725ae77Skettenis set_gdbarch_double_format (gdbarch, &floatformat_ieee_double_big);
2760b725ae77Skettenis set_gdbarch_long_double_format (gdbarch, &floatformat_ieee_double_big);
2761b725ae77Skettenis
2762b725ae77Skettenis break;
2763b725ae77Skettenis
2764b725ae77Skettenis case BFD_ENDIAN_LITTLE:
2765b725ae77Skettenis set_gdbarch_float_format (gdbarch, &floatformat_ieee_single_little);
2766b725ae77Skettenis arm_set_fp (gdbarch);
2767b725ae77Skettenis break;
2768b725ae77Skettenis
2769b725ae77Skettenis default:
2770b725ae77Skettenis internal_error (__FILE__, __LINE__,
2771b725ae77Skettenis "arm_gdbarch_init: bad byte order for float format");
2772b725ae77Skettenis }
2773b725ae77Skettenis
2774b725ae77Skettenis return gdbarch;
2775b725ae77Skettenis }
2776b725ae77Skettenis
2777b725ae77Skettenis static void
arm_dump_tdep(struct gdbarch * current_gdbarch,struct ui_file * file)2778b725ae77Skettenis arm_dump_tdep (struct gdbarch *current_gdbarch, struct ui_file *file)
2779b725ae77Skettenis {
2780b725ae77Skettenis struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
2781b725ae77Skettenis
2782b725ae77Skettenis if (tdep == NULL)
2783b725ae77Skettenis return;
2784b725ae77Skettenis
2785b725ae77Skettenis fprintf_unfiltered (file, "arm_dump_tdep: Lowest pc = 0x%lx",
2786b725ae77Skettenis (unsigned long) tdep->lowest_pc);
2787b725ae77Skettenis }
2788b725ae77Skettenis
2789b725ae77Skettenis static void
arm_init_abi_eabi_v1(struct gdbarch_info info,struct gdbarch * gdbarch)2790b725ae77Skettenis arm_init_abi_eabi_v1 (struct gdbarch_info info,
2791b725ae77Skettenis struct gdbarch *gdbarch)
2792b725ae77Skettenis {
2793b725ae77Skettenis /* Place-holder. */
2794b725ae77Skettenis }
2795b725ae77Skettenis
2796b725ae77Skettenis static void
arm_init_abi_eabi_v2(struct gdbarch_info info,struct gdbarch * gdbarch)2797b725ae77Skettenis arm_init_abi_eabi_v2 (struct gdbarch_info info,
2798b725ae77Skettenis struct gdbarch *gdbarch)
2799b725ae77Skettenis {
2800b725ae77Skettenis /* Place-holder. */
2801b725ae77Skettenis }
2802b725ae77Skettenis
2803b725ae77Skettenis static void
arm_init_abi_apcs(struct gdbarch_info info,struct gdbarch * gdbarch)2804b725ae77Skettenis arm_init_abi_apcs (struct gdbarch_info info,
2805b725ae77Skettenis struct gdbarch *gdbarch)
2806b725ae77Skettenis {
2807b725ae77Skettenis /* Place-holder. */
2808b725ae77Skettenis }
2809b725ae77Skettenis
2810b725ae77Skettenis extern initialize_file_ftype _initialize_arm_tdep; /* -Wmissing-prototypes */
2811b725ae77Skettenis
2812b725ae77Skettenis void
_initialize_arm_tdep(void)2813b725ae77Skettenis _initialize_arm_tdep (void)
2814b725ae77Skettenis {
2815b725ae77Skettenis struct ui_file *stb;
2816b725ae77Skettenis long length;
2817b725ae77Skettenis struct cmd_list_element *new_set, *new_show;
2818b725ae77Skettenis const char *setname;
2819b725ae77Skettenis const char *setdesc;
2820b725ae77Skettenis const char **regnames;
2821b725ae77Skettenis int numregs, i, j;
2822b725ae77Skettenis static char *helptext;
2823b725ae77Skettenis
2824b725ae77Skettenis gdbarch_register (bfd_arch_arm, arm_gdbarch_init, arm_dump_tdep);
2825b725ae77Skettenis
2826b725ae77Skettenis /* Register an ELF OS ABI sniffer for ARM binaries. */
2827b725ae77Skettenis gdbarch_register_osabi_sniffer (bfd_arch_arm,
2828b725ae77Skettenis bfd_target_elf_flavour,
2829b725ae77Skettenis arm_elf_osabi_sniffer);
2830b725ae77Skettenis
2831b725ae77Skettenis /* Register some ABI variants for embedded systems. */
2832b725ae77Skettenis gdbarch_register_osabi (bfd_arch_arm, 0, GDB_OSABI_ARM_EABI_V1,
2833b725ae77Skettenis arm_init_abi_eabi_v1);
2834b725ae77Skettenis gdbarch_register_osabi (bfd_arch_arm, 0, GDB_OSABI_ARM_EABI_V2,
2835b725ae77Skettenis arm_init_abi_eabi_v2);
2836b725ae77Skettenis gdbarch_register_osabi (bfd_arch_arm, 0, GDB_OSABI_ARM_APCS,
2837b725ae77Skettenis arm_init_abi_apcs);
2838b725ae77Skettenis
2839b725ae77Skettenis /* Get the number of possible sets of register names defined in opcodes. */
2840b725ae77Skettenis num_disassembly_options = get_arm_regname_num_options ();
2841b725ae77Skettenis
2842b725ae77Skettenis /* Add root prefix command for all "set arm"/"show arm" commands. */
2843b725ae77Skettenis add_prefix_cmd ("arm", no_class, set_arm_command,
2844b725ae77Skettenis "Various ARM-specific commands.",
2845b725ae77Skettenis &setarmcmdlist, "set arm ", 0, &setlist);
2846b725ae77Skettenis
2847b725ae77Skettenis add_prefix_cmd ("arm", no_class, show_arm_command,
2848b725ae77Skettenis "Various ARM-specific commands.",
2849b725ae77Skettenis &showarmcmdlist, "show arm ", 0, &showlist);
2850b725ae77Skettenis
2851b725ae77Skettenis /* Sync the opcode insn printer with our register viewer. */
2852b725ae77Skettenis parse_arm_disassembler_option ("reg-names-std");
2853b725ae77Skettenis
2854b725ae77Skettenis /* Begin creating the help text. */
2855b725ae77Skettenis stb = mem_fileopen ();
2856b725ae77Skettenis fprintf_unfiltered (stb, "Set the disassembly style.\n"
2857b725ae77Skettenis "The valid values are:\n");
2858b725ae77Skettenis
2859b725ae77Skettenis /* Initialize the array that will be passed to add_set_enum_cmd(). */
2860b725ae77Skettenis valid_disassembly_styles
2861b725ae77Skettenis = xmalloc ((num_disassembly_options + 1) * sizeof (char *));
2862b725ae77Skettenis for (i = 0; i < num_disassembly_options; i++)
2863b725ae77Skettenis {
2864b725ae77Skettenis numregs = get_arm_regnames (i, &setname, &setdesc, ®names);
2865b725ae77Skettenis valid_disassembly_styles[i] = setname;
2866b725ae77Skettenis fprintf_unfiltered (stb, "%s - %s\n", setname,
2867b725ae77Skettenis setdesc);
2868b725ae77Skettenis /* Copy the default names (if found) and synchronize disassembler. */
2869b725ae77Skettenis if (!strcmp (setname, "std"))
2870b725ae77Skettenis {
2871b725ae77Skettenis disassembly_style = setname;
2872b725ae77Skettenis current_option = i;
2873b725ae77Skettenis for (j = 0; j < numregs; j++)
2874b725ae77Skettenis arm_register_names[j] = (char *) regnames[j];
2875b725ae77Skettenis set_arm_regname_option (i);
2876b725ae77Skettenis }
2877b725ae77Skettenis }
2878b725ae77Skettenis /* Mark the end of valid options. */
2879b725ae77Skettenis valid_disassembly_styles[num_disassembly_options] = NULL;
2880b725ae77Skettenis
2881b725ae77Skettenis /* Finish the creation of the help text. */
2882b725ae77Skettenis fprintf_unfiltered (stb, "The default is \"std\".");
2883b725ae77Skettenis helptext = ui_file_xstrdup (stb, &length);
2884b725ae77Skettenis ui_file_delete (stb);
2885b725ae77Skettenis
2886b725ae77Skettenis /* Add the deprecated disassembly-flavor command. */
2887b725ae77Skettenis new_set = add_set_enum_cmd ("disassembly-flavor", no_class,
2888b725ae77Skettenis valid_disassembly_styles,
2889b725ae77Skettenis &disassembly_style,
2890b725ae77Skettenis helptext,
2891b725ae77Skettenis &setlist);
2892b725ae77Skettenis set_cmd_sfunc (new_set, set_disassembly_style_sfunc);
2893b725ae77Skettenis deprecate_cmd (new_set, "set arm disassembly");
2894*63addd46Skettenis deprecate_cmd (deprecated_add_show_from_set (new_set, &showlist),
2895b725ae77Skettenis "show arm disassembly");
2896b725ae77Skettenis
2897b725ae77Skettenis /* And now add the new interface. */
2898b725ae77Skettenis new_set = add_set_enum_cmd ("disassembler", no_class,
2899b725ae77Skettenis valid_disassembly_styles, &disassembly_style,
2900b725ae77Skettenis helptext, &setarmcmdlist);
2901b725ae77Skettenis
2902b725ae77Skettenis set_cmd_sfunc (new_set, set_disassembly_style_sfunc);
2903*63addd46Skettenis deprecated_add_show_from_set (new_set, &showarmcmdlist);
2904b725ae77Skettenis
2905*63addd46Skettenis add_setshow_boolean_cmd ("apcs32", no_class, &arm_apcs_32, "\
2906*63addd46Skettenis Set usage of ARM 32-bit mode.", "\
2907*63addd46Skettenis Show usage of ARM 32-bit mode.", "\
2908*63addd46Skettenis When off, a 26-bit PC will be used.\n\
2909*63addd46Skettenis When off, a 26-bit PC will be used.", "\
2910*63addd46Skettenis Usage of ARM 32-bit mode is %s.",
2911b725ae77Skettenis NULL, NULL,
2912b725ae77Skettenis &setarmcmdlist, &showarmcmdlist);
2913b725ae77Skettenis
2914b725ae77Skettenis /* Add a command to allow the user to force the FPU model. */
2915b725ae77Skettenis new_set = add_set_enum_cmd
2916b725ae77Skettenis ("fpu", no_class, fp_model_strings, ¤t_fp_model,
2917b725ae77Skettenis "Set the floating point type.\n"
2918b725ae77Skettenis "auto - Determine the FP typefrom the OS-ABI.\n"
2919b725ae77Skettenis "softfpa - Software FP, mixed-endian doubles on little-endian ARMs.\n"
2920b725ae77Skettenis "fpa - FPA co-processor (GCC compiled).\n"
2921b725ae77Skettenis "softvfp - Software FP with pure-endian doubles.\n"
2922b725ae77Skettenis "vfp - VFP co-processor.",
2923b725ae77Skettenis &setarmcmdlist);
2924b725ae77Skettenis set_cmd_sfunc (new_set, set_fp_model_sfunc);
2925*63addd46Skettenis set_cmd_sfunc (deprecated_add_show_from_set (new_set, &showarmcmdlist),
2926*63addd46Skettenis show_fp_model);
2927b725ae77Skettenis
2928b725ae77Skettenis /* Add the deprecated "othernames" command. */
2929b725ae77Skettenis deprecate_cmd (add_com ("othernames", class_obscure, arm_othernames,
2930b725ae77Skettenis "Switch to the next set of register names."),
2931b725ae77Skettenis "set arm disassembly");
2932b725ae77Skettenis
2933b725ae77Skettenis /* Debugging flag. */
2934*63addd46Skettenis add_setshow_boolean_cmd ("arm", class_maintenance, &arm_debug, "\
2935*63addd46Skettenis Set ARM debugging.", "\
2936*63addd46Skettenis Show ARM debugging.", "\
2937*63addd46Skettenis When on, arm-specific debugging is enabled.", "\
2938*63addd46Skettenis ARM debugging is %s.",
2939b725ae77Skettenis NULL, NULL,
2940b725ae77Skettenis &setdebuglist, &showdebuglist);
2941e93f7393Sniklas }
2942