OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-stable/] [gdb-7.2/] [gdb/] [arm-linux-tdep.c] - Blame information for rev 857

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 330 jeremybenn
/* GNU/Linux on ARM target support.
2
 
3
   Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008,
4
   2009, 2010 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 "linux-tdep.h"
40
#include "glibc-tdep.h"
41
#include "arch-utils.h"
42
#include "inferior.h"
43
#include "gdbthread.h"
44
#include "symfile.h"
45
 
46
#include "gdb_string.h"
47
 
48
extern int arm_apcs_32;
49
 
50
/* Under ARM GNU/Linux the traditional way of performing a breakpoint
51
   is to execute a particular software interrupt, rather than use a
52
   particular undefined instruction to provoke a trap.  Upon exection
53
   of the software interrupt the kernel stops the inferior with a
54
   SIGTRAP, and wakes the debugger.  */
55
 
56
static const char arm_linux_arm_le_breakpoint[] = { 0x01, 0x00, 0x9f, 0xef };
57
 
58
static const char arm_linux_arm_be_breakpoint[] = { 0xef, 0x9f, 0x00, 0x01 };
59
 
60
/* However, the EABI syscall interface (new in Nov. 2005) does not look at
61
   the operand of the swi if old-ABI compatibility is disabled.  Therefore,
62
   use an undefined instruction instead.  This is supported as of kernel
63
   version 2.5.70 (May 2003), so should be a safe assumption for EABI
64
   binaries.  */
65
 
66
static const char eabi_linux_arm_le_breakpoint[] = { 0xf0, 0x01, 0xf0, 0xe7 };
67
 
68
static const char eabi_linux_arm_be_breakpoint[] = { 0xe7, 0xf0, 0x01, 0xf0 };
69
 
70
/* All the kernels which support Thumb support using a specific undefined
71
   instruction for the Thumb breakpoint.  */
72
 
73
static const char arm_linux_thumb_be_breakpoint[] = {0xde, 0x01};
74
 
75
static const char arm_linux_thumb_le_breakpoint[] = {0x01, 0xde};
76
 
77
/* Because the 16-bit Thumb breakpoint is affected by Thumb-2 IT blocks,
78
   we must use a length-appropriate breakpoint for 32-bit Thumb
79
   instructions.  See also thumb_get_next_pc.  */
80
 
81
static const char arm_linux_thumb2_be_breakpoint[] = { 0xf7, 0xf0, 0xa0, 0x00 };
82
 
83
static const char arm_linux_thumb2_le_breakpoint[] = { 0xf0, 0xf7, 0x00, 0xa0 };
84
 
85
/* Description of the longjmp buffer.  The buffer is treated as an array of
86
   elements of size ARM_LINUX_JB_ELEMENT_SIZE.
87
 
88
   The location of saved registers in this buffer (in particular the PC
89
   to use after longjmp is called) varies depending on the ABI (in
90
   particular the FP model) and also (possibly) the C Library.
91
 
92
   For glibc, eglibc, and uclibc the following holds:  If the FP model is
93
   SoftVFP or VFP (which implies EABI) then the PC is at offset 9 in the
94
   buffer.  This is also true for the SoftFPA model.  However, for the FPA
95
   model the PC is at offset 21 in the buffer.  */
96
#define ARM_LINUX_JB_ELEMENT_SIZE       INT_REGISTER_SIZE
97
#define ARM_LINUX_JB_PC_FPA             21
98
#define ARM_LINUX_JB_PC_EABI            9
99
 
