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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-old/] [gdb-7.1/] [gdb/] [m32r-linux-nat.c] - Blame information for rev 842

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 227 jeremybenn
/* Native-dependent code for GNU/Linux m32r.
2
 
3
   Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010
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 "inferior.h"
23
#include "gdbcore.h"
24
#include "regcache.h"
25
#include "linux-nat.h"
26
#include "target.h"
27
 
28
#include "gdb_assert.h"
29
#include "gdb_string.h"
30
#include <sys/ptrace.h>
31
#include <sys/user.h>
32
#include <sys/procfs.h>
33
 
34
/* Prototypes for supply_gregset etc.  */
35
#include "gregset.h"
36
 
37
#include "m32r-tdep.h"
38
 
39
 
40
 
41
 
42
/* Since EVB register is not available for native debug, we reduce
43
   the number of registers.  */
44
#define M32R_LINUX_NUM_REGS (M32R_NUM_REGS - 1)
45
 
46
/* Mapping between the general-purpose registers in `struct user'
47
   format and GDB's register array layout.  */
48
static int regmap[] = {
49
  4, 5, 6, 7, 0, 1, 2, 8,
50
  9, 10, 11, 12, 13, 24, 25, 23,
51
  19, 19, 26, 23, 22, 20, 16, 15
52
};
53
 
54
#define PSW_REGMAP 19
55
#define BBPSW_REGMAP 21
56
#define SPU_REGMAP 23
57
#define SPI_REGMAP 26
58
 
59
/* Doee apply to the corresponding SET requests as well.  */
60
#define GETREGS_SUPPLIES(regno) (0 <= (regno) && (regno) <= M32R_LINUX_NUM_REGS)
61
 
62
 
63
 
64
/* Transfering the general-purpose registers between GDB, inferiors
65
   and core files.  */
66
 
67
/* Fill GDB's register array with the general-purpose register values
68
   in *GREGSETP.  */
69
 
70
void
71
supply_gregset (struct regcache *regcache, const elf_gregset_t * gregsetp)
72
{
73
  const elf_greg_t *regp = (const elf_greg_t *) gregsetp;
74
  int i;
75
  unsigned long psw, bbpsw;
76
 
77
  psw = *(regp + PSW_REGMAP);
78
  bbpsw = *(regp + BBPSW_REGMAP);
79
 
80
  for (i = 0; i < M32R_LINUX_NUM_REGS; i++)
81
    {
82
      elf_greg_t regval;
83
 
84
      switch (i)
85
        {
86
        case PSW_REGNUM:
87
          regval = ((0x00c1 & bbpsw) << 8) | ((0xc100 & psw) >> 8);
88
          break;
89
        case CBR_REGNUM:
90
          regval = ((psw >> 8) & 1);
91
          break;
92
        default:
93
          regval = *(regp + regmap[i]);
94
          break;
95
        }
96
 
97
      if (i != M32R_SP_REGNUM)
98
        regcache_raw_supply (regcache, i, &regval);
99
      else if (psw & 0x8000)
100
        regcache_raw_supply (regcache, i, regp + SPU_REGMAP);
101
      else
102
        regcache_raw_supply (regcache, i, regp + SPI_REGMAP);
103
    }
104
}
105
 
106
/* Fetch all general-purpose registers from process/thread TID and
107
   store their values in GDB's register array.  */
108
 
109
static void
110
fetch_regs (struct regcache *regcache, int tid)
111
{
112
  elf_gregset_t regs;
113
 
114
  if (ptrace (PTRACE_GETREGS, tid, 0, (int) &regs) < 0)
115
    perror_with_name (_("Couldn't get registers"));
116
 
117
  supply_gregset (regcache, (const elf_gregset_t *) &regs);
118
}
119
 
120
/* Fill register REGNO (if it is a general-purpose register) in
121
   *GREGSETPS with the value in GDB's register array.  If REGNO is -1,
122
   do this for all registers.  */
123
 
124
void
125
fill_gregset (const struct regcache *regcache,
126
              elf_gregset_t * gregsetp, int regno)
