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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [gdb-5.0/] [gdb/] [mips-nat.c] - Blame information for rev 1774

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

Line No. Rev Author Line
1 104 markom
/* Low level DECstation interface to ptrace, for GDB when running native.
2
   Copyright 1988, 1989, 1991, 1992, 1995 Free Software Foundation, Inc.
3
   Contributed by Alessandro Forin(af@cs.cmu.edu) at CMU
4
   and by Per Bothner(bothner@cs.wisc.edu) at U.Wisconsin.
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 "gdbcore.h"
26
#include <sys/ptrace.h>
27
#include <sys/types.h>
28
#include <sys/param.h>
29
#include <sys/user.h>
30
#undef JB_S0
31
#undef JB_S1
32
#undef JB_S2
33
#undef JB_S3
34
#undef JB_S4
35
#undef JB_S5
36
#undef JB_S6
37
#undef JB_S7
38
#undef JB_SP
39
#undef JB_S8
40
#undef JB_PC
41
#undef JB_SR
42
#undef NJBREGS
43
#include <setjmp.h>             /* For JB_XXX.  */
44
 
45
/* Size of elements in jmpbuf */
46
 
47
#define JB_ELEMENT_SIZE 4
48
 
49
/* Map gdb internal register number to ptrace ``address''.
50
   These ``addresses'' are defined in DECstation <sys/ptrace.h> */
51
 
52
#define REGISTER_PTRACE_ADDR(regno) \
53
   (regno < 32 ?                GPR_BASE + regno \
54
  : regno == PC_REGNUM ?        PC      \
55
  : regno == CAUSE_REGNUM ?     CAUSE   \
56
  : regno == HI_REGNUM ?        MMHI    \
57
  : regno == LO_REGNUM ?        MMLO    \
58
  : regno == FCRCS_REGNUM ?     FPC_CSR \
59
  : regno == FCRIR_REGNUM ?     FPC_EIR \
60
  : regno >= FP0_REGNUM ?       FPR_BASE + (regno - FP0_REGNUM) \
61
  : 0)
62
 
63
static char zerobuf[MAX_REGISTER_RAW_SIZE] =
64
{0};
65
 
66
static void fetch_core_registers PARAMS ((char *, unsigned, int, CORE_ADDR));
67
 
68
/* Get all registers from the inferior */
69
 
70
void
71
fetch_inferior_registers (regno)
72
     int regno;
73
{
74
  register unsigned int regaddr;
75
  char buf[MAX_REGISTER_RAW_SIZE];
76
  register int i;
77
 
78
  registers_fetched ();
79
 
80
  for (regno = 1; regno < NUM_REGS; regno++)
81
    {
82
      regaddr = REGISTER_PTRACE_ADDR (regno);
83
      for (i = 0; i < REGISTER_RAW_SIZE (regno); i += sizeof (int))
84
        {
85
          *(int *) &buf[i] = ptrace (PT_READ_U, inferior_pid,
86
                                     (PTRACE_ARG3_TYPE) regaddr, 0);
87
          regaddr += sizeof (int);
88
        }
89
      supply_register (regno, buf);
90
    }
91
 
92
  supply_register (ZERO_REGNUM, zerobuf);
93
  /* Frame ptr reg must appear to be 0; it is faked by stack handling code. */
94
  supply_register (FP_REGNUM, zerobuf);
95
}
96
 
97
/* Store our register values back into the inferior.
98
   If REGNO is -1, do this for all registers.
99
   Otherwise, REGNO specifies which register (so we can save time).  */
100
 
101
void
102
store_inferior_registers (regno)
103
     int regno;
104
{
105
  register unsigned int regaddr;
106
  char buf[80];
107
 
108
  if (regno > 0)
109
    {
110
      if (regno == ZERO_REGNUM || regno == PS_REGNUM
111
          || regno == BADVADDR_REGNUM || regno == CAUSE_REGNUM
112
          || regno == FCRIR_REGNUM || regno == FP_REGNUM
113
          || (regno >= FIRST_EMBED_REGNUM && regno <= LAST_EMBED_REGNUM))
114
        return;
115
      regaddr = REGISTER_PTRACE_ADDR (regno);
116
      errno = 0;
117
      ptrace (PT_WRITE_U, inferior_pid, (PTRACE_ARG3_TYPE) regaddr,
118
              read_register (regno));
119
      if (errno != 0)
120
        {
121
          sprintf (buf, "writing register number %d", regno);
122
          perror_with_name (buf);
123
        }
124
    }
125
  else
126
    {
127
      for (regno = 0; regno < NUM_REGS; regno++)
128
        store_inferior_registers (regno);
129
    }
130
}
131
 