100
/*
101
   Dynamic Linking on ARM GNU/Linux
102
   --------------------------------
103
 
104
   Note: PLT = procedure linkage table
105
   GOT = global offset table
106
 
107
   As much as possible, ELF dynamic linking defers the resolution of
108
   jump/call addresses until the last minute. The technique used is
109
   inspired by the i386 ELF design, and is based on the following
110
   constraints.
111
 
112
   1) The calling technique should not force a change in the assembly
113
   code produced for apps; it MAY cause changes in the way assembly
114
   code is produced for position independent code (i.e. shared
115
   libraries).
116
 
117
   2) The technique must be such that all executable areas must not be
118
   modified; and any modified areas must not be executed.
119
 
120
   To do this, there are three steps involved in a typical jump:
121
 
122
   1) in the code
123
   2) through the PLT
124
   3) using a pointer from the GOT
125
 
126
   When the executable or library is first loaded, each GOT entry is
127
   initialized to point to the code which implements dynamic name
128
   resolution and code finding.  This is normally a function in the
129
   program interpreter (on ARM GNU/Linux this is usually
130
   ld-linux.so.2, but it does not have to be).  On the first
131
   invocation, the function is located and the GOT entry is replaced
132
   with the real function address.  Subsequent calls go through steps
133
   1, 2 and 3 and end up calling the real code.
134
 
135
   1) In the code:
136
 
137
   b    function_call
138
   bl   function_call
139
 
140
   This is typical ARM code using the 26 bit relative branch or branch
141
   and link instructions.  The target of the instruction
142
   (function_call is usually the address of the function to be called.
143
   In position independent code, the target of the instruction is
144
   actually an entry in the PLT when calling functions in a shared
145
   library.  Note that this call is identical to a normal function
146
   call, only the target differs.
147
 
148
   2) In the PLT:
149
 
150
   The PLT is a synthetic area, created by the linker. It exists in
151
   both executables and libraries. It is an array of stubs, one per
152
   imported function call. It looks like this:
153
 
154
   PLT[0]:
155
   str     lr, [sp, #-4]!       @push the return address (lr)
156
   ldr     lr, [pc, #16]   @load from 6 words ahead
157
   add     lr, pc, lr      @form an address for GOT[0]
158
   ldr     pc, [lr, #8]!   @jump to the contents of that addr
159
 
160
   The return address (lr) is pushed on the stack and used for
161
   calculations.  The load on the second line loads the lr with
162
   &GOT[3] - . - 20.  The addition on the third leaves:
163
 
164
   lr = (&GOT[3] - . - 20) + (. + 8)
165
   lr = (&GOT[3] - 12)
166
   lr = &GOT[0]
167
 
168
   On the fourth line, the pc and lr are both updated, so that:
169
 
170
   pc = GOT[2]
171
   lr = &GOT[0] + 8
172
   = &GOT[2]
173
 
174
   NOTE: PLT[0] borrows an offset .word from PLT[1]. This is a little
175
   "tight", but allows us to keep all the PLT entries the same size.
176
 
177
   PLT[n+1]:
178
   ldr     ip, [pc, #4]    @load offset from gotoff
179
   add     ip, pc, ip      @add the offset to the pc
180
   ldr     pc, [ip]        @jump to that address
181
   gotoff: .word   GOT[n+3] - .
182
 
183
   The load on the first line, gets an offset from the fourth word of
184
   the PLT entry.  The add on the second line makes ip = &GOT[n+3],
185
   which contains either a pointer to PLT[0] (the fixup trampoline) or
186
   a pointer to the actual code.
187
 
188
   3) In the GOT:
189
 
190
   The GOT contains helper pointers for both code (PLT) fixups and
191
   data fixups.  The first 3 entries of the GOT are special. The next
192
   M entries (where M is the number of entries in the PLT) belong to
193
   the PLT fixups. The next D (all remaining) entries belong to
194
   various data fixups. The actual size of the GOT is 3 + M + D.
195
 
196
   The GOT is also a synthetic area, created by the linker. It exists
197
   in both executables and libraries.  When the GOT is first
198
   initialized , all the GOT entries relating to PLT fixups are
199
   pointing to code back at PLT[0].
200
 
201
   The special entries in the GOT are:
202
 
203
   GOT[0] = linked list pointer used by the dynamic loader
204
   GOT[1] = pointer to the reloc table for this module
205
   GOT[2] = pointer to the fixup/resolver code
206
 
207
   The first invocation of function call comes through and uses the
208
   fixup/resolver code.  On the entry to the fixup/resolver code:
209
 
210
   ip = &GOT[n+3]
211
   lr = &GOT[2]
212
   stack[0] = return address (lr) of the function call
213
   [r0, r1, r2, r3] are still the arguments to the function call
214
 
215
   This is enough information for the fixup/resolver code to work
216
   with.  Before the fixup/resolver code returns, it actually calls
217
   the requested function and repairs &GOT[n+3].  */
218
 
219
/* The constants below were determined by examining the following files
220
   in the linux kernel sources:
221
 
222
      arch/arm/kernel/signal.c
223
          - see SWI_SYS_SIGRETURN and SWI_SYS_RT_SIGRETURN
224
      include/asm-arm/unistd.h
225
          - see __NR_sigreturn, __NR_rt_sigreturn, and __NR_SYSCALL_BASE */
226
 
227
#define ARM_LINUX_SIGRETURN_INSTR       0xef900077
228
#define ARM_LINUX_RT_SIGRETURN_INSTR    0xef9000ad
229
 
230
/* For ARM EABI, the syscall number is not in the SWI instruction
231
   (instead it is loaded into r7).  We recognize the pattern that
232
   glibc uses...  alternatively, we could arrange to do this by
233
   function name, but they are not always exported.  */
234
#define ARM_SET_R7_SIGRETURN            0xe3a07077
235
#define ARM_SET_R7_RT_SIGRETURN         0xe3a070ad
236
#define ARM_EABI_SYSCALL                0xef000000
237
 
238
/* OABI syscall restart trampoline, used for EABI executables too
239
   whenever OABI support has been enabled in the kernel.  */
240
#define ARM_OABI_SYSCALL_RESTART_SYSCALL 0xef900000
241
#define ARM_LDR_PC_SP_12                0xe49df00c
242
 
243
static void
244
arm_linux_sigtramp_cache (struct frame_info *this_frame,
245
                          struct trad_frame_cache *this_cache,
246
                          CORE_ADDR func, int regs_offset)
247
{
248
  CORE_ADDR sp = get_frame_register_unsigned (this_frame, ARM_SP_REGNUM);
249
  CORE_ADDR base = sp + regs_offset;
250
  int i;
251
 
252
  for (i = 0; i < 16; i++)
253
    trad_frame_set_reg_addr (this_cache, i, base + i * 4);
254
 
255
  trad_frame_set_reg_addr (this_cache, ARM_PS_REGNUM, base + 16 * 4);
256
 
257
  /* The VFP or iWMMXt registers may be saved on the stack, but there's
258
     no reliable way to restore them (yet).  */
259
 
260
  /* Save a frame ID.  */
261
  trad_frame_set_id (this_cache, frame_id_build (sp, func));
262
}
263
 
