aboutsummaryrefslogtreecommitdiffstats
path: root/arch/um
diff options
context:
space:
mode:
authorAl Viro <viro@ftp.linux.org.uk>2011-08-18 15:02:29 -0400
committerRichard Weinberger <richard@nod.at>2011-11-02 09:14:48 -0400
commit412f90ed13c86f066a4ab14ed5bcd0793ef0355d (patch)
tree3c2c69ab63b5becb52e852bfa361c45a17bc345d /arch/um
parentab785c1dd4bef85f308504c83bcf47ce787e1565 (diff)
um: Get rid of UPT_SET/UPT_REG macros
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>
Diffstat (limited to 'arch/um')
-rw-r--r--arch/um/include/asm/ptrace-generic.h3
-rw-r--r--arch/um/sys-i386/ptrace.c69
-rw-r--r--arch/um/sys-i386/shared/sysdep/ptrace.h53
-rw-r--r--arch/um/sys-x86_64/ptrace.c103
-rw-r--r--arch/um/sys-x86_64/shared/sysdep/ptrace.h75
5 files changed, 145 insertions, 158 deletions
diff --git a/arch/um/include/asm/ptrace-generic.h b/arch/um/include/asm/ptrace-generic.h
index 1a7d2757fe05..c3b8a041c13f 100644
--- a/arch/um/include/asm/ptrace-generic.h
+++ b/arch/um/include/asm/ptrace-generic.h
@@ -23,9 +23,6 @@ struct pt_regs {
23#define PT_REGS_IP(r) UPT_IP(&(r)->regs) 23#define PT_REGS_IP(r) UPT_IP(&(r)->regs)
24#define PT_REGS_SP(r) UPT_SP(&(r)->regs) 24#define PT_REGS_SP(r) UPT_SP(&(r)->regs)
25 25
26#define PT_REG(r, reg) UPT_REG(&(r)->regs, reg)
27#define PT_REGS_SET(r, reg, val) UPT_SET(&(r)->regs, reg, val)
28
29#define PT_REGS_SET_SYSCALL_RETURN(r, res) \ 26#define PT_REGS_SET_SYSCALL_RETURN(r, res) \
30 UPT_SET_SYSCALL_RETURN(&(r)->regs, res) 27 UPT_SET_SYSCALL_RETURN(&(r)->regs, res)
31#define PT_REGS_RESTART_SYSCALL(r) UPT_RESTART_SYSCALL(&(r)->regs) 28#define PT_REGS_RESTART_SYSCALL(r) UPT_RESTART_SYSCALL(&(r)->regs)
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)
50/* 1 = access 0 = no access */ 50/* 1 = access 0 = no access */
51#define FLAG_MASK 0x00044dd5 51#define FLAG_MASK 0x00044dd5
52 52
53static const int reg_offsets[] = {
54 [EBX] = HOST_EBX,
55 [ECX] = HOST_ECX,
56 [EDX] = HOST_EDX,
57 [ESI] = HOST_ESI,
58 [EDI] = HOST_EDI,
59 [EBP] = HOST_EBP,
60 [EAX] = HOST_EAX,
61 [DS] = HOST_DS,
62 [ES] = HOST_ES,
63 [FS] = HOST_FS,
64 [GS] = HOST_GS,
65 [EIP] = HOST_IP,
66 [CS] = HOST_CS,
67 [EFL] = HOST_EFLAGS,
68 [UESP] = HOST_SP,
69 [SS] = HOST_SS,
70};
71
53int putreg(struct task_struct *child, int regno, unsigned long value) 72int putreg(struct task_struct *child, int regno, unsigned long value)
54{ 73{
55 regno >>= 2; 74 regno >>= 2;
56 switch (regno) { 75 switch (regno) {
76 case EBX:
77 case ECX:
78 case EDX:
79 case ESI:
80 case EDI:
81 case EBP:
82 case EAX:
83 case EIP:
84 case UESP:
85 break;
57 case FS: 86 case FS:
58 if (value && (value & 3) != 3) 87 if (value && (value & 3) != 3)
59 return -EIO; 88 return -EIO;
60 PT_REGS_FS(&child->thread.regs) = value; 89 break;
61 return 0;
62 case GS: 90 case GS:
63 if (value && (value & 3) != 3) 91 if (value && (value & 3) != 3)
64 return -EIO; 92 return -EIO;
65 PT_REGS_GS(&child->thread.regs) = value; 93 break;
66 return 0;
67 case DS: 94 case DS:
68 case ES: 95 case ES:
69 if (value && (value & 3) != 3) 96 if (value && (value & 3) != 3)
@@ -78,10 +105,15 @@ int putreg(struct task_struct *child, int regno, unsigned long value)
78 break; 105 break;
79 case EFL: 106 case EFL:
80 value &= FLAG_MASK; 107 value &= FLAG_MASK;
81 value |= PT_REGS_EFLAGS(&child->thread.regs); 108 child->thread.regs.regs.gp[HOST_EFLAGS] |= value;
82 break; 109 return 0;
110 case ORIG_EAX:
111 child->thread.regs.regs.syscall = value;
112 return 0;
113 default :
114 panic("Bad register in putreg() : %d\n", regno);
83 } 115 }
84 PT_REGS_SET(&child->thread.regs, regno, value); 116 child->thread.regs.regs.gp[reg_offsets[regno]] = value;
85 return 0; 117 return 0;
86} 118}
87 119
@@ -106,22 +138,35 @@ int poke_user(struct task_struct *child, long addr, long data)
106 138
107unsigned long getreg(struct task_struct *child, int regno) 139unsigned long getreg(struct task_struct *child, int regno)
108{ 140{
109 unsigned long retval = ~0UL; 141 unsigned long mask = ~0UL;
110 142
111 regno >>= 2; 143 regno >>= 2;
112 switch (regno) { 144 switch (regno) {
145 case ORIG_EAX:
146 return child->thread.regs.regs.syscall;
113 case FS: 147 case FS:
114 case GS: 148 case GS:
115 case DS: 149 case DS:
116 case ES: 150 case ES:
117 case SS: 151 case SS:
118 case CS: 152 case CS:
119 retval = 0xffff; 153 mask = 0xffff;
120 /* fall through */ 154 break;
155 case EIP:
156 case UESP:
157 case EAX:
158 case EBX:
159 case ECX:
160 case EDX:
161 case ESI:
162 case EDI:
163 case EBP:
164 case EFL:
165 break;
121 default: 166 default:
122 retval &= PT_REG(&child->thread.regs, regno); 167 panic("Bad register in getreg() : %d\n", regno);
123 } 168 }
124 return retval; 169 return mask & child->thread.regs.regs.gp[reg_offsets[regno]];
125} 170}
126 171
127/* read the word at location addr in the USER area. */ 172/* 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 {
100 UPT_SYSCALL_ARG5(r), \ 100 UPT_SYSCALL_ARG5(r), \
101 UPT_SYSCALL_ARG6(r) } } ) 101 UPT_SYSCALL_ARG6(r) } } )
102 102
103#define UPT_REG(regs, reg) \
104 ({ unsigned long val; \
105 switch(reg){ \
106 case EIP: val = UPT_IP(regs); break; \
107 case UESP: val = UPT_SP(regs); break; \
108 case EAX: val = UPT_EAX(regs); break; \
109 case EBX: val = UPT_EBX(regs); break; \
110 case ECX: val = UPT_ECX(regs); break; \
111 case EDX: val = UPT_EDX(regs); break; \
112 case ESI: val = UPT_ESI(regs); break; \
113 case EDI: val = UPT_EDI(regs); break; \
114 case EBP: val = UPT_EBP(regs); break; \
115 case ORIG_EAX: val = UPT_ORIG_EAX(regs); break; \
116 case CS: val = UPT_CS(regs); break; \
117 case SS: val = UPT_SS(regs); break; \
118 case DS: val = UPT_DS(regs); break; \
119 case ES: val = UPT_ES(regs); break; \
120 case FS: val = UPT_FS(regs); break; \
121 case GS: val = UPT_GS(regs); break; \
122 case EFL: val = UPT_EFLAGS(regs); break; \
123 default : \
124 panic("Bad register in UPT_REG : %d\n", reg); \
125 val = -1; \
126 } \
127 val; \
128 })
129
130#define UPT_SET(regs, reg, val) \
131 do { \
132 switch(reg){ \
133 case EIP: UPT_IP(regs) = val; break; \
134 case UESP: UPT_SP(regs) = val; break; \
135 case EAX: UPT_EAX(regs) = val; break; \
136 case EBX: UPT_EBX(regs) = val; break; \
137 case ECX: UPT_ECX(regs) = val; break; \
138 case EDX: UPT_EDX(regs) = val; break; \
139 case ESI: UPT_ESI(regs) = val; break; \
140 case EDI: UPT_EDI(regs) = val; break; \
141 case EBP: UPT_EBP(regs) = val; break; \
142 case ORIG_EAX: UPT_ORIG_EAX(regs) = val; break; \
143 case CS: UPT_CS(regs) = val; break; \
144 case SS: UPT_SS(regs) = val; break; \
145 case DS: UPT_DS(regs) = val; break; \
146 case ES: UPT_ES(regs) = val; break; \
147 case FS: UPT_FS(regs) = val; break; \
148 case GS: UPT_GS(regs) = val; break; \
149 case EFL: UPT_EFLAGS(regs) = val; break; \
150 default : \
151 panic("Bad register in UPT_SET : %d\n", reg); \
152 break; \
153 } \
154 } while (0)
155
156#define UPT_SET_SYSCALL_RETURN(r, res) \ 103#define UPT_SET_SYSCALL_RETURN(r, res) \
157 REGS_SET_SYSCALL_RETURN((r)->regs, (res)) 104 REGS_SET_SYSCALL_RETURN((r)->regs, (res))
158 105
diff --git a/arch/um/sys-x86_64/ptrace.c b/arch/um/sys-x86_64/ptrace.c
index 4005506834fd..44e68e0c0d10 100644
--- a/arch/um/sys-x86_64/ptrace.c
+++ b/arch/um/sys-x86_64/ptrace.c
@@ -18,10 +18,39 @@
18 */ 18 */
19#define FLAG_MASK 0x44dd5UL 19#define FLAG_MASK 0x44dd5UL
20 20
21int putreg(struct task_struct *child, int regno, unsigned long value) 21static const int reg_offsets[] =
22{ 22{
23 unsigned long tmp; 23 [R8 >> 3] = HOST_R8,
24 [R9 >> 3] = HOST_R9,
25 [R10 >> 3] = HOST_R10,
26 [R11 >> 3] = HOST_R11,
27 [R12 >> 3] = HOST_R12,
28 [R13 >> 3] = HOST_R13,
29 [R14 >> 3] = HOST_R14,
30 [R15 >> 3] = HOST_R15,
31 [RIP >> 3] = HOST_IP,
32 [RSP >> 3] = HOST_SP,
33 [RAX >> 3] = HOST_RAX,
34 [RBX >> 3] = HOST_RBX,
35 [RCX >> 3] = HOST_RCX,
36 [RDX >> 3] = HOST_RDX,
37 [RSI >> 3] = HOST_RSI,
38 [RDI >> 3] = HOST_RDI,
39 [RBP >> 3] = HOST_RBP,
40 [CS >> 3] = HOST_CS,
41 [SS >> 3] = HOST_SS,
42 [FS_BASE >> 3] = HOST_FS_BASE,
43 [GS_BASE >> 3] = HOST_GS_BASE,
44 [DS >> 3] = HOST_DS,
45 [ES >> 3] = HOST_ES,
46 [FS >> 3] = HOST_FS,
47 [GS >> 3] = HOST_GS,
48 [EFLAGS >> 3] = HOST_EFLAGS,
49 [ORIG_RAX >> 3] = HOST_ORIG_RAX,
50};
24 51
52int putreg(struct task_struct *child, int regno, unsigned long value)
53{
25#ifdef TIF_IA32 54#ifdef TIF_IA32
26 /* 55 /*
27 * Some code in the 64bit emulation may not be 64bit clean. 56 * Some code in the 64bit emulation may not be 64bit clean.
@@ -31,6 +60,26 @@ int putreg(struct task_struct *child, int regno, unsigned long value)
31 value &= 0xffffffff; 60 value &= 0xffffffff;
32#endif 61#endif
33 switch (regno) { 62 switch (regno) {
63 case R8:
64 case R9:
65 case R10:
66 case R11:
67 case R12:
68 case R13:
69 case R14:
70 case R15:
71 case RIP:
72 case RSP:
73 case RAX:
74 case RBX:
75 case RCX:
76 case RDX:
77 case RSI:
78 case RDI:
79 case RBP:
80 case ORIG_RAX:
81 break;
82
34 case FS: 83 case FS:
35 case GS: 84 case GS:
36 case DS: 85 case DS:
@@ -50,12 +99,14 @@ int putreg(struct task_struct *child, int regno, unsigned long value)
50 99
51 case EFLAGS: 100 case EFLAGS:
52 value &= FLAG_MASK; 101 value &= FLAG_MASK;
53 tmp = PT_REGS_EFLAGS(&child->thread.regs) & ~FLAG_MASK; 102 child->thread.regs.regs.gp[HOST_EFLAGS] |= value;
54 value |= tmp; 103 return 0;
55 break; 104
105 default:
106 panic("Bad register in putreg(): %d\n", regno);
56 } 107 }
57 108
58 PT_REGS_SET(&child->thread.regs, regno, value); 109 child->thread.regs.regs.gp[reg_offsets[regno >> 3]] = value;
59 return 0; 110 return 0;
60} 111}
61 112
@@ -80,24 +131,46 @@ int poke_user(struct task_struct *child, long addr, long data)
80 131
81unsigned long getreg(struct task_struct *child, int regno) 132unsigned long getreg(struct task_struct *child, int regno)
82{ 133{
83 unsigned long retval = ~0UL; 134 unsigned long mask = ~0UL;
135#ifdef TIF_IA32
136 if (test_tsk_thread_flag(child, TIF_IA32))
137 mask = 0xffffffff;
138#endif
84 switch (regno) { 139 switch (regno) {
140 case R8:
141 case R9:
142 case R10:
143 case R11:
144 case R12:
145 case R13:
146 case R14:
147 case R15:
148 case RIP:
149 case RSP:
150 case RAX:
151 case RBX:
152 case RCX:
153 case RDX:
154 case RSI:
155 case RDI:
156 case RBP:
157 case ORIG_RAX:
158 case EFLAGS:
159 case FS_BASE:
160 case GS_BASE:
161 break;
85 case FS: 162 case FS:
86 case GS: 163 case GS:
87 case DS: 164 case DS:
88 case ES: 165 case ES:
89 case SS: 166 case SS:
90 case CS: 167 case CS:
91 retval = 0xffff; 168 mask = 0xffff;
92 /* fall through */ 169 break;
93 default: 170 default:
94 retval &= PT_REG(&child->thread.regs, regno); 171 panic("Bad register in getreg: %d\n", regno);
95#ifdef TIF_IA32
96 if (test_tsk_thread_flag(child, TIF_IA32))
97 retval &= 0xffffffff;
98#endif
99 } 172 }
100 return retval; 173 return mask & child->thread.regs.regs.gp[reg_offsets[regno >> 3]];
101} 174}
102 175
103int peek_user(struct task_struct *child, long addr, long data) 176int peek_user(struct task_struct *child, long addr, long data)
diff --git a/arch/um/sys-x86_64/shared/sysdep/ptrace.h b/arch/um/sys-x86_64/shared/sysdep/ptrace.h
index ea5d7c1783cb..9ed4597fa942 100644
--- a/arch/um/sys-x86_64/shared/sysdep/ptrace.h
+++ b/arch/um/sys-x86_64/shared/sysdep/ptrace.h
@@ -147,81 +147,6 @@ struct syscall_args {
147 UPT_SYSCALL_ARG5(r), \ 147 UPT_SYSCALL_ARG5(r), \
148 UPT_SYSCALL_ARG6(r) } } ) 148 UPT_SYSCALL_ARG6(r) } } )
149 149
150#define UPT_REG(regs, reg) \
151 ({ unsigned long val; \
152 switch(reg){ \
153 case R8: val = UPT_R8(regs); break; \
154 case R9: val = UPT_R9(regs); break; \
155 case R10: val = UPT_R10(regs); break; \
156 case R11: val = UPT_R11(regs); break; \
157 case R12: val = UPT_R12(regs); break; \
158 case R13: val = UPT_R13(regs); break; \
159 case R14: val = UPT_R14(regs); break; \
160 case R15: val = UPT_R15(regs); break; \
161 case RIP: val = UPT_IP(regs); break; \
162 case RSP: val = UPT_SP(regs); break; \
163 case RAX: val = UPT_RAX(regs); break; \
164 case RBX: val = UPT_RBX(regs); break; \
165 case RCX: val = UPT_RCX(regs); break; \
166 case RDX: val = UPT_RDX(regs); break; \
167 case RSI: val = UPT_RSI(regs); break; \
168 case RDI: val = UPT_RDI(regs); break; \
169 case RBP: val = UPT_RBP(regs); break; \
170 case ORIG_RAX: val = UPT_ORIG_RAX(regs); break; \
171 case CS: val = UPT_CS(regs); break; \
172 case SS: val = UPT_SS(regs); break; \
173 case FS_BASE: val = UPT_FS_BASE(regs); break; \
174 case GS_BASE: val = UPT_GS_BASE(regs); break; \
175 case DS: val = UPT_DS(regs); break; \
176 case ES: val = UPT_ES(regs); break; \
177 case FS : val = UPT_FS (regs); break; \
178 case GS: val = UPT_GS(regs); break; \
179 case EFLAGS: val = UPT_EFLAGS(regs); break; \
180 default : \
181 panic("Bad register in UPT_REG : %d\n", reg); \
182 val = -1; \
183 } \
184 val; \
185 })
186
187
188#define UPT_SET(regs, reg, val) \
189 ({ unsigned long __upt_val = val; \
190 switch(reg){ \
191 case R8: UPT_R8(regs) = __upt_val; break; \
192 case R9: UPT_R9(regs) = __upt_val; break; \
193 case R10: UPT_R10(regs) = __upt_val; break; \
194 case R11: UPT_R11(regs) = __upt_val; break; \
195 case R12: UPT_R12(regs) = __upt_val; break; \
196 case R13: UPT_R13(regs) = __upt_val; break; \
197 case R14: UPT_R14(regs) = __upt_val; break; \
198 case R15: UPT_R15(regs) = __upt_val; break; \
199 case RIP: UPT_IP(regs) = __upt_val; break; \
200 case RSP: UPT_SP(regs) = __upt_val; break; \
201 case RAX: UPT_RAX(regs) = __upt_val; break; \
202 case RBX: UPT_RBX(regs) = __upt_val; break; \
203 case RCX: UPT_RCX(regs) = __upt_val; break; \
204 case RDX: UPT_RDX(regs) = __upt_val; break; \
205 case RSI: UPT_RSI(regs) = __upt_val; break; \
206 case RDI: UPT_RDI(regs) = __upt_val; break; \
207 case RBP: UPT_RBP(regs) = __upt_val; break; \
208 case ORIG_RAX: UPT_ORIG_RAX(regs) = __upt_val; break; \
209 case CS: UPT_CS(regs) = __upt_val; break; \
210 case SS: UPT_SS(regs) = __upt_val; break; \
211 case FS_BASE: UPT_FS_BASE(regs) = __upt_val; break; \
212 case GS_BASE: UPT_GS_BASE(regs) = __upt_val; break; \
213 case DS: UPT_DS(regs) = __upt_val; break; \
214 case ES: UPT_ES(regs) = __upt_val; break; \
215 case FS: UPT_FS(regs) = __upt_val; break; \
216 case GS: UPT_GS(regs) = __upt_val; break; \
217 case EFLAGS: UPT_EFLAGS(regs) = __upt_val; break; \
218 default : \
219 panic("Bad register in UPT_SET : %d\n", reg); \
220 break; \
221 } \
222 __upt_val; \
223 })
224
225#define UPT_SET_SYSCALL_RETURN(r, res) \ 150#define UPT_SET_SYSCALL_RETURN(r, res) \
226 REGS_SET_SYSCALL_RETURN((r)->regs, (res)) 151 REGS_SET_SYSCALL_RETURN((r)->regs, (res))
227 152