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

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [gnu-src/] [gdb-7.2/] [gdb/] [frv-linux-tdep.c] - Blame information for rev 414

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

Line No. Rev Author Line
1 330 jeremybenn
/* Target-dependent code for GNU/Linux running on the Fujitsu FR-V,
2
   for GDB.
3
 
4
   Copyright (C) 2004, 2006, 2007, 2008, 2009, 2010
5
   Free Software Foundation, Inc.
6
 
7
   This file is part of GDB.
8
 
9
   This program is free software; you can redistribute it and/or modify
10
   it under the terms of the GNU General Public License as published by
11
   the Free Software Foundation; either version 3 of the License, or
12
   (at your option) any later version.
13
 
14
   This program is distributed in the hope that it will be useful,
15
   but WITHOUT ANY WARRANTY; without even the implied warranty of
16
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17
   GNU General Public License for more details.
18
 
19
   You should have received a copy of the GNU General Public License
20
   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
21
 
22
#include "defs.h"
23
#include "gdbcore.h"
24
#include "target.h"
25
#include "frame.h"
26
#include "osabi.h"
27
#include "regcache.h"
28
#include "elf-bfd.h"
29
#include "elf/frv.h"
30
#include "frv-tdep.h"
31
#include "trad-frame.h"
32
#include "frame-unwind.h"
33
#include "regset.h"
34
#include "gdb_string.h"
35
 
36
/* Define the size (in bytes) of an FR-V instruction.  */
37
static const int frv_instr_size = 4;
38
 
39
enum {
40
  NORMAL_SIGTRAMP = 1,
41
  RT_SIGTRAMP = 2
42
};
43
 
44
static int
45
frv_linux_pc_in_sigtramp (struct gdbarch *gdbarch, CORE_ADDR pc, char *name)
46
{
47
  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
48
  char buf[frv_instr_size];
49
  LONGEST instr;
50
  int retval = 0;
51
 
52
  if (target_read_memory (pc, buf, sizeof buf) != 0)
53
    return 0;
54
 
55
  instr = extract_unsigned_integer (buf, sizeof buf, byte_order);
56
 
57
  if (instr == 0x8efc0077)      /* setlos #__NR_sigreturn, gr7 */
58
    retval = NORMAL_SIGTRAMP;
59
  else if (instr -= 0x8efc00ad) /* setlos #__NR_rt_sigreturn, gr7 */
60
    retval = RT_SIGTRAMP;
61
  else
62
    return 0;
63
 
64
  if (target_read_memory (pc + frv_instr_size, buf, sizeof buf) != 0)
65
    return 0;
66
  instr = extract_unsigned_integer (buf, sizeof buf, byte_order);
67
  if (instr != 0xc0700000)      /* tira gr0, 0 */
68
    return 0;
69
 
70
  /* If we get this far, we'll return a non-zero value, either
71
     NORMAL_SIGTRAMP (1) or RT_SIGTRAMP (2).  */
72
  return retval;
73
}
74
 
