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
2df556fd
Commit
2df556fd
authored
Jun 10, 2002
by
Anton Blanchard
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
ppc64: ptrace cleanup from Stephen Rothwell
parent
c1aa8ae8
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
176 additions
and
217 deletions
+176
-217
arch/ppc64/kernel/ptrace.c
arch/ppc64/kernel/ptrace.c
+24
-75
arch/ppc64/kernel/ptrace32.c
arch/ppc64/kernel/ptrace32.c
+97
-142
include/asm-ppc64/ptrace-common.h
include/asm-ppc64/ptrace-common.h
+55
-0
No files found.
arch/ppc64/kernel/ptrace.c
View file @
2df556fd
/*
/*
* linux/arch/ppc/kernel/ptrace.c
* linux/arch/ppc
64
/kernel/ptrace.c
*
*
* PowerPC version
* PowerPC version
* Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
* Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
...
@@ -30,59 +30,13 @@
...
@@ -30,59 +30,13 @@
#include <asm/page.h>
#include <asm/page.h>
#include <asm/pgtable.h>
#include <asm/pgtable.h>
#include <asm/system.h>
#include <asm/system.h>
#include <asm/ptrace-common.h>
/*
* Set of msr bits that gdb can change on behalf of a process.
*/
#define MSR_DEBUGCHANGE (MSR_FE0 | MSR_SE | MSR_BE | MSR_FE1)
/*
/*
* does not yet catch signals sent when the child dies.
* does not yet catch signals sent when the child dies.
* in exit.c or in signal.c.
* in exit.c or in signal.c.
*/
*/
/*
* Get contents of register REGNO in task TASK.
*/
static
inline
unsigned
long
get_reg
(
struct
task_struct
*
task
,
int
regno
)
{
if
(
regno
<
sizeof
(
struct
pt_regs
)
/
sizeof
(
unsigned
long
))
return
((
unsigned
long
*
)
task
->
thread
.
regs
)[
regno
];
return
(
0
);
}
/*
* Write contents of register REGNO in task TASK.
*/
static
inline
int
put_reg
(
struct
task_struct
*
task
,
int
regno
,
unsigned
long
data
)
{
if
(
regno
<
PT_SOFTE
)
{
if
(
regno
==
PT_MSR
)
data
=
(
data
&
MSR_DEBUGCHANGE
)
|
(
task
->
thread
.
regs
->
msr
&
~
MSR_DEBUGCHANGE
);
((
unsigned
long
*
)
task
->
thread
.
regs
)[
regno
]
=
data
;
return
0
;
}
return
-
EIO
;
}
static
inline
void
set_single_step
(
struct
task_struct
*
task
)
{
struct
pt_regs
*
regs
=
task
->
thread
.
regs
;
if
(
regs
!=
NULL
)
regs
->
msr
|=
MSR_SE
;
}
static
inline
void
clear_single_step
(
struct
task_struct
*
task
)
{
struct
pt_regs
*
regs
=
task
->
thread
.
regs
;
if
(
regs
!=
NULL
)
regs
->
msr
&=
~
MSR_SE
;
}
/*
/*
* Called by kernel/ptrace.c when detaching..
* Called by kernel/ptrace.c when detaching..
*
*
...
@@ -148,16 +102,17 @@ int sys_ptrace(long request, long pid, long addr, long data)
...
@@ -148,16 +102,17 @@ int sys_ptrace(long request, long pid, long addr, long data)
/* read the word at location addr in the USER area. */
/* read the word at location addr in the USER area. */
case
PTRACE_PEEKUSR
:
{
case
PTRACE_PEEKUSR
:
{
unsigned
long
index
,
tmp
;
unsigned
long
index
;
unsigned
long
tmp
;
ret
=
-
EIO
;
ret
=
-
EIO
;
/* convert to index and check */
/* convert to index and check */
index
=
(
unsigned
long
)
addr
>>
3
;
index
=
(
unsigned
long
)
addr
>>
3
;
if
((
addr
&
7
)
||
index
>
PT_FPSCR
)
if
((
addr
&
7
)
||
(
index
>
PT_FPSCR
)
)
break
;
break
;
if
(
index
<
PT_FPR0
)
{
if
(
index
<
PT_FPR0
)
{
tmp
=
get_reg
(
child
,
(
int
)
index
);
tmp
=
get_reg
(
child
,
(
int
)
index
);
}
else
{
}
else
{
if
(
child
->
thread
.
regs
->
msr
&
MSR_FP
)
if
(
child
->
thread
.
regs
->
msr
&
MSR_FP
)
giveup_fpu
(
child
);
giveup_fpu
(
child
);
...
@@ -171,7 +126,8 @@ int sys_ptrace(long request, long pid, long addr, long data)
...
@@ -171,7 +126,8 @@ int sys_ptrace(long request, long pid, long addr, long data)
case
PTRACE_POKETEXT
:
/* write the word at location addr. */
case
PTRACE_POKETEXT
:
/* write the word at location addr. */
case
PTRACE_POKEDATA
:
case
PTRACE_POKEDATA
:
ret
=
0
;
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
;
break
;
ret
=
-
EIO
;
ret
=
-
EIO
;
break
;
break
;
...
@@ -183,7 +139,7 @@ int sys_ptrace(long request, long pid, long addr, long data)
...
@@ -183,7 +139,7 @@ int sys_ptrace(long request, long pid, long addr, long data)
ret
=
-
EIO
;
ret
=
-
EIO
;
/* convert to index and check */
/* convert to index and check */
index
=
(
unsigned
long
)
addr
>>
3
;
index
=
(
unsigned
long
)
addr
>>
3
;
if
((
addr
&
7
)
||
index
>
PT_FPSCR
)
if
((
addr
&
7
)
||
(
index
>
PT_FPSCR
)
)
break
;
break
;
if
(
index
==
PT_ORIG_R3
)
if
(
index
==
PT_ORIG_R3
)
...
@@ -216,11 +172,11 @@ int sys_ptrace(long request, long pid, long addr, long data)
...
@@ -216,11 +172,11 @@ int sys_ptrace(long request, long pid, long addr, long data)
break
;
break
;
}
}
/*
/*
* make the child exit. Best I can do is send it a sigkill.
* 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
* perhaps it should be put in the status that it wants to
* exit.
* exit.
*/
*/
case
PTRACE_KILL
:
{
case
PTRACE_KILL
:
{
ret
=
0
;
ret
=
0
;
if
(
child
->
state
==
TASK_ZOMBIE
)
/* already dead */
if
(
child
->
state
==
TASK_ZOMBIE
)
/* already dead */
...
@@ -249,56 +205,50 @@ int sys_ptrace(long request, long pid, long addr, long data)
...
@@ -249,56 +205,50 @@ int sys_ptrace(long request, long pid, long addr, long data)
ret
=
ptrace_detach
(
child
,
data
);
ret
=
ptrace_detach
(
child
,
data
);
break
;
break
;
case
PPC_PTRACE_GETREGS
:
case
PPC_PTRACE_GETREGS
:
{
/* Get GPRs 0 - 31. */
{
/* Get GPRs 0 - 31. */
u64
tmp
;
u64
tmp
;
u64
cntr
;
u64
cntr
;
ret
=
0
;
ret
=
0
;
for
(
cntr
=
0
;
cntr
<
32
&&
ret
==
0
;
++
cntr
)
for
(
cntr
=
0
;
cntr
<
32
&&
ret
==
0
;
++
cntr
)
{
{
tmp
=
((
u64
*
)
child
->
thread
.
regs
)[
cntr
];
tmp
=
((
u64
*
)
child
->
thread
.
regs
)[
cntr
];
ret
=
put_user
(
tmp
,
(
u64
*
)(
data
+
cntr
));
ret
=
put_user
(
tmp
,
(
u64
*
)(
data
+
cntr
));
}
}
break
;
break
;
}
}
case
PPC_PTRACE_SETREGS
:
case
PPC_PTRACE_SETREGS
:
{
/* Set GPRs 0 - 31. */
{
/* Set GPRs 0 - 31. */
u64
cntr
;
u64
cntr
;
ret
=
0
;
ret
=
0
;
for
(
cntr
=
0
;
cntr
<
32
&&
ret
==
0
;
++
cntr
)
for
(
cntr
=
0
;
cntr
<
32
&&
ret
==
0
;
++
cntr
)
{
ret
=
put_reg
(
child
,
cntr
,
*
(
u64
*
)(
data
+
cntr
));
ret
=
put_reg
(
child
,
cntr
,
*
(
u64
*
)(
data
+
cntr
));
}
break
;
break
;
}
}
case
PPC_PTRACE_GETFPREGS
:
case
PPC_PTRACE_GETFPREGS
:
{
/* Get FPRs 0 - 31. */
{
/* Get FPRs 0 - 31. */
u64
tmp
;
u64
tmp
;
u64
cntr
;
u64
cntr
;
ret
=
-
EIO
;
ret
=
-
EIO
;
if
(
child
->
thread
.
regs
->
msr
&
MSR_FP
)
if
(
child
->
thread
.
regs
->
msr
&
MSR_FP
)
giveup_fpu
(
child
);
giveup_fpu
(
child
);
ret
=
0
;
ret
=
0
;
for
(
cntr
=
0
;
cntr
<
32
&&
ret
==
0
;
++
cntr
)
for
(
cntr
=
0
;
cntr
<
32
&&
ret
==
0
;
++
cntr
)
{
{
tmp
=
((
u64
*
)
child
->
thread
.
fpr
)[
cntr
];
tmp
=
((
u64
*
)
child
->
thread
.
fpr
)[
cntr
];
ret
=
put_user
(
tmp
,
(
u64
*
)(
data
+
cntr
));
ret
=
put_user
(
tmp
,
(
u64
*
)(
data
+
cntr
));
}
}
break
;
break
;
}
}
case
PPC_PTRACE_SETFPREGS
:
case
PPC_PTRACE_SETFPREGS
:
{
/* Get FPRs 0 - 31. */
{
/* Get FPRs 0 - 31. */
u64
cntr
;
u64
cntr
;
ret
=
-
EIO
;
ret
=
-
EIO
;
if
(
child
->
thread
.
regs
->
msr
&
MSR_FP
)
if
(
child
->
thread
.
regs
->
msr
&
MSR_FP
)
giveup_fpu
(
child
);
giveup_fpu
(
child
);
for
(
cntr
=
0
;
cntr
<
32
;
++
cntr
)
for
(
cntr
=
0
;
cntr
<
32
;
++
cntr
)
{
((
u64
*
)
child
->
thread
.
fpr
)[
cntr
]
=
*
(
u64
*
)(
data
+
cntr
);
((
u64
*
)
child
->
thread
.
fpr
)[
cntr
]
=
*
(
u64
*
)(
data
+
cntr
);
}
ret
=
0
;
ret
=
0
;
break
;
break
;
}
}
...
@@ -334,4 +284,3 @@ void do_syscall_trace(void)
...
@@ -334,4 +284,3 @@ void do_syscall_trace(void)
current
->
exit_code
=
0
;
current
->
exit_code
=
0
;
}
}
}
}
arch/ppc64/kernel/ptrace32.c
View file @
2df556fd
/*
/*
* linux/arch/ppc/kernel/ptrace32.c
* linux/arch/ppc
64
/kernel/ptrace32.c
*
*
* PowerPC version
* PowerPC version
* Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
* Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
...
@@ -30,64 +30,18 @@
...
@@ -30,64 +30,18 @@
#include <asm/page.h>
#include <asm/page.h>
#include <asm/pgtable.h>
#include <asm/pgtable.h>
#include <asm/system.h>
#include <asm/system.h>
#include <asm/ptrace-common.h>
/*
* Set of msr bits that gdb can change on behalf of a process.
*/
#define MSR_DEBUGCHANGE (MSR_FE0 | MSR_SE | MSR_BE | MSR_FE1)
/*
/*
* does not yet catch signals sent when the child dies.
* does not yet catch signals sent when the child dies.
* in exit.c or in signal.c.
* in exit.c or in signal.c.
*/
*/
/*
* Get contents of register REGNO in task TASK.
*/
static
inline
unsigned
long
get_reg
(
struct
task_struct
*
task
,
int
regno
)
{
if
(
regno
<
sizeof
(
struct
pt_regs
)
/
sizeof
(
unsigned
long
))
return
((
unsigned
long
*
)
task
->
thread
.
regs
)[
regno
];
return
(
0
);
}
/*
* Write contents of register REGNO in task TASK.
* (Put DATA into task TASK's register REGNO.)
*/
static
inline
int
put_reg
(
struct
task_struct
*
task
,
int
regno
,
unsigned
long
data
)
{
if
(
regno
<
PT_SOFTE
)
{
if
(
regno
==
PT_MSR
)
data
=
(
data
&
MSR_DEBUGCHANGE
)
|
(
task
->
thread
.
regs
->
msr
&
~
MSR_DEBUGCHANGE
);
((
unsigned
long
*
)
task
->
thread
.
regs
)[
regno
]
=
data
;
return
0
;
}
return
-
EIO
;
}
static
inline
void
set_single_step
(
struct
task_struct
*
task
)
{
struct
pt_regs
*
regs
=
task
->
thread
.
regs
;
if
(
regs
!=
NULL
)
regs
->
msr
|=
MSR_SE
;
}
static
inline
void
clear_single_step
(
struct
task_struct
*
task
)
{
struct
pt_regs
*
regs
=
task
->
thread
.
regs
;
if
(
regs
!=
NULL
)
regs
->
msr
&=
~
MSR_SE
;
}
int
sys32_ptrace
(
long
request
,
long
pid
,
unsigned
long
addr
,
unsigned
long
data
)
int
sys32_ptrace
(
long
request
,
long
pid
,
unsigned
long
addr
,
unsigned
long
data
)
{
{
struct
task_struct
*
child
;
struct
task_struct
*
child
;
int
ret
=
-
EPERM
;
int
ret
=
-
EPERM
;
lock_kernel
();
lock_kernel
();
if
(
request
==
PTRACE_TRACEME
)
{
if
(
request
==
PTRACE_TRACEME
)
{
/* are we already being traced? */
/* are we already being traced? */
...
@@ -120,92 +74,95 @@ int sys32_ptrace(long request, long pid, unsigned long addr, unsigned long data)
...
@@ -120,92 +74,95 @@ int sys32_ptrace(long request, long pid, unsigned long addr, unsigned long data)
if
(
ret
<
0
)
if
(
ret
<
0
)
goto
out_tsk
;
goto
out_tsk
;
switch
(
request
)
switch
(
request
)
{
{
/* Read word at location ADDR */
/* when I and D space are separate, these will need to be fixed. */
/* when I and D space are separate, these will need to be fixed. */
case
PTRACE_PEEKTEXT
:
/* read word at location addr. */
case
PTRACE_PEEKTEXT
:
/* read word at location addr. */
case
PTRACE_PEEKDATA
:
case
PTRACE_PEEKDATA
:
{
{
unsigned
int
tmp
;
unsigned
int
tmp_mem_value
;
int
copied
;
int
copied
;
copied
=
access_process_vm
(
child
,
addr
,
&
tmp
_mem_value
,
sizeof
(
tmp_mem_value
),
0
);
copied
=
access_process_vm
(
child
,
addr
,
&
tmp
,
sizeof
(
tmp
),
0
);
ret
=
-
EIO
;
ret
=
-
EIO
;
if
(
copied
!=
sizeof
(
tmp
_mem_value
))
if
(
copied
!=
sizeof
(
tmp
))
break
;
break
;
ret
=
put_user
(
tmp
_mem_value
,
(
u32
*
)
data
);
// copy 4 bytes of data into the user location specified by the 8 byte pointer in "data".
ret
=
put_user
(
tmp
,
(
u32
*
)
data
);
break
;
break
;
}
}
/* Read 4 bytes of the other process' storage */
/*
/* data is a pointer specifying where the user wants the 4 bytes copied into */
* Read 4 bytes of the other process' storage
/* addr is a pointer in the user's storage that contains an 8 byte address in the other process of the 4 bytes that is to be read */
* data is a pointer specifying where the user wants the
/* (this is run in a 32-bit process looking at a 64-bit process) */
* 4 bytes copied into
/* when I and D space are separate, these will need to be fixed. */
* addr is a pointer in the user's storage that contains an 8 byte
* address in the other process of the 4 bytes that is to be read
* (this is run in a 32-bit process looking at a 64-bit process)
* when I and D space are separate, these will need to be fixed.
*/
case
PPC_PTRACE_PEEKTEXT_3264
:
case
PPC_PTRACE_PEEKTEXT_3264
:
case
PPC_PTRACE_PEEKDATA_3264
:
case
PPC_PTRACE_PEEKDATA_3264
:
{
{
u32
tmp
;
u32
tmp_mem_value
;
int
copied
;
int
copied
;
u32
*
addrOthers
;
u32
*
addrOthers
;
ret
=
-
EIO
;
ret
=
-
EIO
;
/* Get the addr in the other process that we want to read */
/* Get the addr in the other process that we want to read */
if
(
get_user
(
addrOthers
,(
u32
**
)
addr
)
!=
0
)
if
(
get_user
(
addrOthers
,
(
u32
**
)
addr
)
!=
0
)
break
;
break
;
copied
=
access_process_vm
(
child
,
(
u64
)
addrOthers
,
&
tmp_mem_value
,
sizeof
(
tmp_mem_value
),
0
);
copied
=
access_process_vm
(
child
,
(
u64
)
addrOthers
,
&
tmp
,
if
(
copied
!=
sizeof
(
tmp_mem_value
))
sizeof
(
tmp
),
0
);
if
(
copied
!=
sizeof
(
tmp
))
break
;
break
;
ret
=
put_user
(
tmp
_mem_value
,
(
u32
*
)
data
);
// copy 4 bytes of data into the user location specified by the 8 byte pointer in "data".
ret
=
put_user
(
tmp
,
(
u32
*
)
data
);
break
;
break
;
}
}
/* Read a register (specified by ADDR) out of the "user area" */
/* Read a register (specified by ADDR) out of the "user area" */
case
PTRACE_PEEKUSR
:
{
case
PTRACE_PEEKUSR
:
{
int
index
;
int
index
;
unsigned
int
reg32bits
;
unsigned
long
tmp
;
unsigned
long
tmp_reg_value
;
ret
=
-
EIO
;
ret
=
-
EIO
;
/* convert to index and check */
/* convert to index and check */
index
=
(
unsigned
long
)
addr
>>
2
;
index
=
(
unsigned
long
)
addr
>>
2
;
if
((
addr
&
3
)
||
index
>
PT_FPSCR32
)
if
((
addr
&
3
)
||
(
index
>
PT_FPSCR32
)
)
break
;
break
;
if
(
index
<
PT_FPR0
)
{
if
(
index
<
PT_FPR0
)
{
tmp
_reg_value
=
get_reg
(
child
,
index
);
tmp
=
get_reg
(
child
,
index
);
}
else
{
}
else
{
if
(
child
->
thread
.
regs
->
msr
&
MSR_FP
)
if
(
child
->
thread
.
regs
->
msr
&
MSR_FP
)
giveup_fpu
(
child
);
giveup_fpu
(
child
);
/* the user space code considers the floating point to be
/*
* an array of unsigned int (32 bits) - the index passed
* the user space code considers the floating point
* in is based on this assumption.
* to be an array of unsigned int (32 bits) - the
* index passed in is based on this assumption.
*/
*/
tmp
_reg_value
=
((
unsigned
int
*
)
child
->
thread
.
fpr
)[
index
-
PT_FPR0
];
tmp
=
((
unsigned
int
*
)
child
->
thread
.
fpr
)[
index
-
PT_FPR0
];
}
}
reg32bits
=
tmp_reg_value
;
ret
=
put_user
((
unsigned
int
)
tmp
,
(
u32
*
)
data
);
ret
=
put_user
(
reg32bits
,
(
u32
*
)
data
);
// copy 4 bytes of data into the user location specified by the 8 byte pointer in "data".
break
;
break
;
}
}
/* Read 4 bytes out of the other process' pt_regs area */
/*
/* data is a pointer specifying where the user wants the 4 bytes copied into */
* Read 4 bytes out of the other process' pt_regs area
/* addr is the offset into the other process' pt_regs structure that is to be read */
* data is a pointer specifying where the user wants the
/* (this is run in a 32-bit process looking at a 64-bit process) */
* 4 bytes copied into
case
PPC_PTRACE_PEEKUSR_3264
:
* addr is the offset into the other process' pt_regs structure
{
* that is to be read
* (this is run in a 32-bit process looking at a 64-bit process)
*/
case
PPC_PTRACE_PEEKUSR_3264
:
{
u32
index
;
u32
index
;
u32
reg32bits
;
u32
reg32bits
;
u64
tmp
_reg_value
;
u64
tmp
;
u32
numReg
;
u32
numReg
;
u32
part
;
u32
part
;
ret
=
-
EIO
;
ret
=
-
EIO
;
/* Determine which register the user wants */
/* Determine which register the user wants */
index
=
(
u64
)
addr
>>
2
;
/* Divide addr by 4 */
index
=
(
u64
)
addr
>>
2
;
numReg
=
index
/
2
;
numReg
=
index
/
2
;
/* Determine which part of the register the user wants */
/* Determine which part of the register the user wants */
if
(
index
%
2
)
if
(
index
%
2
)
...
@@ -217,117 +174,115 @@ int sys32_ptrace(long request, long pid, unsigned long addr, unsigned long data)
...
@@ -217,117 +174,115 @@ int sys32_ptrace(long request, long pid, unsigned long addr, unsigned long data)
if
((
addr
&
3
)
||
numReg
>
PT_FPSCR
)
if
((
addr
&
3
)
||
numReg
>
PT_FPSCR
)
break
;
break
;
if
(
numReg
>=
PT_FPR0
)
if
(
numReg
>=
PT_FPR0
)
{
{
if
(
child
->
thread
.
regs
->
msr
&
MSR_FP
)
if
(
child
->
thread
.
regs
->
msr
&
MSR_FP
)
giveup_fpu
(
child
);
giveup_fpu
(
child
);
}
}
tmp
_reg_value
=
get_reg
(
child
,
numReg
);
tmp
=
get_reg
(
child
,
numReg
);
reg32bits
=
((
u32
*
)
&
tmp
_reg_value
)[
part
];
reg32bits
=
((
u32
*
)
&
tmp
)[
part
];
ret
=
put_user
(
reg32bits
,
(
u32
*
)
data
);
/* copy 4 bytes of data into the user location specified by the 8 byte pointer in "data". */
ret
=
put_user
(
reg32bits
,
(
u32
*
)
data
);
break
;
break
;
}
}
/* Write the word at location ADDR */
/* If I and D space are separate, this will have to be fixed. */
/* If I and D space are separate, this will have to be fixed. */
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
int
tmp
_value_to_write
;
unsigned
int
tmp
;
tmp
_value_to_write
=
data
;
tmp
=
data
;
ret
=
0
;
ret
=
0
;
if
(
access_process_vm
(
child
,
addr
,
&
tmp_value_to_write
,
sizeof
(
tmp_value_to_write
),
1
)
==
sizeof
(
tmp_value_to_write
))
if
(
access_process_vm
(
child
,
addr
,
&
tmp
,
sizeof
(
tmp
),
1
)
==
sizeof
(
tmp
))
break
;
break
;
ret
=
-
EIO
;
ret
=
-
EIO
;
break
;
break
;
}
}
/* Write 4 bytes into the other process' storage */
/*
/* data is the 4 bytes that the user wants written */
* Write 4 bytes into the other process' storage
/* addr is a pointer in the user's storage that contains an 8 byte address in the other process where the 4 bytes that is to be written */
* data is the 4 bytes that the user wants written
/* (this is run in a 32-bit process looking at a 64-bit process) */
* addr is a pointer in the user's storage that contains an
/* when I and D space are separate, these will need to be fixed. */
* 8 byte address in the other process where the 4 bytes
* that is to be written
* (this is run in a 32-bit process looking at a 64-bit process)
* when I and D space are separate, these will need to be fixed.
*/
case
PPC_PTRACE_POKETEXT_3264
:
case
PPC_PTRACE_POKETEXT_3264
:
case
PPC_PTRACE_POKEDATA_3264
:
case
PPC_PTRACE_POKEDATA_3264
:
{
{
u32
tmp
=
data
;
u32
tmp_value_to_write
=
data
;
u32
*
addrOthers
;
u32
*
addrOthers
;
int
bytesWritten
;
/* Get the addr in the other process that we want to write into */
/* Get the addr in the other process that we want to write into */
ret
=
-
EIO
;
ret
=
-
EIO
;
if
(
get_user
(
addrOthers
,(
u32
**
)
addr
)
!=
0
)
if
(
get_user
(
addrOthers
,
(
u32
**
)
addr
)
!=
0
)
break
;
break
;
ret
=
0
;
ret
=
0
;
bytesWritten
=
access_process_vm
(
child
,
(
u64
)
addrOthers
,
&
tmp_value_to_write
,
sizeof
(
tmp_value_to_write
),
1
);
if
(
access_process_vm
(
child
,
(
u64
)
addrOthers
,
&
tmp
,
if
(
bytesWritten
==
sizeof
(
tmp_value_to_write
))
sizeof
(
tmp
),
1
)
==
sizeof
(
tmp
))
break
;
break
;
ret
=
-
EIO
;
ret
=
-
EIO
;
break
;
break
;
}
}
/*
Write DATA into location ADDR within the USER area
*/
/*
write the word at location addr in the USER area
*/
case
PTRACE_POKEUSR
:
{
case
PTRACE_POKEUSR
:
{
unsigned
long
index
;
unsigned
long
index
;
ret
=
-
EIO
;
ret
=
-
EIO
;
/* convert to index and check */
/* convert to index and check */
index
=
(
unsigned
long
)
addr
>>
2
;
index
=
(
unsigned
long
)
addr
>>
2
;
if
((
addr
&
3
)
||
index
>
PT_FPSCR32
)
if
((
addr
&
3
)
||
(
index
>
PT_FPSCR32
)
)
break
;
break
;
if
(
index
==
PT_ORIG_R3
)
if
(
index
==
PT_ORIG_R3
)
break
;
break
;
if
(
index
<
PT_FPR0
)
{
if
(
index
<
PT_FPR0
)
{
ret
=
put_reg
(
child
,
index
,
data
);
ret
=
put_reg
(
child
,
index
,
data
);
}
else
{
}
else
{
if
(
child
->
thread
.
regs
->
msr
&
MSR_FP
)
if
(
child
->
thread
.
regs
->
msr
&
MSR_FP
)
giveup_fpu
(
child
);
giveup_fpu
(
child
);
/* the user space code considers the floating point to be
/*
* an array of unsigned int (32 bits) - the index passed
* the user space code considers the floating point
* in is based on this assumption.
* to be an array of unsigned int (32 bits) - the
*/
* index passed in is based on this assumption.
*/
((
unsigned
int
*
)
child
->
thread
.
fpr
)[
index
-
PT_FPR0
]
=
data
;
((
unsigned
int
*
)
child
->
thread
.
fpr
)[
index
-
PT_FPR0
]
=
data
;
ret
=
0
;
ret
=
0
;
}
}
break
;
break
;
}
}
/* Write 4 bytes into the other process' pt_regs area */
/*
/* data is the 4 bytes that the user wants written */
* Write 4 bytes into the other process' pt_regs area
/* addr is the offset into the other process' pt_regs structure that is to be written into */
* data is the 4 bytes that the user wants written
/* (this is run in a 32-bit process looking at a 64-bit process) */
* addr is the offset into the other process' pt_regs structure
case
PPC_PTRACE_POKEUSR_3264
:
* that is to be written into
{
* (this is run in a 32-bit process looking at a 64-bit process)
*/
case
PPC_PTRACE_POKEUSR_3264
:
{
u32
index
;
u32
index
;
u32
numReg
;
u32
numReg
;
ret
=
-
EIO
;
ret
=
-
EIO
;
/* Determine which register the user wants */
/* Determine which register the user wants */
index
=
(
u64
)
addr
>>
2
;
/* Divide addr by 4 */
index
=
(
u64
)
addr
>>
2
;
numReg
=
index
/
2
;
numReg
=
index
/
2
;
/*
/* Validate the input - check to see if address is on the wrong boundary or beyond the end of the user area */
* Validate the input - check to see if address is on the
if
((
addr
&
3
)
||
numReg
>
PT_FPSCR
)
* wrong boundary or beyond the end of the user area
*/
if
((
addr
&
3
)
||
(
numReg
>
PT_FPSCR
))
break
;
break
;
/* Insure it is a register we let them change */
/* Insure it is a register we let them change */
if
((
numReg
==
PT_ORIG_R3
)
||
((
numReg
>
PT_CCR
)
&&
(
numReg
<
PT_FPR0
)))
if
((
numReg
==
PT_ORIG_R3
)
||
((
numReg
>
PT_CCR
)
&&
(
numReg
<
PT_FPR0
)))
break
;
break
;
if
(
numReg
>=
PT_FPR0
)
{
if
(
numReg
>=
PT_FPR0
)
{
if
(
child
->
thread
.
regs
->
msr
&
MSR_FP
)
if
(
child
->
thread
.
regs
->
msr
&
MSR_FP
)
giveup_fpu
(
child
);
giveup_fpu
(
child
);
}
}
if
(
numReg
==
PT_MSR
)
if
(
numReg
==
PT_MSR
)
data
=
(
data
&
MSR_DEBUGCHANGE
)
|
(
child
->
thread
.
regs
->
msr
&
~
MSR_DEBUGCHANGE
);
data
=
(
data
&
MSR_DEBUGCHANGE
)
|
(
child
->
thread
.
regs
->
msr
&
~
MSR_DEBUGCHANGE
);
((
u32
*
)
child
->
thread
.
regs
)[
index
]
=
data
;
((
u32
*
)
child
->
thread
.
regs
)[
index
]
=
data
;
ret
=
0
;
ret
=
0
;
break
;
break
;
...
@@ -351,8 +306,8 @@ int sys32_ptrace(long request, long pid, unsigned long addr, unsigned long data)
...
@@ -351,8 +306,8 @@ int sys32_ptrace(long request, long pid, unsigned long addr, unsigned long data)
}
}
/*
/*
* make the child exit. Best I can do is send it a sigkill.
* 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
* perhaps it should be put in the status that it wants to
* exit.
* exit.
*/
*/
case
PTRACE_KILL
:
{
case
PTRACE_KILL
:
{
...
...
include/asm-ppc64/ptrace-common.h
0 → 100644
View file @
2df556fd
/*
* linux/arch/ppc64/kernel/ptrace-common.h
*
* Copyright (c) 2002 Stephen Rothwell, IBM Coproration
* Extracted from ptrace.c and ptrace32.c
*
* 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.
*/
/*
* Set of msr bits that gdb can change on behalf of a process.
*/
#define MSR_DEBUGCHANGE (MSR_FE0 | MSR_SE | MSR_BE | MSR_FE1)
/*
* Get contents of register REGNO in task TASK.
*/
static
inline
unsigned
long
get_reg
(
struct
task_struct
*
task
,
int
regno
)
{
if
(
regno
<
(
sizeof
(
struct
pt_regs
)
/
sizeof
(
unsigned
long
)))
return
((
unsigned
long
*
)
task
->
thread
.
regs
)[
regno
];
return
0
;
}
/*
* Write contents of register REGNO in task TASK.
*/
static
inline
int
put_reg
(
struct
task_struct
*
task
,
int
regno
,
unsigned
long
data
)
{
if
(
regno
<
PT_SOFTE
)
{
if
(
regno
==
PT_MSR
)
data
=
(
data
&
MSR_DEBUGCHANGE
)
|
(
task
->
thread
.
regs
->
msr
&
~
MSR_DEBUGCHANGE
);
((
unsigned
long
*
)
task
->
thread
.
regs
)[
regno
]
=
data
;
return
0
;
}
return
-
EIO
;
}
static
inline
void
set_single_step
(
struct
task_struct
*
task
)
{
struct
pt_regs
*
regs
=
task
->
thread
.
regs
;
if
(
regs
!=
NULL
)
regs
->
msr
|=
MSR_SE
;
}
static
inline
void
clear_single_step
(
struct
task_struct
*
task
)
{
struct
pt_regs
*
regs
=
task
->
thread
.
regs
;
if
(
regs
!=
NULL
)
regs
->
msr
&=
~
MSR_SE
;
}
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