264
/* There are a couple of different possible stack layouts that
265
   we need to support.
266
 
267
   Before version 2.6.18, the kernel used completely independent
268
   layouts for non-RT and RT signals.  For non-RT signals the stack
269
   began directly with a struct sigcontext.  For RT signals the stack
270
   began with two redundant pointers (to the siginfo and ucontext),
271
   and then the siginfo and ucontext.
272
 
273
   As of version 2.6.18, the non-RT signal frame layout starts with
274
   a ucontext and the RT signal frame starts with a siginfo and then
275
   a ucontext.  Also, the ucontext now has a designated save area
276
   for coprocessor registers.
277
 
278
   For RT signals, it's easy to tell the difference: we look for
279
   pinfo, the pointer to the siginfo.  If it has the expected
280
   value, we have an old layout.  If it doesn't, we have the new
281
   layout.
282
 
283
   For non-RT signals, it's a bit harder.  We need something in one
284
   layout or the other with a recognizable offset and value.  We can't
285
   use the return trampoline, because ARM usually uses SA_RESTORER,
286
   in which case the stack return trampoline is not filled in.
287
   We can't use the saved stack pointer, because sigaltstack might
288
   be in use.  So for now we guess the new layout...  */
289
 
290
/* There are three words (trap_no, error_code, oldmask) in
291
   struct sigcontext before r0.  */
292
#define ARM_SIGCONTEXT_R0 0xc
293
 
294
/* There are five words (uc_flags, uc_link, and three for uc_stack)
295
   in the ucontext_t before the sigcontext.  */
296
#define ARM_UCONTEXT_SIGCONTEXT 0x14
297
 
298
/* There are three elements in an rt_sigframe before the ucontext:
299
   pinfo, puc, and info.  The first two are pointers and the third
300
   is a struct siginfo, with size 128 bytes.  We could follow puc
301
   to the ucontext, but it's simpler to skip the whole thing.  */
302
#define ARM_OLD_RT_SIGFRAME_SIGINFO 0x8
303
#define ARM_OLD_RT_SIGFRAME_UCONTEXT 0x88
304
 
305
#define ARM_NEW_RT_SIGFRAME_UCONTEXT 0x80
306
 
307
#define ARM_NEW_SIGFRAME_MAGIC 0x5ac3c35a
308
 
309
static void
310
arm_linux_sigreturn_init (const struct tramp_frame *self,
311
                          struct frame_info *this_frame,
312
                          struct trad_frame_cache *this_cache,
313
                          CORE_ADDR func)
314
{
315
  struct gdbarch *gdbarch = get_frame_arch (this_frame);
316
  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
317
  CORE_ADDR sp = get_frame_register_unsigned (this_frame, ARM_SP_REGNUM);
318
  ULONGEST uc_flags = read_memory_unsigned_integer (sp, 4, byte_order);
319
 
320
  if (uc_flags == ARM_NEW_SIGFRAME_MAGIC)
321
    arm_linux_sigtramp_cache (this_frame, this_cache, func,
322
                              ARM_UCONTEXT_SIGCONTEXT
323
                              + ARM_SIGCONTEXT_R0);
324
  else
325
    arm_linux_sigtramp_cache (this_frame, this_cache, func,
326
                              ARM_SIGCONTEXT_R0);
327
}
328
 
329
static void
330
arm_linux_rt_sigreturn_init (const struct tramp_frame *self,
331
                          struct frame_info *this_frame,
332
                          struct trad_frame_cache *this_cache,
333
                          CORE_ADDR func)
334
{
335
  struct gdbarch *gdbarch = get_frame_arch (this_frame);
336
  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
337
  CORE_ADDR sp = get_frame_register_unsigned (this_frame, ARM_SP_REGNUM);
338
  ULONGEST pinfo = read_memory_unsigned_integer (sp, 4, byte_order);
339
 
340
  if (pinfo == sp + ARM_OLD_RT_SIGFRAME_SIGINFO)
341
    arm_linux_sigtramp_cache (this_frame, this_cache, func,
342
                              ARM_OLD_RT_SIGFRAME_UCONTEXT
343
                              + ARM_UCONTEXT_SIGCONTEXT
344
                              + ARM_SIGCONTEXT_R0);
345
  else
346
    arm_linux_sigtramp_cache (this_frame, this_cache, func,
347
                              ARM_NEW_RT_SIGFRAME_UCONTEXT
348
                              + ARM_UCONTEXT_SIGCONTEXT
349
                              + ARM_SIGCONTEXT_R0);
350
}
351
 
352
static void
353
arm_linux_restart_syscall_init (const struct tramp_frame *self,
354
                                struct frame_info *this_frame,
355
                                struct trad_frame_cache *this_cache,
356
                                CORE_ADDR func)
357
{
358
  CORE_ADDR sp = get_frame_register_unsigned (this_frame, ARM_SP_REGNUM);
359
 
360
  trad_frame_set_reg_addr (this_cache, ARM_PC_REGNUM, sp);
361
  trad_frame_set_reg_value (this_cache, ARM_SP_REGNUM, sp + 12);
362
 
363
  /* Save a frame ID.  */
364
  trad_frame_set_id (this_cache, frame_id_build (sp, func));
365
}
366
 
367
static struct tramp_frame arm_linux_sigreturn_tramp_frame = {
368
  SIGTRAMP_FRAME,
369
  4,
370
  {
371
    { ARM_LINUX_SIGRETURN_INSTR, -1 },
372
    { TRAMP_SENTINEL_INSN }
373
  },
374
  arm_linux_sigreturn_init
375
};
376
 
377
static struct tramp_frame arm_linux_rt_sigreturn_tramp_frame = {
378
  SIGTRAMP_FRAME,
379
  4,
380
  {
381
    { ARM_LINUX_RT_SIGRETURN_INSTR, -1 },
382
    { TRAMP_SENTINEL_INSN }
383
  },
384
  arm_linux_rt_sigreturn_init
385
};
386
 
