1
/* libunwind - a platform-independent unwind library
2
Copyright (C) 2003-2004 Hewlett-Packard Co
3
Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
5
This file is part of libunwind.
7
Permission is hereby granted, free of charge, to any person obtaining
8
a copy of this software and associated documentation files (the
9
"Software"), to deal in the Software without restriction, including
10
without limitation the rights to use, copy, modify, merge, publish,
11
distribute, sublicense, and/or sell copies of the Software, and to
12
permit persons to whom the Software is furnished to do so, subject to
13
the following conditions:
15
The above copyright notice and this permission notice shall be
16
included in all copies or substantial portions of the Software.
18
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
21
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
22
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
23
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
24
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
26
#include "_UPT_internal.h"
30
# ifdef HAVE_ASM_PTRACE_OFFSETS_H
31
# include <asm/ptrace_offsets.h>
33
# include "ia64/rse.h"
37
_UPT_access_reg (unw_addr_space_t as, unw_regnum_t reg, unw_word_t *val,
40
struct UPT_info *ui = arg;
45
Debug (16, "%s <- %lx\n", unw_regname (reg), (long) *val);
49
if ((unsigned) reg - UNW_IA64_NAT < 32)
51
unsigned long nat_bits, mask;
53
/* The Linux ptrace represents the statc NaT bits as a single word. */
54
mask = ((unw_word_t) 1) << (reg - UNW_IA64_NAT);
57
# warning No support for ttrace() yet.
59
nat_bits = ptrace (PTRACE_PEEKUSER, pid, PT_NAT_BITS, 0);
71
# warning No support for ttrace() yet.
74
ptrace (PTRACE_POKEUSER, pid, PT_NAT_BITS, nat_bits);
92
unsigned long ip, psr;
94
/* distribute bundle-addr. & slot-number across PT_IIP & PT_IPSR. */
96
# warning No support for ttrace() yet.
99
psr = ptrace (PTRACE_PEEKUSER, pid, PT_CR_IPSR, 0);
106
psr = (psr & ~0x3UL << 41) | (*val & 0x3);
108
# warning No support for ttrace() yet.
111
ptrace (PTRACE_POKEUSER, pid, PT_CR_IIP, ip);
112
ptrace (PTRACE_POKEUSER, pid, PT_CR_IPSR, psr);
120
# warning No support for ttrace() yet.
123
ip = ptrace (PTRACE_PEEKUSER, pid, PT_CR_IIP, 0);
127
*val = ip + ((psr >> 41) & 0x3);
132
case UNW_IA64_AR_BSPSTORE:
133
reg = UNW_IA64_AR_BSP;
136
case UNW_IA64_AR_BSP:
139
unsigned long sof, cfm, bsp;
142
# warning No support for ttrace() yet.
144
/* Account for the fact that ptrace() expects bsp to point
145
_after_ the current register frame. */
147
cfm = ptrace (PTRACE_PEEKUSER, pid, PT_CFM, 0);
155
bsp = ia64_rse_skip_regs (*val, sof);
157
# warning No support for ttrace() yet.
160
ptrace (PTRACE_POKEUSER, pid, PT_AR_BSP, bsp);
168
# warning No support for ttrace() yet.
171
bsp = ptrace (PTRACE_PEEKUSER, pid, PT_AR_BSP, 0);
175
*val = ia64_rse_skip_regs (bsp, -sof);
181
/* If we change CFM, we need to adjust ptrace's notion of bsp
182
accordingly, so that the real bsp remains unchanged. */
185
unsigned long new_sof, old_sof, cfm, bsp;
188
# warning No support for ttrace() yet.
191
bsp = ptrace (PTRACE_PEEKUSER, pid, PT_AR_BSP, 0);
192
cfm = ptrace (PTRACE_PEEKUSER, pid, PT_CFM, 0);
196
old_sof = (cfm & 0x7f);
197
new_sof = (*val & 0x7f);
198
if (old_sof != new_sof)
200
bsp = ia64_rse_skip_regs (bsp, -old_sof + new_sof);
202
# warning No support for ttrace() yet.
205
ptrace (PTRACE_POKEUSER, pid, PT_AR_BSP, 0);
211
# warning No support for ttrace() yet.
214
ptrace (PTRACE_POKEUSER, pid, PT_CFM, *val);
224
if ((unsigned) reg >= sizeof (_UPT_reg_offset) / sizeof (_UPT_reg_offset[0]))
228
# warning No support for ttrace() yet.
232
ptrace (PTRACE_POKEUSER, pid, _UPT_reg_offset[reg], *val);
234
*val = ptrace (PTRACE_PEEKUSER, pid, _UPT_reg_offset[reg], 0);
239
#ifdef UNW_TARGET_IA64
244
Debug (16, "%s -> %lx\n", unw_regname (reg), (long) *val);
249
Debug (1, "bad register number %u\n", reg);