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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [gdb-5.3/] [gdb/] [sparc-nat.c] - Blame information for rev 1774

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

Line No. Rev Author Line
1 1181 sfurman
/* Functions specific to running gdb native on a SPARC running SunOS4.
2
   Copyright 1989, 1992, 1993, 1994, 1996, 1997, 1998, 1999, 2000, 2001,
3
   2002
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 2 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, write to the Free Software
20
   Foundation, Inc., 59 Temple Place - Suite 330,
21
   Boston, MA 02111-1307, USA.  */
22
 
23
#include "defs.h"
24
#include "inferior.h"
25
#include "target.h"
26
#include "gdbcore.h"
27
#include "regcache.h"
28
 
29
#ifdef HAVE_SYS_PARAM_H
30
#include <sys/param.h>
31
#endif
32
#include <signal.h>
33
#include <sys/ptrace.h>
34
#include <sys/wait.h>
35
#ifdef __linux__
36
#include <asm/reg.h>
37
#else
38
#include <machine/reg.h>
39
#endif
40
#include <sys/user.h>
41
 
42
/* We don't store all registers immediately when requested, since they
43
   get sent over in large chunks anyway.  Instead, we accumulate most
44
   of the changes and send them over once.  "deferred_stores" keeps
45
   track of which sets of registers we have locally-changed copies of,
46
   so we only need send the groups that have changed.  */
47
 
48
#define INT_REGS        1
49
#define STACK_REGS      2
50
#define FP_REGS         4
51
 
52
/* Fetch one or more registers from the inferior.  REGNO == -1 to get
53
   them all.  We actually fetch more than requested, when convenient,
54
   marking them as valid so we won't fetch them again.  */
55
 
