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

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [gnu-src/] [gdb-6.8/] [gdb/] [xtensa-linux-nat.c] - Blame information for rev 402

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

Line No. Rev Author Line
1 24 jeremybenn
/* Xtensa GNU/Linux native support.
2
 
3
   Copyright (C) 2007, 2008 Free Software Foundation, Inc.
4
 
5
   This file is part of GDB.
6
 
7
   This program is free software; you can redistribute it and/or modify
8
   it under the terms of the GNU General Public License as published by
9
   the Free Software Foundation; either version 3 of the License, or
10
   (at your option) any later version.
11
 
12
   This program is distributed in the hope that it will be useful,
13
   but WITHOUT ANY WARRANTY; without even the implied warranty of
14
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
   GNU General Public License for more details.
16
 
17
   You should have received a copy of the GNU General Public License
18
   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
19
 
20
#include "defs.h"
21
#include "gdb_string.h"
22
#include "frame.h"
23
#include "inferior.h"
24
#include "gdbcore.h"
25
#include "regcache.h"
26
#include "gdb_assert.h"
27
#include "target.h"
28
#include "linux-nat.h"
29
 
30
#include <stdint.h>
31
#include <sys/types.h>
32
#include <sys/param.h>
33
#include <signal.h>
34
#include <sys/user.h>
35
#include <sys/ioctl.h>
36
#include "gdb_wait.h"
37
#include <fcntl.h>
38
#include <sys/procfs.h>
39
#include <sys/ptrace.h>
40
 
41
#include "gregset.h"
42
#include "xtensa-tdep.h"
43
 
44
/* Extended register set depends on hardware configs.
45
   Keeping these definitions separately allows to introduce
46
   hardware-specific overlays.  */
47
#include "xtensa-xtregs.c"
48
 
49
int
50
get_thread_id (ptid_t ptid)
51
{
52
  int tid = TIDGET (ptid);
53
  if (0 == tid)
54
    tid = PIDGET (ptid);
55
  return tid;
56
}
57
#define GET_THREAD_ID(PTID)     get_thread_id (PTID)
58
 
59
void
60
fill_gregset (const struct regcache *regcache,
61
              gdb_gregset_t *gregsetp, int regnum)
62
{
63
  int i;
64
  xtensa_elf_gregset_t *regs = (xtensa_elf_gregset_t *) gregsetp;
65
  struct gdbarch *gdbarch = get_regcache_arch (regcache);
66
 
67
  if (regnum == gdbarch_pc_regnum (gdbarch) || regnum == -1)
68
    regcache_raw_collect (regcache, gdbarch_pc_regnum (gdbarch), &regs->pc);
69
  if (regnum == gdbarch_ps_regnum (gdbarch) || regnum == -1)
70
    regcache_raw_collect (regcache, gdbarch_ps_regnum (gdbarch), &regs->ps);
71
 
72
  if (regnum == gdbarch_tdep (gdbarch)->wb_regnum || regnum == -1)
73
    regcache_raw_collect (regcache,
74
                          gdbarch_tdep (gdbarch)->wb_regnum,
75
                          &regs->windowbase);
76
  if (regnum == gdbarch_tdep (gdbarch)->ws_regnum || regnum == -1)
77
    regcache_raw_collect (regcache,
78
                          gdbarch_tdep (gdbarch)->ws_regnum,
79
                          &regs->windowstart);
80
  if (regnum == gdbarch_tdep (gdbarch)->lbeg_regnum || regnum == -1)
81
    regcache_raw_collect (regcache,
82
                          gdbarch_tdep (gdbarch)->lbeg_regnum,
83
                          &regs->lbeg);
84
  if (regnum == gdbarch_tdep (gdbarch)->lend_regnum || regnum == -1)
85
    regcache_raw_collect (regcache,
86
                          gdbarch_tdep (gdbarch)->lend_regnum,
87
                          &regs->lend);
88
  if (regnum == gdbarch_tdep (gdbarch)->lcount_regnum || regnum == -1)
89
    regcache_raw_collect (regcache,
90
                          gdbarch_tdep (gdbarch)->lcount_regnum,
91
                          &regs->lcount);
92
  if (regnum == gdbarch_tdep (gdbarch)->sar_regnum || regnum == -1)
93
    regcache_raw_collect (regcache,
94
                          gdbarch_tdep (gdbarch)->sar_regnum,
95
                          &regs->sar);
96
  if (regnum >=gdbarch_tdep (gdbarch)->ar_base
97
      && regnum < gdbarch_tdep (gdbarch)->ar_base
98
                    + gdbarch_tdep (gdbarch)->num_aregs)
99
    regcache_raw_collect (regcache,regnum,
100
                          &regs->ar[regnum - gdbarch_tdep (gdbarch)->ar_base]);
101
  else if (regnum == -1)
102
    {
103
      for (i = 0; i < gdbarch_tdep (gdbarch)->num_aregs; ++i)
104
        regcache_raw_collect (regcache,
105
                              gdbarch_tdep (gdbarch)->ar_base + i,
106
                              &regs->ar[i]);
107
    }
108
}
109
 