387
static struct tramp_frame arm_eabi_linux_sigreturn_tramp_frame = {
388
  SIGTRAMP_FRAME,
389
  4,
390
  {
391
    { ARM_SET_R7_SIGRETURN, -1 },
392
    { ARM_EABI_SYSCALL, -1 },
393
    { TRAMP_SENTINEL_INSN }
394
  },
395
  arm_linux_sigreturn_init
396
};
397
 
398
static struct tramp_frame arm_eabi_linux_rt_sigreturn_tramp_frame = {
399
  SIGTRAMP_FRAME,
400
  4,
401
  {
402
    { ARM_SET_R7_RT_SIGRETURN, -1 },
403
    { ARM_EABI_SYSCALL, -1 },
404
    { TRAMP_SENTINEL_INSN }
405
  },
406
  arm_linux_rt_sigreturn_init
407
};
408
 
409
static struct tramp_frame arm_linux_restart_syscall_tramp_frame = {
410
  NORMAL_FRAME,
411
  4,
412
  {
413
    { ARM_OABI_SYSCALL_RESTART_SYSCALL, -1 },
414
    { ARM_LDR_PC_SP_12, -1 },
415
    { TRAMP_SENTINEL_INSN }
416
  },
417
  arm_linux_restart_syscall_init
418
};
419
 
420
/* Core file and register set support.  */
421
 
422
#define ARM_LINUX_SIZEOF_GREGSET (18 * INT_REGISTER_SIZE)
423
 
424
void
425
arm_linux_supply_gregset (const struct regset *regset,
426
                          struct regcache *regcache,
427
                          int regnum, const void *gregs_buf, size_t len)
428
{
429
  struct gdbarch *gdbarch = get_regcache_arch (regcache);
430
  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
431
  const gdb_byte *gregs = gregs_buf;
432
  int regno;
433
  CORE_ADDR reg_pc;
434
  gdb_byte pc_buf[INT_REGISTER_SIZE];
435
 
436
  for (regno = ARM_A1_REGNUM; regno < ARM_PC_REGNUM; regno++)
437
    if (regnum == -1 || regnum == regno)
438
      regcache_raw_supply (regcache, regno,
439
                           gregs + INT_REGISTER_SIZE * regno);
440
 
441
  if (regnum == ARM_PS_REGNUM || regnum == -1)
442
    {
443
      if (arm_apcs_32)
444
        regcache_raw_supply (regcache, ARM_PS_REGNUM,
445
                             gregs + INT_REGISTER_SIZE * ARM_CPSR_GREGNUM);
446
      else
447
        regcache_raw_supply (regcache, ARM_PS_REGNUM,
448
                             gregs + INT_REGISTER_SIZE * ARM_PC_REGNUM);
449
    }
450
 
451
  if (regnum == ARM_PC_REGNUM || regnum == -1)
452
    {
453
      reg_pc = extract_unsigned_integer (gregs
454
                                         + INT_REGISTER_SIZE * ARM_PC_REGNUM,
455
                                         INT_REGISTER_SIZE, byte_order);
456
      reg_pc = gdbarch_addr_bits_remove (gdbarch, reg_pc);
457
      store_unsigned_integer (pc_buf, INT_REGISTER_SIZE, byte_order, reg_pc);
458
      regcache_raw_supply (regcache, ARM_PC_REGNUM, pc_buf);
459
    }
460
}
461
 
462
void
463
arm_linux_collect_gregset (const struct regset *regset,
464
                           const struct regcache *regcache,
465
                           int regnum, void *gregs_buf, size_t len)
466
{
467
  gdb_byte *gregs = gregs_buf;
468
  int regno;
469
 
470
  for (regno = ARM_A1_REGNUM; regno < ARM_PC_REGNUM; regno++)
471
    if (regnum == -1 || regnum == regno)
472
      regcache_raw_collect (regcache, regno,
473
                            gregs + INT_REGISTER_SIZE * regno);
474
 
475
  if (regnum == ARM_PS_REGNUM || regnum == -1)
476
    {
477
      if (arm_apcs_32)
478
        regcache_raw_collect (regcache, ARM_PS_REGNUM,
479
                              gregs + INT_REGISTER_SIZE * ARM_CPSR_GREGNUM);
480
      else
481
        regcache_raw_collect (regcache, ARM_PS_REGNUM,
482
                              gregs + INT_REGISTER_SIZE * ARM_PC_REGNUM);
483
    }
484
 
485
  if (regnum == ARM_PC_REGNUM || regnum == -1)
486
    regcache_raw_collect (regcache, ARM_PC_REGNUM,
487
                          gregs + INT_REGISTER_SIZE * ARM_PC_REGNUM);
488
}
489
 
490
/* Support for register format used by the NWFPE FPA emulator.  */
491
 
492
#define typeNone                0x00
493
#define typeSingle              0x01
494
#define typeDouble              0x02
495
#define typeExtended            0x03
496
 
497
void
498
supply_nwfpe_register (struct regcache *regcache, int regno,
499
                       const gdb_byte *regs)
500
{
501
  const gdb_byte *reg_data;
502
  gdb_byte reg_tag;
503
  gdb_byte buf[FP_REGISTER_SIZE];
504
 
505
  reg_data = regs + (regno - ARM_F0_REGNUM) * FP_REGISTER_SIZE;
506
  reg_tag = regs[(regno - ARM_F0_REGNUM) + NWFPE_TAGS_OFFSET];
507
  memset (buf, 0, FP_REGISTER_SIZE);
508
 
509
  switch (reg_tag)
510
    {
511
    case typeSingle:
512
      memcpy (buf, reg_data, 4);
513
      break;
514
    case typeDouble:
515
      memcpy (buf, reg_data + 4, 4);
516
      memcpy (buf + 4, reg_data, 4);
517
      break;
518
    case typeExtended:
519
      /* We want sign and exponent, then least significant bits,
520
         then most significant.  NWFPE does sign, most, least.  */
521
      memcpy (buf, reg_data, 4);
522
      memcpy (buf + 4, reg_data + 8, 4);
523
      memcpy (buf + 8, reg_data + 4, 4);
524
      break;
525
    default:
526
      break;
527
    }
528
 
529
  regcache_raw_supply (regcache, regno, buf);
530
}
531
 