75
/* Given NEXT_FRAME, the "callee" frame of the sigtramp frame that we
76
   wish to decode, and REGNO, one of the frv register numbers defined
77
   in frv-tdep.h, return the address of the saved register (corresponding
78
   to REGNO) in the sigtramp frame.  Return -1 if the register is not
79
   found in the sigtramp frame.  The magic numbers in the code below
80
   were computed by examining the following kernel structs:
81
 
82
   From arch/frv/kernel/signal.c:
83
 
84
      struct sigframe
85
      {
86
              void (*pretcode)(void);
87
              int sig;
88
              struct sigcontext sc;
89
              unsigned long extramask[_NSIG_WORDS-1];
90
              uint32_t retcode[2];
91
      };
92
 
93
      struct rt_sigframe
94
      {
95
              void (*pretcode)(void);
96
              int sig;
97
              struct siginfo *pinfo;
98
              void *puc;
99
              struct siginfo info;
100
              struct ucontext uc;
101
              uint32_t retcode[2];
102
      };
103
 
104
   From include/asm-frv/ucontext.h:
105
 
106
      struct ucontext {
107
              unsigned long             uc_flags;
108
              struct ucontext           *uc_link;
109
              stack_t                   uc_stack;
110
              struct sigcontext uc_mcontext;
111
              sigset_t          uc_sigmask;
112
      };
113
 
114
   From include/asm-frv/signal.h:
115
 
116
      typedef struct sigaltstack {
117
              void *ss_sp;
118
              int ss_flags;
119
              size_t ss_size;
120
      } stack_t;
121
 
122
   From include/asm-frv/sigcontext.h:
123
 
124
      struct sigcontext {
125
              struct user_context       sc_context;
126
              unsigned long             sc_oldmask;
127
      } __attribute__((aligned(8)));
128
 
129
   From include/asm-frv/registers.h:
130
      struct user_int_regs
131
      {
132
              unsigned long             psr;
133
              unsigned long             isr;
134
              unsigned long             ccr;
135
              unsigned long             cccr;
136
              unsigned long             lr;
137
              unsigned long             lcr;
138
              unsigned long             pc;
139
              unsigned long             __status;
140
              unsigned long             syscallno;
141
              unsigned long             orig_gr8;
142
              unsigned long             gner[2];
143
              unsigned long long        iacc[1];
144
 
145
              union {
146
                      unsigned long     tbr;
147
                      unsigned long     gr[64];
148
              };
149
      };
150
 
151
      struct user_fpmedia_regs
152
      {
153
              unsigned long     fr[64];
154
              unsigned long     fner[2];
155
              unsigned long     msr[2];
156
              unsigned long     acc[8];
157
              unsigned char     accg[8];
158
              unsigned long     fsr[1];
159
      };
160
 
161
      struct user_context
162
      {
163
              struct user_int_regs              i;
164
              struct user_fpmedia_regs  f;
165
 
166
              void *extension;
167
      } __attribute__((aligned(8)));  */
168
 
169
static LONGEST
170
frv_linux_sigcontext_reg_addr (struct frame_info *this_frame, int regno,
171
                               CORE_ADDR *sc_addr_cache_ptr)
172
{
173
  struct gdbarch *gdbarch = get_frame_arch (this_frame);
174
  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
175
  CORE_ADDR sc_addr;
176
 
177
  if (sc_addr_cache_ptr && *sc_addr_cache_ptr)
178
    {
179
      sc_addr = *sc_addr_cache_ptr;
180
    }
181
  else
182
    {
183
      CORE_ADDR pc, sp;
184
      char buf[4];
185
      int tramp_type;
186
 
187
      pc = get_frame_pc (this_frame);
188
      tramp_type = frv_linux_pc_in_sigtramp (gdbarch, pc, 0);
189
 
190
      get_frame_register (this_frame, sp_regnum, buf);
191
      sp = extract_unsigned_integer (buf, sizeof buf, byte_order);
192
 
193
      if (tramp_type == NORMAL_SIGTRAMP)
194
        {
195
          /* For a normal sigtramp frame, the sigcontext struct starts
196
             at SP + 8.  */
197
          sc_addr = sp + 8;
198
        }
199
      else if (tramp_type == RT_SIGTRAMP)
200
        {
201
          /* For a realtime sigtramp frame, SP + 12 contains a pointer
202
             to a ucontext struct.  The ucontext struct contains a
203
             sigcontext struct starting 24 bytes in.  (The offset of
204
             uc_mcontext within struct ucontext is derived as follows:
205
             stack_t is a 12-byte struct and struct sigcontext is
206
             8-byte aligned.  This gives an offset of 8 + 12 + 4 (for
207
             padding) = 24.) */
208
          if (target_read_memory (sp + 12, buf, sizeof buf) != 0)
209
            {
210
              warning (_("Can't read realtime sigtramp frame."));
211
              return 0;
212
            }
213
          sc_addr = extract_unsigned_integer (buf, sizeof buf, byte_order);
214
          sc_addr += 24;
215
        }
216
      else
217
        internal_error (__FILE__, __LINE__, _("not a signal trampoline"));
218
 
219
      if (sc_addr_cache_ptr)
220
        *sc_addr_cache_ptr = sc_addr;
221
    }
222
 
223
  switch (regno)
224
    {
225
    case psr_regnum :
226
      return sc_addr + 0;
227
    /* sc_addr + 4 has "isr", the Integer Status Register.  */
228
    case ccr_regnum :
229
      return sc_addr + 8;
230
    case cccr_regnum :
231
      return sc_addr + 12;
232
    case lr_regnum :
233
      return sc_addr + 16;
234
    case lcr_regnum :
235
      return sc_addr + 20;
236
    case pc_regnum :
237
      return sc_addr + 24;
238
    /* sc_addr + 28 is __status, the exception status.
239
       sc_addr + 32 is syscallno, the syscall number or -1.
240
       sc_addr + 36 is orig_gr8, the original syscall arg #1.
241
       sc_addr + 40 is gner[0].
242
       sc_addr + 44 is gner[1]. */
243
    case iacc0h_regnum :
244
      return sc_addr + 48;
245
    case iacc0l_regnum :
246
      return sc_addr + 52;
247
    default :
248
      if (first_gpr_regnum <= regno && regno <= last_gpr_regnum)
249
        return sc_addr + 56 + 4 * (regno - first_gpr_regnum);
250
      else if (first_fpr_regnum <= regno && regno <= last_fpr_regnum)
251
        return sc_addr + 312 + 4 * (regno - first_fpr_regnum);
252
      else
253
        return -1;  /* not saved. */
254
    }
255
}
256
 
