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

Subversion Repositories scarts

[/] [scarts/] [trunk/] [toolchain/] [scarts-gdb/] [gdb-6.8/] [gdb/] [hppa-hpux-nat.c] - Blame information for rev 25

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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