110
void
111
supply_gregset_reg (struct regcache *regcache,
112
                    const gdb_gregset_t *gregsetp, int regnum)
113
{
114
  int i;
115
  xtensa_elf_gregset_t *regs = (xtensa_elf_gregset_t *) gregsetp;
116
 
117
  struct gdbarch *gdbarch = get_regcache_arch (regcache);
118
 
119
  if (regnum == gdbarch_pc_regnum (gdbarch) || regnum == -1)
120
    regcache_raw_supply (regcache, gdbarch_pc_regnum (gdbarch), &regs->pc);
121
  if (regnum == gdbarch_ps_regnum (gdbarch) || regnum == -1)
122
    regcache_raw_supply (regcache, gdbarch_ps_regnum (gdbarch), &regs->ps);
123
 
124
  if (regnum == gdbarch_tdep (gdbarch)->wb_regnum || regnum == -1)
125
    regcache_raw_supply (regcache,
126
                          gdbarch_tdep (gdbarch)->wb_regnum,
127
                          &regs->windowbase);
128
  if (regnum == gdbarch_tdep (gdbarch)->ws_regnum || regnum == -1)
129
    regcache_raw_supply (regcache,
130
                          gdbarch_tdep (gdbarch)->ws_regnum,
131
                          &regs->windowstart);
132
  if (regnum == gdbarch_tdep (gdbarch)->lbeg_regnum || regnum == -1)
133
    regcache_raw_supply (regcache,
134
                          gdbarch_tdep (gdbarch)->lbeg_regnum,
135
                          &regs->lbeg);
136
  if (regnum == gdbarch_tdep (gdbarch)->lend_regnum || regnum == -1)
137
    regcache_raw_supply (regcache,
138
                          gdbarch_tdep (gdbarch)->lend_regnum,
139
                          &regs->lend);
140
  if (regnum == gdbarch_tdep (gdbarch)->lcount_regnum || regnum == -1)
141
    regcache_raw_supply (regcache,
142
                          gdbarch_tdep (gdbarch)->lcount_regnum,
143
                          &regs->lcount);
144
  if (regnum == gdbarch_tdep (gdbarch)->sar_regnum || regnum == -1)
145
    regcache_raw_supply (regcache,
146
                          gdbarch_tdep (gdbarch)->sar_regnum,
147
                          &regs->sar);
148
  if (regnum >=gdbarch_tdep (gdbarch)->ar_base
149
      && regnum < gdbarch_tdep (gdbarch)->ar_base
150
                    + gdbarch_tdep (gdbarch)->num_aregs)
151
    regcache_raw_supply (regcache,regnum,
152
                          &regs->ar[regnum - gdbarch_tdep (gdbarch)->ar_base]);
153
  else if (regnum == -1)
154
    {
155
      for (i = 0; i < gdbarch_tdep (gdbarch)->num_aregs; ++i)
156
        regcache_raw_supply (regcache,
157
                              gdbarch_tdep (gdbarch)->ar_base + i,
158
                              &regs->ar[i]);
159
    }
160
}
161
 
162
void
163
supply_gregset (struct regcache *regcache, const gdb_gregset_t *gregsetp)
164
{
165
  supply_gregset_reg (regcache, gregsetp, -1);
166
}
167
 
168
void
169
fill_fpregset (const struct regcache *regcache,
170
               gdb_fpregset_t *fpregsetp, int regnum)
171
{
172
  return;
173
}
174
 
175
void
176
supply_fpregset (struct regcache *regcache,
177
                 const gdb_fpregset_t *fpregsetp)
178
{
179
  return;
180
}
181
 
182
/* Fetch greg-register(s) from process/thread TID
183
   and store value(s) in GDB's register array.  */
184
 
185
static void
186
fetch_gregs (struct regcache *regcache, int regnum)
187
{
188
  int tid = GET_THREAD_ID (inferior_ptid);
189
  const gdb_gregset_t regs;
190
  int areg;
191
 
192
  if (ptrace (PTRACE_GETREGS, tid, 0, (long) &regs) < 0)
193
    {
194
      perror_with_name (_("Couldn't get registers"));
195
      return;
196
    }
197
 
198
  supply_gregset_reg (regcache, &regs, regnum);
199
}
200
 
201
/* Store greg-register(s) in GDB's register
202
   array into the process/thread specified by TID.  */
203
 
