Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
linux
Commits
9775369e
Commit
9775369e
authored
Feb 07, 2008
by
David S. Miller
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[SPARC]: Move over to arch_ptrace().
Signed-off-by:
David S. Miller
<
davem@davemloft.net
>
parent
190aa9f6
Changes
6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
172 additions
and
721 deletions
+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
No files found.
arch/sparc/kernel/entry.S
View file @
9775369e
...
@@ -1224,23 +1224,6 @@ sys_nis_syscall:
...
@@ -1224,23 +1224,6 @@ sys_nis_syscall:
call
c_sys_nis_syscall
call
c_sys_nis_syscall
mov
%
l5
,
%
o7
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
.
align
4
.
globl
sys_execve
.
globl
sys_execve
sys_execve
:
sys_execve
:
...
...
arch/sparc/kernel/ptrace.c
View file @
9775369e
...
@@ -26,215 +26,6 @@
...
@@ -26,215 +26,6 @@
#include <asm/system.h>
#include <asm/system.h>
#include <asm/uaccess.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 */
/* #define ALLOW_INIT_TRACING */
/*
/*
...
@@ -528,113 +319,42 @@ const struct user_regset_view *task_user_regset_view(struct task_struct *task)
...
@@ -528,113 +319,42 @@ const struct user_regset_view *task_user_regset_view(struct task_struct *task)
return
&
user_sparc32_view
;
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
addr2
=
current
->
thread
.
kregs
->
u_regs
[
UREG_I4
];
unsigned
long
pid
=
regs
->
u_regs
[
UREG_I1
];
int
i
,
ret
;
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
;
}
switch
(
request
)
{
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
:
{
case
PTRACE_GETREGS
:
{
struct
pt_regs
__user
*
pregs
=
(
struct
pt_regs
__user
*
)
addr
;
struct
pt_regs
__user
*
pregs
=
(
struct
pt_regs
__user
*
)
addr
;
struct
pt_regs
*
cregs
=
child
->
thread
.
kregs
;
struct
pt_regs
*
cregs
=
child
->
thread
.
kregs
;
int
rval
;
if
(
!
access_ok
(
VERIFY_WRITE
,
pregs
,
sizeof
(
struct
pt_regs
)))
{
ret
=
-
EFAULT
;
rval
=
-
EFAULT
;
if
(
!
access_ok
(
VERIFY_WRITE
,
pregs
,
sizeof
(
struct
pt_regs
)))
pt_error_return
(
regs
,
-
rval
);
break
;
goto
out_tsk
;
}
__put_user
(
cregs
->
psr
,
(
&
pregs
->
psr
));
__put_user
(
cregs
->
psr
,
(
&
pregs
->
psr
));
__put_user
(
cregs
->
pc
,
(
&
pregs
->
pc
));
__put_user
(
cregs
->
pc
,
(
&
pregs
->
pc
));
__put_user
(
cregs
->
npc
,
(
&
pregs
->
npc
));
__put_user
(
cregs
->
npc
,
(
&
pregs
->
npc
));
__put_user
(
cregs
->
y
,
(
&
pregs
->
y
));
__put_user
(
cregs
->
y
,
(
&
pregs
->
y
));
for
(
rval
=
1
;
rval
<
16
;
rval
++
)
for
(
i
=
1
;
i
<
16
;
i
++
)
__put_user
(
cregs
->
u_regs
[
rval
],
(
&
pregs
->
u_regs
[
rval
-
1
])
);
__put_user
(
cregs
->
u_regs
[
i
],
&
pregs
->
u_regs
[
i
-
1
]
);
pt_succ_return
(
regs
,
0
)
;
ret
=
0
;
goto
out_ts
k
;
brea
k
;
}
}
case
PTRACE_SETREGS
:
{
case
PTRACE_SETREGS
:
{
struct
pt_regs
__user
*
pregs
=
(
struct
pt_regs
__user
*
)
addr
;
struct
pt_regs
__user
*
pregs
=
(
struct
pt_regs
__user
*
)
addr
;
struct
pt_regs
*
cregs
=
child
->
thread
.
kregs
;
struct
pt_regs
*
cregs
=
child
->
thread
.
kregs
;
unsigned
long
psr
,
pc
,
npc
,
y
;
unsigned
long
psr
,
pc
,
npc
,
y
;
int
i
;
/* Must be careful, tracing process can only set certain
/* Must be careful, tracing process can only set certain
* bits in the psr.
* bits in the psr.
*/
*/
if
(
!
access_ok
(
VERIFY_READ
,
pregs
,
sizeof
(
struct
pt_regs
)))
{
ret
=
-
EFAULT
;
pt_error_return
(
regs
,
EFAULT
);
if
(
!
access_ok
(
VERIFY_READ
,
pregs
,
sizeof
(
struct
pt_regs
)))
goto
out_ts
k
;
brea
k
;
}
__get_user
(
psr
,
(
&
pregs
->
psr
));
__get_user
(
psr
,
(
&
pregs
->
psr
));
__get_user
(
pc
,
(
&
pregs
->
pc
));
__get_user
(
pc
,
(
&
pregs
->
pc
));
__get_user
(
npc
,
(
&
pregs
->
npc
));
__get_user
(
npc
,
(
&
pregs
->
npc
));
...
@@ -647,10 +367,10 @@ asmlinkage void do_ptrace(struct pt_regs *regs)
...
@@ -647,10 +367,10 @@ asmlinkage void do_ptrace(struct pt_regs *regs)
cregs
->
npc
=
npc
;
cregs
->
npc
=
npc
;
}
}
cregs
->
y
=
y
;
cregs
->
y
=
y
;
for
(
i
=
1
;
i
<
16
;
i
++
)
for
(
i
=
1
;
i
<
16
;
i
++
)
__get_user
(
cregs
->
u_regs
[
i
],
(
&
pregs
->
u_regs
[
i
-
1
])
);
__get_user
(
cregs
->
u_regs
[
i
],
&
pregs
->
u_regs
[
i
-
1
]
);
pt_succ_return
(
regs
,
0
)
;
ret
=
0
;
goto
out_ts
k
;
brea
k
;
}
}
case
PTRACE_GETFPREGS
:
{
case
PTRACE_GETFPREGS
:
{
...
@@ -666,26 +386,25 @@ asmlinkage void do_ptrace(struct pt_regs *regs)
...
@@ -666,26 +386,25 @@ asmlinkage void do_ptrace(struct pt_regs *regs)
}
fpq
[
16
];
}
fpq
[
16
];
};
};
struct
fps
__user
*
fps
=
(
struct
fps
__user
*
)
addr
;
struct
fps
__user
*
fps
=
(
struct
fps
__user
*
)
addr
;
int
i
;
if
(
!
access_ok
(
VERIFY_WRITE
,
fps
,
sizeof
(
struct
fps
)))
{
ret
=
-
EFAULT
;
i
=
-
EFAULT
;
if
(
!
access_ok
(
VERIFY_WRITE
,
fps
,
sizeof
(
struct
fps
)))
pt_error_return
(
regs
,
-
i
);
break
;
goto
out_tsk
;
}
for
(
i
=
0
;
i
<
32
;
i
++
)
for
(
i
=
0
;
i
<
32
;
i
++
)
__put_user
(
child
->
thread
.
float_regs
[
i
],
&
fps
->
regs
[
i
]);
__put_user
(
child
->
thread
.
float_regs
[
i
],
(
&
fps
->
regs
[
i
]));
__put_user
(
child
->
thread
.
fsr
,
(
&
fps
->
fsr
));
__put_user
(
child
->
thread
.
fsr
,
(
&
fps
->
fsr
));
__put_user
(
child
->
thread
.
fpqdepth
,
(
&
fps
->
fpqd
));
__put_user
(
child
->
thread
.
fpqdepth
,
(
&
fps
->
fpqd
));
__put_user
(
0
,
(
&
fps
->
flags
));
__put_user
(
0
,
(
&
fps
->
flags
));
__put_user
(
0
,
(
&
fps
->
extra
));
__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
,
__put_user
(
child
->
thread
.
fpqueue
[
i
].
insn_addr
,
(
&
fps
->
fpq
[
i
].
insnaddr
));
(
&
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
)
;
ret
=
0
;
goto
out_ts
k
;
brea
k
;
}
}
case
PTRACE_SETFPREGS
:
{
case
PTRACE_SETFPREGS
:
{
...
@@ -701,107 +420,53 @@ asmlinkage void do_ptrace(struct pt_regs *regs)
...
@@ -701,107 +420,53 @@ asmlinkage void do_ptrace(struct pt_regs *regs)
}
fpq
[
16
];
}
fpq
[
16
];
};
};
struct
fps
__user
*
fps
=
(
struct
fps
__user
*
)
addr
;
struct
fps
__user
*
fps
=
(
struct
fps
__user
*
)
addr
;
int
i
;
if
(
!
access_ok
(
VERIFY_READ
,
fps
,
sizeof
(
struct
fps
)))
{
ret
=
-
EFAULT
;
i
=
-
EFAULT
;
if
(
!
access_ok
(
VERIFY_READ
,
fps
,
sizeof
(
struct
fps
)))
pt_error_return
(
regs
,
-
i
)
;
break
;
goto
out_tsk
;
}
copy_from_user
(
&
child
->
thread
.
float_regs
[
0
],
&
fps
->
regs
[
0
],
copy_from_user
(
&
child
->
thread
.
float_regs
[
0
],
&
fps
->
regs
[
0
],
(
32
*
sizeof
(
unsigned
long
)));
(
32
*
sizeof
(
unsigned
long
)));
__get_user
(
child
->
thread
.
fsr
,
(
&
fps
->
fsr
));
__get_user
(
child
->
thread
.
fsr
,
(
&
fps
->
fsr
));
__get_user
(
child
->
thread
.
fpqdepth
,
(
&
fps
->
fpqd
));
__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
,
__get_user
(
child
->
thread
.
fpqueue
[
i
].
insn_addr
,
(
&
fps
->
fpq
[
i
].
insnaddr
));
(
&
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
)
;
ret
=
0
;
goto
out_ts
k
;
brea
k
;
}
}
case
PTRACE_READTEXT
:
case
PTRACE_READTEXT
:
case
PTRACE_READDATA
:
{
case
PTRACE_READDATA
:
int
res
=
ptrace_readdata
(
child
,
addr
,
ret
=
ptrace_readdata
(
child
,
addr
,
(
void
__user
*
)
addr2
,
data
);
(
void
__user
*
)
addr2
,
data
);
if
(
res
==
data
)
{
if
(
ret
==
data
)
pt_succ_return
(
regs
,
0
);
ret
=
0
;
goto
out_tsk
;
else
if
(
ret
>=
0
)
}
ret
=
-
EIO
;
/* Partial read is an IO failure */
break
;
if
(
res
>=
0
)
res
=
-
EIO
;
pt_error_return
(
regs
,
-
res
);
goto
out_tsk
;
}
case
PTRACE_WRITETEXT
:
case
PTRACE_WRITETEXT
:
case
PTRACE_WRITEDATA
:
{
case
PTRACE_WRITEDATA
:
int
res
=
ptrace_writedata
(
child
,
(
void
__user
*
)
addr2
,
ret
=
ptrace_writedata
(
child
,
(
void
__user
*
)
addr2
,
addr
,
data
);
addr
,
data
);
if
(
res
==
data
)
{
if
(
ret
==
data
)
pt_succ_return
(
regs
,
0
);
ret
=
0
;
goto
out_tsk
;
else
if
(
ret
>=
0
)
}
ret
=
-
EIO
;
/* Partial write is an IO failure */
break
;
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
;
}
/*
default:
* make the child exit. Best I can do is send it a sigkill.
ret
=
ptrace_request
(
child
,
request
,
addr
,
data
);
* perhaps it should be put in the status that it wants to
break
;
* 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:
{
return
ret
;
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
();
}
}
asmlinkage
void
syscall_trace
(
void
)
asmlinkage
void
syscall_trace
(
void
)
...
@@ -810,7 +475,6 @@ asmlinkage void syscall_trace(void)
...
@@ -810,7 +475,6 @@ asmlinkage void syscall_trace(void)
return
;
return
;
if
(
!
(
current
->
ptrace
&
PT_PTRACED
))
if
(
!
(
current
->
ptrace
&
PT_PTRACED
))
return
;
return
;
current
->
thread
.
flags
^=
MAGIC_CONSTANT
;
ptrace_notify
(
SIGTRAP
|
((
current
->
ptrace
&
PT_TRACESYSGOOD
)
ptrace_notify
(
SIGTRAP
|
((
current
->
ptrace
&
PT_TRACESYSGOOD
)
?
0x80
:
0
));
?
0x80
:
0
));
/*
/*
...
...
arch/sparc64/kernel/entry.S
View file @
9775369e
...
@@ -1477,10 +1477,6 @@ sys32_rt_sigreturn:
...
@@ -1477,10 +1477,6 @@ sys32_rt_sigreturn:
add
%
o7
,
1
f
-
.
-
4
,
%
o7
add
%
o7
,
1
f
-
.
-
4
,
%
o7
nop
nop
#endif
#endif
sys_ptrace
:
add
%
sp
,
PTREGS_OFF
,
%
o0
call
do_ptrace
add
%
o7
,
1
f
-
.
-
4
,
%
o7
nop
.
align
32
.
align
32
1
:
ldx
[%
curptr
+
TI_FLAGS
],
%
l5
1
:
ldx
[%
curptr
+
TI_FLAGS
],
%
l5
andcc
%
l5
,
(
_TIF_SYSCALL_TRACE|_TIF_SECCOMP|_TIF_SYSCALL_AUDIT
),
%
g0
andcc
%
l5
,
(
_TIF_SYSCALL_TRACE|_TIF_SECCOMP|_TIF_SYSCALL_AUDIT
),
%
g0
...
...
arch/sparc64/kernel/ptrace.c
View file @
9775369e
...
@@ -36,56 +36,6 @@
...
@@ -36,56 +36,6 @@
#include <asm/page.h>
#include <asm/page.h>
#include <asm/cpudata.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 */
/* #define ALLOW_INIT_TRACING */
/*
/*
...
@@ -734,171 +684,113 @@ const struct user_regset_view *task_user_regset_view(struct task_struct *task)
...
@@ -734,171 +684,113 @@ const struct user_regset_view *task_user_regset_view(struct task_struct *task)
return
&
user_sparc64_view
;
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
];
long
addr2
=
task_pt_regs
(
current
)
->
u_regs
[
UREG_I4
];
pid_t
pid
=
regs
->
u_regs
[
UREG_I1
];
int
i
,
ret
;
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
;
if
(
test_thread_flag
(
TIF_32BIT
))
{
#if 1
addr
&=
0xffffffffUL
;
printk
(
KERN_INFO
data
&=
0xffffffffUL
;
"arch_ptrace: request[%ld] addr[%lx] data[%lx] addr2[%lx]
\n
"
,
request
,
addr
,
data
,
addr2
);
#endif
if
(
test_thread_flag
(
TIF_32BIT
))
addr2
&=
0xffffffffUL
;
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
)
{
switch
(
request
)
{
case
PTRACE_PEEKUSR
:
case
PTRACE_PEEKUSR
:
if
(
addr
!=
0
)
ret
=
(
addr
!=
0
)
?
-
EIO
:
0
;
pt_error_return
(
regs
,
EIO
);
break
;
else
pt_succ_return
(
regs
,
0
);
goto
out_tsk
;
case
PTRACE_PEEKTEXT
:
/* read word at location addr. */
case
PTRACE_PEEKTEXT
:
/* read word at location addr. */
case
PTRACE_PEEKDATA
:
{
case
PTRACE_PEEKDATA
:
{
unsigned
long
tmp64
;
unsigned
long
tmp64
;
unsigned
int
tmp32
;
unsigned
int
tmp32
;
int
res
,
copied
;
int
copied
;
re
s
=
-
EIO
;
re
t
=
-
EIO
;
if
(
test_thread_flag
(
TIF_32BIT
))
{
if
(
test_thread_flag
(
TIF_32BIT
))
{
copied
=
access_process_vm
(
child
,
addr
,
copied
=
access_process_vm
(
child
,
addr
,
&
tmp32
,
sizeof
(
tmp32
),
0
);
&
tmp32
,
sizeof
(
tmp32
),
0
);
tmp64
=
(
unsigned
long
)
tmp32
;
if
(
copied
==
sizeof
(
tmp32
))
if
(
copied
==
sizeof
(
tmp32
))
res
=
0
;
ret
=
put_user
(
tmp32
,
(
unsigned
int
__user
*
)
data
);
}
else
{
}
else
{
copied
=
access_process_vm
(
child
,
addr
,
copied
=
access_process_vm
(
child
,
addr
,
&
tmp64
,
sizeof
(
tmp64
),
0
);
&
tmp64
,
sizeof
(
tmp64
),
0
);
if
(
copied
==
sizeof
(
tmp64
))
if
(
copied
==
sizeof
(
tmp64
))
res
=
0
;
ret
=
put_user
(
tmp64
,
(
unsigned
long
__user
*
)
data
);
}
}
if
(
res
<
0
)
break
;
pt_error_return
(
regs
,
-
res
);
else
pt_os_succ_return
(
regs
,
tmp64
,
(
void
__user
*
)
data
);
goto
out_tsk
;
}
}
case
PTRACE_POKETEXT
:
/* write the word at location addr. */
case
PTRACE_POKETEXT
:
/* write the word at location addr. */
case
PTRACE_POKEDATA
:
{
case
PTRACE_POKEDATA
:
{
unsigned
long
tmp64
;
unsigned
long
tmp64
;
unsigned
int
tmp32
;
unsigned
int
tmp32
;
int
copied
,
res
=
-
EIO
;
int
copied
;
ret
=
-
EIO
;
if
(
test_thread_flag
(
TIF_32BIT
))
{
if
(
test_thread_flag
(
TIF_32BIT
))
{
tmp32
=
data
;
tmp32
=
data
;
copied
=
access_process_vm
(
child
,
addr
,
copied
=
access_process_vm
(
child
,
addr
,
&
tmp32
,
sizeof
(
tmp32
),
1
);
&
tmp32
,
sizeof
(
tmp32
),
1
);
if
(
copied
==
sizeof
(
tmp32
))
if
(
copied
==
sizeof
(
tmp32
))
re
s
=
0
;
re
t
=
0
;
}
else
{
}
else
{
tmp64
=
data
;
tmp64
=
data
;
copied
=
access_process_vm
(
child
,
addr
,
copied
=
access_process_vm
(
child
,
addr
,
&
tmp64
,
sizeof
(
tmp64
),
1
);
&
tmp64
,
sizeof
(
tmp64
),
1
);
if
(
copied
==
sizeof
(
tmp64
))
if
(
copied
==
sizeof
(
tmp64
))
re
s
=
0
;
re
t
=
0
;
}
}
if
(
res
<
0
)
break
;
pt_error_return
(
regs
,
-
res
);
else
pt_succ_return
(
regs
,
res
);
goto
out_tsk
;
}
}
case
PTRACE_GETREGS
:
{
case
PTRACE_GETREGS
:
{
struct
pt_regs32
__user
*
pregs
=
struct
pt_regs32
__user
*
pregs
=
(
struct
pt_regs32
__user
*
)
addr
;
(
struct
pt_regs32
__user
*
)
addr
;
struct
pt_regs
*
cregs
=
task_pt_regs
(
child
);
struct
pt_regs
*
cregs
=
task_pt_regs
(
child
);
int
rval
;
ret
=
-
EFAULT
;
if
(
__put_user
(
tstate_to_psr
(
cregs
->
tstate
),
(
&
pregs
->
psr
))
||
if
(
__put_user
(
tstate_to_psr
(
cregs
->
tstate
),
(
&
pregs
->
psr
))
||
__put_user
(
cregs
->
tpc
,
(
&
pregs
->
pc
))
||
__put_user
(
cregs
->
tpc
,
(
&
pregs
->
pc
))
||
__put_user
(
cregs
->
tnpc
,
(
&
pregs
->
npc
))
||
__put_user
(
cregs
->
tnpc
,
(
&
pregs
->
npc
))
||
__put_user
(
cregs
->
y
,
(
&
pregs
->
y
)))
{
__put_user
(
cregs
->
y
,
(
&
pregs
->
y
)))
pt_error_return
(
regs
,
EFAULT
);
break
;
goto
out_tsk
;
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
(
i
==
16
)
if
(
__put_user
(
cregs
->
u_regs
[
rval
],
(
&
pregs
->
u_regs
[
rval
-
1
])))
{
ret
=
0
;
pt_error_return
(
regs
,
EFAULT
);
break
;
goto
out_tsk
;
}
pt_succ_return
(
regs
,
0
);
goto
out_tsk
;
}
}
case
PTRACE_GETREGS64
:
{
case
PTRACE_GETREGS64
:
{
struct
pt_regs
__user
*
pregs
=
(
struct
pt_regs
__user
*
)
addr
;
struct
pt_regs
__user
*
pregs
=
(
struct
pt_regs
__user
*
)
addr
;
struct
pt_regs
*
cregs
=
task_pt_regs
(
child
);
struct
pt_regs
*
cregs
=
task_pt_regs
(
child
);
unsigned
long
tpc
=
cregs
->
tpc
;
unsigned
long
tpc
=
cregs
->
tpc
;
int
rval
;
if
((
task_thread_info
(
child
)
->
flags
&
_TIF_32BIT
)
!=
0
)
if
((
task_thread_info
(
child
)
->
flags
&
_TIF_32BIT
)
!=
0
)
tpc
&=
0xffffffff
;
tpc
&=
0xffffffff
;
ret
=
-
EFAULT
;
if
(
__put_user
(
cregs
->
tstate
,
(
&
pregs
->
tstate
))
||
if
(
__put_user
(
cregs
->
tstate
,
(
&
pregs
->
tstate
))
||
__put_user
(
tpc
,
(
&
pregs
->
tpc
))
||
__put_user
(
tpc
,
(
&
pregs
->
tpc
))
||
__put_user
(
cregs
->
tnpc
,
(
&
pregs
->
tnpc
))
||
__put_user
(
cregs
->
tnpc
,
(
&
pregs
->
tnpc
))
||
__put_user
(
cregs
->
y
,
(
&
pregs
->
y
)))
{
__put_user
(
cregs
->
y
,
(
&
pregs
->
y
)))
pt_error_return
(
regs
,
EFAULT
);
break
;
goto
out_tsk
;
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
(
i
==
16
)
if
(
__put_user
(
cregs
->
u_regs
[
rval
],
(
&
pregs
->
u_regs
[
rval
-
1
])))
{
ret
=
0
;
pt_error_return
(
regs
,
EFAULT
);
break
;
goto
out_tsk
;
}
pt_succ_return
(
regs
,
0
);
goto
out_tsk
;
}
}
case
PTRACE_SETREGS
:
{
case
PTRACE_SETREGS
:
{
...
@@ -906,18 +798,16 @@ asmlinkage void do_ptrace(struct pt_regs *regs)
...
@@ -906,18 +798,16 @@ asmlinkage void do_ptrace(struct pt_regs *regs)
(
struct
pt_regs32
__user
*
)
addr
;
(
struct
pt_regs32
__user
*
)
addr
;
struct
pt_regs
*
cregs
=
task_pt_regs
(
child
);
struct
pt_regs
*
cregs
=
task_pt_regs
(
child
);
unsigned
int
psr
,
pc
,
npc
,
y
;
unsigned
int
psr
,
pc
,
npc
,
y
;
int
i
;
/* Must be careful, tracing process can only set certain
/* Must be careful, tracing process can only set certain
* bits in the psr.
* bits in the psr.
*/
*/
ret
=
-
EFAULT
;
if
(
__get_user
(
psr
,
(
&
pregs
->
psr
))
||
if
(
__get_user
(
psr
,
(
&
pregs
->
psr
))
||
__get_user
(
pc
,
(
&
pregs
->
pc
))
||
__get_user
(
pc
,
(
&
pregs
->
pc
))
||
__get_user
(
npc
,
(
&
pregs
->
npc
))
||
__get_user
(
npc
,
(
&
pregs
->
npc
))
||
__get_user
(
y
,
(
&
pregs
->
y
)))
{
__get_user
(
y
,
(
&
pregs
->
y
)))
pt_error_return
(
regs
,
EFAULT
);
break
;
goto
out_tsk
;
}
cregs
->
tstate
&=
~
(
TSTATE_ICC
);
cregs
->
tstate
&=
~
(
TSTATE_ICC
);
cregs
->
tstate
|=
psr_to_tstate_icc
(
psr
);
cregs
->
tstate
|=
psr_to_tstate_icc
(
psr
);
if
(
!
((
pc
|
npc
)
&
3
))
{
if
(
!
((
pc
|
npc
)
&
3
))
{
...
@@ -926,31 +816,28 @@ asmlinkage void do_ptrace(struct pt_regs *regs)
...
@@ -926,31 +816,28 @@ asmlinkage void do_ptrace(struct pt_regs *regs)
}
}
cregs
->
y
=
y
;
cregs
->
y
=
y
;
for
(
i
=
1
;
i
<
16
;
i
++
)
{
for
(
i
=
1
;
i
<
16
;
i
++
)
{
if
(
__get_user
(
cregs
->
u_regs
[
i
],
(
&
pregs
->
u_regs
[
i
-
1
])))
{
if
(
__get_user
(
cregs
->
u_regs
[
i
],
(
&
pregs
->
u_regs
[
i
-
1
])))
pt_error_return
(
regs
,
EFAULT
);
break
;
goto
out_tsk
;
}
}
}
pt_succ_return
(
regs
,
0
);
if
(
i
==
16
)
goto
out_tsk
;
ret
=
0
;
break
;
}
}
case
PTRACE_SETREGS64
:
{
case
PTRACE_SETREGS64
:
{
struct
pt_regs
__user
*
pregs
=
(
struct
pt_regs
__user
*
)
addr
;
struct
pt_regs
__user
*
pregs
=
(
struct
pt_regs
__user
*
)
addr
;
struct
pt_regs
*
cregs
=
task_pt_regs
(
child
);
struct
pt_regs
*
cregs
=
task_pt_regs
(
child
);
unsigned
long
tstate
,
tpc
,
tnpc
,
y
;
unsigned
long
tstate
,
tpc
,
tnpc
,
y
;
int
i
;
/* Must be careful, tracing process can only set certain
/* Must be careful, tracing process can only set certain
* bits in the psr.
* bits in the psr.
*/
*/
ret
=
-
EFAULT
;
if
(
__get_user
(
tstate
,
(
&
pregs
->
tstate
))
||
if
(
__get_user
(
tstate
,
(
&
pregs
->
tstate
))
||
__get_user
(
tpc
,
(
&
pregs
->
tpc
))
||
__get_user
(
tpc
,
(
&
pregs
->
tpc
))
||
__get_user
(
tnpc
,
(
&
pregs
->
tnpc
))
||
__get_user
(
tnpc
,
(
&
pregs
->
tnpc
))
||
__get_user
(
y
,
(
&
pregs
->
y
)))
{
__get_user
(
y
,
(
&
pregs
->
y
)))
pt_error_return
(
regs
,
EFAULT
);
break
;
goto
out_tsk
;
}
if
((
task_thread_info
(
child
)
->
flags
&
_TIF_32BIT
)
!=
0
)
{
if
((
task_thread_info
(
child
)
->
flags
&
_TIF_32BIT
)
!=
0
)
{
tpc
&=
0xffffffff
;
tpc
&=
0xffffffff
;
tnpc
&=
0xffffffff
;
tnpc
&=
0xffffffff
;
...
@@ -964,13 +851,12 @@ asmlinkage void do_ptrace(struct pt_regs *regs)
...
@@ -964,13 +851,12 @@ asmlinkage void do_ptrace(struct pt_regs *regs)
}
}
cregs
->
y
=
y
;
cregs
->
y
=
y
;
for
(
i
=
1
;
i
<
16
;
i
++
)
{
for
(
i
=
1
;
i
<
16
;
i
++
)
{
if
(
__get_user
(
cregs
->
u_regs
[
i
],
(
&
pregs
->
u_regs
[
i
-
1
])))
{
if
(
__get_user
(
cregs
->
u_regs
[
i
],
(
&
pregs
->
u_regs
[
i
-
1
])))
pt_error_return
(
regs
,
EFAULT
);
break
;
goto
out_tsk
;
}
}
}
pt_succ_return
(
regs
,
0
);
if
(
i
==
16
)
goto
out_tsk
;
ret
=
0
;
break
;
}
}
case
PTRACE_GETFPREGS
:
{
case
PTRACE_GETFPREGS
:
{
...
@@ -988,18 +874,18 @@ asmlinkage void do_ptrace(struct pt_regs *regs)
...
@@ -988,18 +874,18 @@ asmlinkage void do_ptrace(struct pt_regs *regs)
struct
fps
__user
*
fps
=
(
struct
fps
__user
*
)
addr
;
struct
fps
__user
*
fps
=
(
struct
fps
__user
*
)
addr
;
unsigned
long
*
fpregs
=
task_thread_info
(
child
)
->
fpregs
;
unsigned
long
*
fpregs
=
task_thread_info
(
child
)
->
fpregs
;
ret
=
-
EFAULT
;
if
(
copy_to_user
(
&
fps
->
regs
[
0
],
fpregs
,
if
(
copy_to_user
(
&
fps
->
regs
[
0
],
fpregs
,
(
32
*
sizeof
(
unsigned
int
)))
||
(
32
*
sizeof
(
unsigned
int
)))
||
__put_user
(
task_thread_info
(
child
)
->
xfsr
[
0
],
(
&
fps
->
fsr
))
||
__put_user
(
task_thread_info
(
child
)
->
xfsr
[
0
],
(
&
fps
->
fsr
))
||
__put_user
(
0
,
(
&
fps
->
fpqd
))
||
__put_user
(
0
,
(
&
fps
->
fpqd
))
||
__put_user
(
0
,
(
&
fps
->
flags
))
||
__put_user
(
0
,
(
&
fps
->
flags
))
||
__put_user
(
0
,
(
&
fps
->
extra
))
||
__put_user
(
0
,
(
&
fps
->
extra
))
||
clear_user
(
&
fps
->
fpq
[
0
],
32
*
sizeof
(
unsigned
int
)))
{
clear_user
(
&
fps
->
fpq
[
0
],
32
*
sizeof
(
unsigned
int
)))
pt_error_return
(
regs
,
EFAULT
);
break
;
goto
out_tsk
;
}
ret
=
0
;
pt_succ_return
(
regs
,
0
);
break
;
goto
out_tsk
;
}
}
case
PTRACE_GETFPREGS64
:
{
case
PTRACE_GETFPREGS64
:
{
...
@@ -1010,14 +896,14 @@ asmlinkage void do_ptrace(struct pt_regs *regs)
...
@@ -1010,14 +896,14 @@ asmlinkage void do_ptrace(struct pt_regs *regs)
struct
fps
__user
*
fps
=
(
struct
fps
__user
*
)
addr
;
struct
fps
__user
*
fps
=
(
struct
fps
__user
*
)
addr
;
unsigned
long
*
fpregs
=
task_thread_info
(
child
)
->
fpregs
;
unsigned
long
*
fpregs
=
task_thread_info
(
child
)
->
fpregs
;
ret
=
-
EFAULT
;
if
(
copy_to_user
(
&
fps
->
regs
[
0
],
fpregs
,
if
(
copy_to_user
(
&
fps
->
regs
[
0
],
fpregs
,
(
64
*
sizeof
(
unsigned
int
)))
||
(
64
*
sizeof
(
unsigned
int
)))
||
__put_user
(
task_thread_info
(
child
)
->
xfsr
[
0
],
(
&
fps
->
fsr
)))
{
__put_user
(
task_thread_info
(
child
)
->
xfsr
[
0
],
(
&
fps
->
fsr
)))
pt_error_return
(
regs
,
EFAULT
);
break
;
goto
out_tsk
;
}
ret
=
0
;
pt_succ_return
(
regs
,
0
);
break
;
goto
out_tsk
;
}
}
case
PTRACE_SETFPREGS
:
{
case
PTRACE_SETFPREGS
:
{
...
@@ -1036,19 +922,19 @@ asmlinkage void do_ptrace(struct pt_regs *regs)
...
@@ -1036,19 +922,19 @@ asmlinkage void do_ptrace(struct pt_regs *regs)
unsigned
long
*
fpregs
=
task_thread_info
(
child
)
->
fpregs
;
unsigned
long
*
fpregs
=
task_thread_info
(
child
)
->
fpregs
;
unsigned
fsr
;
unsigned
fsr
;
ret
=
-
EFAULT
;
if
(
copy_from_user
(
fpregs
,
&
fps
->
regs
[
0
],
if
(
copy_from_user
(
fpregs
,
&
fps
->
regs
[
0
],
(
32
*
sizeof
(
unsigned
int
)))
||
(
32
*
sizeof
(
unsigned
int
)))
||
__get_user
(
fsr
,
(
&
fps
->
fsr
)))
{
__get_user
(
fsr
,
(
&
fps
->
fsr
)))
pt_error_return
(
regs
,
EFAULT
);
break
;
goto
out_tsk
;
}
task_thread_info
(
child
)
->
xfsr
[
0
]
&=
0xffffffff00000000UL
;
task_thread_info
(
child
)
->
xfsr
[
0
]
&=
0xffffffff00000000UL
;
task_thread_info
(
child
)
->
xfsr
[
0
]
|=
fsr
;
task_thread_info
(
child
)
->
xfsr
[
0
]
|=
fsr
;
if
(
!
(
task_thread_info
(
child
)
->
fpsaved
[
0
]
&
FPRS_FEF
))
if
(
!
(
task_thread_info
(
child
)
->
fpsaved
[
0
]
&
FPRS_FEF
))
task_thread_info
(
child
)
->
gsr
[
0
]
=
0
;
task_thread_info
(
child
)
->
gsr
[
0
]
=
0
;
task_thread_info
(
child
)
->
fpsaved
[
0
]
|=
(
FPRS_FEF
|
FPRS_DL
);
task_thread_info
(
child
)
->
fpsaved
[
0
]
|=
(
FPRS_FEF
|
FPRS_DL
);
pt_succ_return
(
regs
,
0
)
;
ret
=
0
;
goto
out_ts
k
;
brea
k
;
}
}
case
PTRACE_SETFPREGS64
:
{
case
PTRACE_SETFPREGS64
:
{
...
@@ -1059,113 +945,56 @@ asmlinkage void do_ptrace(struct pt_regs *regs)
...
@@ -1059,113 +945,56 @@ asmlinkage void do_ptrace(struct pt_regs *regs)
struct
fps
__user
*
fps
=
(
struct
fps
__user
*
)
addr
;
struct
fps
__user
*
fps
=
(
struct
fps
__user
*
)
addr
;
unsigned
long
*
fpregs
=
task_thread_info
(
child
)
->
fpregs
;
unsigned
long
*
fpregs
=
task_thread_info
(
child
)
->
fpregs
;
ret
=
-
EFAULT
;
if
(
copy_from_user
(
fpregs
,
&
fps
->
regs
[
0
],
if
(
copy_from_user
(
fpregs
,
&
fps
->
regs
[
0
],
(
64
*
sizeof
(
unsigned
int
)))
||
(
64
*
sizeof
(
unsigned
int
)))
||
__get_user
(
task_thread_info
(
child
)
->
xfsr
[
0
],
(
&
fps
->
fsr
)))
{
__get_user
(
task_thread_info
(
child
)
->
xfsr
[
0
],
(
&
fps
->
fsr
)))
pt_error_return
(
regs
,
EFAULT
);
break
;
goto
out_tsk
;
}
if
(
!
(
task_thread_info
(
child
)
->
fpsaved
[
0
]
&
FPRS_FEF
))
if
(
!
(
task_thread_info
(
child
)
->
fpsaved
[
0
]
&
FPRS_FEF
))
task_thread_info
(
child
)
->
gsr
[
0
]
=
0
;
task_thread_info
(
child
)
->
gsr
[
0
]
=
0
;
task_thread_info
(
child
)
->
fpsaved
[
0
]
|=
(
FPRS_FEF
|
FPRS_DL
|
FPRS_DU
);
task_thread_info
(
child
)
->
fpsaved
[
0
]
|=
pt_succ_return
(
regs
,
0
);
(
FPRS_FEF
|
FPRS_DL
|
FPRS_DU
);
goto
out_tsk
;
ret
=
0
;
break
;
}
}
case
PTRACE_READTEXT
:
case
PTRACE_READTEXT
:
case
PTRACE_READDATA
:
{
case
PTRACE_READDATA
:
int
res
=
ptrace_readdata
(
child
,
addr
,
ret
=
ptrace_readdata
(
child
,
addr
,
(
char
__user
*
)
addr2
,
data
);
(
char
__user
*
)
addr2
,
data
);
if
(
res
==
data
)
{
if
(
ret
==
data
)
pt_succ_return
(
regs
,
0
);
ret
=
0
;
goto
out_tsk
;
else
if
(
ret
>=
0
)
}
ret
=
-
EIO
;
if
(
res
>=
0
)
break
;
res
=
-
EIO
;
pt_error_return
(
regs
,
-
res
);
goto
out_tsk
;
}
case
PTRACE_WRITETEXT
:
case
PTRACE_WRITETEXT
:
case
PTRACE_WRITEDATA
:
{
case
PTRACE_WRITEDATA
:
int
res
=
ptrace_writedata
(
child
,
(
char
__user
*
)
addr2
,
ret
=
ptrace_writedata
(
child
,
(
char
__user
*
)
addr2
,
addr
,
data
);
addr
,
data
);
if
(
res
==
data
)
{
if
(
ret
==
data
)
pt_succ_return
(
regs
,
0
);
ret
=
0
;
goto
out_tsk
;
else
if
(
ret
>=
0
)
}
ret
=
-
EIO
;
if
(
res
>=
0
)
break
;
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_GETEVENTMSG
:
{
case
PTRACE_GETEVENTMSG
:
{
int
err
;
if
(
test_thread_flag
(
TIF_32BIT
))
if
(
test_thread_flag
(
TIF_32BIT
))
err
=
put_user
(
child
->
ptrace_message
,
ret
=
put_user
(
child
->
ptrace_message
,
(
unsigned
int
__user
*
)
data
);
(
unsigned
int
__user
*
)
data
);
else
else
err
=
put_user
(
child
->
ptrace_message
,
ret
=
put_user
(
child
->
ptrace_message
,
(
unsigned
long
__user
*
)
data
);
(
unsigned
long
__user
*
)
data
);
if
(
err
)
pt_error_return
(
regs
,
-
err
);
else
pt_succ_return
(
regs
,
0
);
break
;
break
;
}
}
default:
{
default:
int
err
=
ptrace_request
(
child
,
request
,
addr
,
data
);
ret
=
ptrace_request
(
child
,
request
,
addr
,
data
);
if
(
err
)
break
;
pt_error_return
(
regs
,
-
err
);
else
pt_succ_return
(
regs
,
0
);
goto
out_tsk
;
}
}
}
out_tsk:
if
(
child
)
return
ret
;
put_task_struct
(
child
);
out:
unlock_kernel
();
}
}
asmlinkage
void
syscall_trace
(
struct
pt_regs
*
regs
,
int
syscall_exit_p
)
asmlinkage
void
syscall_trace
(
struct
pt_regs
*
regs
,
int
syscall_exit_p
)
...
...
include/asm-sparc/ptrace.h
View file @
9775369e
...
@@ -61,8 +61,6 @@ struct sparc_stackf {
...
@@ -61,8 +61,6 @@ struct sparc_stackf {
#ifdef __KERNEL__
#ifdef __KERNEL__
#define __ARCH_SYS_PTRACE 1
#define user_mode(regs) (!((regs)->psr & PSR_PS))
#define user_mode(regs) (!((regs)->psr & PSR_PS))
#define instruction_pointer(regs) ((regs)->pc)
#define instruction_pointer(regs) ((regs)->pc)
unsigned
long
profile_pc
(
struct
pt_regs
*
);
unsigned
long
profile_pc
(
struct
pt_regs
*
);
...
@@ -162,7 +160,4 @@ extern void show_regs(struct pt_regs *);
...
@@ -162,7 +160,4 @@ extern void show_regs(struct pt_regs *);
#define PTRACE_GETFPAREGS 20
#define PTRACE_GETFPAREGS 20
#define PTRACE_SETFPAREGS 21
#define PTRACE_SETFPAREGS 21
#define PTRACE_GETUCODE 29
/* stupid bsd-ism */
#endif
/* !(_SPARC_PTRACE_H) */
#endif
/* !(_SPARC_PTRACE_H) */
include/asm-sparc64/ptrace.h
View file @
9775369e
...
@@ -95,8 +95,6 @@ struct sparc_trapf {
...
@@ -95,8 +95,6 @@ struct sparc_trapf {
#ifdef __KERNEL__
#ifdef __KERNEL__
#define __ARCH_SYS_PTRACE 1
#define force_successful_syscall_return() \
#define force_successful_syscall_return() \
do { current_thread_info()->syscall_noerror = 1; \
do { current_thread_info()->syscall_noerror = 1; \
} while (0)
} while (0)
...
@@ -282,18 +280,4 @@ extern void show_regs(struct pt_regs *);
...
@@ -282,18 +280,4 @@ extern void show_regs(struct pt_regs *);
#define PTRACE_GETFPREGS64 25
#define PTRACE_GETFPREGS64 25
#define PTRACE_SETFPREGS64 26
#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) */
#endif
/* !(_SPARC64_PTRACE_H) */
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment