git://git.onelab.eu
/
linux-2.6.git
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
fedora core 6 1.2949 + vserver 2.2.0
[linux-2.6.git]
/
arch
/
x86_64
/
kernel
/
ptrace.c
diff --git
a/arch/x86_64/kernel/ptrace.c
b/arch/x86_64/kernel/ptrace.c
index
280bc88
..
57bf883
100644
(file)
--- a/
arch/x86_64/kernel/ptrace.c
+++ b/
arch/x86_64/kernel/ptrace.c
@@
-119,17
+119,17
@@
unsigned long convert_rip_to_linear(struct task_struct *child, struct pt_regs *r
return addr;
}
return addr;
}
-static int is_
at_popf
(struct task_struct *child, struct pt_regs *regs)
+static int is_
setting_trap_flag
(struct task_struct *child, struct pt_regs *regs)
{
int i, copied;
{
int i, copied;
- unsigned char opcode[1
6
];
+ unsigned char opcode[1
5
];
unsigned long addr = convert_rip_to_linear(child, regs);
copied = access_process_vm(child, addr, opcode, sizeof(opcode), 0);
for (i = 0; i < copied; i++) {
switch (opcode[i]) {
unsigned long addr = convert_rip_to_linear(child, regs);
copied = access_process_vm(child, addr, opcode, sizeof(opcode), 0);
for (i = 0; i < copied; i++) {
switch (opcode[i]) {
- /* popf */
- case 0x9d:
+ /* popf
and iret
*/
+ case 0x9d:
case 0xcf:
return 1;
/* CHECKME: 64 65 */
return 1;
/* CHECKME: 64 65 */
@@
-141,14
+141,17
@@
static int is_at_popf(struct task_struct *child, struct pt_regs *regs)
case 0x26: case 0x2e:
case 0x36: case 0x3e:
case 0x64: case 0x65:
case 0x26: case 0x2e:
case 0x36: case 0x3e:
case 0x64: case 0x65:
- case 0xf
0: case 0xf
2: case 0xf3:
+ case 0xf2: case 0xf3:
continue;
continue;
- /* REX prefixes */
case 0x40 ... 0x4f:
case 0x40 ... 0x4f:
+ if (regs->cs != __USER_CS)
+ /* 32-bit mode: register increment */
+ return 0;
+ /* 64-bit mode: REX prefix */
continue;
continue;
- /* CHECKME: f
0, f
2, f3 */
+ /* CHECKME: f2, f3 */
/*
* pushf: NOTE! We should probably not let
/*
* pushf: NOTE! We should probably not let
@@
-189,10
+192,8
@@
void tracehook_enable_single_step(struct task_struct *child)
* ..but if TF is changed by the instruction we will trace,
* don't mark it as being "us" that set it, so that we
* won't clear it by hand later.
* ..but if TF is changed by the instruction we will trace,
* don't mark it as being "us" that set it, so that we
* won't clear it by hand later.
- *
- * AK: this is not enough, LAHF and IRET can change TF in user space too.
*/
*/
- if (is_
at_popf
(child, regs))
+ if (is_
setting_trap_flag
(child, regs))
return;
set_tsk_thread_flag(child, TIF_FORCED_TF);
return;
set_tsk_thread_flag(child, TIF_FORCED_TF);
@@
-424,6
+425,7
@@
dbregs_set(struct task_struct *target,
unsigned int pos, unsigned int count,
const void *kbuf, const void __user *ubuf)
{
unsigned int pos, unsigned int count,
const void *kbuf, const void __user *ubuf)
{
+
unsigned long maxaddr = TASK_SIZE_OF(target);
maxaddr -= test_tsk_thread_flag(target, TIF_IA32) ? 3 : 7;
unsigned long maxaddr = TASK_SIZE_OF(target);
maxaddr -= test_tsk_thread_flag(target, TIF_IA32) ? 3 : 7;
@@
-487,6
+489,10
@@
dbregs_set(struct task_struct *target,
if ((0x5554 >> ((val >> (16 + 4*i)) & 0xf))
& 1)
return -EIO;
if ((0x5554 >> ((val >> (16 + 4*i)) & 0xf))
& 1)
return -EIO;
+ if (val)
+ set_tsk_thread_flag(target, TIF_DEBUG);
+ else
+ clear_tsk_thread_flag(target, TIF_DEBUG);
SET_DBREG(7);
break;
#undef SET_DBREG
SET_DBREG(7);
break;
#undef SET_DBREG
@@
-512,7
+518,7
@@
fpregs_get(struct task_struct *target,
if (tsk_used_math(target)) {
if (target == current)
unlazy_fpu(target);
if (tsk_used_math(target)) {
if (target == current)
unlazy_fpu(target);
- }
+ }
else
init_fpu(target);
else
init_fpu(target);
@@
-669,8
+675,7
@@
static const struct utrace_regset native_regsets[] = {
const struct utrace_regset_view utrace_x86_64_native = {
.name = "x86-64", .e_machine = EM_X86_64,
const struct utrace_regset_view utrace_x86_64_native = {
.name = "x86-64", .e_machine = EM_X86_64,
- .regsets = native_regsets,
- .n = sizeof native_regsets / sizeof native_regsets[0],
+ .regsets = native_regsets, .n = ARRAY_SIZE(native_regsets)
};
EXPORT_SYMBOL_GPL(utrace_x86_64_native);
};
EXPORT_SYMBOL_GPL(utrace_x86_64_native);
@@
-678,16
+683,16
@@
EXPORT_SYMBOL_GPL(utrace_x86_64_native);
#ifdef CONFIG_PTRACE
static const struct ptrace_layout_segment x86_64_uarea[] = {
{0, sizeof(struct user_regs_struct), 0, 0},
#ifdef CONFIG_PTRACE
static const struct ptrace_layout_segment x86_64_uarea[] = {
{0, sizeof(struct user_regs_struct), 0, 0},
+ {sizeof(struct user_regs_struct),
+ offsetof(struct user, u_debugreg[0]), -1, 0},
{offsetof(struct user, u_debugreg[0]),
{offsetof(struct user, u_debugreg[0]),
- offsetof(struct user, u_debugreg[4]), 3, 0},
- {offsetof(struct user, u_debugreg[6]),
- offsetof(struct user, u_debugreg[8]), 3, 6 * sizeof(long)},
+ offsetof(struct user, u_debugreg[8]), 3, 0},
{0, 0, -1, 0}
};
{0, 0, -1, 0}
};
-
fastcall
int arch_ptrace(long *req, struct task_struct *child,
-
struct utrace_attached_engine *engine,
-
unsigned long addr, unsigned long data, long *val)
+int arch_ptrace(long *req, struct task_struct *child,
+ struct utrace_attached_engine *engine,
+ unsigned long addr, unsigned long data, long *val)
{
switch (*req) {
case PTRACE_PEEKUSR:
{
switch (*req) {
case PTRACE_PEEKUSR: