OpenCores
URL https://opencores.org/ocsvn/openrisc_2011-10-31/openrisc_2011-10-31/trunk

Subversion Repositories openrisc_2011-10-31

[/] [openrisc/] [trunk/] [gnu-src/] [gdb-7.1/] [gdb/] [ppcnbsd-nat.c] - Blame information for rev 634

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

Line No. Rev Author Line
1 227 jeremybenn
/* Native-dependent code for NetBSD/powerpc.
2
 
3
   Copyright (C) 2002, 2004, 2005, 2006, 2007, 2008, 2009, 2010
4
   Free Software Foundation, Inc.
5
 
6
   Contributed by Wasabi Systems, Inc.
7
 
8
   This file is part of GDB.
9
 
10
   This program is free software; you can redistribute it and/or modify
11
   it under the terms of the GNU General Public License as published by
12
   the Free Software Foundation; either version 3 of the License, or
13
   (at your option) any later version.
14
 
15
   This program is distributed in the hope that it will be useful,
16
   but WITHOUT ANY WARRANTY; without even the implied warranty of
17
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18
   GNU General Public License for more details.
19
 
20
   You should have received a copy of the GNU General Public License
21
   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
22
 
23
#include <sys/types.h>
24
#include <sys/ptrace.h>
25
#include <machine/reg.h>
26
#include <machine/frame.h>
27
#include <machine/pcb.h>
28
 
29
#include "defs.h"
30
#include "gdbcore.h"
31
#include "inferior.h"
32
#include "regcache.h"
33
 
34
#include "gdb_assert.h"
35
 
36
#include "ppc-tdep.h"
37
#include "ppcnbsd-tdep.h"
38
#include "bsd-kvm.h"
39
#include "inf-ptrace.h"
40
 
41
/* Returns true if PT_GETREGS fetches this register.  */
42
 
43
static int
44
getregs_supplies (struct gdbarch *gdbarch, int regnum)
45
{
46
  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
47
 
48
  return ((regnum >= tdep->ppc_gp0_regnum
49
           && regnum < tdep->ppc_gp0_regnum + ppc_num_gprs)
50
          || regnum == tdep->ppc_lr_regnum
51
          || regnum == tdep->ppc_cr_regnum
52
          || regnum == tdep->ppc_xer_regnum
53
          || regnum == tdep->ppc_ctr_regnum
54
          || regnum == gdbarch_pc_regnum (gdbarch));
55
}
56
 
57
/* Like above, but for PT_GETFPREGS.  */
58
 
59
static int
60
getfpregs_supplies (struct gdbarch *gdbarch, int regnum)
61
{
62
  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
63
 
64
  /* FIXME: jimb/2004-05-05: Some PPC variants don't have floating
65
     point registers.  Traditionally, GDB's register set has still
66
     listed the floating point registers for such machines, so this
67
     code is harmless.  However, the new E500 port actually omits the
68
     floating point registers entirely from the register set --- they
69
     don't even have register numbers assigned to them.
70
 
71
     It's not clear to me how best to update this code, so this assert
72
     will alert the first person to encounter the NetBSD/E500
73
     combination to the problem.  */
74
  gdb_assert (ppc_floating_point_unit_p (gdbarch));
75
 
76
  return ((regnum >= tdep->ppc_fp0_regnum
77
           && regnum < tdep->ppc_fp0_regnum + ppc_num_fprs)
78
          || regnum == tdep->ppc_fpscr_regnum);
79
}
80
 
81
static void
82
ppcnbsd_fetch_inferior_registers (struct target_ops *ops,
83
                                  struct regcache *regcache, int regnum)