56
void
57
fetch_inferior_registers (int regno)
58
{
59
  struct regs inferior_registers;
60
  struct fp_status inferior_fp_registers;
61
  int i;
62
  int fetch_pid;
63
 
64
  /* NOTE: cagney/2002-12-03: This code assumes that the currently
65
     selected light weight processes' registers can be written
66
     directly into the selected thread's register cache.  This works
67
     fine when given an 1:1 LWP:thread model (such as found on
68
     GNU/Linux) but will, likely, have problems when used on an N:1
69
     (userland threads) or N:M (userland multiple LWP) model.  In the
70
     case of the latter two, the LWP's registers do not necessarily
71
     belong to the selected thread (the LWP could be in the middle of
72
     executing the thread switch code).
73
 
74
     These functions should instead be paramaterized with an explicit
75
     object (struct regcache, struct thread_info?) into which the LWPs
76
     registers can be written.  */
77
 
78
  fetch_pid = TIDGET (inferior_ptid);
79
  if (fetch_pid == 0)
80
    fetch_pid = PIDGET (inferior_ptid);
81
 
82
  /* We should never be called with deferred stores, because a prerequisite
83
     for writing regs is to have fetched them all (PREPARE_TO_STORE), sigh.  */
84
  if (deferred_stores)
85
    internal_error (__FILE__, __LINE__, "failed internal consistency check");
86
 
87
  DO_DEFERRED_STORES;
88
 
89
  /* Global and Out regs are fetched directly, as well as the control
90
     registers.  If we're getting one of the in or local regs,
91
     and the stack pointer has not yet been fetched,
92
     we have to do that first, since they're found in memory relative
93
     to the stack pointer.  */
94
  if (regno < O7_REGNUM         /* including -1 */
95
      || regno >= Y_REGNUM
96
      || (!register_valid[SP_REGNUM] && regno < I7_REGNUM))
97
    {
98
      if (0 != ptrace (PTRACE_GETREGS, fetch_pid,
99
                       (PTRACE_ARG3_TYPE) & inferior_registers, 0))
100
        perror ("ptrace_getregs");
101
 
102
      registers[REGISTER_BYTE (0)] = 0;
103
      memcpy (&registers[REGISTER_BYTE (1)], &inferior_registers.r_g1,
104
              15 * REGISTER_RAW_SIZE (G0_REGNUM));
105
      *(int *) &registers[REGISTER_BYTE (PS_REGNUM)] = inferior_registers.r_ps;
106
      *(int *) &registers[REGISTER_BYTE (PC_REGNUM)] = inferior_registers.r_pc;
107
      *(int *) &registers[REGISTER_BYTE (NPC_REGNUM)] = inferior_registers.r_npc;
108
      *(int *) &registers[REGISTER_BYTE (Y_REGNUM)] = inferior_registers.r_y;
109
 
110
      for (i = G0_REGNUM; i <= O7_REGNUM; i++)
111
        register_valid[i] = 1;
112
      register_valid[Y_REGNUM] = 1;
113
      register_valid[PS_REGNUM] = 1;
114
      register_valid[PC_REGNUM] = 1;
115
      register_valid[NPC_REGNUM] = 1;
116
      /* If we don't set these valid, read_register_bytes() rereads
117
         all the regs every time it is called!  FIXME.  */
118
      register_valid[WIM_REGNUM] = 1;   /* Not true yet, FIXME */
119
      register_valid[TBR_REGNUM] = 1;   /* Not true yet, FIXME */
120
      register_valid[CPS_REGNUM] = 1;   /* Not true yet, FIXME */
121
    }
122
 
123
  /* Floating point registers */
124
  if (regno == -1 ||
125
      regno == FPS_REGNUM ||
126
      (regno >= FP0_REGNUM && regno <= FP0_REGNUM + 31))
127
    {
128
      if (0 != ptrace (PTRACE_GETFPREGS, fetch_pid,
129
                       (PTRACE_ARG3_TYPE) & inferior_fp_registers,
130
                       0))
131
        perror ("ptrace_getfpregs");
132
      memcpy (&registers[REGISTER_BYTE (FP0_REGNUM)], &inferior_fp_registers,
133
              sizeof inferior_fp_registers.fpu_fr);
134
      memcpy (&registers[REGISTER_BYTE (FPS_REGNUM)],
135
              &inferior_fp_registers.Fpu_fsr,
136
              sizeof (FPU_FSR_TYPE));
137
      for (i = FP0_REGNUM; i <= FP0_REGNUM + 31; i++)
138
        register_valid[i] = 1;
139
      register_valid[FPS_REGNUM] = 1;
140
    }
141
 
142
  /* These regs are saved on the stack by the kernel.  Only read them
143
     all (16 ptrace calls!) if we really need them.  */
144
  if (regno == -1)
145
    {
146
      CORE_ADDR sp = *(unsigned int *) & registers[REGISTER_BYTE (SP_REGNUM)];
147
      target_read_memory (sp, &registers[REGISTER_BYTE (L0_REGNUM)],
148
                          16 * REGISTER_RAW_SIZE (L0_REGNUM));
149
      for (i = L0_REGNUM; i <= I7_REGNUM; i++)
150
        register_valid[i] = 1;
151
    }
152
  else if (regno >= L0_REGNUM && regno <= I7_REGNUM)
153
    {
154
      CORE_ADDR sp = *(unsigned int *) & registers[REGISTER_BYTE (SP_REGNUM)];
155
      i = REGISTER_BYTE (regno);
156
      if (register_valid[regno])
157
        printf_unfiltered ("register %d valid and read\n", regno);
158
      target_read_memory (sp + i - REGISTER_BYTE (L0_REGNUM),
159
                          &registers[i], REGISTER_RAW_SIZE (regno));
160
      register_valid[regno] = 1;
161
    }
162
}
163
 
164
/* Store our register values back into the inferior.
165
   If REGNO is -1, do this for all registers.
166
   Otherwise, REGNO specifies which register (so we can save time).  */
167
 