257
/* Signal trampolines.  */
258
 
259
static struct trad_frame_cache *
260
frv_linux_sigtramp_frame_cache (struct frame_info *this_frame, void **this_cache)
261
{
262
  struct gdbarch *gdbarch = get_frame_arch (this_frame);
263
  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
264
  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
265
  struct trad_frame_cache *cache;
266
  CORE_ADDR addr;
267
  char buf[4];
268
  int regnum;
269
  CORE_ADDR sc_addr_cache_val = 0;
270
  struct frame_id this_id;
271
 
272
  if (*this_cache)
273
    return *this_cache;
274
 
275
  cache = trad_frame_cache_zalloc (this_frame);
276
 
277
  /* FIXME: cagney/2004-05-01: This is is long standing broken code.
278
     The frame ID's code address should be the start-address of the
279
     signal trampoline and not the current PC within that
280
     trampoline.  */
281
  get_frame_register (this_frame, sp_regnum, buf);
282
  addr = extract_unsigned_integer (buf, sizeof buf, byte_order);
283
  this_id = frame_id_build (addr, get_frame_pc (this_frame));
284
  trad_frame_set_id (cache, this_id);
285
 
286
  for (regnum = 0; regnum < frv_num_regs; regnum++)
287
    {
288
      LONGEST reg_addr = frv_linux_sigcontext_reg_addr (this_frame, regnum,
289
                                                        &sc_addr_cache_val);
290
      if (reg_addr != -1)
291
        trad_frame_set_reg_addr (cache, regnum, reg_addr);
292
    }
293
 
294
  *this_cache = cache;
295
  return cache;
296
}
297
 
298
static void
299
frv_linux_sigtramp_frame_this_id (struct frame_info *this_frame, void **this_cache,
300
                             struct frame_id *this_id)
301
{
302
  struct trad_frame_cache *cache =
303
    frv_linux_sigtramp_frame_cache (this_frame, this_cache);
304
  trad_frame_get_id (cache, this_id);
305
}
306
 
307
static struct value *
308
frv_linux_sigtramp_frame_prev_register (struct frame_info *this_frame,
309
                                        void **this_cache, int regnum)
310
{
311
  /* Make sure we've initialized the cache.  */
312
  struct trad_frame_cache *cache =
313
    frv_linux_sigtramp_frame_cache (this_frame, this_cache);
314
  return trad_frame_get_register (cache, this_frame, regnum);
315
}
316
 
317
static int
318
frv_linux_sigtramp_frame_sniffer (const struct frame_unwind *self,
319
                                  struct frame_info *this_frame,
320
                                  void **this_cache)
321
{
322
  struct gdbarch *gdbarch = get_frame_arch (this_frame);
323
  CORE_ADDR pc = get_frame_pc (this_frame);
324
  char *name;
325
 
326
  find_pc_partial_function (pc, &name, NULL, NULL);
327
  if (frv_linux_pc_in_sigtramp (gdbarch, pc, name))
328
    return 1;
329
 
330
  return 0;
331
}
332
 
333
static const struct frame_unwind frv_linux_sigtramp_frame_unwind =
334
{
335
  SIGTRAMP_FRAME,
336
  frv_linux_sigtramp_frame_this_id,
337
  frv_linux_sigtramp_frame_prev_register,
338
  NULL,
339
  frv_linux_sigtramp_frame_sniffer
340
};
341
 
342
/* The FRV kernel defines ELF_NGREG as 46.  We add 2 in order to include
343
   the loadmap addresses in the register set.  (See below for more info.)  */