84
{
85
  struct gdbarch *gdbarch = get_regcache_arch (regcache);
86
 
87
  if (regnum == -1 || getregs_supplies (gdbarch, regnum))
88
    {
89
      struct reg regs;
90
 
91
      if (ptrace (PT_GETREGS, PIDGET (inferior_ptid),
92
                  (PTRACE_TYPE_ARG3) &regs, 0) == -1)
93
        perror_with_name (_("Couldn't get registers"));
94
 
95
      ppc_supply_gregset (&ppcnbsd_gregset, regcache,
96
                          regnum, &regs, sizeof regs);
97
    }
98
 
99
  if (regnum == -1 || getfpregs_supplies (gdbarch, regnum))
100
    {
101
      struct fpreg fpregs;
102
 
103
      if (ptrace (PT_GETFPREGS, PIDGET (inferior_ptid),
104
                  (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
105
        perror_with_name (_("Couldn't get FP registers"));
106
 
107
      ppc_supply_fpregset (&ppcnbsd_fpregset, regcache,
108
                           regnum, &fpregs, sizeof fpregs);
109
    }
110
}
111
 
112
static void
113
ppcnbsd_store_inferior_registers (struct target_ops *ops,
114
                                  struct regcache *regcache, int regnum)
115
{
116
  struct gdbarch *gdbarch = get_regcache_arch (regcache);
117
 
118
  if (regnum == -1 || getregs_supplies (gdbarch, regnum))
119
    {
120
      struct reg regs;
121
 
122
      if (ptrace (PT_GETREGS, PIDGET (inferior_ptid),
123
                  (PTRACE_TYPE_ARG3) &regs, 0) == -1)
124
        perror_with_name (_("Couldn't get registers"));
125
 
126
      ppc_collect_gregset (&ppcnbsd_gregset, regcache,
127
                           regnum, &regs, sizeof regs);
128
 
129
      if (ptrace (PT_SETREGS, PIDGET (inferior_ptid),
130
                  (PTRACE_TYPE_ARG3) &regs, 0) == -1)
131
        perror_with_name (_("Couldn't write registers"));
132
    }
133
 
134
  if (regnum == -1 || getfpregs_supplies (gdbarch, regnum))
135
    {
136
      struct fpreg fpregs;
137
 
138
      if (ptrace (PT_GETFPREGS, PIDGET (inferior_ptid),
139
                  (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
140
        perror_with_name (_("Couldn't get FP registers"));
141
 
142
      ppc_collect_fpregset (&ppcnbsd_fpregset, regcache,
143
                            regnum, &fpregs, sizeof fpregs);
144
 
145
      if (ptrace (PT_SETFPREGS, PIDGET (inferior_ptid),
146
                  (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
147
        perror_with_name (_("Couldn't set FP registers"));
148
    }
149
}
150
 
151
static int
152
ppcnbsd_supply_pcb (struct regcache *regcache, struct pcb *pcb)
153
{
154
  struct switchframe sf;
155
  struct callframe cf;
156
  struct gdbarch *gdbarch = get_regcache_arch (regcache);
157
  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
158
  int i;
159
 
160
  /* The stack pointer shouldn't be zero.  */
161
  if (pcb->pcb_sp == 0)
162
    return 0;
163
 
164
  read_memory (pcb->pcb_sp, (gdb_byte *)&sf, sizeof sf);
165
  regcache_raw_supply (regcache, tdep->ppc_cr_regnum, &sf.cr);
166
  regcache_raw_supply (regcache, tdep->ppc_gp0_regnum + 2, &sf.fixreg2);
167
  for (i = 0 ; i < 19 ; i++)
168
    regcache_raw_supply (regcache, tdep->ppc_gp0_regnum + 13 + i,
169
                         &sf.fixreg[i]);
170
 
171
  read_memory(sf.sp, (gdb_byte *)&cf, sizeof(cf));
172
  regcache_raw_supply (regcache, tdep->ppc_gp0_regnum + 30, &cf.r30);
173
  regcache_raw_supply (regcache, tdep->ppc_gp0_regnum + 31, &cf.r31);
174
  regcache_raw_supply (regcache, tdep->ppc_gp0_regnum + 1, &cf.sp);
175
 
176
  read_memory(cf.sp, (gdb_byte *)&cf, sizeof(cf));
177
  regcache_raw_supply (regcache, tdep->ppc_lr_regnum, &cf.lr);
178
  regcache_raw_supply (regcache, gdbarch_pc_regnum (gdbarch), &cf.lr);
179
 
180
  return 1;
181
}
182
 
183
/* Provide a prototype to silence -Wmissing-prototypes.  */
184
void _initialize_ppcnbsd_nat (void);
185
 
186
void
187
_initialize_ppcnbsd_nat (void)
188
{
189
  struct target_ops *t;
190
 
191
  /* Support debugging kernel virtual memory images.  */
192
  bsd_kvm_add_target (ppcnbsd_supply_pcb);
193
 
194
  /* Add in local overrides.  */
195
  t = inf_ptrace_target ();
196
  t->to_fetch_registers = ppcnbsd_fetch_inferior_registers;
197
  t->to_store_registers = ppcnbsd_store_inferior_registers;
198
  add_target (t);
199
}

powered by: WebSVN 2.1.0

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