132
 
133
/* Figure out where the longjmp will land.
134
   We expect the first arg to be a pointer to the jmp_buf structure from which
135
   we extract the pc (JB_PC) that we will land at.  The pc is copied into PC.
136
   This routine returns true on success. */
137
 
138
int
139
get_longjmp_target (pc)
140
     CORE_ADDR *pc;
141
{
142
  CORE_ADDR jb_addr;
143
  char buf[TARGET_PTR_BIT / TARGET_CHAR_BIT];
144
 
145
  jb_addr = read_register (A0_REGNUM);
146
 
147
  if (target_read_memory (jb_addr + JB_PC * JB_ELEMENT_SIZE, buf,
148
                          TARGET_PTR_BIT / TARGET_CHAR_BIT))
149
    return 0;
150
 
151
  *pc = extract_address (buf, TARGET_PTR_BIT / TARGET_CHAR_BIT);
152
 
153
  return 1;
154
}
155
 
156
/* Extract the register values out of the core file and store
157
   them where `read_register' will find them.
158
 
159
   CORE_REG_SECT points to the register values themselves, read into memory.
160
   CORE_REG_SIZE is the size of that area.
161
   WHICH says which set of registers we are handling (0 = int, 2 = float
162
   on machines where they are discontiguous).
163
   REG_ADDR is the offset from u.u_ar0 to the register values relative to
164
   core_reg_sect.  This is used with old-fashioned core files to
165
   locate the registers in a large upage-plus-stack ".reg" section.
166
   Original upage address X is at location core_reg_sect+x+reg_addr.
167
 */
168
 
169
static void
170
fetch_core_registers (core_reg_sect, core_reg_size, which, reg_addr)
171
     char *core_reg_sect;
172
     unsigned core_reg_size;
173
     int which;
174
     CORE_ADDR reg_addr;
175
{
176
  register int regno;
177
  register unsigned int addr;
178
  int bad_reg = -1;
179
  register reg_ptr = -reg_addr; /* Original u.u_ar0 is -reg_addr. */
180
 
181
  /* If u.u_ar0 was an absolute address in the core file, relativize it now,
182
     so we can use it as an offset into core_reg_sect.  When we're done,
183
     "register 0" will be at core_reg_sect+reg_ptr, and we can use
184
     register_addr to offset to the other registers.  If this is a modern
185
     core file without a upage, reg_ptr will be zero and this is all a big
186
     NOP.  */
187
  if (reg_ptr > core_reg_size)
188
#ifdef KERNEL_U_ADDR
189
    reg_ptr -= KERNEL_U_ADDR;
190
#else
191
    error ("Old mips core file can't be processed on this machine.");
192
#endif
193
 
194
  for (regno = 0; regno < NUM_REGS; regno++)
195
    {
196
      addr = register_addr (regno, reg_ptr);
197
      if (addr >= core_reg_size)
198
        {
199
          if (bad_reg < 0)
200
            bad_reg = regno;
201
        }
202
      else
203
        {
204
          supply_register (regno, core_reg_sect + addr);
205
        }
206
    }
207
  if (bad_reg >= 0)
208
    {
209
      error ("Register %s not found in core file.", REGISTER_NAME (bad_reg));
210
    }
211
  supply_register (ZERO_REGNUM, zerobuf);
212
  /* Frame ptr reg must appear to be 0; it is faked by stack handling code. */
213
  supply_register (FP_REGNUM, zerobuf);
214
}
215
 
216
/* Return the address in the core dump or inferior of register REGNO.
217
   BLOCKEND is the address of the end of the user structure.  */
218
 
219
CORE_ADDR
220
register_addr (regno, blockend)
221
     int regno;
222
     CORE_ADDR blockend;
223
{
224
  CORE_ADDR addr;
225
 
226
  if (regno < 0 || regno >= NUM_REGS)
227
    error ("Invalid register number %d.", regno);
228
 
229
  REGISTER_U_ADDR (addr, blockend, regno);
230
 
231
  return addr;
232
}
233
 
234
 
235
/* Register that we are able to handle mips core file formats.
236
   FIXME: is this really bfd_target_unknown_flavour? */
237
 
238
static struct core_fns mips_core_fns =
239
{
240
  bfd_target_unknown_flavour,           /* core_flavour */
241
  default_check_format,                 /* check_format */
242
  default_core_sniffer,                 /* core_sniffer */
243
  fetch_core_registers,                 /* core_read_registers */
244
  NULL                                  /* next */
245
};
246
 
247
void
248
_initialize_core_mips ()
249
{
250
  add_core_fns (&mips_core_fns);
251
}

powered by: WebSVN 2.1.0

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