344
#define FRV_ELF_NGREG (46 + 2)
345
typedef unsigned char frv_elf_greg_t[4];
346
typedef struct { frv_elf_greg_t reg[FRV_ELF_NGREG]; } frv_elf_gregset_t;
347
 
348
typedef unsigned char frv_elf_fpreg_t[4];
349
typedef struct
350
{
351
  frv_elf_fpreg_t fr[64];
352
  frv_elf_fpreg_t fner[2];
353
  frv_elf_fpreg_t msr[2];
354
  frv_elf_fpreg_t acc[8];
355
  unsigned char accg[8];
356
  frv_elf_fpreg_t fsr[1];
357
} frv_elf_fpregset_t;
358
 
359
/* Constants for accessing elements of frv_elf_gregset_t.  */
360
 
361
#define FRV_PT_PSR 0
362
#define FRV_PT_ISR 1
363
#define FRV_PT_CCR 2
364
#define FRV_PT_CCCR 3
365
#define FRV_PT_LR 4
366
#define FRV_PT_LCR 5
367
#define FRV_PT_PC 6
368
#define FRV_PT_GNER0 10
369
#define FRV_PT_GNER1 11
370
#define FRV_PT_IACC0H 12
371
#define FRV_PT_IACC0L 13
372
 
373
/* Note: Only 32 of the GRs will be found in the corefile.  */
374
#define FRV_PT_GR(j)    ( 14 + (j))     /* GRj for 0<=j<=63. */
375
 
376
#define FRV_PT_TBR FRV_PT_GR(0)         /* gr0 is always 0, so TBR is stuffed
377
                                           there.  */
378
 
379
/* Technically, the loadmap addresses are not part of `pr_reg' as
380
   found in the elf_prstatus struct.  The fields which communicate the
381
   loadmap address appear (by design) immediately after `pr_reg'
382
   though, and the BFD function elf32_frv_grok_prstatus() has been
383
   implemented to include these fields in the register section that it
384
   extracts from the core file.  So, for our purposes, they may be
385
   viewed as registers.  */
386
 
387
#define FRV_PT_EXEC_FDPIC_LOADMAP 46
388
#define FRV_PT_INTERP_FDPIC_LOADMAP 47
389
 
390
 
391
/* Unpack an frv_elf_gregset_t into GDB's register cache.  */
392
 
393
static void
394
frv_linux_supply_gregset (const struct regset *regset,
395
                          struct regcache *regcache,
396
                          int regnum, const void *gregs, size_t len)
397
{
398
  int regi;
399
  char zerobuf[MAX_REGISTER_SIZE];
400
  const frv_elf_gregset_t *gregsetp = gregs;
401
 
402
  memset (zerobuf, 0, MAX_REGISTER_SIZE);
403
 
404
  /* gr0 always contains 0.  Also, the kernel passes the TBR value in
405
     this slot.  */
406
  regcache_raw_supply (regcache, first_gpr_regnum, zerobuf);
407
 
408
  for (regi = first_gpr_regnum + 1; regi <= last_gpr_regnum; regi++)
409
    {
410
      if (regi >= first_gpr_regnum + 32)
411
        regcache_raw_supply (regcache, regi, zerobuf);
412
      else
413
        regcache_raw_supply (regcache, regi,
414
                             gregsetp->reg[FRV_PT_GR (regi - first_gpr_regnum)]);
415
    }
416
 
417
  regcache_raw_supply (regcache, pc_regnum, gregsetp->reg[FRV_PT_PC]);
418
  regcache_raw_supply (regcache, psr_regnum, gregsetp->reg[FRV_PT_PSR]);
419
  regcache_raw_supply (regcache, ccr_regnum, gregsetp->reg[FRV_PT_CCR]);
420
  regcache_raw_supply (regcache, cccr_regnum, gregsetp->reg[FRV_PT_CCCR]);
421
  regcache_raw_supply (regcache, lr_regnum, gregsetp->reg[FRV_PT_LR]);
422
  regcache_raw_supply (regcache, lcr_regnum, gregsetp->reg[FRV_PT_LCR]);
423
  regcache_raw_supply (regcache, gner0_regnum, gregsetp->reg[FRV_PT_GNER0]);
424
  regcache_raw_supply (regcache, gner1_regnum, gregsetp->reg[FRV_PT_GNER1]);
425
  regcache_raw_supply (regcache, tbr_regnum, gregsetp->reg[FRV_PT_TBR]);
426
  regcache_raw_supply (regcache, fdpic_loadmap_exec_regnum,
427
                       gregsetp->reg[FRV_PT_EXEC_FDPIC_LOADMAP]);
428
  regcache_raw_supply (regcache, fdpic_loadmap_interp_regnum,
429
                       gregsetp->reg[FRV_PT_INTERP_FDPIC_LOADMAP]);
430
}
431
 