168
void
169
store_inferior_registers (int regno)
170
{
171
  struct regs inferior_registers;
172
  struct fp_status inferior_fp_registers;
173
  int wanna_store = INT_REGS + STACK_REGS + FP_REGS;
174
  int store_pid;
175
 
176
  /* NOTE: cagney/2002-12-02: See comment in fetch_inferior_registers
177
     about threaded assumptions.  */
178
  store_pid = TIDGET (inferior_ptid);
179
  if (store_pid == 0)
180
    store_pid = PIDGET (inferior_ptid);
181
 
182
  /* First decide which pieces of machine-state we need to modify.
183
     Default for regno == -1 case is all pieces.  */
184
  if (regno >= 0)
185
    {
186
      if (FP0_REGNUM <= regno && regno < FP0_REGNUM + 32)
187
        {
188
          wanna_store = FP_REGS;
189
        }
190
      else
191
        {
192
          if (regno == SP_REGNUM)
193
            wanna_store = INT_REGS + STACK_REGS;
194
          else if (regno < L0_REGNUM || regno > I7_REGNUM)
195
            wanna_store = INT_REGS;
196
          else if (regno == FPS_REGNUM)
197
            wanna_store = FP_REGS;
198
          else
199
            wanna_store = STACK_REGS;
200
        }
201
    }
202
 
203
  /* See if we're forcing the stores to happen now, or deferring. */
204
  if (regno == -2)
205
    {
206
      wanna_store = deferred_stores;
207
      deferred_stores = 0;
208
    }
209
  else
210
    {
211
      if (wanna_store == STACK_REGS)
212
        {
213
          /* Fall through and just store one stack reg.  If we deferred
214
             it, we'd have to store them all, or remember more info.  */
215
        }
216
      else
217
        {
218
          deferred_stores |= wanna_store;
219
          return;
220
        }
221
    }
222
 
223
  if (wanna_store & STACK_REGS)
224
    {
225
      CORE_ADDR sp = *(unsigned int *) & registers[REGISTER_BYTE (SP_REGNUM)];
226
 
227
      if (regno < 0 || regno == SP_REGNUM)
228
        {
229
          if (!register_valid[L0_REGNUM + 5])
230
            internal_error (__FILE__, __LINE__, "failed internal consistency check");
231
          target_write_memory (sp,
232
                               &registers[REGISTER_BYTE (L0_REGNUM)],
233
                               16 * REGISTER_RAW_SIZE (L0_REGNUM));
234
        }
235
      else
236
        {
237
          if (!register_valid[regno])
238
            internal_error (__FILE__, __LINE__, "failed internal consistency check");
239
          target_write_memory (sp + REGISTER_BYTE (regno) - REGISTER_BYTE (L0_REGNUM),
240
                               &registers[REGISTER_BYTE (regno)],
241
                               REGISTER_RAW_SIZE (regno));
242
        }
243
 
244
    }
245
 
246
  if (wanna_store & INT_REGS)
247
    {
248
      if (!register_valid[G1_REGNUM])
249
        internal_error (__FILE__, __LINE__, "failed internal consistency check");
250
 
251
      memcpy (&inferior_registers.r_g1, &registers[REGISTER_BYTE (G1_REGNUM)],
252
              15 * REGISTER_RAW_SIZE (G1_REGNUM));
253
 
254
      inferior_registers.r_ps =
255
        *(int *) &registers[REGISTER_BYTE (PS_REGNUM)];
256
      inferior_registers.r_pc =
257
        *(int *) &registers[REGISTER_BYTE (PC_REGNUM)];
258
      inferior_registers.r_npc =
259
        *(int *) &registers[REGISTER_BYTE (NPC_REGNUM)];
260
      inferior_registers.r_y =
261
        *(int *) &registers[REGISTER_BYTE (Y_REGNUM)];
262
 
263
      if (0 != ptrace (PTRACE_SETREGS, store_pid,
264
                       (PTRACE_ARG3_TYPE) & inferior_registers, 0))
265
        perror ("ptrace_setregs");
266
    }
267
 
268
  if (wanna_store & FP_REGS)
269
    {
270
      if (!register_valid[FP0_REGNUM + 9])
271
        internal_error (__FILE__, __LINE__, "failed internal consistency check");
272
      memcpy (&inferior_fp_registers, &registers[REGISTER_BYTE (FP0_REGNUM)],
273
              sizeof inferior_fp_registers.fpu_fr);
274
      memcpy (&inferior_fp_registers.Fpu_fsr,
275
              &registers[REGISTER_BYTE (FPS_REGNUM)], sizeof (FPU_FSR_TYPE));
276
      if (0 !=
277
          ptrace (PTRACE_SETFPREGS, store_pid,
278
                  (PTRACE_ARG3_TYPE) & inferior_fp_registers, 0))
279
        perror ("ptrace_setfpregs");
280
    }
281
}
282
 
