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