aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kernel/ptrace.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86/kernel/ptrace.c')
-rw-r--r--arch/x86/kernel/ptrace.c130
1 files changed, 128 insertions, 2 deletions
diff --git a/arch/x86/kernel/ptrace.c b/arch/x86/kernel/ptrace.c
index 509804957f5f..d56aa18309f8 100644
--- a/arch/x86/kernel/ptrace.c
+++ b/arch/x86/kernel/ptrace.c
@@ -215,14 +215,14 @@ static int set_segment_reg(struct task_struct *task,
215#ifdef CONFIG_IA32_EMULATION 215#ifdef CONFIG_IA32_EMULATION
216 if (test_tsk_thread_flag(task, TIF_IA32)) 216 if (test_tsk_thread_flag(task, TIF_IA32))
217 task_pt_regs(task)->cs = value; 217 task_pt_regs(task)->cs = value;
218 break;
219#endif 218#endif
219 break;
220 case offsetof(struct user_regs_struct,ss): 220 case offsetof(struct user_regs_struct,ss):
221#ifdef CONFIG_IA32_EMULATION 221#ifdef CONFIG_IA32_EMULATION
222 if (test_tsk_thread_flag(task, TIF_IA32)) 222 if (test_tsk_thread_flag(task, TIF_IA32))
223 task_pt_regs(task)->ss = value; 223 task_pt_regs(task)->ss = value;
224 break;
225#endif 224#endif
225 break;
226 } 226 }
227 227
228 return 0; 228 return 0;
@@ -634,6 +634,132 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
634 return ret; 634 return ret;
635} 635}
636 636
637#ifdef CONFIG_IA32_EMULATION
638
639#include <asm/user32.h>
640
641#define R32(l,q) \
642 case offsetof(struct user32, regs.l): \
643 regs->q = value; break
644
645#define SEG32(rs) \
646 case offsetof(struct user32, regs.rs): \
647 return set_segment_reg(child, \
648 offsetof(struct user_regs_struct, rs), \
649 value); \
650 break
651
652static int putreg32(struct task_struct *child, unsigned regno, u32 value)
653{
654 struct pt_regs *regs = task_pt_regs(child);
655
656 switch (regno) {
657
658 SEG32(cs);
659 SEG32(ds);
660 SEG32(es);
661 SEG32(fs);
662 SEG32(gs);
663 SEG32(ss);
664
665 R32(ebx, bx);
666 R32(ecx, cx);
667 R32(edx, dx);
668 R32(edi, di);
669 R32(esi, si);
670 R32(ebp, bp);
671 R32(eax, ax);
672 R32(orig_eax, orig_ax);
673 R32(eip, ip);
674 R32(esp, sp);
675
676 case offsetof(struct user32, regs.eflags):
677 return set_flags(child, value);
678
679 case offsetof(struct user32, u_debugreg[0]) ...
680 offsetof(struct user32, u_debugreg[7]):
681 regno -= offsetof(struct user32, u_debugreg[0]);
682 return ptrace_set_debugreg(child, regno / 4, value);
683
684 default:
685 if (regno > sizeof(struct user32) || (regno & 3))
686 return -EIO;
687
688 /*
689 * Other dummy fields in the virtual user structure
690 * are ignored
691 */
692 break;
693 }
694 return 0;
695}
696
697#undef R32
698#undef SEG32
699
700#define R32(l,q) \
701 case offsetof(struct user32, regs.l): \
702 *val = regs->q; break
703
704#define SEG32(rs) \
705 case offsetof(struct user32, regs.rs): \
706 *val = get_segment_reg(child, \
707 offsetof(struct user_regs_struct, rs)); \
708 break
709
710static int getreg32(struct task_struct *child, unsigned regno, u32 *val)
711{
712 struct pt_regs *regs = task_pt_regs(child);
713
714 switch (regno) {
715
716 SEG32(ds);
717 SEG32(es);
718 SEG32(fs);
719 SEG32(gs);
720
721 R32(cs, cs);
722 R32(ss, ss);
723 R32(ebx, bx);
724 R32(ecx, cx);
725 R32(edx, dx);
726 R32(edi, di);
727 R32(esi, si);
728 R32(ebp, bp);
729 R32(eax, ax);
730 R32(orig_eax, orig_ax);
731 R32(eip, ip);
732 R32(esp, sp);
733
734 case offsetof(struct user32, regs.eflags):
735 *val = get_flags(child);
736 break;
737
738 case offsetof(struct user32, u_debugreg[0]) ...
739 offsetof(struct user32, u_debugreg[7]):
740 regno -= offsetof(struct user32, u_debugreg[0]);
741 *val = ptrace_get_debugreg(child, regno / 4);
742 break;
743
744 default:
745 if (regno > sizeof(struct user32) || (regno & 3))
746 return -EIO;
747
748 /*
749 * Other dummy fields in the virtual user structure
750 * are ignored
751 */
752 *val = 0;
753 break;
754 }
755 return 0;
756}
757
758#undef R32
759#undef SEG32
760
761#endif /* CONFIG_IA32_EMULATION */
762
637#ifdef CONFIG_X86_32 763#ifdef CONFIG_X86_32
638 764
639void send_sigtrap(struct task_struct *tsk, struct pt_regs *regs, int error_code) 765void send_sigtrap(struct task_struct *tsk, struct pt_regs *regs, int error_code)