Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openanolis
cloud-kernel
提交
9775369e
cloud-kernel
项目概览
openanolis
/
cloud-kernel
大约 1 年 前同步成功
通知
153
Star
36
Fork
7
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
10
列表
看板
标记
里程碑
合并请求
2
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
cloud-kernel
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
10
Issue
10
列表
看板
标记
里程碑
合并请求
2
合并请求
2
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
9775369e
编写于
2月 07, 2008
作者:
D
David S. Miller
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
[SPARC]: Move over to arch_ptrace().
Signed-off-by:
N
David S. Miller
<
davem@davemloft.net
>
上级
190aa9f6
变更
6
隐藏空白更改
内联
并排
Showing
6 changed file
with
172 addition
and
721 deletion
+172
-721
arch/sparc/kernel/entry.S
arch/sparc/kernel/entry.S
+0
-17
arch/sparc/kernel/ptrace.c
arch/sparc/kernel/ptrace.c
+63
-399
arch/sparc64/kernel/entry.S
arch/sparc64/kernel/entry.S
+0
-4
arch/sparc64/kernel/ptrace.c
arch/sparc64/kernel/ptrace.c
+109
-280
include/asm-sparc/ptrace.h
include/asm-sparc/ptrace.h
+0
-5
include/asm-sparc64/ptrace.h
include/asm-sparc64/ptrace.h
+0
-16
未找到文件。
arch/sparc/kernel/entry.S
浏览文件 @
9775369e
...
...
@@ -1224,23 +1224,6 @@ sys_nis_syscall:
call
c_sys_nis_syscall
mov
%
l5
,
%
o7
.
align
4
.
globl
sys_ptrace
sys_ptrace
:
call
do_ptrace
add
%
sp
,
STACKFRAME_SZ
,
%
o0
ld
[%
curptr
+
TI_FLAGS
],
%
l5
andcc
%
l5
,
_TIF_SYSCALL_TRACE
,
%
g0
be
1
f
nop
call
syscall_trace
nop
1
:
RESTORE_ALL
.
align
4
.
globl
sys_execve
sys_execve
:
...
...
arch/sparc/kernel/ptrace.c
浏览文件 @
9775369e
...
...
@@ -26,215 +26,6 @@
#include <asm/system.h>
#include <asm/uaccess.h>
#define MAGIC_CONSTANT 0x80000000
/* Returning from ptrace is a bit tricky because the syscall return
* low level code assumes any value returned which is negative and
* is a valid errno will mean setting the condition codes to indicate
* an error return. This doesn't work, so we have this hook.
*/
static
inline
void
pt_error_return
(
struct
pt_regs
*
regs
,
unsigned
long
error
)
{
regs
->
u_regs
[
UREG_I0
]
=
error
;
regs
->
psr
|=
PSR_C
;
regs
->
pc
=
regs
->
npc
;
regs
->
npc
+=
4
;
}
static
inline
void
pt_succ_return
(
struct
pt_regs
*
regs
,
unsigned
long
value
)
{
regs
->
u_regs
[
UREG_I0
]
=
value
;
regs
->
psr
&=
~
PSR_C
;
regs
->
pc
=
regs
->
npc
;
regs
->
npc
+=
4
;
}
static
void
pt_succ_return_linux
(
struct
pt_regs
*
regs
,
unsigned
long
value
,
long
__user
*
addr
)
{
if
(
put_user
(
value
,
addr
))
{
pt_error_return
(
regs
,
EFAULT
);
return
;
}
regs
->
u_regs
[
UREG_I0
]
=
0
;
regs
->
psr
&=
~
PSR_C
;
regs
->
pc
=
regs
->
npc
;
regs
->
npc
+=
4
;
}
static
void
pt_os_succ_return
(
struct
pt_regs
*
regs
,
unsigned
long
val
,
long
__user
*
addr
)
{
if
(
current
->
personality
==
PER_SUNOS
)
pt_succ_return
(
regs
,
val
);
else
pt_succ_return_linux
(
regs
,
val
,
addr
);
}
/* Fuck me gently with a chainsaw... */
static
inline
void
read_sunos_user
(
struct
pt_regs
*
regs
,
unsigned
long
offset
,
struct
task_struct
*
tsk
,
long
__user
*
addr
)
{
struct
pt_regs
*
cregs
=
tsk
->
thread
.
kregs
;
struct
thread_info
*
t
=
task_thread_info
(
tsk
);
int
v
;
if
(
offset
>=
1024
)
offset
-=
1024
;
/* whee... */
if
(
offset
&
((
sizeof
(
unsigned
long
)
-
1
)))
{
pt_error_return
(
regs
,
EIO
);
return
;
}
if
(
offset
>=
16
&&
offset
<
784
)
{
offset
-=
16
;
offset
>>=
2
;
pt_os_succ_return
(
regs
,
*
(((
unsigned
long
*
)(
&
t
->
reg_window
[
0
]))
+
offset
),
addr
);
return
;
}
if
(
offset
>=
784
&&
offset
<
832
)
{
offset
-=
784
;
offset
>>=
2
;
pt_os_succ_return
(
regs
,
*
(((
unsigned
long
*
)(
&
t
->
rwbuf_stkptrs
[
0
]))
+
offset
),
addr
);
return
;
}
switch
(
offset
)
{
case
0
:
v
=
t
->
ksp
;
break
;
case
4
:
v
=
t
->
kpc
;
break
;
case
8
:
v
=
t
->
kpsr
;
break
;
case
12
:
v
=
t
->
uwinmask
;
break
;
case
832
:
v
=
t
->
w_saved
;
break
;
case
896
:
v
=
cregs
->
u_regs
[
UREG_I0
];
break
;
case
900
:
v
=
cregs
->
u_regs
[
UREG_I1
];
break
;
case
904
:
v
=
cregs
->
u_regs
[
UREG_I2
];
break
;
case
908
:
v
=
cregs
->
u_regs
[
UREG_I3
];
break
;
case
912
:
v
=
cregs
->
u_regs
[
UREG_I4
];
break
;
case
916
:
v
=
cregs
->
u_regs
[
UREG_I5
];
break
;
case
920
:
v
=
cregs
->
u_regs
[
UREG_I6
];
break
;
case
924
:
if
(
tsk
->
thread
.
flags
&
MAGIC_CONSTANT
)
v
=
cregs
->
u_regs
[
UREG_G1
];
else
v
=
0
;
break
;
case
940
:
v
=
cregs
->
u_regs
[
UREG_I0
];
break
;
case
944
:
v
=
cregs
->
u_regs
[
UREG_I1
];
break
;
case
948
:
/* Isn't binary compatibility _fun_??? */
if
(
cregs
->
psr
&
PSR_C
)
v
=
cregs
->
u_regs
[
UREG_I0
]
<<
24
;
else
v
=
0
;
break
;
/* Rest of them are completely unsupported. */
default:
printk
(
"%s [%d]: Wants to read user offset %ld
\n
"
,
current
->
comm
,
task_pid_nr
(
current
),
offset
);
pt_error_return
(
regs
,
EIO
);
return
;
}
if
(
current
->
personality
==
PER_SUNOS
)
pt_succ_return
(
regs
,
v
);
else
pt_succ_return_linux
(
regs
,
v
,
addr
);
return
;
}
static
inline
void
write_sunos_user
(
struct
pt_regs
*
regs
,
unsigned
long
offset
,
struct
task_struct
*
tsk
)
{
struct
pt_regs
*
cregs
=
tsk
->
thread
.
kregs
;
struct
thread_info
*
t
=
task_thread_info
(
tsk
);
unsigned
long
value
=
regs
->
u_regs
[
UREG_I3
];
if
(
offset
>=
1024
)
offset
-=
1024
;
/* whee... */
if
(
offset
&
((
sizeof
(
unsigned
long
)
-
1
)))
goto
failure
;
if
(
offset
>=
16
&&
offset
<
784
)
{
offset
-=
16
;
offset
>>=
2
;
*
(((
unsigned
long
*
)(
&
t
->
reg_window
[
0
]))
+
offset
)
=
value
;
goto
success
;
}
if
(
offset
>=
784
&&
offset
<
832
)
{
offset
-=
784
;
offset
>>=
2
;
*
(((
unsigned
long
*
)(
&
t
->
rwbuf_stkptrs
[
0
]))
+
offset
)
=
value
;
goto
success
;
}
switch
(
offset
)
{
case
896
:
cregs
->
u_regs
[
UREG_I0
]
=
value
;
break
;
case
900
:
cregs
->
u_regs
[
UREG_I1
]
=
value
;
break
;
case
904
:
cregs
->
u_regs
[
UREG_I2
]
=
value
;
break
;
case
908
:
cregs
->
u_regs
[
UREG_I3
]
=
value
;
break
;
case
912
:
cregs
->
u_regs
[
UREG_I4
]
=
value
;
break
;
case
916
:
cregs
->
u_regs
[
UREG_I5
]
=
value
;
break
;
case
920
:
cregs
->
u_regs
[
UREG_I6
]
=
value
;
break
;
case
924
:
cregs
->
u_regs
[
UREG_I7
]
=
value
;
break
;
case
940
:
cregs
->
u_regs
[
UREG_I0
]
=
value
;
break
;
case
944
:
cregs
->
u_regs
[
UREG_I1
]
=
value
;
break
;
/* Rest of them are completely unsupported or "no-touch". */
default:
printk
(
"%s [%d]: Wants to write user offset %ld
\n
"
,
current
->
comm
,
task_pid_nr
(
current
),
offset
);
goto
failure
;
}
success:
pt_succ_return
(
regs
,
0
);
return
;
failure:
pt_error_return
(
regs
,
EIO
);
return
;
}
/* #define ALLOW_INIT_TRACING */
/*
...
...
@@ -528,113 +319,42 @@ const struct user_regset_view *task_user_regset_view(struct task_struct *task)
return
&
user_sparc32_view
;
}
asmlinkage
void
do_ptrace
(
struct
pt_regs
*
regs
)
long
arch_ptrace
(
struct
task_struct
*
child
,
long
request
,
long
addr
,
long
data
)
{
unsigned
long
request
=
regs
->
u_regs
[
UREG_I0
];
unsigned
long
pid
=
regs
->
u_regs
[
UREG_I1
];
unsigned
long
addr
=
regs
->
u_regs
[
UREG_I2
];
unsigned
long
data
=
regs
->
u_regs
[
UREG_I3
];
unsigned
long
addr2
=
regs
->
u_regs
[
UREG_I4
];
struct
task_struct
*
child
;
int
ret
;
lock_kernel
();
if
(
request
==
PTRACE_TRACEME
)
{
ret
=
ptrace_traceme
();
if
(
ret
<
0
)
pt_error_return
(
regs
,
-
ret
);
else
pt_succ_return
(
regs
,
0
);
goto
out
;
}
child
=
ptrace_get_task_struct
(
pid
);
if
(
IS_ERR
(
child
))
{
ret
=
PTR_ERR
(
child
);
pt_error_return
(
regs
,
-
ret
);
goto
out
;
}
if
(
request
==
PTRACE_ATTACH
)
{
if
(
ptrace_attach
(
child
))
{
pt_error_return
(
regs
,
EPERM
);
goto
out_tsk
;
}
pt_succ_return
(
regs
,
0
);
goto
out_tsk
;
}
ret
=
ptrace_check_attach
(
child
,
request
==
PTRACE_KILL
);
if
(
ret
<
0
)
{
pt_error_return
(
regs
,
-
ret
);
goto
out_tsk
;
}
unsigned
long
addr2
=
current
->
thread
.
kregs
->
u_regs
[
UREG_I4
];
int
i
,
ret
;
switch
(
request
)
{
case
PTRACE_PEEKTEXT
:
/* read word at location addr. */
case
PTRACE_PEEKDATA
:
{
unsigned
long
tmp
;
if
(
access_process_vm
(
child
,
addr
,
&
tmp
,
sizeof
(
tmp
),
0
)
==
sizeof
(
tmp
))
pt_os_succ_return
(
regs
,
tmp
,
(
long
__user
*
)
data
);
else
pt_error_return
(
regs
,
EIO
);
goto
out_tsk
;
}
case
PTRACE_PEEKUSR
:
read_sunos_user
(
regs
,
addr
,
child
,
(
long
__user
*
)
data
);
goto
out_tsk
;
case
PTRACE_POKEUSR
:
write_sunos_user
(
regs
,
addr
,
child
);
goto
out_tsk
;
case
PTRACE_POKETEXT
:
/* write the word at location addr. */
case
PTRACE_POKEDATA
:
{
if
(
access_process_vm
(
child
,
addr
,
&
data
,
sizeof
(
data
),
1
)
==
sizeof
(
data
))
pt_succ_return
(
regs
,
0
);
else
pt_error_return
(
regs
,
EIO
);
goto
out_tsk
;
}
case
PTRACE_GETREGS
:
{
struct
pt_regs
__user
*
pregs
=
(
struct
pt_regs
__user
*
)
addr
;
struct
pt_regs
*
cregs
=
child
->
thread
.
kregs
;
int
rval
;
if
(
!
access_ok
(
VERIFY_WRITE
,
pregs
,
sizeof
(
struct
pt_regs
)))
{
rval
=
-
EFAULT
;
pt_error_return
(
regs
,
-
rval
);
goto
out_tsk
;
}
ret
=
-
EFAULT
;
if
(
!
access_ok
(
VERIFY_WRITE
,
pregs
,
sizeof
(
struct
pt_regs
)))
break
;
__put_user
(
cregs
->
psr
,
(
&
pregs
->
psr
));
__put_user
(
cregs
->
pc
,
(
&
pregs
->
pc
));
__put_user
(
cregs
->
npc
,
(
&
pregs
->
npc
));
__put_user
(
cregs
->
y
,
(
&
pregs
->
y
));
for
(
rval
=
1
;
rval
<
16
;
rval
++
)
__put_user
(
cregs
->
u_regs
[
rval
],
(
&
pregs
->
u_regs
[
rval
-
1
])
);
pt_succ_return
(
regs
,
0
)
;
goto
out_ts
k
;
for
(
i
=
1
;
i
<
16
;
i
++
)
__put_user
(
cregs
->
u_regs
[
i
],
&
pregs
->
u_regs
[
i
-
1
]
);
ret
=
0
;
brea
k
;
}
case
PTRACE_SETREGS
:
{
struct
pt_regs
__user
*
pregs
=
(
struct
pt_regs
__user
*
)
addr
;
struct
pt_regs
*
cregs
=
child
->
thread
.
kregs
;
unsigned
long
psr
,
pc
,
npc
,
y
;
int
i
;
/* Must be careful, tracing process can only set certain
* bits in the psr.
*/
if
(
!
access_ok
(
VERIFY_READ
,
pregs
,
sizeof
(
struct
pt_regs
)))
{
pt_error_return
(
regs
,
EFAULT
);
goto
out_ts
k
;
}
ret
=
-
EFAULT
;
if
(
!
access_ok
(
VERIFY_READ
,
pregs
,
sizeof
(
struct
pt_regs
)))
brea
k
;
__get_user
(
psr
,
(
&
pregs
->
psr
));
__get_user
(
pc
,
(
&
pregs
->
pc
));
__get_user
(
npc
,
(
&
pregs
->
npc
));
...
...
@@ -647,10 +367,10 @@ asmlinkage void do_ptrace(struct pt_regs *regs)
cregs
->
npc
=
npc
;
}
cregs
->
y
=
y
;
for
(
i
=
1
;
i
<
16
;
i
++
)
__get_user
(
cregs
->
u_regs
[
i
],
(
&
pregs
->
u_regs
[
i
-
1
])
);
pt_succ_return
(
regs
,
0
)
;
goto
out_ts
k
;
for
(
i
=
1
;
i
<
16
;
i
++
)
__get_user
(
cregs
->
u_regs
[
i
],
&
pregs
->
u_regs
[
i
-
1
]
);
ret
=
0
;
brea
k
;
}
case
PTRACE_GETFPREGS
:
{
...
...
@@ -666,26 +386,25 @@ asmlinkage void do_ptrace(struct pt_regs *regs)
}
fpq
[
16
];
};
struct
fps
__user
*
fps
=
(
struct
fps
__user
*
)
addr
;
int
i
;
if
(
!
access_ok
(
VERIFY_WRITE
,
fps
,
sizeof
(
struct
fps
)))
{
i
=
-
EFAULT
;
pt_error_return
(
regs
,
-
i
);
goto
out_tsk
;
}
for
(
i
=
0
;
i
<
32
;
i
++
)
__put_user
(
child
->
thread
.
float_regs
[
i
],
(
&
fps
->
regs
[
i
]));
ret
=
-
EFAULT
;
if
(
!
access_ok
(
VERIFY_WRITE
,
fps
,
sizeof
(
struct
fps
)))
break
;
for
(
i
=
0
;
i
<
32
;
i
++
)
__put_user
(
child
->
thread
.
float_regs
[
i
],
&
fps
->
regs
[
i
]);
__put_user
(
child
->
thread
.
fsr
,
(
&
fps
->
fsr
));
__put_user
(
child
->
thread
.
fpqdepth
,
(
&
fps
->
fpqd
));
__put_user
(
0
,
(
&
fps
->
flags
));
__put_user
(
0
,
(
&
fps
->
extra
));
for
(
i
=
0
;
i
<
16
;
i
++
)
{
for
(
i
=
0
;
i
<
16
;
i
++
)
{
__put_user
(
child
->
thread
.
fpqueue
[
i
].
insn_addr
,
(
&
fps
->
fpq
[
i
].
insnaddr
));
__put_user
(
child
->
thread
.
fpqueue
[
i
].
insn
,
(
&
fps
->
fpq
[
i
].
insn
));
__put_user
(
child
->
thread
.
fpqueue
[
i
].
insn
,
&
fps
->
fpq
[
i
].
insn
);
}
pt_succ_return
(
regs
,
0
)
;
goto
out_ts
k
;
ret
=
0
;
brea
k
;
}
case
PTRACE_SETFPREGS
:
{
...
...
@@ -701,107 +420,53 @@ asmlinkage void do_ptrace(struct pt_regs *regs)
}
fpq
[
16
];
};
struct
fps
__user
*
fps
=
(
struct
fps
__user
*
)
addr
;
int
i
;
if
(
!
access_ok
(
VERIFY_READ
,
fps
,
sizeof
(
struct
fps
)))
{
i
=
-
EFAULT
;
pt_error_return
(
regs
,
-
i
)
;
goto
out_tsk
;
}
copy_from_user
(
&
child
->
thread
.
float_regs
[
0
],
&
fps
->
regs
[
0
],
(
32
*
sizeof
(
unsigned
long
)));
ret
=
-
EFAULT
;
if
(
!
access_ok
(
VERIFY_READ
,
fps
,
sizeof
(
struct
fps
)))
break
;
copy_from_user
(
&
child
->
thread
.
float_regs
[
0
],
&
fps
->
regs
[
0
],
(
32
*
sizeof
(
unsigned
long
)));
__get_user
(
child
->
thread
.
fsr
,
(
&
fps
->
fsr
));
__get_user
(
child
->
thread
.
fpqdepth
,
(
&
fps
->
fpqd
));
for
(
i
=
0
;
i
<
16
;
i
++
)
{
for
(
i
=
0
;
i
<
16
;
i
++
)
{
__get_user
(
child
->
thread
.
fpqueue
[
i
].
insn_addr
,
(
&
fps
->
fpq
[
i
].
insnaddr
));
__get_user
(
child
->
thread
.
fpqueue
[
i
].
insn
,
(
&
fps
->
fpq
[
i
].
insn
));
__get_user
(
child
->
thread
.
fpqueue
[
i
].
insn
,
&
fps
->
fpq
[
i
].
insn
);
}
pt_succ_return
(
regs
,
0
)
;
goto
out_ts
k
;
ret
=
0
;
brea
k
;
}
case
PTRACE_READTEXT
:
case
PTRACE_READDATA
:
{
int
res
=
ptrace_readdata
(
child
,
addr
,
(
void
__user
*
)
addr2
,
data
);
if
(
res
==
data
)
{
pt_succ_return
(
regs
,
0
);
goto
out_tsk
;
}
/* Partial read is an IO failure */
if
(
res
>=
0
)
res
=
-
EIO
;
pt_error_return
(
regs
,
-
res
);
goto
out_tsk
;
}
case
PTRACE_READDATA
:
ret
=
ptrace_readdata
(
child
,
addr
,
(
void
__user
*
)
addr2
,
data
);
if
(
ret
==
data
)
ret
=
0
;
else
if
(
ret
>=
0
)
ret
=
-
EIO
;
break
;
case
PTRACE_WRITETEXT
:
case
PTRACE_WRITEDATA
:
{
int
res
=
ptrace_writedata
(
child
,
(
void
__user
*
)
addr2
,
addr
,
data
);
if
(
res
==
data
)
{
pt_succ_return
(
regs
,
0
);
goto
out_tsk
;
}
/* Partial write is an IO failure */
if
(
res
>=
0
)
res
=
-
EIO
;
pt_error_return
(
regs
,
-
res
);
goto
out_tsk
;
}
case
PTRACE_SYSCALL
:
/* continue and stop at (return from) syscall */
addr
=
1
;
case
PTRACE_CONT
:
{
/* restart after signal. */
if
(
!
valid_signal
(
data
))
{
pt_error_return
(
regs
,
EIO
);
goto
out_tsk
;
}
if
(
request
==
PTRACE_SYSCALL
)
set_tsk_thread_flag
(
child
,
TIF_SYSCALL_TRACE
);
else
clear_tsk_thread_flag
(
child
,
TIF_SYSCALL_TRACE
);
child
->
exit_code
=
data
;
wake_up_process
(
child
);
pt_succ_return
(
regs
,
0
);
goto
out_tsk
;
}
case
PTRACE_WRITEDATA
:
ret
=
ptrace_writedata
(
child
,
(
void
__user
*
)
addr2
,
addr
,
data
);
if
(
ret
==
data
)
ret
=
0
;
else
if
(
ret
>=
0
)
ret
=
-
EIO
;
break
;
/*
* make the child exit. Best I can do is send it a sigkill.
* perhaps it should be put in the status that it wants to
* exit.
*/
case
PTRACE_KILL
:
{
if
(
child
->
exit_state
==
EXIT_ZOMBIE
)
{
/* already dead */
pt_succ_return
(
regs
,
0
);
goto
out_tsk
;
}
wake_up_process
(
child
);
child
->
exit_code
=
SIGKILL
;
pt_succ_return
(
regs
,
0
);
goto
out_tsk
;
default:
ret
=
ptrace_request
(
child
,
request
,
addr
,
data
);
break
;
}
default:
{
int
err
=
ptrace_request
(
child
,
request
,
addr
,
data
);
if
(
err
)
pt_error_return
(
regs
,
-
err
);
else
pt_succ_return
(
regs
,
0
);
goto
out_tsk
;
}
}
out_tsk:
if
(
child
)
put_task_struct
(
child
);
out:
unlock_kernel
();
return
ret
;
}
asmlinkage
void
syscall_trace
(
void
)
...
...
@@ -810,7 +475,6 @@ asmlinkage void syscall_trace(void)
return
;
if
(
!
(
current
->
ptrace
&
PT_PTRACED
))
return
;
current
->
thread
.
flags
^=
MAGIC_CONSTANT
;
ptrace_notify
(
SIGTRAP
|
((
current
->
ptrace
&
PT_TRACESYSGOOD
)
?
0x80
:
0
));
/*
...
...
arch/sparc64/kernel/entry.S
浏览文件 @
9775369e
...
...
@@ -1477,10 +1477,6 @@ sys32_rt_sigreturn:
add
%
o7
,
1
f
-
.
-
4
,
%
o7
nop
#endif
sys_ptrace
:
add
%
sp
,
PTREGS_OFF
,
%
o0
call
do_ptrace
add
%
o7
,
1
f
-
.
-
4
,
%
o7
nop
.
align
32
1
:
ldx
[%
curptr
+
TI_FLAGS
],
%
l5
andcc
%
l5
,
(
_TIF_SYSCALL_TRACE|_TIF_SECCOMP|_TIF_SYSCALL_AUDIT
),
%
g0
...
...
arch/sparc64/kernel/ptrace.c
浏览文件 @
9775369e
...
...
@@ -36,56 +36,6 @@
#include <asm/page.h>
#include <asm/cpudata.h>
/* Returning from ptrace is a bit tricky because the syscall return
* low level code assumes any value returned which is negative and
* is a valid errno will mean setting the condition codes to indicate
* an error return. This doesn't work, so we have this hook.
*/
static
inline
void
pt_error_return
(
struct
pt_regs
*
regs
,
unsigned
long
error
)
{
regs
->
u_regs
[
UREG_I0
]
=
error
;
regs
->
tstate
|=
(
TSTATE_ICARRY
|
TSTATE_XCARRY
);
regs
->
tpc
=
regs
->
tnpc
;
regs
->
tnpc
+=
4
;
}
static
inline
void
pt_succ_return
(
struct
pt_regs
*
regs
,
unsigned
long
value
)
{
regs
->
u_regs
[
UREG_I0
]
=
value
;
regs
->
tstate
&=
~
(
TSTATE_ICARRY
|
TSTATE_XCARRY
);
regs
->
tpc
=
regs
->
tnpc
;
regs
->
tnpc
+=
4
;
}
static
inline
void
pt_succ_return_linux
(
struct
pt_regs
*
regs
,
unsigned
long
value
,
void
__user
*
addr
)
{
if
(
test_thread_flag
(
TIF_32BIT
))
{
if
(
put_user
(
value
,
(
unsigned
int
__user
*
)
addr
))
{
pt_error_return
(
regs
,
EFAULT
);
return
;
}
}
else
{
if
(
put_user
(
value
,
(
long
__user
*
)
addr
))
{
pt_error_return
(
regs
,
EFAULT
);
return
;
}
}
regs
->
u_regs
[
UREG_I0
]
=
0
;
regs
->
tstate
&=
~
(
TSTATE_ICARRY
|
TSTATE_XCARRY
);
regs
->
tpc
=
regs
->
tnpc
;
regs
->
tnpc
+=
4
;
}
static
void
pt_os_succ_return
(
struct
pt_regs
*
regs
,
unsigned
long
val
,
void
__user
*
addr
)
{
if
(
current
->
personality
==
PER_SUNOS
)
pt_succ_return
(
regs
,
val
);
else
pt_succ_return_linux
(
regs
,
val
,
addr
);
}
/* #define ALLOW_INIT_TRACING */
/*
...
...
@@ -734,171 +684,113 @@ const struct user_regset_view *task_user_regset_view(struct task_struct *task)
return
&
user_sparc64_view
;
}
asmlinkage
void
do_ptrace
(
struct
pt_regs
*
regs
)
long
arch_ptrace
(
struct
task_struct
*
child
,
long
request
,
long
addr
,
long
data
)
{
int
request
=
regs
->
u_regs
[
UREG_I0
];
pid_t
pid
=
regs
->
u_regs
[
UREG_I1
];
unsigned
long
addr
=
regs
->
u_regs
[
UREG_I2
];
unsigned
long
data
=
regs
->
u_regs
[
UREG_I3
];
unsigned
long
addr2
=
regs
->
u_regs
[
UREG_I4
];
struct
task_struct
*
child
;
int
ret
;
long
addr2
=
task_pt_regs
(
current
)
->
u_regs
[
UREG_I4
];
int
i
,
ret
;
if
(
test_thread_flag
(
TIF_32BIT
))
{
addr
&=
0xffffffffUL
;
data
&=
0xffffffffUL
;
#if 1
printk
(
KERN_INFO
"arch_ptrace: request[%ld] addr[%lx] data[%lx] addr2[%lx]
\n
"
,
request
,
addr
,
data
,
addr2
);
#endif
if
(
test_thread_flag
(
TIF_32BIT
))
addr2
&=
0xffffffffUL
;
}
lock_kernel
();
if
(
request
==
PTRACE_TRACEME
)
{
ret
=
ptrace_traceme
();
if
(
ret
<
0
)
pt_error_return
(
regs
,
-
ret
);
else
pt_succ_return
(
regs
,
0
);
goto
out
;
}
child
=
ptrace_get_task_struct
(
pid
);
if
(
IS_ERR
(
child
))
{
ret
=
PTR_ERR
(
child
);
pt_error_return
(
regs
,
-
ret
);
goto
out
;
}
if
(
request
==
PTRACE_ATTACH
)
{
if
(
ptrace_attach
(
child
))
{
pt_error_return
(
regs
,
EPERM
);
goto
out_tsk
;
}
pt_succ_return
(
regs
,
0
);
goto
out_tsk
;
}
ret
=
ptrace_check_attach
(
child
,
request
==
PTRACE_KILL
);
if
(
ret
<
0
)
{
pt_error_return
(
regs
,
-
ret
);
goto
out_tsk
;
}
if
(
!
(
test_thread_flag
(
TIF_32BIT
))
&&
((
request
==
PTRACE_READDATA64
)
||
(
request
==
PTRACE_WRITEDATA64
)
||
(
request
==
PTRACE_READTEXT64
)
||
(
request
==
PTRACE_WRITETEXT64
)
||
(
request
==
PTRACE_PEEKTEXT64
)
||
(
request
==
PTRACE_POKETEXT64
)
||
(
request
==
PTRACE_PEEKDATA64
)
||
(
request
==
PTRACE_POKEDATA64
)))
{
addr
=
regs
->
u_regs
[
UREG_G2
];
addr2
=
regs
->
u_regs
[
UREG_G3
];
request
-=
30
;
/* wheee... */
}
switch
(
request
)
{
case
PTRACE_PEEKUSR
:
if
(
addr
!=
0
)
pt_error_return
(
regs
,
EIO
);
else
pt_succ_return
(
regs
,
0
);
goto
out_tsk
;
ret
=
(
addr
!=
0
)
?
-
EIO
:
0
;
break
;
case
PTRACE_PEEKTEXT
:
/* read word at location addr. */
case
PTRACE_PEEKDATA
:
{
unsigned
long
tmp64
;
unsigned
int
tmp32
;
int
res
,
copied
;
int
copied
;
re
s
=
-
EIO
;
re
t
=
-
EIO
;
if
(
test_thread_flag
(
TIF_32BIT
))
{
copied
=
access_process_vm
(
child
,
addr
,
&
tmp32
,
sizeof
(
tmp32
),
0
);
tmp64
=
(
unsigned
long
)
tmp32
;
if
(
copied
==
sizeof
(
tmp32
))
res
=
0
;
ret
=
put_user
(
tmp32
,
(
unsigned
int
__user
*
)
data
);
}
else
{
copied
=
access_process_vm
(
child
,
addr
,
&
tmp64
,
sizeof
(
tmp64
),
0
);
if
(
copied
==
sizeof
(
tmp64
))
res
=
0
;
ret
=
put_user
(
tmp64
,
(
unsigned
long
__user
*
)
data
);
}
if
(
res
<
0
)
pt_error_return
(
regs
,
-
res
);
else
pt_os_succ_return
(
regs
,
tmp64
,
(
void
__user
*
)
data
);
goto
out_tsk
;
break
;
}
case
PTRACE_POKETEXT
:
/* write the word at location addr. */
case
PTRACE_POKEDATA
:
{
unsigned
long
tmp64
;
unsigned
int
tmp32
;
int
copied
,
res
=
-
EIO
;
int
copied
;
ret
=
-
EIO
;
if
(
test_thread_flag
(
TIF_32BIT
))
{
tmp32
=
data
;
copied
=
access_process_vm
(
child
,
addr
,
&
tmp32
,
sizeof
(
tmp32
),
1
);
if
(
copied
==
sizeof
(
tmp32
))
re
s
=
0
;
re
t
=
0
;
}
else
{
tmp64
=
data
;
copied
=
access_process_vm
(
child
,
addr
,
&
tmp64
,
sizeof
(
tmp64
),
1
);
if
(
copied
==
sizeof
(
tmp64
))
re
s
=
0
;
re
t
=
0
;
}
if
(
res
<
0
)
pt_error_return
(
regs
,
-
res
);
else
pt_succ_return
(
regs
,
res
);
goto
out_tsk
;
break
;
}
case
PTRACE_GETREGS
:
{
struct
pt_regs32
__user
*
pregs
=
(
struct
pt_regs32
__user
*
)
addr
;
struct
pt_regs
*
cregs
=
task_pt_regs
(
child
);
int
rval
;
ret
=
-
EFAULT
;
if
(
__put_user
(
tstate_to_psr
(
cregs
->
tstate
),
(
&
pregs
->
psr
))
||
__put_user
(
cregs
->
tpc
,
(
&
pregs
->
pc
))
||
__put_user
(
cregs
->
tnpc
,
(
&
pregs
->
npc
))
||
__put_user
(
cregs
->
y
,
(
&
pregs
->
y
)))
{
pt_error_return
(
regs
,
EFAULT
);
goto
out_tsk
;
__put_user
(
cregs
->
y
,
(
&
pregs
->
y
)))
break
;
for
(
i
=
1
;
i
<
16
;
i
++
)
{
if
(
__put_user
(
cregs
->
u_regs
[
i
],
(
&
pregs
->
u_regs
[
i
-
1
])))
break
;
}
for
(
rval
=
1
;
rval
<
16
;
rval
++
)
if
(
__put_user
(
cregs
->
u_regs
[
rval
],
(
&
pregs
->
u_regs
[
rval
-
1
])))
{
pt_error_return
(
regs
,
EFAULT
);
goto
out_tsk
;
}
pt_succ_return
(
regs
,
0
);
goto
out_tsk
;
if
(
i
==
16
)
ret
=
0
;
break
;
}
case
PTRACE_GETREGS64
:
{
struct
pt_regs
__user
*
pregs
=
(
struct
pt_regs
__user
*
)
addr
;
struct
pt_regs
*
cregs
=
task_pt_regs
(
child
);
unsigned
long
tpc
=
cregs
->
tpc
;
int
rval
;
if
((
task_thread_info
(
child
)
->
flags
&
_TIF_32BIT
)
!=
0
)
tpc
&=
0xffffffff
;
ret
=
-
EFAULT
;
if
(
__put_user
(
cregs
->
tstate
,
(
&
pregs
->
tstate
))
||
__put_user
(
tpc
,
(
&
pregs
->
tpc
))
||
__put_user
(
cregs
->
tnpc
,
(
&
pregs
->
tnpc
))
||
__put_user
(
cregs
->
y
,
(
&
pregs
->
y
)))
{
pt_error_return
(
regs
,
EFAULT
);
goto
out_tsk
;
__put_user
(
cregs
->
y
,
(
&
pregs
->
y
)))
break
;
for
(
i
=
1
;
i
<
16
;
i
++
)
{
if
(
__put_user
(
cregs
->
u_regs
[
i
],
(
&
pregs
->
u_regs
[
i
-
1
])))
break
;
}
for
(
rval
=
1
;
rval
<
16
;
rval
++
)
if
(
__put_user
(
cregs
->
u_regs
[
rval
],
(
&
pregs
->
u_regs
[
rval
-
1
])))
{
pt_error_return
(
regs
,
EFAULT
);
goto
out_tsk
;
}
pt_succ_return
(
regs
,
0
);
goto
out_tsk
;
if
(
i
==
16
)
ret
=
0
;
break
;
}
case
PTRACE_SETREGS
:
{
...
...
@@ -906,18 +798,16 @@ asmlinkage void do_ptrace(struct pt_regs *regs)
(
struct
pt_regs32
__user
*
)
addr
;
struct
pt_regs
*
cregs
=
task_pt_regs
(
child
);
unsigned
int
psr
,
pc
,
npc
,
y
;
int
i
;
/* Must be careful, tracing process can only set certain
* bits in the psr.
*/
ret
=
-
EFAULT
;
if
(
__get_user
(
psr
,
(
&
pregs
->
psr
))
||
__get_user
(
pc
,
(
&
pregs
->
pc
))
||
__get_user
(
npc
,
(
&
pregs
->
npc
))
||
__get_user
(
y
,
(
&
pregs
->
y
)))
{
pt_error_return
(
regs
,
EFAULT
);
goto
out_tsk
;
}
__get_user
(
y
,
(
&
pregs
->
y
)))
break
;
cregs
->
tstate
&=
~
(
TSTATE_ICC
);
cregs
->
tstate
|=
psr_to_tstate_icc
(
psr
);
if
(
!
((
pc
|
npc
)
&
3
))
{
...
...
@@ -926,31 +816,28 @@ asmlinkage void do_ptrace(struct pt_regs *regs)
}
cregs
->
y
=
y
;
for
(
i
=
1
;
i
<
16
;
i
++
)
{
if
(
__get_user
(
cregs
->
u_regs
[
i
],
(
&
pregs
->
u_regs
[
i
-
1
])))
{
pt_error_return
(
regs
,
EFAULT
);
goto
out_tsk
;
}
if
(
__get_user
(
cregs
->
u_regs
[
i
],
(
&
pregs
->
u_regs
[
i
-
1
])))
break
;
}
pt_succ_return
(
regs
,
0
);
goto
out_tsk
;
if
(
i
==
16
)
ret
=
0
;
break
;
}
case
PTRACE_SETREGS64
:
{
struct
pt_regs
__user
*
pregs
=
(
struct
pt_regs
__user
*
)
addr
;
struct
pt_regs
*
cregs
=
task_pt_regs
(
child
);
unsigned
long
tstate
,
tpc
,
tnpc
,
y
;
int
i
;
/* Must be careful, tracing process can only set certain
* bits in the psr.
*/
ret
=
-
EFAULT
;
if
(
__get_user
(
tstate
,
(
&
pregs
->
tstate
))
||
__get_user
(
tpc
,
(
&
pregs
->
tpc
))
||
__get_user
(
tnpc
,
(
&
pregs
->
tnpc
))
||
__get_user
(
y
,
(
&
pregs
->
y
)))
{
pt_error_return
(
regs
,
EFAULT
);
goto
out_tsk
;
}
__get_user
(
y
,
(
&
pregs
->
y
)))
break
;
if
((
task_thread_info
(
child
)
->
flags
&
_TIF_32BIT
)
!=
0
)
{
tpc
&=
0xffffffff
;
tnpc
&=
0xffffffff
;
...
...
@@ -964,13 +851,12 @@ asmlinkage void do_ptrace(struct pt_regs *regs)
}
cregs
->
y
=
y
;
for
(
i
=
1
;
i
<
16
;
i
++
)
{
if
(
__get_user
(
cregs
->
u_regs
[
i
],
(
&
pregs
->
u_regs
[
i
-
1
])))
{
pt_error_return
(
regs
,
EFAULT
);
goto
out_tsk
;
}
if
(
__get_user
(
cregs
->
u_regs
[
i
],
(
&
pregs
->
u_regs
[
i
-
1
])))
break
;
}
pt_succ_return
(
regs
,
0
);
goto
out_tsk
;
if
(
i
==
16
)
ret
=
0
;
break
;
}
case
PTRACE_GETFPREGS
:
{
...
...
@@ -988,18 +874,18 @@ asmlinkage void do_ptrace(struct pt_regs *regs)
struct
fps
__user
*
fps
=
(
struct
fps
__user
*
)
addr
;
unsigned
long
*
fpregs
=
task_thread_info
(
child
)
->
fpregs
;
ret
=
-
EFAULT
;
if
(
copy_to_user
(
&
fps
->
regs
[
0
],
fpregs
,
(
32
*
sizeof
(
unsigned
int
)))
||
__put_user
(
task_thread_info
(
child
)
->
xfsr
[
0
],
(
&
fps
->
fsr
))
||
__put_user
(
0
,
(
&
fps
->
fpqd
))
||
__put_user
(
0
,
(
&
fps
->
flags
))
||
__put_user
(
0
,
(
&
fps
->
extra
))
||
clear_user
(
&
fps
->
fpq
[
0
],
32
*
sizeof
(
unsigned
int
)))
{
pt_error_return
(
regs
,
EFAULT
);
goto
out_tsk
;
}
pt_succ_return
(
regs
,
0
);
goto
out_tsk
;
clear_user
(
&
fps
->
fpq
[
0
],
32
*
sizeof
(
unsigned
int
)))
break
;
ret
=
0
;
break
;
}
case
PTRACE_GETFPREGS64
:
{
...
...
@@ -1010,14 +896,14 @@ asmlinkage void do_ptrace(struct pt_regs *regs)
struct
fps
__user
*
fps
=
(
struct
fps
__user
*
)
addr
;
unsigned
long
*
fpregs
=
task_thread_info
(
child
)
->
fpregs
;
ret
=
-
EFAULT
;
if
(
copy_to_user
(
&
fps
->
regs
[
0
],
fpregs
,
(
64
*
sizeof
(
unsigned
int
)))
||
__put_user
(
task_thread_info
(
child
)
->
xfsr
[
0
],
(
&
fps
->
fsr
)))
{
pt_error_return
(
regs
,
EFAULT
);
goto
out_tsk
;
}
pt_succ_return
(
regs
,
0
);
goto
out_tsk
;
__put_user
(
task_thread_info
(
child
)
->
xfsr
[
0
],
(
&
fps
->
fsr
)))
break
;
ret
=
0
;
break
;
}
case
PTRACE_SETFPREGS
:
{
...
...
@@ -1036,19 +922,19 @@ asmlinkage void do_ptrace(struct pt_regs *regs)
unsigned
long
*
fpregs
=
task_thread_info
(
child
)
->
fpregs
;
unsigned
fsr
;
ret
=
-
EFAULT
;
if
(
copy_from_user
(
fpregs
,
&
fps
->
regs
[
0
],
(
32
*
sizeof
(
unsigned
int
)))
||
__get_user
(
fsr
,
(
&
fps
->
fsr
)))
{
pt_error_return
(
regs
,
EFAULT
);
goto
out_tsk
;
}
__get_user
(
fsr
,
(
&
fps
->
fsr
)))
break
;
task_thread_info
(
child
)
->
xfsr
[
0
]
&=
0xffffffff00000000UL
;
task_thread_info
(
child
)
->
xfsr
[
0
]
|=
fsr
;
if
(
!
(
task_thread_info
(
child
)
->
fpsaved
[
0
]
&
FPRS_FEF
))
task_thread_info
(
child
)
->
gsr
[
0
]
=
0
;
task_thread_info
(
child
)
->
fpsaved
[
0
]
|=
(
FPRS_FEF
|
FPRS_DL
);
pt_succ_return
(
regs
,
0
)
;
goto
out_ts
k
;
ret
=
0
;
brea
k
;
}
case
PTRACE_SETFPREGS64
:
{
...
...
@@ -1059,113 +945,56 @@ asmlinkage void do_ptrace(struct pt_regs *regs)
struct
fps
__user
*
fps
=
(
struct
fps
__user
*
)
addr
;
unsigned
long
*
fpregs
=
task_thread_info
(
child
)
->
fpregs
;
ret
=
-
EFAULT
;
if
(
copy_from_user
(
fpregs
,
&
fps
->
regs
[
0
],
(
64
*
sizeof
(
unsigned
int
)))
||
__get_user
(
task_thread_info
(
child
)
->
xfsr
[
0
],
(
&
fps
->
fsr
)))
{
pt_error_return
(
regs
,
EFAULT
);
goto
out_tsk
;
}
__get_user
(
task_thread_info
(
child
)
->
xfsr
[
0
],
(
&
fps
->
fsr
)))
break
;
if
(
!
(
task_thread_info
(
child
)
->
fpsaved
[
0
]
&
FPRS_FEF
))
task_thread_info
(
child
)
->
gsr
[
0
]
=
0
;
task_thread_info
(
child
)
->
fpsaved
[
0
]
|=
(
FPRS_FEF
|
FPRS_DL
|
FPRS_DU
);
pt_succ_return
(
regs
,
0
);
goto
out_tsk
;
task_thread_info
(
child
)
->
fpsaved
[
0
]
|=
(
FPRS_FEF
|
FPRS_DL
|
FPRS_DU
);
ret
=
0
;
break
;
}
case
PTRACE_READTEXT
:
case
PTRACE_READDATA
:
{
int
res
=
ptrace_readdata
(
child
,
addr
,
(
char
__user
*
)
addr2
,
data
);
if
(
res
==
data
)
{
pt_succ_return
(
regs
,
0
);
goto
out_tsk
;
}
if
(
res
>=
0
)
res
=
-
EIO
;
pt_error_return
(
regs
,
-
res
);
goto
out_tsk
;
}
case
PTRACE_READDATA
:
ret
=
ptrace_readdata
(
child
,
addr
,
(
char
__user
*
)
addr2
,
data
);
if
(
ret
==
data
)
ret
=
0
;
else
if
(
ret
>=
0
)
ret
=
-
EIO
;
break
;
case
PTRACE_WRITETEXT
:
case
PTRACE_WRITEDATA
:
{
int
res
=
ptrace_writedata
(
child
,
(
char
__user
*
)
addr2
,
addr
,
data
);
if
(
res
==
data
)
{
pt_succ_return
(
regs
,
0
);
goto
out_tsk
;
}
if
(
res
>=
0
)
res
=
-
EIO
;
pt_error_return
(
regs
,
-
res
);
goto
out_tsk
;
}
case
PTRACE_SYSCALL
:
/* continue and stop at (return from) syscall */
addr
=
1
;
case
PTRACE_CONT
:
{
/* restart after signal. */
if
(
!
valid_signal
(
data
))
{
pt_error_return
(
regs
,
EIO
);
goto
out_tsk
;
}
if
(
request
==
PTRACE_SYSCALL
)
{
set_tsk_thread_flag
(
child
,
TIF_SYSCALL_TRACE
);
}
else
{
clear_tsk_thread_flag
(
child
,
TIF_SYSCALL_TRACE
);
}
child
->
exit_code
=
data
;
wake_up_process
(
child
);
pt_succ_return
(
regs
,
0
);
goto
out_tsk
;
}
/*
* make the child exit. Best I can do is send it a sigkill.
* perhaps it should be put in the status that it wants to
* exit.
*/
case
PTRACE_KILL
:
{
if
(
child
->
exit_state
==
EXIT_ZOMBIE
)
{
/* already dead */
pt_succ_return
(
regs
,
0
);
goto
out_tsk
;
}
child
->
exit_code
=
SIGKILL
;
wake_up_process
(
child
);
pt_succ_return
(
regs
,
0
);
goto
out_tsk
;
}
case
PTRACE_WRITEDATA
:
ret
=
ptrace_writedata
(
child
,
(
char
__user
*
)
addr2
,
addr
,
data
);
if
(
ret
==
data
)
ret
=
0
;
else
if
(
ret
>=
0
)
ret
=
-
EIO
;
break
;
case
PTRACE_GETEVENTMSG
:
{
int
err
;
if
(
test_thread_flag
(
TIF_32BIT
))
err
=
put_user
(
child
->
ptrace_message
,
ret
=
put_user
(
child
->
ptrace_message
,
(
unsigned
int
__user
*
)
data
);
else
err
=
put_user
(
child
->
ptrace_message
,
ret
=
put_user
(
child
->
ptrace_message
,
(
unsigned
long
__user
*
)
data
);
if
(
err
)
pt_error_return
(
regs
,
-
err
);
else
pt_succ_return
(
regs
,
0
);
break
;
}
default:
{
int
err
=
ptrace_request
(
child
,
request
,
addr
,
data
);
if
(
err
)
pt_error_return
(
regs
,
-
err
);
else
pt_succ_return
(
regs
,
0
);
goto
out_tsk
;
}
default:
ret
=
ptrace_request
(
child
,
request
,
addr
,
data
);
break
;
}
out_tsk:
if
(
child
)
put_task_struct
(
child
);
out:
unlock_kernel
();
return
ret
;
}
asmlinkage
void
syscall_trace
(
struct
pt_regs
*
regs
,
int
syscall_exit_p
)
...
...
include/asm-sparc/ptrace.h
浏览文件 @
9775369e
...
...
@@ -61,8 +61,6 @@ struct sparc_stackf {
#ifdef __KERNEL__
#define __ARCH_SYS_PTRACE 1
#define user_mode(regs) (!((regs)->psr & PSR_PS))
#define instruction_pointer(regs) ((regs)->pc)
unsigned
long
profile_pc
(
struct
pt_regs
*
);
...
...
@@ -162,7 +160,4 @@ extern void show_regs(struct pt_regs *);
#define PTRACE_GETFPAREGS 20
#define PTRACE_SETFPAREGS 21
#define PTRACE_GETUCODE 29
/* stupid bsd-ism */
#endif
/* !(_SPARC_PTRACE_H) */
include/asm-sparc64/ptrace.h
浏览文件 @
9775369e
...
...
@@ -95,8 +95,6 @@ struct sparc_trapf {
#ifdef __KERNEL__
#define __ARCH_SYS_PTRACE 1
#define force_successful_syscall_return() \
do { current_thread_info()->syscall_noerror = 1; \
} while (0)
...
...
@@ -282,18 +280,4 @@ extern void show_regs(struct pt_regs *);
#define PTRACE_GETFPREGS64 25
#define PTRACE_SETFPREGS64 26
#define PTRACE_GETUCODE 29
/* stupid bsd-ism */
/* These are for 32-bit processes debugging 64-bit ones.
* Here addr and addr2 are passed in %g2 and %g3 respectively.
*/
#define PTRACE_PEEKTEXT64 (30 + PTRACE_PEEKTEXT)
#define PTRACE_POKETEXT64 (30 + PTRACE_POKETEXT)
#define PTRACE_PEEKDATA64 (30 + PTRACE_PEEKDATA)
#define PTRACE_POKEDATA64 (30 + PTRACE_POKEDATA)
#define PTRACE_READDATA64 (30 + PTRACE_READDATA)
#define PTRACE_WRITEDATA64 (30 + PTRACE_WRITEDATA)
#define PTRACE_READTEXT64 (30 + PTRACE_READTEXT)
#define PTRACE_WRITETEXT64 (30 + PTRACE_WRITETEXT)
#endif
/* !(_SPARC64_PTRACE_H) */
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录