432
/* Unpack an frv_elf_fpregset_t into GDB's register cache.  */
433
 
434
static void
435
frv_linux_supply_fpregset (const struct regset *regset,
436
                           struct regcache *regcache,
437
                           int regnum, const void *gregs, size_t len)
438
{
439
  int regi;
440
  const frv_elf_fpregset_t *fpregsetp = gregs;
441
 
442
  for (regi = first_fpr_regnum; regi <= last_fpr_regnum; regi++)
443
    regcache_raw_supply (regcache, regi, fpregsetp->fr[regi - first_fpr_regnum]);
444
 
445
  regcache_raw_supply (regcache, fner0_regnum, fpregsetp->fner[0]);
446
  regcache_raw_supply (regcache, fner1_regnum, fpregsetp->fner[1]);
447
 
448
  regcache_raw_supply (regcache, msr0_regnum, fpregsetp->msr[0]);
449
  regcache_raw_supply (regcache, msr1_regnum, fpregsetp->msr[1]);
450
 
451
  for (regi = acc0_regnum; regi <= acc7_regnum; regi++)
452
    regcache_raw_supply (regcache, regi, fpregsetp->acc[regi - acc0_regnum]);
453
 
454
  regcache_raw_supply (regcache, accg0123_regnum, fpregsetp->accg);
455
  regcache_raw_supply (regcache, accg4567_regnum, fpregsetp->accg + 4);
456
 
457
  regcache_raw_supply (regcache, fsr0_regnum, fpregsetp->fsr[0]);
458
}
459
 
460
/* FRV Linux kernel register sets.  */
461
 
462
static struct regset frv_linux_gregset =
463
{
464
  NULL,
465
  frv_linux_supply_gregset
466
};
467
 
468
static struct regset frv_linux_fpregset =
469
{
470
  NULL,
471
  frv_linux_supply_fpregset
472
};
473
 
474
static const struct regset *
475
frv_linux_regset_from_core_section (struct gdbarch *gdbarch,
476
                                    const char *sect_name, size_t sect_size)
477
{
478
  if (strcmp (sect_name, ".reg") == 0
479
      && sect_size >= sizeof (frv_elf_gregset_t))
480
    return &frv_linux_gregset;
481
 
482
  if (strcmp (sect_name, ".reg2") == 0
483
      && sect_size >= sizeof (frv_elf_fpregset_t))
484
    return &frv_linux_fpregset;
485
 
486
  return NULL;
487
}
488
 
489
 
490
static void
491
frv_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
492
{
493
  /* Set the sigtramp frame sniffer.  */
494
  frame_unwind_append_unwinder (gdbarch, &frv_linux_sigtramp_frame_unwind);
495
  set_gdbarch_regset_from_core_section (gdbarch,
496
                                        frv_linux_regset_from_core_section);
497
}
498
 
499
static enum gdb_osabi
500
frv_linux_elf_osabi_sniffer (bfd *abfd)
501
{
502
  int elf_flags;
503
 
504
  elf_flags = elf_elfheader (abfd)->e_flags;
505
 
506
  /* Assume GNU/Linux if using the FDPIC ABI.  If/when another OS shows
507
     up that uses this ABI, we'll need to start using .note sections
508
     or some such.  */
509
  if (elf_flags & EF_FRV_FDPIC)
510
    return GDB_OSABI_LINUX;
511
  else
512
    return GDB_OSABI_UNKNOWN;
513
}
514
 
515
/* Provide a prototype to silence -Wmissing-prototypes.  */
516
void _initialize_frv_linux_tdep (void);
517
 
518
void
519
_initialize_frv_linux_tdep (void)
520
{
521
  gdbarch_register_osabi (bfd_arch_frv, 0, GDB_OSABI_LINUX, frv_linux_init_abi);
522
  gdbarch_register_osabi_sniffer (bfd_arch_frv,
523
                                  bfd_target_elf_flavour,
524
                                  frv_linux_elf_osabi_sniffer);
525
}

powered by: WebSVN 2.1.0

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