Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
L
linux-davinci
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Redmine
Redmine
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Metrics
Environments
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
linux
linux-davinci
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
Hide 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