OSDN Git Service

Updated copyright notices for most files.
[pf3gnuchains/pf3gnuchains3x.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, 2008
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 (get_regcache_arch (regcache), 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 }