204
static void
205
store_gregs (struct regcache *regcache, int regnum)
206
{
207
  int tid = GET_THREAD_ID (inferior_ptid);
208
  gdb_gregset_t regs;
209
  int areg;
210
 
211
  if (ptrace (PTRACE_GETREGS, tid, 0, (long) &regs) < 0)
212
    {
213
      perror_with_name (_("Couldn't get registers"));
214
      return;
215
    }
216
 
217
  fill_gregset (regcache, &regs, regnum);
218
 
219
  if (ptrace (PTRACE_SETREGS, tid, 0, (long) &regs) < 0)
220
    {
221
      perror_with_name (_("Couldn't write registers"));
222
      return;
223
    }
224
}
225
 
226
static int xtreg_lo;
227
static int xtreg_high;
228
 
229
/* Fetch/Store Xtensa TIE registers.  Xtensa GNU/Linux PTRACE
230
   interface provides special requests for this.  */
231
 
232
static void
233
fetch_xtregs (struct regcache *regcache, int regnum)
234
{
235
  int tid = GET_THREAD_ID (inferior_ptid);
236
  const xtensa_regtable_t *ptr;
237
  char xtregs [XTENSA_ELF_XTREG_SIZE];
238
 
239
  if (ptrace (PTRACE_GETXTREGS, tid, 0, (long)&xtregs) < 0)
240
    perror_with_name (_("Couldn't get extended registers"));
241
 
242
  for (ptr = xtensa_regmap_table; ptr->name; ptr++)
243
    if (regnum == ptr->gdb_regnum || regnum == -1)
244
      regcache_raw_supply (regcache, ptr->gdb_regnum,
245
                           xtregs + ptr->ptrace_offset);
246
}
247
 
248
static void
249
store_xtregs (struct regcache *regcache, int regnum)
250
{
251
  int tid = GET_THREAD_ID (inferior_ptid);
252
  const xtensa_regtable_t *ptr;
253
  char xtregs [XTENSA_ELF_XTREG_SIZE];
254
 
255
  if (ptrace (PTRACE_GETXTREGS, tid, 0, (long)&xtregs) < 0)
256
    perror_with_name (_("Couldn't get extended registers"));
257
 
258
  for (ptr = xtensa_regmap_table; ptr->name; ptr++)
259
    if (regnum == ptr->gdb_regnum || regnum == -1)
260
      regcache_raw_collect (regcache, ptr->gdb_regnum,
261
                            xtregs + ptr->ptrace_offset);
262
 
263
  if (ptrace (PTRACE_SETXTREGS, tid, 0, (long)&xtregs) < 0)
264
    perror_with_name (_("Couldn't write extended registers"));
265
}
266
 
267
void
268
xtensa_linux_fetch_inferior_registers (struct regcache *regcache, int regnum)
269
{
270
  if (regnum == -1)
271
    {
272
      fetch_gregs (regcache, regnum);
273
      fetch_xtregs (regcache, regnum);
274
    }
275
  else if ((regnum < xtreg_lo) || (regnum > xtreg_high))
276
    fetch_gregs (regcache, regnum);
277
  else
278
    fetch_xtregs (regcache, regnum);
279
}
280
 
281
void
282
xtensa_linux_store_inferior_registers (struct regcache *regcache, int regnum)
283
{
284
  if (regnum == -1)
285
    {
286
      store_gregs (regcache, regnum);
287
      store_xtregs (regcache, regnum);
288
    }
289
  else if ((regnum < xtreg_lo) || (regnum > xtreg_high))
290
    store_gregs (regcache, regnum);
291
  else
292
    store_xtregs (regcache, regnum);
293
}
294
 
295
void _initialize_xtensa_linux_nat (void);
296
 
297
void
298
_initialize_xtensa_linux_nat (void)
299
{
300
  struct target_ops *t;
301
  const xtensa_regtable_t *ptr;
302
 
303
  /* Calculate the number range for extended registers.  */
304
  xtreg_lo = 1000000000;
305
  xtreg_high = -1;
306
  for (ptr = xtensa_regmap_table; ptr->name; ptr++)
307
    {
308
      if (ptr->gdb_regnum < xtreg_lo)
309
        xtreg_lo = ptr->gdb_regnum;
310
      if (ptr->gdb_regnum > xtreg_high)
311
        xtreg_high = ptr->gdb_regnum;
312
    }
313
 
314
  /* Fill in the generic GNU/Linux methods.  */
315
  t = linux_target ();
316
 
317
  /* Add our register access methods.  */
318
  t->to_fetch_registers = xtensa_linux_fetch_inferior_registers;
319
  t->to_store_registers = xtensa_linux_store_inferior_registers;
320
 
321
  linux_nat_add_target (t);
322
}

powered by: WebSVN 2.1.0

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