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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [insight/] [gdb/] [sparc-nat.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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