532
void
533
collect_nwfpe_register (const struct regcache *regcache, int regno,
534
                        gdb_byte *regs)
535
{
536
  gdb_byte *reg_data;
537
  gdb_byte reg_tag;
538
  gdb_byte buf[FP_REGISTER_SIZE];
539
 
540
  regcache_raw_collect (regcache, regno, buf);
541
 
542
  /* NOTE drow/2006-06-07: This code uses the tag already in the
543
     register buffer.  I've preserved that when moving the code
544
     from the native file to the target file.  But this doesn't
545
     always make sense.  */
546
 
547
  reg_data = regs + (regno - ARM_F0_REGNUM) * FP_REGISTER_SIZE;
548
  reg_tag = regs[(regno - ARM_F0_REGNUM) + NWFPE_TAGS_OFFSET];
549
 
550
  switch (reg_tag)
551
    {
552
    case typeSingle:
553
      memcpy (reg_data, buf, 4);
554
      break;
555
    case typeDouble:
556
      memcpy (reg_data, buf + 4, 4);
557
      memcpy (reg_data + 4, buf, 4);
558
      break;
559
    case typeExtended:
560
      memcpy (reg_data, buf, 4);
561
      memcpy (reg_data + 4, buf + 8, 4);
562
      memcpy (reg_data + 8, buf + 4, 4);
563
      break;
564
    default:
565
      break;
566
    }
567
}
568
 
569
void
570
arm_linux_supply_nwfpe (const struct regset *regset,
571
                        struct regcache *regcache,
572
                        int regnum, const void *regs_buf, size_t len)
573
{
574
  const gdb_byte *regs = regs_buf;
575
  int regno;
576
 
577
  if (regnum == ARM_FPS_REGNUM || regnum == -1)
578
    regcache_raw_supply (regcache, ARM_FPS_REGNUM,
579
                         regs + NWFPE_FPSR_OFFSET);
580
 
581
  for (regno = ARM_F0_REGNUM; regno <= ARM_F7_REGNUM; regno++)
582
    if (regnum == -1 || regnum == regno)
583
      supply_nwfpe_register (regcache, regno, regs);
584
}
585
 
586
void
587
arm_linux_collect_nwfpe (const struct regset *regset,
588
                         const struct regcache *regcache,
589
                         int regnum, void *regs_buf, size_t len)
590
{
591
  gdb_byte *regs = regs_buf;
592
  int regno;
593
 
594
  for (regno = ARM_F0_REGNUM; regno <= ARM_F7_REGNUM; regno++)
595
    if (regnum == -1 || regnum == regno)
596
      collect_nwfpe_register (regcache, regno, regs);
597
 
598
  if (regnum == ARM_FPS_REGNUM || regnum == -1)
599
    regcache_raw_collect (regcache, ARM_FPS_REGNUM,
600
                          regs + INT_REGISTER_SIZE * ARM_FPS_REGNUM);
601
}
602
 
603
/* Return the appropriate register set for the core section identified
604
   by SECT_NAME and SECT_SIZE.  */
605
 
606
static const struct regset *
607
arm_linux_regset_from_core_section (struct gdbarch *gdbarch,
608
                                    const char *sect_name, size_t sect_size)
609
{
610
  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
611
 
612
  if (strcmp (sect_name, ".reg") == 0
613
      && sect_size == ARM_LINUX_SIZEOF_GREGSET)
614
    {
615
      if (tdep->gregset == NULL)
616
        tdep->gregset = regset_alloc (gdbarch, arm_linux_supply_gregset,
617
                                      arm_linux_collect_gregset);
618
      return tdep->gregset;
619
    }
620
 
621
  if (strcmp (sect_name, ".reg2") == 0
622
      && sect_size == ARM_LINUX_SIZEOF_NWFPE)
623
    {
624
      if (tdep->fpregset == NULL)
625
        tdep->fpregset = regset_alloc (gdbarch, arm_linux_supply_nwfpe,
626
                                       arm_linux_collect_nwfpe);
627
      return tdep->fpregset;
628
    }
629
 
630
  return NULL;
631
}
632
 
633
/* Copy the value of next pc of sigreturn and rt_sigrturn into PC,
634
   and return 1.  Return 0 if it is not a rt_sigreturn/sigreturn
635
   syscall.  */
636
static int
637
arm_linux_sigreturn_return_addr (struct frame_info *frame,
638
                                 unsigned long svc_number,
639
                                 CORE_ADDR *pc)
640
{
641
  /* Is this a sigreturn or rt_sigreturn syscall?  */
642
  if (svc_number == 119 || svc_number == 173)
643
    {
644
      if (get_frame_type (frame) == SIGTRAMP_FRAME)
645
        {
646
          *pc = frame_unwind_caller_pc (frame);
647
          return 1;
648
        }
649
    }
650
  return 0;
651
}
652
 
653
/* When FRAME is at a syscall instruction, return the PC of the next
654
   instruction to be executed.  */
655
 
