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

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [gnu-src/] [gdb-7.2/] [gdb/] [hppa-hpux-nat.c] - Blame information for rev 330

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 330 jeremybenn
/* Native-dependent code for PA-RISC HP-UX.
2
 
3
   Copyright (C) 2004, 2005, 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 "regcache.h"
24
#include "target.h"
25
 
26
#include "gdb_assert.h"
27
#include <sys/ptrace.h>
28
#include <machine/save_state.h>
29
 
30
#ifdef HAVE_TTRACE
31
#include <sys/ttrace.h>
32
#endif
33
 
34
#include "hppa-tdep.h"
35
#include "inf-ptrace.h"
36
#include "inf-ttrace.h"
37
 
38
/* Non-zero if we should pretend not to be a runnable target.  */
39
int child_suppress_run = 0;
40
 
41
/* Return the offset of register REGNUM within `struct save_state'.
42
   The offset returns depends on the flags in the "flags" register and
43
   the register size (32-bit or 64-bit).  These are taken from
44
   REGCACHE.  */
45
 
46
LONGEST
47
hppa_hpux_save_state_offset (struct regcache *regcache, int regnum)
48
{
49
  LONGEST offset;
50
 
51
  if (regnum == HPPA_FLAGS_REGNUM)
52
    return ssoff (ss_flags);
53
 
54
  if (HPPA_R0_REGNUM < regnum && regnum < HPPA_FP0_REGNUM)
55
    {
56
      struct gdbarch *arch = get_regcache_arch (regcache);
57
      size_t size = register_size (arch, HPPA_R1_REGNUM);
58
      ULONGEST flags;
59
 
60
      gdb_assert (size == 4 || size == 8);
61
 
62
      regcache_cooked_read_unsigned (regcache, HPPA_FLAGS_REGNUM, &flags);
63
      if (flags & SS_WIDEREGS)
64
        offset = ssoff (ss_wide) + (8 - size) + (regnum - HPPA_R0_REGNUM) * 8;
65
      else
66
        offset = ssoff (ss_narrow) + (regnum - HPPA_R1_REGNUM) * 4;
67
    }
68
  else
69
    {
70
      struct gdbarch *arch = get_regcache_arch (regcache);
71
      size_t size = register_size (arch, HPPA_FP0_REGNUM);
72
 
73
      gdb_assert (size == 4 || size == 8);
74
      gdb_assert (regnum >= HPPA_FP0_REGNUM);
75
      offset = ssoff(ss_fpblock) + (regnum - HPPA_FP0_REGNUM) * size;
76
    }
77
 
78
  gdb_assert (offset < sizeof (save_state_t));
79
  return offset;
80
}
81
 
82
/* Just in case a future version of PA-RISC HP-UX won't have ptrace(2)
83
   at all.  */
84
#ifndef PTRACE_TYPE_RET
85
#define PTRACE_TYPE_RET void
86
#endif
87
 
88
static void
89
hppa_hpux_fetch_register (struct regcache *regcache, int regnum)
90
{
91
  struct gdbarch *gdbarch = get_regcache_arch (regcache);
92
  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
93
  CORE_ADDR addr;
94
  size_t size;
95
  PTRACE_TYPE_RET *buf;
96
  pid_t pid;
97
  int i;
98
 
99
  pid = ptid_get_pid (inferior_ptid);
100
 
101
  /* This isn't really an address, but ptrace thinks of it as one.  */
102
  addr = hppa_hpux_save_state_offset (regcache, regnum);
103
  size = register_size (gdbarch, regnum);
104
 
105
  gdb_assert (size == 4 || size == 8);
106
  buf = alloca (size);
107
 
108
#ifdef HAVE_TTRACE
109
  {
110
    lwpid_t lwp = ptid_get_lwp (inferior_ptid);
111
 
112
    if (ttrace (TT_LWP_RUREGS, pid, lwp, addr, size, (uintptr_t)buf) == -1)
113
      error (_("Couldn't read register %s (#%d): %s"),
114
             gdbarch_register_name (gdbarch, regnum),
115
             regnum, safe_strerror (errno));
116
  }
117
#else
118
  {
119
    int i;
120
 
121
    /* Read the register contents from the inferior a chuck at the time.  */
122
    for (i = 0; i < size / sizeof (PTRACE_TYPE_RET); i++)
123
      {
124
        errno = 0;
125
        buf[i] = ptrace (PT_RUREGS, pid, (PTRACE_TYPE_ARG3) addr, 0, 0);
126
        if (errno != 0)
127
          error (_("Couldn't read register %s (#%d): %s"),
128
                 gdbarch_register_name (gdbarch, regnum),
129
                 regnum, safe_strerror (errno));
130
 
131
        addr += sizeof (PTRACE_TYPE_RET);
132
      }
133
  }
134
#endif
135
 
136
  /* Take care with the "flags" register.  It's stored as an `int' in
137
     `struct save_state', even for 64-bit code.  */
138
  if (regnum == HPPA_FLAGS_REGNUM && size == 8)
139
    {
140
      ULONGEST flags;
141
      flags = extract_unsigned_integer ((gdb_byte *)buf, 4, byte_order);
142
      store_unsigned_integer ((gdb_byte *)buf, 8, byte_order, flags);
143
    }
144
 
145
  regcache_raw_supply (regcache, regnum, buf);
146
}
147
 
