Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 79913
b: refs/heads/master
c: cb757c4
h: refs/heads/master
i:
  79911: 26c1349
v: v3
  • Loading branch information
Roland McGrath authored and Ingo Molnar committed Jan 30, 2008
1 parent 6c44288 commit 9cb3c44
Show file tree
Hide file tree
Showing 2 changed files with 129 additions and 3 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 86976cd805eccf46d9b720bb188a540fc5769427
refs/heads/master: cb757c41f3c2e1ac6f950f9d070e9849983efc18
130 changes: 128 additions & 2 deletions trunk/arch/x86/kernel/ptrace.c
Original file line number Diff line number Diff line change
Expand Up @@ -215,14 +215,14 @@ static int set_segment_reg(struct task_struct *task,
#ifdef CONFIG_IA32_EMULATION
if (test_tsk_thread_flag(task, TIF_IA32))
task_pt_regs(task)->cs = value;
break;
#endif
break;
case offsetof(struct user_regs_struct,ss):
#ifdef CONFIG_IA32_EMULATION
if (test_tsk_thread_flag(task, TIF_IA32))
task_pt_regs(task)->ss = value;
break;
#endif
break;
}

return 0;
Expand Down Expand Up @@ -634,6 +634,132 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
return ret;
}

#ifdef CONFIG_IA32_EMULATION

#include <asm/user32.h>

#define R32(l,q) \
case offsetof(struct user32, regs.l): \
regs->q = value; break

#define SEG32(rs) \
case offsetof(struct user32, regs.rs): \
return set_segment_reg(child, \
offsetof(struct user_regs_struct, rs), \
value); \
break

static int putreg32(struct task_struct *child, unsigned regno, u32 value)
{
struct pt_regs *regs = task_pt_regs(child);

switch (regno) {

SEG32(cs);
SEG32(ds);
SEG32(es);
SEG32(fs);
SEG32(gs);
SEG32(ss);

R32(ebx, bx);
R32(ecx, cx);
R32(edx, dx);
R32(edi, di);
R32(esi, si);
R32(ebp, bp);
R32(eax, ax);
R32(orig_eax, orig_ax);
R32(eip, ip);
R32(esp, sp);

case offsetof(struct user32, regs.eflags):
return set_flags(child, value);

case offsetof(struct user32, u_debugreg[0]) ...
offsetof(struct user32, u_debugreg[7]):
regno -= offsetof(struct user32, u_debugreg[0]);
return ptrace_set_debugreg(child, regno / 4, value);

default:
if (regno > sizeof(struct user32) || (regno & 3))
return -EIO;

/*
* Other dummy fields in the virtual user structure
* are ignored
*/
break;
}
return 0;
}

#undef R32
#undef SEG32

#define R32(l,q) \
case offsetof(struct user32, regs.l): \
*val = regs->q; break

#define SEG32(rs) \
case offsetof(struct user32, regs.rs): \
*val = get_segment_reg(child, \
offsetof(struct user_regs_struct, rs)); \
break

static int getreg32(struct task_struct *child, unsigned regno, u32 *val)
{
struct pt_regs *regs = task_pt_regs(child);

switch (regno) {

SEG32(ds);
SEG32(es);
SEG32(fs);
SEG32(gs);

R32(cs, cs);
R32(ss, ss);
R32(ebx, bx);
R32(ecx, cx);
R32(edx, dx);
R32(edi, di);
R32(esi, si);
R32(ebp, bp);
R32(eax, ax);
R32(orig_eax, orig_ax);
R32(eip, ip);
R32(esp, sp);

case offsetof(struct user32, regs.eflags):
*val = get_flags(child);
break;

case offsetof(struct user32, u_debugreg[0]) ...
offsetof(struct user32, u_debugreg[7]):
regno -= offsetof(struct user32, u_debugreg[0]);
*val = ptrace_get_debugreg(child, regno / 4);
break;

default:
if (regno > sizeof(struct user32) || (regno & 3))
return -EIO;

/*
* Other dummy fields in the virtual user structure
* are ignored
*/
*val = 0;
break;
}
return 0;
}

#undef R32
#undef SEG32

#endif /* CONFIG_IA32_EMULATION */

#ifdef CONFIG_X86_32

void send_sigtrap(struct task_struct *tsk, struct pt_regs *regs, int error_code)
Expand Down

0 comments on commit 9cb3c44

Please sign in to comment.