656
static CORE_ADDR
657
arm_linux_syscall_next_pc (struct frame_info *frame)
658
{
659
  CORE_ADDR pc = get_frame_pc (frame);
660
  CORE_ADDR return_addr = 0;
661
  int is_thumb = arm_frame_is_thumb (frame);
662
  ULONGEST svc_number = 0;
663
  int is_sigreturn = 0;
664
 
665
  if (is_thumb)
666
    {
667
      svc_number = get_frame_register_unsigned (frame, 7);
668
    }
669
  else
670
    {
671
      struct gdbarch *gdbarch = get_frame_arch (frame);
672
      enum bfd_endian byte_order_for_code =
673
        gdbarch_byte_order_for_code (gdbarch);
674
      unsigned long this_instr =
675
        read_memory_unsigned_integer (pc, 4, byte_order_for_code);
676
 
677
      unsigned long svc_operand = (0x00ffffff & this_instr);
678
      if (svc_operand)  /* OABI.  */
679
        {
680
          svc_number = svc_operand - 0x900000;
681
        }
682
      else /* EABI.  */
683
        {
684
          svc_number = get_frame_register_unsigned (frame, 7);
685
        }
686
    }
687
 
688
  is_sigreturn = arm_linux_sigreturn_return_addr (frame, svc_number,
689
                                                  &return_addr);
690
 
691
  if (is_sigreturn)
692
    return return_addr;
693
 
694
  if (is_thumb)
695
    {
696
      return_addr = pc + 2;
697
      /* Addresses for calling Thumb functions have the bit 0 set.  */
698
      return_addr |= 1;
699
    }
700
  else
701
    {
702
      return_addr = pc + 4;
703
    }
704
 
705
  return return_addr;
706
}
707
 
708
 
709
/* Insert a single step breakpoint at the next executed instruction.  */
710
 
711
static int
712
arm_linux_software_single_step (struct frame_info *frame)
713
{
714
  struct gdbarch *gdbarch = get_frame_arch (frame);
715
  struct address_space *aspace = get_frame_address_space (frame);
716
  CORE_ADDR next_pc = arm_get_next_pc (frame, get_frame_pc (frame));
717
 
718
  /* The Linux kernel offers some user-mode helpers in a high page.  We can
719
     not read this page (as of 2.6.23), and even if we could then we couldn't
720
     set breakpoints in it, and even if we could then the atomic operations
721
     would fail when interrupted.  They are all called as functions and return
722
     to the address in LR, so step to there instead.  */
723
  if (next_pc > 0xffff0000)
724
    next_pc = get_frame_register_unsigned (frame, ARM_LR_REGNUM);
725
 
726
  insert_single_step_breakpoint (gdbarch, aspace, next_pc);
727
 
728
  return 1;
729
}
730
 
731
/* Support for displaced stepping of Linux SVC instructions.  */
732
 
733
static void
734
arm_linux_cleanup_svc (struct gdbarch *gdbarch,
735
                       struct regcache *regs,
736
                       struct displaced_step_closure *dsc)
737
{
738
  CORE_ADDR from = dsc->insn_addr;
739
  ULONGEST apparent_pc;
740
  int within_scratch;
741
 
742
  regcache_cooked_read_unsigned (regs, ARM_PC_REGNUM, &apparent_pc);
743
 
744
  within_scratch = (apparent_pc >= dsc->scratch_base
745
                    && apparent_pc < (dsc->scratch_base
746
                                      + DISPLACED_MODIFIED_INSNS * 4 + 4));
747
 
748
  if (debug_displaced)
749
    {
750
      fprintf_unfiltered (gdb_stdlog, "displaced: PC is apparently %.8lx after "
751
                          "SVC step ", (unsigned long) apparent_pc);
752
      if (within_scratch)
753
        fprintf_unfiltered (gdb_stdlog, "(within scratch space)\n");
754
      else
755
        fprintf_unfiltered (gdb_stdlog, "(outside scratch space)\n");
756
    }
757
 
758
  if (within_scratch)
759
    displaced_write_reg (regs, dsc, ARM_PC_REGNUM, from + 4, BRANCH_WRITE_PC);
760
}
761
 
762
static int
763
arm_linux_copy_svc (struct gdbarch *gdbarch, uint32_t insn, CORE_ADDR to,
764
                    struct regcache *regs, struct displaced_step_closure *dsc)
