1/* 2 * Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) 3 * Licensed under the GPL 4 */ 5 6#ifndef __SYSDEP_I386_PTRACE_H 7#define __SYSDEP_I386_PTRACE_H 8 9#include "user_constants.h" 10#include "sysdep/faultinfo.h" 11 12#define MAX_REG_NR (UM_FRAME_SIZE / sizeof(unsigned long)) 13#define MAX_REG_OFFSET (UM_FRAME_SIZE) 14 15static inline void update_debugregs(int seq) {} 16 17/* syscall emulation path in ptrace */ 18 19#ifndef PTRACE_SYSEMU 20#define PTRACE_SYSEMU 31 21#endif 22 23void set_using_sysemu(int value); 24int get_using_sysemu(void); 25extern int sysemu_supported; 26 27#include "skas_ptregs.h" 28 29#define REGS_IP(r) ((r)[HOST_IP]) 30#define REGS_SP(r) ((r)[HOST_SP]) 31#define REGS_EFLAGS(r) ((r)[HOST_EFLAGS]) 32#define REGS_EAX(r) ((r)[HOST_EAX]) 33#define REGS_EBX(r) ((r)[HOST_EBX]) 34#define REGS_ECX(r) ((r)[HOST_ECX]) 35#define REGS_EDX(r) ((r)[HOST_EDX]) 36#define REGS_ESI(r) ((r)[HOST_ESI]) 37#define REGS_EDI(r) ((r)[HOST_EDI]) 38#define REGS_EBP(r) ((r)[HOST_EBP]) 39#define REGS_CS(r) ((r)[HOST_CS]) 40#define REGS_SS(r) ((r)[HOST_SS]) 41#define REGS_DS(r) ((r)[HOST_DS]) 42#define REGS_ES(r) ((r)[HOST_ES]) 43#define REGS_FS(r) ((r)[HOST_FS]) 44#define REGS_GS(r) ((r)[HOST_GS]) 45 46#define REGS_SET_SYSCALL_RETURN(r, res) REGS_EAX(r) = (res) 47 48#define REGS_RESTART_SYSCALL(r) IP_RESTART_SYSCALL(REGS_IP(r)) 49 50#ifndef PTRACE_SYSEMU_SINGLESTEP 51#define PTRACE_SYSEMU_SINGLESTEP 32 52#endif 53 54struct uml_pt_regs { 55 unsigned long gp[MAX_REG_NR]; 56 struct faultinfo faultinfo; 57 long syscall; 58 int is_user; 59}; 60 61#define EMPTY_UML_PT_REGS { } 62 63#define UPT_IP(r) REGS_IP((r)->gp) 64#define UPT_SP(r) REGS_SP((r)->gp) 65#define UPT_EFLAGS(r) REGS_EFLAGS((r)->gp) 66#define UPT_EAX(r) REGS_EAX((r)->gp) 67#define UPT_EBX(r) REGS_EBX((r)->gp) 68#define UPT_ECX(r) REGS_ECX((r)->gp) 69#define UPT_EDX(r) REGS_EDX((r)->gp) 70#define UPT_ESI(r) REGS_ESI((r)->gp) 71#define UPT_EDI(r) REGS_EDI((r)->gp) 72#define UPT_EBP(r) REGS_EBP((r)->gp) 73#define UPT_ORIG_EAX(r) ((r)->syscall) 74#define UPT_CS(r) REGS_CS((r)->gp) 75#define UPT_SS(r) REGS_SS((r)->gp) 76#define UPT_DS(r) REGS_DS((r)->gp) 77#define UPT_ES(r) REGS_ES((r)->gp) 78#define UPT_FS(r) REGS_FS((r)->gp) 79#define UPT_GS(r) REGS_GS((r)->gp) 80 81#define UPT_SYSCALL_ARG1(r) UPT_EBX(r) 82#define UPT_SYSCALL_ARG2(r) UPT_ECX(r) 83#define UPT_SYSCALL_ARG3(r) UPT_EDX(r) 84#define UPT_SYSCALL_ARG4(r) UPT_ESI(r) 85#define UPT_SYSCALL_ARG5(r) UPT_EDI(r) 86#define UPT_SYSCALL_ARG6(r) UPT_EBP(r) 87 88extern int user_context(unsigned long sp); 89 90#define UPT_IS_USER(r) ((r)->is_user) 91 92struct syscall_args { 93 unsigned long args[6]; 94}; 95 96#define SYSCALL_ARGS(r) ((struct syscall_args) \ 97 { .args = { UPT_SYSCALL_ARG1(r), \ 98 UPT_SYSCALL_ARG2(r), \ 99 UPT_SYSCALL_ARG3(r), \ 100 UPT_SYSCALL_ARG4(r), \ 101 UPT_SYSCALL_ARG5(r), \ 102 UPT_SYSCALL_ARG6(r) } } ) 103 104#define UPT_REG(regs, reg) \ 105 ({ unsigned long val; \ 106 switch(reg){ \ 107 case EIP: val = UPT_IP(regs); break; \ 108 case UESP: val = UPT_SP(regs); break; \ 109 case EAX: val = UPT_EAX(regs); break; \ 110 case EBX: val = UPT_EBX(regs); break; \ 111 case ECX: val = UPT_ECX(regs); break; \ 112 case EDX: val = UPT_EDX(regs); break; \ 113 case ESI: val = UPT_ESI(regs); break; \ 114 case EDI: val = UPT_EDI(regs); break; \ 115 case EBP: val = UPT_EBP(regs); break; \ 116 case ORIG_EAX: val = UPT_ORIG_EAX(regs); break; \ 117 case CS: val = UPT_CS(regs); break; \ 118 case SS: val = UPT_SS(regs); break; \ 119 case DS: val = UPT_DS(regs); break; \ 120 case ES: val = UPT_ES(regs); break; \ 121 case FS: val = UPT_FS(regs); break; \ 122 case GS: val = UPT_GS(regs); break; \ 123 case EFL: val = UPT_EFLAGS(regs); break; \ 124 default : \ 125 panic("Bad register in UPT_REG : %d\n", reg); \ 126 val = -1; \ 127 } \ 128 val; \ 129 }) 130 131#define UPT_SET(regs, reg, val) \ 132 do { \ 133 switch(reg){ \ 134 case EIP: UPT_IP(regs) = val; break; \ 135 case UESP: UPT_SP(regs) = val; break; \ 136 case EAX: UPT_EAX(regs) = val; break; \ 137 case EBX: UPT_EBX(regs) = val; break; \ 138 case ECX: UPT_ECX(regs) = val; break; \ 139 case EDX: UPT_EDX(regs) = val; break; \ 140 case ESI: UPT_ESI(regs) = val; break; \ 141 case EDI: UPT_EDI(regs) = val; break; \ 142 case EBP: UPT_EBP(regs) = val; break; \ 143 case ORIG_EAX: UPT_ORIG_EAX(regs) = val; break; \ 144 case CS: UPT_CS(regs) = val; break; \ 145 case SS: UPT_SS(regs) = val; break; \ 146 case DS: UPT_DS(regs) = val; break; \ 147 case ES: UPT_ES(regs) = val; break; \ 148 case FS: UPT_FS(regs) = val; break; \ 149 case GS: UPT_GS(regs) = val; break; \ 150 case EFL: UPT_EFLAGS(regs) = val; break; \ 151 default : \ 152 panic("Bad register in UPT_SET : %d\n", reg); \ 153 break; \ 154 } \ 155 } while (0) 156 157#define UPT_SET_SYSCALL_RETURN(r, res) \ 158 REGS_SET_SYSCALL_RETURN((r)->regs, (res)) 159 160#define UPT_RESTART_SYSCALL(r) REGS_RESTART_SYSCALL((r)->gp) 161 162#define UPT_ORIG_SYSCALL(r) UPT_EAX(r) 163#define UPT_SYSCALL_NR(r) UPT_ORIG_EAX(r) 164#define UPT_SYSCALL_RET(r) UPT_EAX(r) 165 166#define UPT_FAULTINFO(r) (&(r)->faultinfo) 167 168extern void arch_init_registers(int pid); 169 170#endif 171