diff options
Diffstat (limited to 'arch/um/sys-i386')
-rw-r--r-- | arch/um/sys-i386/ptrace.c | 69 | ||||
-rw-r--r-- | arch/um/sys-i386/shared/sysdep/ptrace.h | 53 |
2 files changed, 57 insertions, 65 deletions
diff --git a/arch/um/sys-i386/ptrace.c b/arch/um/sys-i386/ptrace.c index 3375c2717851..a174fde2531c 100644 --- a/arch/um/sys-i386/ptrace.c +++ b/arch/um/sys-i386/ptrace.c @@ -50,20 +50,47 @@ int is_syscall(unsigned long addr) /* 1 = access 0 = no access */ #define FLAG_MASK 0x00044dd5 +static const int reg_offsets[] = { + [EBX] = HOST_EBX, + [ECX] = HOST_ECX, + [EDX] = HOST_EDX, + [ESI] = HOST_ESI, + [EDI] = HOST_EDI, + [EBP] = HOST_EBP, + [EAX] = HOST_EAX, + [DS] = HOST_DS, + [ES] = HOST_ES, + [FS] = HOST_FS, + [GS] = HOST_GS, + [EIP] = HOST_IP, + [CS] = HOST_CS, + [EFL] = HOST_EFLAGS, + [UESP] = HOST_SP, + [SS] = HOST_SS, +}; + int putreg(struct task_struct *child, int regno, unsigned long value) { regno >>= 2; switch (regno) { + case EBX: + case ECX: + case EDX: + case ESI: + case EDI: + case EBP: + case EAX: + case EIP: + case UESP: + break; case FS: if (value && (value & 3) != 3) return -EIO; - PT_REGS_FS(&child->thread.regs) = value; - return 0; + break; case GS: if (value && (value & 3) != 3) return -EIO; - PT_REGS_GS(&child->thread.regs) = value; - return 0; + break; case DS: case ES: if (value && (value & 3) != 3) @@ -78,10 +105,15 @@ int putreg(struct task_struct *child, int regno, unsigned long value) break; case EFL: value &= FLAG_MASK; - value |= PT_REGS_EFLAGS(&child->thread.regs); - break; + child->thread.regs.regs.gp[HOST_EFLAGS] |= value; + return 0; + case ORIG_EAX: + child->thread.regs.regs.syscall = value; + return 0; + default : + panic("Bad register in putreg() : %d\n", regno); } - PT_REGS_SET(&child->thread.regs, regno, value); + child->thread.regs.regs.gp[reg_offsets[regno]] = value; return 0; } @@ -106,22 +138,35 @@ int poke_user(struct task_struct *child, long addr, long data) unsigned long getreg(struct task_struct *child, int regno) { - unsigned long retval = ~0UL; + unsigned long mask = ~0UL; regno >>= 2; switch (regno) { + case ORIG_EAX: + return child->thread.regs.regs.syscall; case FS: case GS: case DS: case ES: case SS: case CS: - retval = 0xffff; - /* fall through */ + mask = 0xffff; + break; + case EIP: + case UESP: + case EAX: + case EBX: + case ECX: + case EDX: + case ESI: + case EDI: + case EBP: + case EFL: + break; default: - retval &= PT_REG(&child->thread.regs, regno); + panic("Bad register in getreg() : %d\n", regno); } - return retval; + return mask & child->thread.regs.regs.gp[reg_offsets[regno]]; } /* read the word at location addr in the USER area. */ diff --git a/arch/um/sys-i386/shared/sysdep/ptrace.h b/arch/um/sys-i386/shared/sysdep/ptrace.h index 36006994148e..6096c8f89f4f 100644 --- a/arch/um/sys-i386/shared/sysdep/ptrace.h +++ b/arch/um/sys-i386/shared/sysdep/ptrace.h @@ -100,59 +100,6 @@ struct syscall_args { UPT_SYSCALL_ARG5(r), \ UPT_SYSCALL_ARG6(r) } } ) -#define UPT_REG(regs, reg) \ - ({ unsigned long val; \ - switch(reg){ \ - case EIP: val = UPT_IP(regs); break; \ - case UESP: val = UPT_SP(regs); break; \ - case EAX: val = UPT_EAX(regs); break; \ - case EBX: val = UPT_EBX(regs); break; \ - case ECX: val = UPT_ECX(regs); break; \ - case EDX: val = UPT_EDX(regs); break; \ - case ESI: val = UPT_ESI(regs); break; \ - case EDI: val = UPT_EDI(regs); break; \ - case EBP: val = UPT_EBP(regs); break; \ - case ORIG_EAX: val = UPT_ORIG_EAX(regs); break; \ - case CS: val = UPT_CS(regs); break; \ - case SS: val = UPT_SS(regs); break; \ - case DS: val = UPT_DS(regs); break; \ - case ES: val = UPT_ES(regs); break; \ - case FS: val = UPT_FS(regs); break; \ - case GS: val = UPT_GS(regs); break; \ - case EFL: val = UPT_EFLAGS(regs); break; \ - default : \ - panic("Bad register in UPT_REG : %d\n", reg); \ - val = -1; \ - } \ - val; \ - }) - -#define UPT_SET(regs, reg, val) \ - do { \ - switch(reg){ \ - case EIP: UPT_IP(regs) = val; break; \ - case UESP: UPT_SP(regs) = val; break; \ - case EAX: UPT_EAX(regs) = val; break; \ - case EBX: UPT_EBX(regs) = val; break; \ - case ECX: UPT_ECX(regs) = val; break; \ - case EDX: UPT_EDX(regs) = val; break; \ - case ESI: UPT_ESI(regs) = val; break; \ - case EDI: UPT_EDI(regs) = val; break; \ - case EBP: UPT_EBP(regs) = val; break; \ - case ORIG_EAX: UPT_ORIG_EAX(regs) = val; break; \ - case CS: UPT_CS(regs) = val; break; \ - case SS: UPT_SS(regs) = val; break; \ - case DS: UPT_DS(regs) = val; break; \ - case ES: UPT_ES(regs) = val; break; \ - case FS: UPT_FS(regs) = val; break; \ - case GS: UPT_GS(regs) = val; break; \ - case EFL: UPT_EFLAGS(regs) = val; break; \ - default : \ - panic("Bad register in UPT_SET : %d\n", reg); \ - break; \ - } \ - } while (0) - #define UPT_SET_SYSCALL_RETURN(r, res) \ REGS_SET_SYSCALL_RETURN((r)->regs, (res)) |