765
{
766
  CORE_ADDR from = dsc->insn_addr;
767
  CORE_ADDR return_to = 0;
768
 
769
  struct frame_info *frame;
770
  unsigned int svc_number = displaced_read_reg (regs, from, 7);
771
  int is_sigreturn = 0;
772
 
773
  if (debug_displaced)
774
    fprintf_unfiltered (gdb_stdlog, "displaced: copying Linux svc insn %.8lx\n",
775
                        (unsigned long) insn);
776
 
777
  frame = get_current_frame ();
778
 
779
  is_sigreturn = arm_linux_sigreturn_return_addr(frame, svc_number,
780
                                                 &return_to);
781
  if (is_sigreturn)
782
    {
783
          struct symtab_and_line sal;
784
 
785
          if (debug_displaced)
786
            fprintf_unfiltered (gdb_stdlog, "displaced: found "
787
              "sigreturn/rt_sigreturn SVC call. PC in frame = %lx\n",
788
              (unsigned long) get_frame_pc (frame));
789
 
790
          if (debug_displaced)
791
            fprintf_unfiltered (gdb_stdlog, "displaced: unwind pc = %lx. "
792
              "Setting momentary breakpoint.\n", (unsigned long) return_to);
793
 
794
          gdb_assert (inferior_thread ()->step_resume_breakpoint == NULL);
795
 
796
          sal = find_pc_line (return_to, 0);
797
          sal.pc = return_to;
798
          sal.section = find_pc_overlay (return_to);
799
          sal.explicit_pc = 1;
800
 
801
          frame = get_prev_frame (frame);
802
 
803
          if (frame)
804
            {
805
              inferior_thread ()->step_resume_breakpoint
806
                = set_momentary_breakpoint (gdbarch, sal, get_frame_id (frame),
807
                                            bp_step_resume);
808
 
809
              /* We need to make sure we actually insert the momentary
810
                 breakpoint set above.  */
811
              insert_breakpoints ();
812
            }
813
          else if (debug_displaced)
814
            fprintf_unfiltered (gdb_stderr, "displaced: couldn't find previous "
815
                                "frame to set momentary breakpoint for "
816
                                "sigreturn/rt_sigreturn\n");
817
        }
818
      else if (debug_displaced)
819
        fprintf_unfiltered (gdb_stdlog, "displaced: sigreturn/rt_sigreturn "
820
                            "SVC call not in signal trampoline frame\n");
821
 
822
 
823
  /* Preparation: If we detect sigreturn, set momentary breakpoint at resume
824
                  location, else nothing.
825
     Insn: unmodified svc.
826
     Cleanup: if pc lands in scratch space, pc <- insn_addr + 4
827
              else leave pc alone.  */
828
 
829
  dsc->modinsn[0] = insn;
830
 
831
  dsc->cleanup = &arm_linux_cleanup_svc;
832
  /* Pretend we wrote to the PC, so cleanup doesn't set PC to the next
833
     instruction.  */
834
  dsc->wrote_to_pc = 1;
835
 
836
  return 0;
837
}
838
 
839
 
840
/* The following two functions implement single-stepping over calls to Linux
841
   kernel helper routines, which perform e.g. atomic operations on architecture
842
   variants which don't support them natively.
843
 
844
   When this function is called, the PC will be pointing at the kernel helper
845
   (at an address inaccessible to GDB), and r14 will point to the return
846
   address.  Displaced stepping always executes code in the copy area:
847
   so, make the copy-area instruction branch back to the kernel helper (the
848
   "from" address), and make r14 point to the breakpoint in the copy area.  In
849
   that way, we regain control once the kernel helper returns, and can clean
850
   up appropriately (as if we had just returned from the kernel helper as it
851
   would have been called from the non-displaced location).  */
852
 
853
static void
854
cleanup_kernel_helper_return (struct gdbarch *gdbarch,
855
                              struct regcache *regs,
856
                              struct displaced_step_closure *dsc)
857
{
858
  displaced_write_reg (regs, dsc, ARM_LR_REGNUM, dsc->tmp[0], CANNOT_WRITE_PC);
859
  displaced_write_reg (regs, dsc, ARM_PC_REGNUM, dsc->tmp[0], BRANCH_WRITE_PC);
860
}
861
 
862
static void
863
arm_catch_kernel_helper_return (struct gdbarch *gdbarch, CORE_ADDR from,
864
                                CORE_ADDR to, struct regcache *regs,
865
                                struct displaced_step_closure *dsc)
866
{
867
  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
868
 
869
  dsc->numinsns = 1;
870
  dsc->insn_addr = from;
871
  dsc->cleanup = &cleanup_kernel_helper_return;
872
  /* Say we wrote to the PC, else cleanup will set PC to the next
873
     instruction in the helper, which isn't helpful.  */
874
  dsc->wrote_to_pc = 1;
875
 
876
  /* Preparation: tmp[0] <- r14
877
                  r14 <- <scratch space>+4
878
                  *(<scratch space>+8) <- from
879
     Insn: ldr pc, [r14, #4]
880
     Cleanup: r14 <- tmp[0], pc <- tmp[0].  */
881
 
882
  dsc->tmp[0] = displaced_read_reg (regs, from, ARM_LR_REGNUM);
883
  displaced_write_reg (regs, dsc, ARM_LR_REGNUM, (ULONGEST) to + 4,
884
                       CANNOT_WRITE_PC);
885
  write_memory_unsigned_integer (to + 8, 4, byte_order, from);
886
 
887
  dsc->modinsn[0] = 0xe59ef004;  /* ldr pc, [lr, #4].  */
888
}
889
 
890
/* Linux-specific displaced step instruction copying function.  Detects when
891
   the program has stepped into a Linux kernel helper routine (which must be
892
   handled as a special case), falling back to arm_displaced_step_copy_insn()
893
   if it hasn't.  */
894
 
895
static struct displaced_step_closure *
896
arm_linux_displaced_step_copy_insn (struct gdbarch *gdbarch,
897
                                    CORE_ADDR from, CORE_ADDR to,
898
                                    struct regcache *regs)
899
{
900
  struct displaced_step_closure *dsc
901
    = xmalloc (sizeof (struct displaced_step_closure));
902
 
903
  /* Detect when we enter an (inaccessible by GDB) Linux kernel helper, and
904
     stop at the return location.  */
905
  if (from > 0xffff0000)
906
    {
907
      if (debug_displaced)
908
        fprintf_unfiltered (gdb_stdlog, "displaced: detected kernel helper "
909
                            "at %.8lx\n", (unsigned long) from);
910
 
911
      arm_catch_kernel_helper_return (gdbarch, from, to, regs, dsc);
912
    }
913
  else
914
    {
915
      enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
916
      uint32_t insn = read_memory_unsigned_integer (from, 4, byte_order);
917
 
918
      if (debug_displaced)
919
        fprintf_unfiltered (gdb_stdlog, "displaced: stepping insn %.8lx "
920
                            "at %.8lx\n", (unsigned long) insn,
921
                            (unsigned long) from);
922
 
923
      /* Override the default handling of SVC instructions.  */
924
      dsc->u.svc.copy_svc_os = arm_linux_copy_svc;
925
 
926
      arm_process_displaced_insn (gdbarch, insn, from, to, regs, dsc);
927
    }
928
 
929
  arm_displaced_init_closure (gdbarch, from, to, dsc);
930
 
931
  return dsc;
932
}
933
 