283
/* Provide registers to GDB from a core file.
284
 
285
   CORE_REG_SECT points to an array of bytes, which are the contents
286
   of a `note' from a core file which BFD thinks might contain
287
   register contents.  CORE_REG_SIZE is its size.
288
 
289
   WHICH says which register set corelow suspects this is:
290
 
291
     2 --- the floating-point register set
292
 
293
   IGNORE is unused.  */
294
 
295
static void
296
fetch_core_registers (char *core_reg_sect, unsigned core_reg_size,
297
                      int which, CORE_ADDR ignore)
298
{
299
 
300
  if (which == 0)
301
    {
302
 
303
      /* Integer registers */
304
 
305
#define gregs ((struct regs *)core_reg_sect)
306
      /* G0 *always* holds 0.  */
307
      *(int *) &registers[REGISTER_BYTE (0)] = 0;
308
 
309
      /* The globals and output registers.  */
310
      memcpy (&registers[REGISTER_BYTE (G1_REGNUM)], &gregs->r_g1,
311
              15 * REGISTER_RAW_SIZE (G1_REGNUM));
312
      *(int *) &registers[REGISTER_BYTE (PS_REGNUM)] = gregs->r_ps;
313
      *(int *) &registers[REGISTER_BYTE (PC_REGNUM)] = gregs->r_pc;
314
      *(int *) &registers[REGISTER_BYTE (NPC_REGNUM)] = gregs->r_npc;
315
      *(int *) &registers[REGISTER_BYTE (Y_REGNUM)] = gregs->r_y;
316
 
317
      /* My best guess at where to get the locals and input
318
         registers is exactly where they usually are, right above
319
         the stack pointer.  If the core dump was caused by a bus error
320
         from blowing away the stack pointer (as is possible) then this
321
         won't work, but it's worth the try. */
322
      {
323
        int sp;
324
 
325
        sp = *(int *) &registers[REGISTER_BYTE (SP_REGNUM)];
326
        if (0 != target_read_memory (sp, &registers[REGISTER_BYTE (L0_REGNUM)],
327
                                     16 * REGISTER_RAW_SIZE (L0_REGNUM)))
328
          {
329
            /* fprintf_unfiltered so user can still use gdb */
330
            fprintf_unfiltered (gdb_stderr,
331
                "Couldn't read input and local registers from core file\n");
332
          }
333
      }
334
    }
335
  else if (which == 2)
336
    {
337
 
338
      /* Floating point registers */
339
 
340
#define fpuregs  ((struct fpu *) core_reg_sect)
341
      if (core_reg_size >= sizeof (struct fpu))
342
        {
343
          memcpy (&registers[REGISTER_BYTE (FP0_REGNUM)], fpuregs->fpu_regs,
344
                  sizeof (fpuregs->fpu_regs));
345
          memcpy (&registers[REGISTER_BYTE (FPS_REGNUM)], &fpuregs->fpu_fsr,
346
                  sizeof (FPU_FSR_TYPE));
347
        }
348
      else
349
        fprintf_unfiltered (gdb_stderr, "Couldn't read float regs from core file\n");
350
    }
351
}
352
 
353
int
354
kernel_u_size (void)
355
{
356
  return (sizeof (struct user));
357
}
358
 
359
 
360
/* Register that we are able to handle sparc core file formats.
361
   FIXME: is this really bfd_target_unknown_flavour? */
362
 
363
static struct core_fns sparc_core_fns =
364
{
365
  bfd_target_unknown_flavour,           /* core_flavour */
366
  default_check_format,                 /* check_format */
367
  default_core_sniffer,                 /* core_sniffer */
368
  fetch_core_registers,                 /* core_read_registers */
369
  NULL                                  /* next */
370
};
371
 
372
void
373
_initialize_core_sparc (void)
374
{
375
  add_core_fns (&sparc_core_fns);
376
}

powered by: WebSVN 2.1.0

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