* arm-linux-tdep.c (arm_linux_software_single_step): New.
[deliverable/binutils-gdb.git] / gdb / arm-linux-tdep.c
1 /* GNU/Linux on ARM target support.
2
3 Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
4 Free Software Foundation, Inc.
5
6 This file is part of GDB.
7
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3 of the License, or
11 (at your option) any later version.
12
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with this program. If not, see <http://www.gnu.org/licenses/>. */
20
21 #include "defs.h"
22 #include "target.h"
23 #include "value.h"
24 #include "gdbtypes.h"
25 #include "floatformat.h"
26 #include "gdbcore.h"
27 #include "frame.h"
28 #include "regcache.h"
29 #include "doublest.h"
30 #include "solib-svr4.h"
31 #include "osabi.h"
32 #include "regset.h"
33 #include "trad-frame.h"
34 #include "tramp-frame.h"
35 #include "breakpoint.h"
36
37 #include "arm-tdep.h"
38 #include "arm-linux-tdep.h"
39 #include "glibc-tdep.h"
40
41 #include "gdb_string.h"
42
43 extern int arm_apcs_32;
44
45 /* Under ARM GNU/Linux the traditional way of performing a breakpoint
46 is to execute a particular software interrupt, rather than use a
47 particular undefined instruction to provoke a trap. Upon exection
48 of the software interrupt the kernel stops the inferior with a
49 SIGTRAP, and wakes the debugger. */
50
51 static const char arm_linux_arm_le_breakpoint[] = { 0x01, 0x00, 0x9f, 0xef };
52
53 static const char arm_linux_arm_be_breakpoint[] = { 0xef, 0x9f, 0x00, 0x01 };
54
55 /* However, the EABI syscall interface (new in Nov. 2005) does not look at
56 the operand of the swi if old-ABI compatibility is disabled. Therefore,
57 use an undefined instruction instead. This is supported as of kernel
58 version 2.5.70 (May 2003), so should be a safe assumption for EABI
59 binaries. */
60
61 static const char eabi_linux_arm_le_breakpoint[] = { 0xf0, 0x01, 0xf0, 0xe7 };
62
63 static const char eabi_linux_arm_be_breakpoint[] = { 0xe7, 0xf0, 0x01, 0xf0 };
64
65 /* All the kernels which support Thumb support using a specific undefined
66 instruction for the Thumb breakpoint. */
67
68 static const char arm_linux_thumb_be_breakpoint[] = {0xde, 0x01};
69
70 static const char arm_linux_thumb_le_breakpoint[] = {0x01, 0xde};
71
72 /* Description of the longjmp buffer. */
73 #define ARM_LINUX_JB_ELEMENT_SIZE INT_REGISTER_SIZE
74 #define ARM_LINUX_JB_PC 21
75
76 /*
77 Dynamic Linking on ARM GNU/Linux
78 --------------------------------
79
80 Note: PLT = procedure linkage table
81 GOT = global offset table
82
83 As much as possible, ELF dynamic linking defers the resolution of
84 jump/call addresses until the last minute. The technique used is
85 inspired by the i386 ELF design, and is based on the following
86 constraints.
87
88 1) The calling technique should not force a change in the assembly
89 code produced for apps; it MAY cause changes in the way assembly
90 code is produced for position independent code (i.e. shared
91 libraries).
92
93 2) The technique must be such that all executable areas must not be
94 modified; and any modified areas must not be executed.
95
96 To do this, there are three steps involved in a typical jump:
97
98 1) in the code
99 2) through the PLT
100 3) using a pointer from the GOT
101
102 When the executable or library is first loaded, each GOT entry is
103 initialized to point to the code which implements dynamic name
104 resolution and code finding. This is normally a function in the
105 program interpreter (on ARM GNU/Linux this is usually
106 ld-linux.so.2, but it does not have to be). On the first
107 invocation, the function is located and the GOT entry is replaced
108 with the real function address. Subsequent calls go through steps
109 1, 2 and 3 and end up calling the real code.
110
111 1) In the code:
112
113 b function_call
114 bl function_call
115
116 This is typical ARM code using the 26 bit relative branch or branch
117 and link instructions. The target of the instruction
118 (function_call is usually the address of the function to be called.
119 In position independent code, the target of the instruction is
120 actually an entry in the PLT when calling functions in a shared
121 library. Note that this call is identical to a normal function
122 call, only the target differs.
123
124 2) In the PLT:
125
126 The PLT is a synthetic area, created by the linker. It exists in
127 both executables and libraries. It is an array of stubs, one per
128 imported function call. It looks like this:
129
130 PLT[0]:
131 str lr, [sp, #-4]! @push the return address (lr)
132 ldr lr, [pc, #16] @load from 6 words ahead
133 add lr, pc, lr @form an address for GOT[0]
134 ldr pc, [lr, #8]! @jump to the contents of that addr
135
136 The return address (lr) is pushed on the stack and used for
137 calculations. The load on the second line loads the lr with
138 &GOT[3] - . - 20. The addition on the third leaves:
139
140 lr = (&GOT[3] - . - 20) + (. + 8)
141 lr = (&GOT[3] - 12)
142 lr = &GOT[0]
143
144 On the fourth line, the pc and lr are both updated, so that:
145
146 pc = GOT[2]
147 lr = &GOT[0] + 8
148 = &GOT[2]
149
150 NOTE: PLT[0] borrows an offset .word from PLT[1]. This is a little
151 "tight", but allows us to keep all the PLT entries the same size.
152
153 PLT[n+1]:
154 ldr ip, [pc, #4] @load offset from gotoff
155 add ip, pc, ip @add the offset to the pc
156 ldr pc, [ip] @jump to that address
157 gotoff: .word GOT[n+3] - .
158
159 The load on the first line, gets an offset from the fourth word of
160 the PLT entry. The add on the second line makes ip = &GOT[n+3],
161 which contains either a pointer to PLT[0] (the fixup trampoline) or
162 a pointer to the actual code.
163
164 3) In the GOT:
165
166 The GOT contains helper pointers for both code (PLT) fixups and
167 data fixups. The first 3 entries of the GOT are special. The next
168 M entries (where M is the number of entries in the PLT) belong to
169 the PLT fixups. The next D (all remaining) entries belong to
170 various data fixups. The actual size of the GOT is 3 + M + D.
171
172 The GOT is also a synthetic area, created by the linker. It exists
173 in both executables and libraries. When the GOT is first
174 initialized , all the GOT entries relating to PLT fixups are
175 pointing to code back at PLT[0].
176
177 The special entries in the GOT are:
178
179 GOT[0] = linked list pointer used by the dynamic loader
180 GOT[1] = pointer to the reloc table for this module
181 GOT[2] = pointer to the fixup/resolver code
182
183 The first invocation of function call comes through and uses the
184 fixup/resolver code. On the entry to the fixup/resolver code:
185
186 ip = &GOT[n+3]
187 lr = &GOT[2]
188 stack[0] = return address (lr) of the function call
189 [r0, r1, r2, r3] are still the arguments to the function call
190
191 This is enough information for the fixup/resolver code to work
192 with. Before the fixup/resolver code returns, it actually calls
193 the requested function and repairs &GOT[n+3]. */
194
195 /* The constants below were determined by examining the following files
196 in the linux kernel sources:
197
198 arch/arm/kernel/signal.c
199 - see SWI_SYS_SIGRETURN and SWI_SYS_RT_SIGRETURN
200 include/asm-arm/unistd.h
201 - see __NR_sigreturn, __NR_rt_sigreturn, and __NR_SYSCALL_BASE */
202
203 #define ARM_LINUX_SIGRETURN_INSTR 0xef900077
204 #define ARM_LINUX_RT_SIGRETURN_INSTR 0xef9000ad
205
206 /* For ARM EABI, the syscall number is not in the SWI instruction
207 (instead it is loaded into r7). We recognize the pattern that
208 glibc uses... alternatively, we could arrange to do this by
209 function name, but they are not always exported. */
210 #define ARM_SET_R7_SIGRETURN 0xe3a07077
211 #define ARM_SET_R7_RT_SIGRETURN 0xe3a070ad
212 #define ARM_EABI_SYSCALL 0xef000000
213
214 static void
215 arm_linux_sigtramp_cache (struct frame_info *next_frame,
216 struct trad_frame_cache *this_cache,
217 CORE_ADDR func, int regs_offset)
218 {
219 CORE_ADDR sp = frame_unwind_register_unsigned (next_frame, ARM_SP_REGNUM);
220 CORE_ADDR base = sp + regs_offset;
221 int i;
222
223 for (i = 0; i < 16; i++)
224 trad_frame_set_reg_addr (this_cache, i, base + i * 4);
225
226 trad_frame_set_reg_addr (this_cache, ARM_PS_REGNUM, base + 16 * 4);
227
228 /* The VFP or iWMMXt registers may be saved on the stack, but there's
229 no reliable way to restore them (yet). */
230
231 /* Save a frame ID. */
232 trad_frame_set_id (this_cache, frame_id_build (sp, func));
233 }
234
235 /* There are a couple of different possible stack layouts that
236 we need to support.
237
238 Before version 2.6.18, the kernel used completely independent
239 layouts for non-RT and RT signals. For non-RT signals the stack
240 began directly with a struct sigcontext. For RT signals the stack
241 began with two redundant pointers (to the siginfo and ucontext),
242 and then the siginfo and ucontext.
243
244 As of version 2.6.18, the non-RT signal frame layout starts with
245 a ucontext and the RT signal frame starts with a siginfo and then
246 a ucontext. Also, the ucontext now has a designated save area
247 for coprocessor registers.
248
249 For RT signals, it's easy to tell the difference: we look for
250 pinfo, the pointer to the siginfo. If it has the expected
251 value, we have an old layout. If it doesn't, we have the new
252 layout.
253
254 For non-RT signals, it's a bit harder. We need something in one
255 layout or the other with a recognizable offset and value. We can't
256 use the return trampoline, because ARM usually uses SA_RESTORER,
257 in which case the stack return trampoline is not filled in.
258 We can't use the saved stack pointer, because sigaltstack might
259 be in use. So for now we guess the new layout... */
260
261 /* There are three words (trap_no, error_code, oldmask) in
262 struct sigcontext before r0. */
263 #define ARM_SIGCONTEXT_R0 0xc
264
265 /* There are five words (uc_flags, uc_link, and three for uc_stack)
266 in the ucontext_t before the sigcontext. */
267 #define ARM_UCONTEXT_SIGCONTEXT 0x14
268
269 /* There are three elements in an rt_sigframe before the ucontext:
270 pinfo, puc, and info. The first two are pointers and the third
271 is a struct siginfo, with size 128 bytes. We could follow puc
272 to the ucontext, but it's simpler to skip the whole thing. */
273 #define ARM_OLD_RT_SIGFRAME_SIGINFO 0x8
274 #define ARM_OLD_RT_SIGFRAME_UCONTEXT 0x88
275
276 #define ARM_NEW_RT_SIGFRAME_UCONTEXT 0x80
277
278 #define ARM_NEW_SIGFRAME_MAGIC 0x5ac3c35a
279
280 static void
281 arm_linux_sigreturn_init (const struct tramp_frame *self,
282 struct frame_info *next_frame,
283 struct trad_frame_cache *this_cache,
284 CORE_ADDR func)
285 {
286 CORE_ADDR sp = frame_unwind_register_unsigned (next_frame, ARM_SP_REGNUM);
287 ULONGEST uc_flags = read_memory_unsigned_integer (sp, 4);
288
289 if (uc_flags == ARM_NEW_SIGFRAME_MAGIC)
290 arm_linux_sigtramp_cache (next_frame, this_cache, func,
291 ARM_UCONTEXT_SIGCONTEXT
292 + ARM_SIGCONTEXT_R0);
293 else
294 arm_linux_sigtramp_cache (next_frame, this_cache, func,
295 ARM_SIGCONTEXT_R0);
296 }
297
298 static void
299 arm_linux_rt_sigreturn_init (const struct tramp_frame *self,
300 struct frame_info *next_frame,
301 struct trad_frame_cache *this_cache,
302 CORE_ADDR func)
303 {
304 CORE_ADDR sp = frame_unwind_register_unsigned (next_frame, ARM_SP_REGNUM);
305 ULONGEST pinfo = read_memory_unsigned_integer (sp, 4);
306
307 if (pinfo == sp + ARM_OLD_RT_SIGFRAME_SIGINFO)
308 arm_linux_sigtramp_cache (next_frame, this_cache, func,
309 ARM_OLD_RT_SIGFRAME_UCONTEXT
310 + ARM_UCONTEXT_SIGCONTEXT
311 + ARM_SIGCONTEXT_R0);
312 else
313 arm_linux_sigtramp_cache (next_frame, this_cache, func,
314 ARM_NEW_RT_SIGFRAME_UCONTEXT
315 + ARM_UCONTEXT_SIGCONTEXT
316 + ARM_SIGCONTEXT_R0);
317 }
318
319 static struct tramp_frame arm_linux_sigreturn_tramp_frame = {
320 SIGTRAMP_FRAME,
321 4,
322 {
323 { ARM_LINUX_SIGRETURN_INSTR, -1 },
324 { TRAMP_SENTINEL_INSN }
325 },
326 arm_linux_sigreturn_init
327 };
328
329 static struct tramp_frame arm_linux_rt_sigreturn_tramp_frame = {
330 SIGTRAMP_FRAME,
331 4,
332 {
333 { ARM_LINUX_RT_SIGRETURN_INSTR, -1 },
334 { TRAMP_SENTINEL_INSN }
335 },
336 arm_linux_rt_sigreturn_init
337 };
338
339 static struct tramp_frame arm_eabi_linux_sigreturn_tramp_frame = {
340 SIGTRAMP_FRAME,
341 4,
342 {
343 { ARM_SET_R7_SIGRETURN, -1 },
344 { ARM_EABI_SYSCALL, -1 },
345 { TRAMP_SENTINEL_INSN }
346 },
347 arm_linux_sigreturn_init
348 };
349
350 static struct tramp_frame arm_eabi_linux_rt_sigreturn_tramp_frame = {
351 SIGTRAMP_FRAME,
352 4,
353 {
354 { ARM_SET_R7_RT_SIGRETURN, -1 },
355 { ARM_EABI_SYSCALL, -1 },
356 { TRAMP_SENTINEL_INSN }
357 },
358 arm_linux_rt_sigreturn_init
359 };
360
361 /* Core file and register set support. */
362
363 #define ARM_LINUX_SIZEOF_GREGSET (18 * INT_REGISTER_SIZE)
364
365 void
366 arm_linux_supply_gregset (const struct regset *regset,
367 struct regcache *regcache,
368 int regnum, const void *gregs_buf, size_t len)
369 {
370 const gdb_byte *gregs = gregs_buf;
371 int regno;
372 CORE_ADDR reg_pc;
373 gdb_byte pc_buf[INT_REGISTER_SIZE];
374
375 for (regno = ARM_A1_REGNUM; regno < ARM_PC_REGNUM; regno++)
376 if (regnum == -1 || regnum == regno)
377 regcache_raw_supply (regcache, regno,
378 gregs + INT_REGISTER_SIZE * regno);
379
380 if (regnum == ARM_PS_REGNUM || regnum == -1)
381 {
382 if (arm_apcs_32)
383 regcache_raw_supply (regcache, ARM_PS_REGNUM,
384 gregs + INT_REGISTER_SIZE * ARM_CPSR_REGNUM);
385 else
386 regcache_raw_supply (regcache, ARM_PS_REGNUM,
387 gregs + INT_REGISTER_SIZE * ARM_PC_REGNUM);
388 }
389
390 if (regnum == ARM_PC_REGNUM || regnum == -1)
391 {
392 reg_pc = extract_unsigned_integer (gregs
393 + INT_REGISTER_SIZE * ARM_PC_REGNUM,
394 INT_REGISTER_SIZE);
395 reg_pc = gdbarch_addr_bits_remove (current_gdbarch, reg_pc);
396 store_unsigned_integer (pc_buf, INT_REGISTER_SIZE, reg_pc);
397 regcache_raw_supply (regcache, ARM_PC_REGNUM, pc_buf);
398 }
399 }
400
401 void
402 arm_linux_collect_gregset (const struct regset *regset,
403 const struct regcache *regcache,
404 int regnum, void *gregs_buf, size_t len)
405 {
406 gdb_byte *gregs = gregs_buf;
407 int regno;
408
409 for (regno = ARM_A1_REGNUM; regno < ARM_PC_REGNUM; regno++)
410 if (regnum == -1 || regnum == regno)
411 regcache_raw_collect (regcache, regno,
412 gregs + INT_REGISTER_SIZE * regno);
413
414 if (regnum == ARM_PS_REGNUM || regnum == -1)
415 {
416 if (arm_apcs_32)
417 regcache_raw_collect (regcache, ARM_PS_REGNUM,
418 gregs + INT_REGISTER_SIZE * ARM_CPSR_REGNUM);
419 else
420 regcache_raw_collect (regcache, ARM_PS_REGNUM,
421 gregs + INT_REGISTER_SIZE * ARM_PC_REGNUM);
422 }
423
424 if (regnum == ARM_PC_REGNUM || regnum == -1)
425 regcache_raw_collect (regcache, ARM_PC_REGNUM,
426 gregs + INT_REGISTER_SIZE * ARM_PC_REGNUM);
427 }
428
429 /* Support for register format used by the NWFPE FPA emulator. */
430
431 #define typeNone 0x00
432 #define typeSingle 0x01
433 #define typeDouble 0x02
434 #define typeExtended 0x03
435
436 void
437 supply_nwfpe_register (struct regcache *regcache, int regno,
438 const gdb_byte *regs)
439 {
440 const gdb_byte *reg_data;
441 gdb_byte reg_tag;
442 gdb_byte buf[FP_REGISTER_SIZE];
443
444 reg_data = regs + (regno - ARM_F0_REGNUM) * FP_REGISTER_SIZE;
445 reg_tag = regs[(regno - ARM_F0_REGNUM) + NWFPE_TAGS_OFFSET];
446 memset (buf, 0, FP_REGISTER_SIZE);
447
448 switch (reg_tag)
449 {
450 case typeSingle:
451 memcpy (buf, reg_data, 4);
452 break;
453 case typeDouble:
454 memcpy (buf, reg_data + 4, 4);
455 memcpy (buf + 4, reg_data, 4);
456 break;
457 case typeExtended:
458 /* We want sign and exponent, then least significant bits,
459 then most significant. NWFPE does sign, most, least. */
460 memcpy (buf, reg_data, 4);
461 memcpy (buf + 4, reg_data + 8, 4);
462 memcpy (buf + 8, reg_data + 4, 4);
463 break;
464 default:
465 break;
466 }
467
468 regcache_raw_supply (regcache, regno, buf);
469 }
470
471 void
472 collect_nwfpe_register (const struct regcache *regcache, int regno,
473 gdb_byte *regs)
474 {
475 gdb_byte *reg_data;
476 gdb_byte reg_tag;
477 gdb_byte buf[FP_REGISTER_SIZE];
478
479 regcache_raw_collect (regcache, regno, buf);
480
481 /* NOTE drow/2006-06-07: This code uses the tag already in the
482 register buffer. I've preserved that when moving the code
483 from the native file to the target file. But this doesn't
484 always make sense. */
485
486 reg_data = regs + (regno - ARM_F0_REGNUM) * FP_REGISTER_SIZE;
487 reg_tag = regs[(regno - ARM_F0_REGNUM) + NWFPE_TAGS_OFFSET];
488
489 switch (reg_tag)
490 {
491 case typeSingle:
492 memcpy (reg_data, buf, 4);
493 break;
494 case typeDouble:
495 memcpy (reg_data, buf + 4, 4);
496 memcpy (reg_data + 4, buf, 4);
497 break;
498 case typeExtended:
499 memcpy (reg_data, buf, 4);
500 memcpy (reg_data + 4, buf + 8, 4);
501 memcpy (reg_data + 8, buf + 4, 4);
502 break;
503 default:
504 break;
505 }
506 }
507
508 void
509 arm_linux_supply_nwfpe (const struct regset *regset,
510 struct regcache *regcache,
511 int regnum, const void *regs_buf, size_t len)
512 {
513 const gdb_byte *regs = regs_buf;
514 int regno;
515
516 if (regnum == ARM_FPS_REGNUM || regnum == -1)
517 regcache_raw_supply (regcache, ARM_FPS_REGNUM,
518 regs + NWFPE_FPSR_OFFSET);
519
520 for (regno = ARM_F0_REGNUM; regno <= ARM_F7_REGNUM; regno++)
521 if (regnum == -1 || regnum == regno)
522 supply_nwfpe_register (regcache, regno, regs);
523 }
524
525 void
526 arm_linux_collect_nwfpe (const struct regset *regset,
527 const struct regcache *regcache,
528 int regnum, void *regs_buf, size_t len)
529 {
530 gdb_byte *regs = regs_buf;
531 int regno;
532
533 for (regno = ARM_F0_REGNUM; regno <= ARM_F7_REGNUM; regno++)
534 if (regnum == -1 || regnum == regno)
535 collect_nwfpe_register (regcache, regno, regs);
536
537 if (regnum == ARM_FPS_REGNUM || regnum == -1)
538 regcache_raw_collect (regcache, ARM_FPS_REGNUM,
539 regs + INT_REGISTER_SIZE * ARM_FPS_REGNUM);
540 }
541
542 /* Return the appropriate register set for the core section identified
543 by SECT_NAME and SECT_SIZE. */
544
545 static const struct regset *
546 arm_linux_regset_from_core_section (struct gdbarch *gdbarch,
547 const char *sect_name, size_t sect_size)
548 {
549 struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
550
551 if (strcmp (sect_name, ".reg") == 0
552 && sect_size == ARM_LINUX_SIZEOF_GREGSET)
553 {
554 if (tdep->gregset == NULL)
555 tdep->gregset = regset_alloc (gdbarch, arm_linux_supply_gregset,
556 arm_linux_collect_gregset);
557 return tdep->gregset;
558 }
559
560 if (strcmp (sect_name, ".reg2") == 0
561 && sect_size == ARM_LINUX_SIZEOF_NWFPE)
562 {
563 if (tdep->fpregset == NULL)
564 tdep->fpregset = regset_alloc (gdbarch, arm_linux_supply_nwfpe,
565 arm_linux_collect_nwfpe);
566 return tdep->fpregset;
567 }
568
569 return NULL;
570 }
571
572 /* Insert a single step breakpoint at the next executed instruction. */
573
574 int
575 arm_linux_software_single_step (struct frame_info *frame)
576 {
577 CORE_ADDR next_pc = arm_get_next_pc (frame, get_frame_pc (frame));
578
579 /* The Linux kernel offers some user-mode helpers in a high page. We can
580 not read this page (as of 2.6.23), and even if we could then we couldn't
581 set breakpoints in it, and even if we could then the atomic operations
582 would fail when interrupted. They are all called as functions and return
583 to the address in LR, so step to there instead. */
584 if (next_pc > 0xffff0000)
585 next_pc = get_frame_register_unsigned (frame, ARM_LR_REGNUM);
586
587 insert_single_step_breakpoint (next_pc);
588
589 return 1;
590 }
591
592 static void
593 arm_linux_init_abi (struct gdbarch_info info,
594 struct gdbarch *gdbarch)
595 {
596 struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
597
598 tdep->lowest_pc = 0x8000;
599 if (info.byte_order == BFD_ENDIAN_BIG)
600 {
601 if (tdep->arm_abi == ARM_ABI_AAPCS)
602 tdep->arm_breakpoint = eabi_linux_arm_be_breakpoint;
603 else
604 tdep->arm_breakpoint = arm_linux_arm_be_breakpoint;
605 tdep->thumb_breakpoint = arm_linux_thumb_be_breakpoint;
606 }
607 else
608 {
609 if (tdep->arm_abi == ARM_ABI_AAPCS)
610 tdep->arm_breakpoint = eabi_linux_arm_le_breakpoint;
611 else
612 tdep->arm_breakpoint = arm_linux_arm_le_breakpoint;
613 tdep->thumb_breakpoint = arm_linux_thumb_le_breakpoint;
614 }
615 tdep->arm_breakpoint_size = sizeof (arm_linux_arm_le_breakpoint);
616 tdep->thumb_breakpoint_size = sizeof (arm_linux_thumb_le_breakpoint);
617
618 if (tdep->fp_model == ARM_FLOAT_AUTO)
619 tdep->fp_model = ARM_FLOAT_FPA;
620
621 tdep->jb_pc = ARM_LINUX_JB_PC;
622 tdep->jb_elt_size = ARM_LINUX_JB_ELEMENT_SIZE;
623
624 set_solib_svr4_fetch_link_map_offsets
625 (gdbarch, svr4_ilp32_fetch_link_map_offsets);
626
627 /* Single stepping. */
628 set_gdbarch_software_single_step (gdbarch, arm_linux_software_single_step);
629
630 /* Shared library handling. */
631 set_gdbarch_skip_trampoline_code (gdbarch, find_solib_trampoline_target);
632 set_gdbarch_skip_solib_resolver (gdbarch, glibc_skip_solib_resolver);
633
634 /* Enable TLS support. */
635 set_gdbarch_fetch_tls_load_module_address (gdbarch,
636 svr4_fetch_objfile_link_map);
637
638 tramp_frame_prepend_unwinder (gdbarch,
639 &arm_linux_sigreturn_tramp_frame);
640 tramp_frame_prepend_unwinder (gdbarch,
641 &arm_linux_rt_sigreturn_tramp_frame);
642 tramp_frame_prepend_unwinder (gdbarch,
643 &arm_eabi_linux_sigreturn_tramp_frame);
644 tramp_frame_prepend_unwinder (gdbarch,
645 &arm_eabi_linux_rt_sigreturn_tramp_frame);
646
647 /* Core file support. */
648 set_gdbarch_regset_from_core_section (gdbarch,
649 arm_linux_regset_from_core_section);
650 }
651
652 void
653 _initialize_arm_linux_tdep (void)
654 {
655 gdbarch_register_osabi (bfd_arch_arm, 0, GDB_OSABI_LINUX,
656 arm_linux_init_abi);
657 }
This page took 0.04234 seconds and 4 git commands to generate.