934
static void
935
arm_linux_init_abi (struct gdbarch_info info,
936
                    struct gdbarch *gdbarch)
937
{
938
  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
939
 
940
  tdep->lowest_pc = 0x8000;
941
  if (info.byte_order == BFD_ENDIAN_BIG)
942
    {
943
      if (tdep->arm_abi == ARM_ABI_AAPCS)
944
        tdep->arm_breakpoint = eabi_linux_arm_be_breakpoint;
945
      else
946
        tdep->arm_breakpoint = arm_linux_arm_be_breakpoint;
947
      tdep->thumb_breakpoint = arm_linux_thumb_be_breakpoint;
948
      tdep->thumb2_breakpoint = arm_linux_thumb2_be_breakpoint;
949
    }
950
  else
951
    {
952
      if (tdep->arm_abi == ARM_ABI_AAPCS)
953
        tdep->arm_breakpoint = eabi_linux_arm_le_breakpoint;
954
      else
955
        tdep->arm_breakpoint = arm_linux_arm_le_breakpoint;
956
      tdep->thumb_breakpoint = arm_linux_thumb_le_breakpoint;
957
      tdep->thumb2_breakpoint = arm_linux_thumb2_le_breakpoint;
958
    }
959
  tdep->arm_breakpoint_size = sizeof (arm_linux_arm_le_breakpoint);
960
  tdep->thumb_breakpoint_size = sizeof (arm_linux_thumb_le_breakpoint);
961
  tdep->thumb2_breakpoint_size = sizeof (arm_linux_thumb2_le_breakpoint);
962
 
963
  if (tdep->fp_model == ARM_FLOAT_AUTO)
964
    tdep->fp_model = ARM_FLOAT_FPA;
965
 
966
  switch (tdep->fp_model)
967
    {
968
    case ARM_FLOAT_FPA:
969
      tdep->jb_pc = ARM_LINUX_JB_PC_FPA;
970
      break;
971
    case ARM_FLOAT_SOFT_FPA:
972
    case ARM_FLOAT_SOFT_VFP:
973
    case ARM_FLOAT_VFP:
974
      tdep->jb_pc = ARM_LINUX_JB_PC_EABI;
975
      break;
976
    default:
977
      internal_error
978
        (__FILE__, __LINE__,
979
         _("arm_linux_init_abi: Floating point model not supported"));
980
      break;
981
    }
982
  tdep->jb_elt_size = ARM_LINUX_JB_ELEMENT_SIZE;
983
 
984
  set_solib_svr4_fetch_link_map_offsets
985
    (gdbarch, svr4_ilp32_fetch_link_map_offsets);
986
 
987
  /* Single stepping.  */
988
  set_gdbarch_software_single_step (gdbarch, arm_linux_software_single_step);
989
 
990
  /* Shared library handling.  */
991
  set_gdbarch_skip_trampoline_code (gdbarch, find_solib_trampoline_target);
992
  set_gdbarch_skip_solib_resolver (gdbarch, glibc_skip_solib_resolver);
993
 
994
  /* Enable TLS support.  */
995
  set_gdbarch_fetch_tls_load_module_address (gdbarch,
996
                                             svr4_fetch_objfile_link_map);
997
 
998
  tramp_frame_prepend_unwinder (gdbarch,
999
                                &arm_linux_sigreturn_tramp_frame);
1000
  tramp_frame_prepend_unwinder (gdbarch,
1001
                                &arm_linux_rt_sigreturn_tramp_frame);
1002
  tramp_frame_prepend_unwinder (gdbarch,
1003
                                &arm_eabi_linux_sigreturn_tramp_frame);
1004
  tramp_frame_prepend_unwinder (gdbarch,
1005
                                &arm_eabi_linux_rt_sigreturn_tramp_frame);
1006
  tramp_frame_prepend_unwinder (gdbarch,
1007
                                &arm_linux_restart_syscall_tramp_frame);
1008
 
1009
  /* Core file support.  */
1010
  set_gdbarch_regset_from_core_section (gdbarch,
1011
                                        arm_linux_regset_from_core_section);
1012
 
1013
  set_gdbarch_get_siginfo_type (gdbarch, linux_get_siginfo_type);
1014
 
1015
  /* Displaced stepping.  */
1016
  set_gdbarch_displaced_step_copy_insn (gdbarch,
1017
                                        arm_linux_displaced_step_copy_insn);
1018
  set_gdbarch_displaced_step_fixup (gdbarch, arm_displaced_step_fixup);
1019
  set_gdbarch_displaced_step_free_closure (gdbarch,
1020
                                           simple_displaced_step_free_closure);
1021
  set_gdbarch_displaced_step_location (gdbarch, displaced_step_at_entry_point);
1022
 
1023
 
1024
  tdep->syscall_next_pc = arm_linux_syscall_next_pc;
1025
}
1026
 
1027
/* Provide a prototype to silence -Wmissing-prototypes.  */
1028
extern initialize_file_ftype _initialize_arm_linux_tdep;
1029
 
1030
void
1031
_initialize_arm_linux_tdep (void)
1032
{
1033
  gdbarch_register_osabi (bfd_arch_arm, 0, GDB_OSABI_LINUX,
1034
                          arm_linux_init_abi);
1035
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.