Skip to content

Commit

Permalink
um: Get rid of UPT_SET/UPT_REG macros
Browse files Browse the repository at this point in the history
the only users are arch getreg()/putreg() and it's easier to handle
it there instead of playing with macros from hell

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Signed-off-by: Richard Weinberger <richard@nod.at>
  • Loading branch information
Al Viro authored and Richard Weinberger committed Nov 2, 2011
1 parent ab785c1 commit 412f90e
Show file tree
Hide file tree
Showing 5 changed files with 145 additions and 158 deletions.
3 changes: 0 additions & 3 deletions arch/um/include/asm/ptrace-generic.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,6 @@ struct pt_regs {
#define PT_REGS_IP(r) UPT_IP(&(r)->regs)
#define PT_REGS_SP(r) UPT_SP(&(r)->regs)

#define PT_REG(r, reg) UPT_REG(&(r)->regs, reg)
#define PT_REGS_SET(r, reg, val) UPT_SET(&(r)->regs, reg, val)

#define PT_REGS_SET_SYSCALL_RETURN(r, res) \
UPT_SET_SYSCALL_RETURN(&(r)->regs, res)
#define PT_REGS_RESTART_SYSCALL(r) UPT_RESTART_SYSCALL(&(r)->regs)
Expand Down
69 changes: 57 additions & 12 deletions arch/um/sys-i386/ptrace.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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;
}

Expand All @@ -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. */
Expand Down
53 changes: 0 additions & 53 deletions arch/um/sys-i386/shared/sysdep/ptrace.h
Original file line number Diff line number Diff line change
Expand Up @@ -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))

Expand Down
103 changes: 88 additions & 15 deletions arch/um/sys-x86_64/ptrace.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,39 @@
*/
#define FLAG_MASK 0x44dd5UL

int putreg(struct task_struct *child, int regno, unsigned long value)
static const int reg_offsets[] =
{
unsigned long tmp;
[R8 >> 3] = HOST_R8,
[R9 >> 3] = HOST_R9,
[R10 >> 3] = HOST_R10,
[R11 >> 3] = HOST_R11,
[R12 >> 3] = HOST_R12,
[R13 >> 3] = HOST_R13,
[R14 >> 3] = HOST_R14,
[R15 >> 3] = HOST_R15,
[RIP >> 3] = HOST_IP,
[RSP >> 3] = HOST_SP,
[RAX >> 3] = HOST_RAX,
[RBX >> 3] = HOST_RBX,
[RCX >> 3] = HOST_RCX,
[RDX >> 3] = HOST_RDX,
[RSI >> 3] = HOST_RSI,
[RDI >> 3] = HOST_RDI,
[RBP >> 3] = HOST_RBP,
[CS >> 3] = HOST_CS,
[SS >> 3] = HOST_SS,
[FS_BASE >> 3] = HOST_FS_BASE,
[GS_BASE >> 3] = HOST_GS_BASE,
[DS >> 3] = HOST_DS,
[ES >> 3] = HOST_ES,
[FS >> 3] = HOST_FS,
[GS >> 3] = HOST_GS,
[EFLAGS >> 3] = HOST_EFLAGS,
[ORIG_RAX >> 3] = HOST_ORIG_RAX,
};

int putreg(struct task_struct *child, int regno, unsigned long value)
{
#ifdef TIF_IA32
/*
* Some code in the 64bit emulation may not be 64bit clean.
Expand All @@ -31,6 +60,26 @@ int putreg(struct task_struct *child, int regno, unsigned long value)
value &= 0xffffffff;
#endif
switch (regno) {
case R8:
case R9:
case R10:
case R11:
case R12:
case R13:
case R14:
case R15:
case RIP:
case RSP:
case RAX:
case RBX:
case RCX:
case RDX:
case RSI:
case RDI:
case RBP:
case ORIG_RAX:
break;

case FS:
case GS:
case DS:
Expand All @@ -50,12 +99,14 @@ int putreg(struct task_struct *child, int regno, unsigned long value)

case EFLAGS:
value &= FLAG_MASK;
tmp = PT_REGS_EFLAGS(&child->thread.regs) & ~FLAG_MASK;
value |= tmp;
break;
child->thread.regs.regs.gp[HOST_EFLAGS] |= 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 >> 3]] = value;
return 0;
}

Expand All @@ -80,24 +131,46 @@ 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;
#ifdef TIF_IA32
if (test_tsk_thread_flag(child, TIF_IA32))
mask = 0xffffffff;
#endif
switch (regno) {
case R8:
case R9:
case R10:
case R11:
case R12:
case R13:
case R14:
case R15:
case RIP:
case RSP:
case RAX:
case RBX:
case RCX:
case RDX:
case RSI:
case RDI:
case RBP:
case ORIG_RAX:
case EFLAGS:
case FS_BASE:
case GS_BASE:
break;
case FS:
case GS:
case DS:
case ES:
case SS:
case CS:
retval = 0xffff;
/* fall through */
mask = 0xffff;
break;
default:
retval &= PT_REG(&child->thread.regs, regno);
#ifdef TIF_IA32
if (test_tsk_thread_flag(child, TIF_IA32))
retval &= 0xffffffff;
#endif
panic("Bad register in getreg: %d\n", regno);
}
return retval;
return mask & child->thread.regs.regs.gp[reg_offsets[regno >> 3]];
}

int peek_user(struct task_struct *child, long addr, long data)
Expand Down
Loading

0 comments on commit 412f90e

Please sign in to comment.