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
Kirill Smelkov
linux
Commits
e8a30302
Commit
e8a30302
authored
Oct 13, 2005
by
Stephen Rothwell
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
powerpc: merge ptrace.c
Signed-off-by:
Stephen Rothwell
<
sfr@canb.auug.org.au
>
parent
eec5ef90
Changes
5
Show whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
141 additions
and
398 deletions
+141
-398
arch/powerpc/kernel/Makefile
arch/powerpc/kernel/Makefile
+1
-1
arch/powerpc/kernel/ptrace.c
arch/powerpc/kernel/ptrace.c
+137
-31
arch/ppc/kernel/Makefile
arch/ppc/kernel/Makefile
+2
-2
arch/ppc64/kernel/Makefile
arch/ppc64/kernel/Makefile
+1
-1
arch/ppc64/kernel/ptrace.c
arch/ppc64/kernel/ptrace.c
+0
-363
No files found.
arch/powerpc/kernel/Makefile
View file @
e8a30302
...
...
@@ -10,7 +10,7 @@ CFLAGS_prom_init.o += -fPIC
CFLAGS_btext.o
+=
-fPIC
endif
obj-y
:=
semaphore.o cputable.o
obj-y
:=
semaphore.o cputable.o
ptrace.o
obj-$(CONFIG_PPC64)
+=
binfmt_elf32.o
obj-$(CONFIG_ALTIVEC)
+=
vecemu.o vector.o
obj-$(CONFIG_POWER4)
+=
idle_power4.o
...
...
arch/ppc/kernel/ptrace.c
→
arch/p
ower
pc/kernel/ptrace.c
View file @
e8a30302
/*
* arch/ppc/kernel/ptrace.c
*
* PowerPC version
* Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
*
...
...
@@ -17,6 +15,7 @@
* this archive for more details.
*/
#include <linux/config.h>
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/mm.h>
...
...
@@ -29,13 +28,19 @@
#include <linux/signal.h>
#include <linux/seccomp.h>
#include <linux/audit.h>
#ifdef CONFIG_PPC32
#include <linux/module.h>
#endif
#include <asm/uaccess.h>
#include <asm/page.h>
#include <asm/pgtable.h>
#include <asm/system.h>
#ifdef CONFIG_PPC64
#include <asm/ptrace-common.h>
#endif
#ifdef CONFIG_PPC32
/*
* Set of msr bits that gdb can change on behalf of a process.
*/
...
...
@@ -44,12 +49,14 @@
#else
#define MSR_DEBUGCHANGE (MSR_SE | MSR_BE)
#endif
#endif
/* CONFIG_PPC32 */
/*
* does not yet catch signals sent when the child dies.
* in exit.c or in signal.c.
*/
#ifdef CONFIG_PPC32
/*
* Get contents of register REGNO in task TASK.
*/
...
...
@@ -228,6 +235,7 @@ clear_single_step(struct task_struct *task)
#endif
}
}
#endif
/* CONFIG_PPC32 */
/*
* Called by kernel/ptrace.c when detaching..
...
...
@@ -296,25 +304,28 @@ int sys_ptrace(long request, long pid, long addr, long data)
}
/* read the word at location addr in the USER area. */
/* XXX this will need fixing for 64-bit */
case
PTRACE_PEEKUSR
:
{
unsigned
long
index
,
tmp
;
ret
=
-
EIO
;
/* convert to index and check */
#ifdef CONFIG_PPC32
index
=
(
unsigned
long
)
addr
>>
2
;
if
((
addr
&
3
)
||
index
>
PT_FPSCR
||
child
->
thread
.
regs
==
NULL
)
if
((
addr
&
3
)
||
(
index
>
PT_FPSCR
)
||
(
child
->
thread
.
regs
==
NULL
))
#else
index
=
(
unsigned
long
)
addr
>>
3
;
if
((
addr
&
7
)
||
(
index
>
PT_FPSCR
))
#endif
break
;
#ifdef CONFIG_PPC32
CHECK_FULL_REGS
(
child
->
thread
.
regs
);
#endif
if
(
index
<
PT_FPR0
)
{
tmp
=
get_reg
(
child
,
(
int
)
index
);
}
else
{
preempt_disable
();
if
(
child
->
thread
.
regs
->
msr
&
MSR_FP
)
giveup_fpu
(
child
);
preempt_enable
();
flush_fp_to_thread
(
child
);
tmp
=
((
unsigned
long
*
)
child
->
thread
.
fpr
)[
index
-
PT_FPR0
];
}
ret
=
put_user
(
tmp
,(
unsigned
long
__user
*
)
data
);
...
...
@@ -325,7 +336,8 @@ int sys_ptrace(long request, long pid, long addr, long data)
case
PTRACE_POKETEXT
:
/* write the word at location addr. */
case
PTRACE_POKEDATA
:
ret
=
0
;
if
(
access_process_vm
(
child
,
addr
,
&
data
,
sizeof
(
data
),
1
)
==
sizeof
(
data
))
if
(
access_process_vm
(
child
,
addr
,
&
data
,
sizeof
(
data
),
1
)
==
sizeof
(
data
))
break
;
ret
=
-
EIO
;
break
;
...
...
@@ -336,21 +348,25 @@ int sys_ptrace(long request, long pid, long addr, long data)
ret
=
-
EIO
;
/* convert to index and check */
#ifdef CONFIG_PPC32
index
=
(
unsigned
long
)
addr
>>
2
;
if
((
addr
&
3
)
||
index
>
PT_FPSCR
||
child
->
thread
.
regs
==
NULL
)
if
((
addr
&
3
)
||
(
index
>
PT_FPSCR
)
||
(
child
->
thread
.
regs
==
NULL
))
#else
index
=
(
unsigned
long
)
addr
>>
3
;
if
((
addr
&
7
)
||
(
index
>
PT_FPSCR
))
#endif
break
;
#ifdef CONFIG_PPC32
CHECK_FULL_REGS
(
child
->
thread
.
regs
);
#endif
if
(
index
==
PT_ORIG_R3
)
break
;
if
(
index
<
PT_FPR0
)
{
ret
=
put_reg
(
child
,
index
,
data
);
}
else
{
preempt_disable
();
if
(
child
->
thread
.
regs
->
msr
&
MSR_FP
)
giveup_fpu
(
child
);
preempt_enable
();
flush_fp_to_thread
(
child
);
((
unsigned
long
*
)
child
->
thread
.
fpr
)[
index
-
PT_FPR0
]
=
data
;
ret
=
0
;
}
...
...
@@ -362,11 +378,10 @@ int sys_ptrace(long request, long pid, long addr, long data)
ret
=
-
EIO
;
if
(
!
valid_signal
(
data
))
break
;
if
(
request
==
PTRACE_SYSCALL
)
{
if
(
request
==
PTRACE_SYSCALL
)
set_tsk_thread_flag
(
child
,
TIF_SYSCALL_TRACE
);
}
else
{
else
clear_tsk_thread_flag
(
child
,
TIF_SYSCALL_TRACE
);
}
child
->
exit_code
=
data
;
/* make sure the single step bit is not set. */
clear_single_step
(
child
);
...
...
@@ -404,28 +419,102 @@ int sys_ptrace(long request, long pid, long addr, long data)
break
;
}
#ifdef CONFIG_PPC64
case
PTRACE_GET_DEBUGREG
:
{
ret
=
-
EINVAL
;
/* We only support one DABR and no IABRS at the moment */
if
(
addr
>
0
)
break
;
ret
=
put_user
(
child
->
thread
.
dabr
,
(
unsigned
long
__user
*
)
data
);
break
;
}
case
PTRACE_SET_DEBUGREG
:
ret
=
ptrace_set_debugreg
(
child
,
addr
,
data
);
break
;
#endif
case
PTRACE_DETACH
:
ret
=
ptrace_detach
(
child
,
data
);
break
;
#ifdef CONFIG_PPC64
case
PPC_PTRACE_GETREGS
:
{
/* Get GPRs 0 - 31. */
int
i
;
unsigned
long
*
reg
=
&
((
unsigned
long
*
)
child
->
thread
.
regs
)[
0
];
unsigned
long
__user
*
tmp
=
(
unsigned
long
__user
*
)
addr
;
for
(
i
=
0
;
i
<
32
;
i
++
)
{
ret
=
put_user
(
*
reg
,
tmp
);
if
(
ret
)
break
;
reg
++
;
tmp
++
;
}
break
;
}
case
PPC_PTRACE_SETREGS
:
{
/* Set GPRs 0 - 31. */
int
i
;
unsigned
long
*
reg
=
&
((
unsigned
long
*
)
child
->
thread
.
regs
)[
0
];
unsigned
long
__user
*
tmp
=
(
unsigned
long
__user
*
)
addr
;
for
(
i
=
0
;
i
<
32
;
i
++
)
{
ret
=
get_user
(
*
reg
,
tmp
);
if
(
ret
)
break
;
reg
++
;
tmp
++
;
}
break
;
}
case
PPC_PTRACE_GETFPREGS
:
{
/* Get FPRs 0 - 31. */
int
i
;
unsigned
long
*
reg
=
&
((
unsigned
long
*
)
child
->
thread
.
fpr
)[
0
];
unsigned
long
__user
*
tmp
=
(
unsigned
long
__user
*
)
addr
;
flush_fp_to_thread
(
child
);
for
(
i
=
0
;
i
<
32
;
i
++
)
{
ret
=
put_user
(
*
reg
,
tmp
);
if
(
ret
)
break
;
reg
++
;
tmp
++
;
}
break
;
}
case
PPC_PTRACE_SETFPREGS
:
{
/* Get FPRs 0 - 31. */
int
i
;
unsigned
long
*
reg
=
&
((
unsigned
long
*
)
child
->
thread
.
fpr
)[
0
];
unsigned
long
__user
*
tmp
=
(
unsigned
long
__user
*
)
addr
;
flush_fp_to_thread
(
child
);
for
(
i
=
0
;
i
<
32
;
i
++
)
{
ret
=
get_user
(
*
reg
,
tmp
);
if
(
ret
)
break
;
reg
++
;
tmp
++
;
}
break
;
}
#endif
/* CONFIG_PPC64 */
#ifdef CONFIG_ALTIVEC
case
PTRACE_GETVRREGS
:
/* Get the child altivec register state. */
preempt_disable
();
if
(
child
->
thread
.
regs
->
msr
&
MSR_VEC
)
giveup_altivec
(
child
);
preempt_enable
();
flush_altivec_to_thread
(
child
);
ret
=
get_vrregs
((
unsigned
long
__user
*
)
data
,
child
);
break
;
case
PTRACE_SETVRREGS
:
/* Set the child altivec register state. */
/* this is to clear the MSR_VEC bit to force a reload
* of register state from memory */
preempt_disable
();
if
(
child
->
thread
.
regs
->
msr
&
MSR_VEC
)
giveup_altivec
(
child
);
preempt_enable
();
flush_altivec_to_thread
(
child
);
ret
=
set_vrregs
(
child
,
(
unsigned
long
__user
*
)
data
);
break
;
#endif
...
...
@@ -478,12 +567,21 @@ static void do_syscall_trace(void)
void
do_syscall_trace_enter
(
struct
pt_regs
*
regs
)
{
#ifdef CONFIG_PPC64
secure_computing
(
regs
->
gpr
[
0
]);
#endif
if
(
test_thread_flag
(
TIF_SYSCALL_TRACE
)
&&
(
current
->
ptrace
&
PT_PTRACED
))
do_syscall_trace
();
if
(
unlikely
(
current
->
audit_context
))
audit_syscall_entry
(
current
,
AUDIT_ARCH_PPC
,
audit_syscall_entry
(
current
,
#ifdef CONFIG_PPC32
AUDIT_ARCH_PPC
,
#else
test_thread_flag
(
TIF_32BIT
)
?
AUDIT_ARCH_PPC
:
AUDIT_ARCH_PPC64
,
#endif
regs
->
gpr
[
0
],
regs
->
gpr
[
3
],
regs
->
gpr
[
4
],
regs
->
gpr
[
5
],
regs
->
gpr
[
6
]);
...
...
@@ -491,17 +589,25 @@ void do_syscall_trace_enter(struct pt_regs *regs)
void
do_syscall_trace_leave
(
struct
pt_regs
*
regs
)
{
#ifdef CONFIG_PPC32
secure_computing
(
regs
->
gpr
[
0
]);
#endif
if
(
unlikely
(
current
->
audit_context
))
audit_syscall_exit
(
current
,
(
regs
->
ccr
&
0x1000
)
?
AUDITSC_FAILURE
:
AUDITSC_SUCCESS
,
regs
->
result
);
if
((
test_thread_flag
(
TIF_SYSCALL_TRACE
))
if
((
test_thread_flag
(
TIF_SYSCALL_TRACE
)
#ifdef CONFIG_PPC64
||
test_thread_flag
(
TIF_SINGLESTEP
)
#endif
)
&&
(
current
->
ptrace
&
PT_PTRACED
))
do_syscall_trace
();
}
#ifdef CONFIG_PPC32
EXPORT_SYMBOL
(
do_syscall_trace_enter
);
EXPORT_SYMBOL
(
do_syscall_trace_leave
);
#endif
arch/ppc/kernel/Makefile
View file @
e8a30302
...
...
@@ -13,7 +13,7 @@ extra-$(CONFIG_POWER4) += idle_power4.o
extra-y
+=
vmlinux.lds
obj-y
:=
entry.o traps.o irq.o idle.o time.o misc.o
\
process.o signal.o
ptrace.o
align.o
\
process.o signal.o align.o
\
syscalls.o setup.o
\
ppc_htab.o perfmon.o
obj-$(CONFIG_6xx)
+=
l2cr.o cpu_setup_6xx.o
...
...
@@ -38,7 +38,7 @@ endif
else
obj-y
:=
irq.o idle.o time.o
\
signal.o
ptrace.o
align.o
\
signal.o align.o
\
syscalls.o perfmon.o
obj-$(CONFIG_6xx)
+=
l2cr.o cpu_setup_6xx.o
obj-$(CONFIG_SOFTWARE_SUSPEND)
+=
swsusp.o
...
...
arch/ppc64/kernel/Makefile
View file @
e8a30302
...
...
@@ -12,7 +12,7 @@ obj-y := setup.o entry.o misc.o prom.o
endif
obj-y
+=
irq.o idle.o dma.o
\
time.o signal.o syscalls.o
ptrace.o
\
time.o signal.o syscalls.o
\
align.o bitops.o pacaData.o
\
udbg.o sys_ppc32.o ioctl32.o
\
ptrace32.o signal32.o rtc.o
\
...
...
arch/ppc64/kernel/ptrace.c
deleted
100644 → 0
View file @
eec5ef90
/*
* linux/arch/ppc64/kernel/ptrace.c
*
* PowerPC version
* Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
*
* Derived from "arch/m68k/kernel/ptrace.c"
* Copyright (C) 1994 by Hamish Macdonald
* Taken from linux/kernel/ptrace.c and modified for M680x0.
* linux/kernel/ptrace.c is by Ross Biro 1/23/92, edited by Linus Torvalds
*
* Modified by Cort Dougan (cort@hq.fsmlabs.com)
* and Paul Mackerras (paulus@linuxcare.com.au).
*
* This file is subject to the terms and conditions of the GNU General
* Public License. See the file README.legal in the main directory of
* this archive for more details.
*/
#include <linux/config.h>
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/mm.h>
#include <linux/smp.h>
#include <linux/smp_lock.h>
#include <linux/errno.h>
#include <linux/ptrace.h>
#include <linux/user.h>
#include <linux/security.h>
#include <linux/audit.h>
#include <linux/seccomp.h>
#include <linux/signal.h>
#include <asm/uaccess.h>
#include <asm/page.h>
#include <asm/pgtable.h>
#include <asm/system.h>
#include <asm/ptrace-common.h>
/*
* does not yet catch signals sent when the child dies.
* in exit.c or in signal.c.
*/
/*
* Called by kernel/ptrace.c when detaching..
*
* Make sure single step bits etc are not set.
*/
void
ptrace_disable
(
struct
task_struct
*
child
)
{
/* make sure the single step bit is not set. */
clear_single_step
(
child
);
}
int
sys_ptrace
(
long
request
,
long
pid
,
long
addr
,
long
data
)
{
struct
task_struct
*
child
;
int
ret
=
-
EPERM
;
lock_kernel
();
if
(
request
==
PTRACE_TRACEME
)
{
/* are we already being traced? */
if
(
current
->
ptrace
&
PT_PTRACED
)
goto
out
;
ret
=
security_ptrace
(
current
->
parent
,
current
);
if
(
ret
)
goto
out
;
/* set the ptrace bit in the process flags. */
current
->
ptrace
|=
PT_PTRACED
;
ret
=
0
;
goto
out
;
}
ret
=
-
ESRCH
;
read_lock
(
&
tasklist_lock
);
child
=
find_task_by_pid
(
pid
);
if
(
child
)
get_task_struct
(
child
);
read_unlock
(
&
tasklist_lock
);
if
(
!
child
)
goto
out
;
ret
=
-
EPERM
;
if
(
pid
==
1
)
/* you may not mess with init */
goto
out_tsk
;
if
(
request
==
PTRACE_ATTACH
)
{
ret
=
ptrace_attach
(
child
);
goto
out_tsk
;
}
ret
=
ptrace_check_attach
(
child
,
request
==
PTRACE_KILL
);
if
(
ret
<
0
)
goto
out_tsk
;
switch
(
request
)
{
/* when I and D space are separate, these will need to be fixed. */
case
PTRACE_PEEKTEXT
:
/* read word at location addr. */
case
PTRACE_PEEKDATA
:
{
unsigned
long
tmp
;
int
copied
;
copied
=
access_process_vm
(
child
,
addr
,
&
tmp
,
sizeof
(
tmp
),
0
);
ret
=
-
EIO
;
if
(
copied
!=
sizeof
(
tmp
))
break
;
ret
=
put_user
(
tmp
,(
unsigned
long
__user
*
)
data
);
break
;
}
/* read the word at location addr in the USER area. */
case
PTRACE_PEEKUSR
:
{
unsigned
long
index
;
unsigned
long
tmp
;
ret
=
-
EIO
;
/* convert to index and check */
index
=
(
unsigned
long
)
addr
>>
3
;
if
((
addr
&
7
)
||
(
index
>
PT_FPSCR
))
break
;
if
(
index
<
PT_FPR0
)
{
tmp
=
get_reg
(
child
,
(
int
)
index
);
}
else
{
flush_fp_to_thread
(
child
);
tmp
=
((
unsigned
long
*
)
child
->
thread
.
fpr
)[
index
-
PT_FPR0
];
}
ret
=
put_user
(
tmp
,(
unsigned
long
__user
*
)
data
);
break
;
}
/* If I and D space are separate, this will have to be fixed. */
case
PTRACE_POKETEXT
:
/* write the word at location addr. */
case
PTRACE_POKEDATA
:
ret
=
0
;
if
(
access_process_vm
(
child
,
addr
,
&
data
,
sizeof
(
data
),
1
)
==
sizeof
(
data
))
break
;
ret
=
-
EIO
;
break
;
/* write the word at location addr in the USER area */
case
PTRACE_POKEUSR
:
{
unsigned
long
index
;
ret
=
-
EIO
;
/* convert to index and check */
index
=
(
unsigned
long
)
addr
>>
3
;
if
((
addr
&
7
)
||
(
index
>
PT_FPSCR
))
break
;
if
(
index
==
PT_ORIG_R3
)
break
;
if
(
index
<
PT_FPR0
)
{
ret
=
put_reg
(
child
,
index
,
data
);
}
else
{
flush_fp_to_thread
(
child
);
((
unsigned
long
*
)
child
->
thread
.
fpr
)[
index
-
PT_FPR0
]
=
data
;
ret
=
0
;
}
break
;
}
case
PTRACE_SYSCALL
:
/* continue and stop at next (return from) syscall */
case
PTRACE_CONT
:
{
/* restart after signal. */
ret
=
-
EIO
;
if
(
!
valid_signal
(
data
))
break
;
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
;
/* make sure the single step bit is not set. */
clear_single_step
(
child
);
wake_up_process
(
child
);
ret
=
0
;
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
:
{
ret
=
0
;
if
(
child
->
exit_state
==
EXIT_ZOMBIE
)
/* already dead */
break
;
child
->
exit_code
=
SIGKILL
;
/* make sure the single step bit is not set. */
clear_single_step
(
child
);
wake_up_process
(
child
);
break
;
}
case
PTRACE_SINGLESTEP
:
{
/* set the trap flag. */
ret
=
-
EIO
;
if
(
!
valid_signal
(
data
))
break
;
clear_tsk_thread_flag
(
child
,
TIF_SYSCALL_TRACE
);
set_single_step
(
child
);
child
->
exit_code
=
data
;
/* give it a chance to run. */
wake_up_process
(
child
);
ret
=
0
;
break
;
}
case
PTRACE_GET_DEBUGREG
:
{
ret
=
-
EINVAL
;
/* We only support one DABR and no IABRS at the moment */
if
(
addr
>
0
)
break
;
ret
=
put_user
(
child
->
thread
.
dabr
,
(
unsigned
long
__user
*
)
data
);
break
;
}
case
PTRACE_SET_DEBUGREG
:
ret
=
ptrace_set_debugreg
(
child
,
addr
,
data
);
break
;
case
PTRACE_DETACH
:
ret
=
ptrace_detach
(
child
,
data
);
break
;
case
PPC_PTRACE_GETREGS
:
{
/* Get GPRs 0 - 31. */
int
i
;
unsigned
long
*
reg
=
&
((
unsigned
long
*
)
child
->
thread
.
regs
)[
0
];
unsigned
long
__user
*
tmp
=
(
unsigned
long
__user
*
)
addr
;
for
(
i
=
0
;
i
<
32
;
i
++
)
{
ret
=
put_user
(
*
reg
,
tmp
);
if
(
ret
)
break
;
reg
++
;
tmp
++
;
}
break
;
}
case
PPC_PTRACE_SETREGS
:
{
/* Set GPRs 0 - 31. */
int
i
;
unsigned
long
*
reg
=
&
((
unsigned
long
*
)
child
->
thread
.
regs
)[
0
];
unsigned
long
__user
*
tmp
=
(
unsigned
long
__user
*
)
addr
;
for
(
i
=
0
;
i
<
32
;
i
++
)
{
ret
=
get_user
(
*
reg
,
tmp
);
if
(
ret
)
break
;
reg
++
;
tmp
++
;
}
break
;
}
case
PPC_PTRACE_GETFPREGS
:
{
/* Get FPRs 0 - 31. */
int
i
;
unsigned
long
*
reg
=
&
((
unsigned
long
*
)
child
->
thread
.
fpr
)[
0
];
unsigned
long
__user
*
tmp
=
(
unsigned
long
__user
*
)
addr
;
flush_fp_to_thread
(
child
);
for
(
i
=
0
;
i
<
32
;
i
++
)
{
ret
=
put_user
(
*
reg
,
tmp
);
if
(
ret
)
break
;
reg
++
;
tmp
++
;
}
break
;
}
case
PPC_PTRACE_SETFPREGS
:
{
/* Get FPRs 0 - 31. */
int
i
;
unsigned
long
*
reg
=
&
((
unsigned
long
*
)
child
->
thread
.
fpr
)[
0
];
unsigned
long
__user
*
tmp
=
(
unsigned
long
__user
*
)
addr
;
flush_fp_to_thread
(
child
);
for
(
i
=
0
;
i
<
32
;
i
++
)
{
ret
=
get_user
(
*
reg
,
tmp
);
if
(
ret
)
break
;
reg
++
;
tmp
++
;
}
break
;
}
#ifdef CONFIG_ALTIVEC
case
PTRACE_GETVRREGS
:
/* Get the child altivec register state. */
flush_altivec_to_thread
(
child
);
ret
=
get_vrregs
((
unsigned
long
__user
*
)
data
,
child
);
break
;
case
PTRACE_SETVRREGS
:
/* Set the child altivec register state. */
flush_altivec_to_thread
(
child
);
ret
=
set_vrregs
(
child
,
(
unsigned
long
__user
*
)
data
);
break
;
#endif
default:
ret
=
ptrace_request
(
child
,
request
,
addr
,
data
);
break
;
}
out_tsk:
put_task_struct
(
child
);
out:
unlock_kernel
();
return
ret
;
}
static
void
do_syscall_trace
(
void
)
{
/* the 0x80 provides a way for the tracing parent to distinguish
between a syscall stop and SIGTRAP delivery */
ptrace_notify
(
SIGTRAP
|
((
current
->
ptrace
&
PT_TRACESYSGOOD
)
?
0x80
:
0
));
/*
* this isn't the same as continuing with a signal, but it will do
* for normal use. strace only continues with a signal if the
* stopping signal is not SIGTRAP. -brl
*/
if
(
current
->
exit_code
)
{
send_sig
(
current
->
exit_code
,
current
,
1
);
current
->
exit_code
=
0
;
}
}
void
do_syscall_trace_enter
(
struct
pt_regs
*
regs
)
{
secure_computing
(
regs
->
gpr
[
0
]);
if
(
test_thread_flag
(
TIF_SYSCALL_TRACE
)
&&
(
current
->
ptrace
&
PT_PTRACED
))
do_syscall_trace
();
if
(
unlikely
(
current
->
audit_context
))
audit_syscall_entry
(
current
,
test_thread_flag
(
TIF_32BIT
)
?
AUDIT_ARCH_PPC
:
AUDIT_ARCH_PPC64
,
regs
->
gpr
[
0
],
regs
->
gpr
[
3
],
regs
->
gpr
[
4
],
regs
->
gpr
[
5
],
regs
->
gpr
[
6
]);
}
void
do_syscall_trace_leave
(
struct
pt_regs
*
regs
)
{
if
(
unlikely
(
current
->
audit_context
))
audit_syscall_exit
(
current
,
(
regs
->
ccr
&
0x1000
)
?
AUDITSC_FAILURE
:
AUDITSC_SUCCESS
,
regs
->
result
);
if
((
test_thread_flag
(
TIF_SYSCALL_TRACE
)
||
test_thread_flag
(
TIF_SINGLESTEP
))
&&
(
current
->
ptrace
&
PT_PTRACED
))
do_syscall_trace
();
}
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