148
static void
149
hppa_hpux_fetch_inferior_registers (struct target_ops *ops,
150
                                    struct regcache *regcache, int regnum)
151
{
152
  if (regnum == -1)
153
    for (regnum = 0;
154
         regnum < gdbarch_num_regs (get_regcache_arch (regcache));
155
         regnum++)
156
      hppa_hpux_fetch_register (regcache, regnum);
157
  else
158
    hppa_hpux_fetch_register (regcache, regnum);
159
}
160
 
161
/* Store register REGNUM into the inferior.  */
162
 
163
static void
164
hppa_hpux_store_register (struct regcache *regcache, int regnum)
165
{
166
  struct gdbarch *gdbarch = get_regcache_arch (regcache);
167
  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
168
  CORE_ADDR addr;
169
  size_t size;
170
  PTRACE_TYPE_RET *buf;
171
  pid_t pid;
172
 
173
  pid = ptid_get_pid (inferior_ptid);
174
 
175
  /* This isn't really an address, but ptrace thinks of it as one.  */
176
  addr = hppa_hpux_save_state_offset (regcache, regnum);
177
  size = register_size (gdbarch, regnum);
178
 
179
  gdb_assert (size == 4 || size == 8);
180
  buf = alloca (size);
181
 
182
  regcache_raw_collect (regcache, regnum, buf);
183
 
184
  /* Take care with the "flags" register.  It's stored as an `int' in
185
     `struct save_state', even for 64-bit code.  */
186
  if (regnum == HPPA_FLAGS_REGNUM && size == 8)
187
    {
188
      ULONGEST flags;
189
      flags = extract_unsigned_integer ((gdb_byte *)buf, 8, byte_order);
190
      store_unsigned_integer ((gdb_byte *)buf, 4, byte_order, flags);
191
      size = 4;
192
    }
193
 
194
#ifdef HAVE_TTRACE
195
  {
196
    lwpid_t lwp = ptid_get_lwp (inferior_ptid);
197
 
198
    if (ttrace (TT_LWP_WUREGS, pid, lwp, addr, size, (uintptr_t)buf) == -1)
199
      error (_("Couldn't write register %s (#%d): %s"),
200
             gdbarch_register_name (gdbarch, regnum),
201
             regnum, safe_strerror (errno));
202
  }
203
#else
204
  {
205
    int i;
206
 
207
    /* Write the register contents into the inferior a chunk at the time.  */
208
    for (i = 0; i < size / sizeof (PTRACE_TYPE_RET); i++)
209
      {
210
        errno = 0;
211
        ptrace (PT_WUREGS, pid, (PTRACE_TYPE_ARG3) addr, buf[i], 0);
212
        if (errno != 0)
213
          error (_("Couldn't write register %s (#%d): %s"),
214
                 gdbarch_register_name (gdbarch, regnum),
215
                 regnum, safe_strerror (errno));
216
 
217
        addr += sizeof (PTRACE_TYPE_RET);
218
      }
219
  }
220
#endif
221
}
222
 
223
/* Store register REGNUM back into the inferior.  If REGNUM is -1, do
224
   this for all registers (including the floating point registers).  */
225
 
226
static void
227
hppa_hpux_store_inferior_registers (struct target_ops *ops,
228
                                    struct regcache *regcache, int regnum)
229
{
230
  if (regnum == -1)
231
    for (regnum = 0;
232
         regnum < gdbarch_num_regs (get_regcache_arch (regcache));
233
         regnum++)
234
      hppa_hpux_store_register (regcache, regnum);
235
  else
236
    hppa_hpux_store_register (regcache, regnum);
237
}
238
 
239
static int
240
hppa_hpux_child_can_run (void)
241
{
242
  /* This variable is controlled by modules that layer their own
243
     process structure atop that provided here.  The code in
244
     hpux-thread.c does this to support the HP-UX user-mode DCE
245
     threads.  */
246
  return !child_suppress_run;
247
}
248
 
249
 
250
/* Prevent warning from -Wmissing-prototypes.  */
251
void _initialize_hppa_hpux_nat (void);
252
 
253
void
254
_initialize_hppa_hpux_nat (void)
255
{
256
  struct target_ops *t;
257
 
258
#ifdef HAVE_TTRACE
259
  t = inf_ttrace_target ();
260
#else
261
  t = inf_ptrace_target ();
262
#endif
263
 
264
  t->to_fetch_registers = hppa_hpux_fetch_inferior_registers;
265
  t->to_store_registers = hppa_hpux_store_inferior_registers;
266
  t->to_can_run = hppa_hpux_child_can_run;
267
 
268
  add_target (t);
269
}

powered by: WebSVN 2.1.0

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