127
{
128
  elf_greg_t *regp = (elf_greg_t *) gregsetp;
129
  int i;
130
  unsigned long psw, bbpsw, tmp;
131
 
132
  psw = *(regp + PSW_REGMAP);
133
  bbpsw = *(regp + BBPSW_REGMAP);
134
 
135
  for (i = 0; i < M32R_LINUX_NUM_REGS; i++)
136
    {
137
      if (regno != -1 && regno != i)
138
        continue;
139
 
140
      if (i == CBR_REGNUM || i == PSW_REGNUM)
141
        continue;
142
 
143
      if (i == SPU_REGNUM || i == SPI_REGNUM)
144
        continue;
145
 
146
      if (i != M32R_SP_REGNUM)
147
        regcache_raw_collect (regcache, i, regp + regmap[i]);
148
      else if (psw & 0x8000)
149
        regcache_raw_collect (regcache, i, regp + SPU_REGMAP);
150
      else
151
        regcache_raw_collect (regcache, i, regp + SPI_REGMAP);
152
    }
153
}
154
 
155
/* Store all valid general-purpose registers in GDB's register array
156
   into the process/thread specified by TID.  */
157
 
158
static void
159
store_regs (const struct regcache *regcache, int tid, int regno)
160
{
161
  elf_gregset_t regs;
162
 
163
  if (ptrace (PTRACE_GETREGS, tid, 0, (int) &regs) < 0)
164
    perror_with_name (_("Couldn't get registers"));
165
 
166
  fill_gregset (regcache, &regs, regno);
167
 
168
  if (ptrace (PTRACE_SETREGS, tid, 0, (int) &regs) < 0)
169
    perror_with_name (_("Couldn't write registers"));
170
}
171
 
172
 
173
 
174
/* Transfering floating-point registers between GDB, inferiors and cores.
175
   Since M32R has no floating-point registers, these functions do nothing.  */
176
 
177
void
178
supply_fpregset (struct regcache *regcache, const gdb_fpregset_t *fpregs)
179
{
180
}
181
 
182
void
183
fill_fpregset (const struct regcache *regcache,
184
               gdb_fpregset_t *fpregs, int regno)
185
{
186
}
187
 
188
 
189
 
190
/* Transferring arbitrary registers between GDB and inferior.  */
191
 
192
/* Fetch register REGNO from the child process.  If REGNO is -1, do
193
   this for all registers (including the floating point and SSE
194
   registers).  */
195
 
196
static void
197
m32r_linux_fetch_inferior_registers (struct target_ops *ops,
198
                                     struct regcache *regcache, int regno)
199
{
200
  int tid;
201
 
202
  /* GNU/Linux LWP ID's are process ID's.  */
203
  tid = TIDGET (inferior_ptid);
204
  if (tid == 0)
205
    tid = PIDGET (inferior_ptid);       /* Not a threaded program.  */
206
 
207
  /* Use the PTRACE_GETREGS request whenever possible, since it
208
     transfers more registers in one system call, and we'll cache the
209
     results.  */
210
  if (regno == -1 || GETREGS_SUPPLIES (regno))
211
    {
212
      fetch_regs (regcache, tid);
213
      return;
214
    }
215
 
216
  internal_error (__FILE__, __LINE__,
217
                  _("Got request for bad register number %d."), regno);
218
}
219
 
220
/* Store register REGNO back into the child process.  If REGNO is -1,
221
   do this for all registers (including the floating point and SSE
222
   registers).  */
223
static void
224
m32r_linux_store_inferior_registers (struct target_ops *ops,
225
                                     struct regcache *regcache, int regno)
226
{
227
  int tid;
228
 
229
  /* GNU/Linux LWP ID's are process ID's.  */
230
  if ((tid = TIDGET (inferior_ptid)) == 0)
231
    tid = PIDGET (inferior_ptid);       /* Not a threaded program.  */
232
 
233
  /* Use the PTRACE_SETREGS request whenever possible, since it
234
     transfers more registers in one system call.  */
235
  if (regno == -1 || GETREGS_SUPPLIES (regno))
236
    {
237
      store_regs (regcache, tid, regno);
238
      return;
239
    }
240
 
241
  internal_error (__FILE__, __LINE__,
242
                  _("Got request to store bad register number %d."), regno);
243
}
244
 
245
void _initialize_m32r_linux_nat (void);
246
 
247
void
248
_initialize_m32r_linux_nat (void)
249
{
250
  struct target_ops *t;
251
 
252
  /* Fill in the generic GNU/Linux methods.  */
253
  t = linux_target ();
254
 
255
  /* Add our register access methods.  */
256
  t->to_fetch_registers = m32r_linux_fetch_inferior_registers;
257
  t->to_store_registers = m32r_linux_store_inferior_registers;
258
 
259
  /* Register the target.  */
260
  linux_nat_add_target (t);
261
}

powered by: WebSVN 2.1.0

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