aboutsummaryrefslogtreecommitdiffstats
path: root/arch/ia64
diff options
context:
space:
mode:
Diffstat (limited to 'arch/ia64')
-rw-r--r--arch/ia64/ia32/ia32_entry.S2
-rw-r--r--arch/ia64/ia32/sys_ia32.c83
-rw-r--r--arch/ia64/include/asm/ptrace.h2
-rw-r--r--arch/ia64/include/asm/syscall.h89
4 files changed, 89 insertions, 87 deletions
diff --git a/arch/ia64/ia32/ia32_entry.S b/arch/ia64/ia32/ia32_entry.S
index b905dcb791ff..a73ec0089d43 100644
--- a/arch/ia64/ia32/ia32_entry.S
+++ b/arch/ia64/ia32/ia32_entry.S
@@ -204,7 +204,7 @@ ia32_syscall_table:
204 data8 sys_setuid /* 16-bit version */ 204 data8 sys_setuid /* 16-bit version */
205 data8 sys_getuid /* 16-bit version */ 205 data8 sys_getuid /* 16-bit version */
206 data8 compat_sys_stime /* 25 */ 206 data8 compat_sys_stime /* 25 */
207 data8 sys32_ptrace 207 data8 compat_sys_ptrace
208 data8 sys32_alarm 208 data8 sys32_alarm
209 data8 sys_ni_syscall 209 data8 sys_ni_syscall
210 data8 sys32_pause 210 data8 sys32_pause
diff --git a/arch/ia64/ia32/sys_ia32.c b/arch/ia64/ia32/sys_ia32.c
index bf196cbb3796..5df5e4c90e4d 100644
--- a/arch/ia64/ia32/sys_ia32.c
+++ b/arch/ia64/ia32/sys_ia32.c
@@ -1300,25 +1300,6 @@ sys32_waitpid (int pid, unsigned int *stat_addr, int options)
1300 return compat_sys_wait4(pid, stat_addr, options, NULL); 1300 return compat_sys_wait4(pid, stat_addr, options, NULL);
1301} 1301}
1302 1302
1303static unsigned int
1304ia32_peek (struct task_struct *child, unsigned long addr, unsigned int *val)
1305{
1306 size_t copied;
1307 unsigned int ret;
1308
1309 copied = access_process_vm(child, addr, val, sizeof(*val), 0);
1310 return (copied != sizeof(ret)) ? -EIO : 0;
1311}
1312
1313static unsigned int
1314ia32_poke (struct task_struct *child, unsigned long addr, unsigned int val)
1315{
1316
1317 if (access_process_vm(child, addr, &val, sizeof(val), 1) != sizeof(val))
1318 return -EIO;
1319 return 0;
1320}
1321
1322/* 1303/*
1323 * The order in which registers are stored in the ptrace regs structure 1304 * The order in which registers are stored in the ptrace regs structure
1324 */ 1305 */
@@ -1616,49 +1597,15 @@ restore_ia32_fpxstate (struct task_struct *tsk, struct ia32_user_fxsr_struct __u
1616 return 0; 1597 return 0;
1617} 1598}
1618 1599
1619asmlinkage long 1600long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
1620sys32_ptrace (int request, pid_t pid, unsigned int addr, unsigned int data) 1601 compat_ulong_t caddr, compat_ulong_t cdata)
1621{ 1602{
1622 struct task_struct *child; 1603 unsigned long addr = caddr;
1623 unsigned int value, tmp; 1604 unsigned long data = cdata;
1605 unsigned int tmp;
1624 long i, ret; 1606 long i, ret;
1625 1607
1626 lock_kernel();
1627 if (request == PTRACE_TRACEME) {
1628 ret = ptrace_traceme();
1629 goto out;
1630 }
1631
1632 child = ptrace_get_task_struct(pid);
1633 if (IS_ERR(child)) {
1634 ret = PTR_ERR(child);
1635 goto out;
1636 }
1637
1638 if (request == PTRACE_ATTACH) {
1639 ret = sys_ptrace(request, pid, addr, data);
1640 goto out_tsk;
1641 }
1642
1643 ret = ptrace_check_attach(child, request == PTRACE_KILL);
1644 if (ret < 0)
1645 goto out_tsk;
1646
1647 switch (request) { 1608 switch (request) {
1648 case PTRACE_PEEKTEXT:
1649 case PTRACE_PEEKDATA: /* read word at location addr */
1650 ret = ia32_peek(child, addr, &value);
1651 if (ret == 0)
1652 ret = put_user(value, (unsigned int __user *) compat_ptr(data));
1653 else
1654 ret = -EIO;
1655 goto out_tsk;
1656
1657 case PTRACE_POKETEXT:
1658 case PTRACE_POKEDATA: /* write the word at location addr */
1659 ret = ia32_poke(child, addr, data);
1660 goto out_tsk;
1661
1662 case PTRACE_PEEKUSR: /* read word at addr in USER area */ 1609 case PTRACE_PEEKUSR: /* read word at addr in USER area */
1663 ret = -EIO; 1610 ret = -EIO;
1664 if ((addr & 3) || addr > 17*sizeof(int)) 1611 if ((addr & 3) || addr > 17*sizeof(int))
@@ -1723,27 +1670,9 @@ sys32_ptrace (int request, pid_t pid, unsigned int addr, unsigned int data)
1723 compat_ptr(data)); 1670 compat_ptr(data));
1724 break; 1671 break;
1725 1672
1726 case PTRACE_GETEVENTMSG:
1727 ret = put_user(child->ptrace_message, (unsigned int __user *) compat_ptr(data));
1728 break;
1729
1730 case PTRACE_SYSCALL: /* continue, stop after next syscall */
1731 case PTRACE_CONT: /* restart after signal. */
1732 case PTRACE_KILL:
1733 case PTRACE_SINGLESTEP: /* execute chile for one instruction */
1734 case PTRACE_DETACH: /* detach a process */
1735 ret = sys_ptrace(request, pid, addr, data);
1736 break;
1737
1738 default: 1673 default:
1739 ret = ptrace_request(child, request, addr, data); 1674 return compat_ptrace_request(child, request, caddr, cdata);
1740 break;
1741
1742 } 1675 }
1743 out_tsk:
1744 put_task_struct(child);
1745 out:
1746 unlock_kernel();
1747 return ret; 1676 return ret;
1748} 1677}
1749 1678
diff --git a/arch/ia64/include/asm/ptrace.h b/arch/ia64/include/asm/ptrace.h
index 14055c636adf..6417c1ecb44e 100644
--- a/arch/ia64/include/asm/ptrace.h
+++ b/arch/ia64/include/asm/ptrace.h
@@ -325,6 +325,8 @@ static inline unsigned long user_stack_pointer(struct pt_regs *regs)
325 #define arch_has_block_step() (1) 325 #define arch_has_block_step() (1)
326 extern void user_enable_block_step(struct task_struct *); 326 extern void user_enable_block_step(struct task_struct *);
327 327
328#define __ARCH_WANT_COMPAT_SYS_PTRACE
329
328#endif /* !__KERNEL__ */ 330#endif /* !__KERNEL__ */
329 331
330/* pt_all_user_regs is used for PTRACE_GETREGS PTRACE_SETREGS */ 332/* pt_all_user_regs is used for PTRACE_GETREGS PTRACE_SETREGS */
diff --git a/arch/ia64/include/asm/syscall.h b/arch/ia64/include/asm/syscall.h
index 3fd4fa6c48dd..2f758a42f94b 100644
--- a/arch/ia64/include/asm/syscall.h
+++ b/arch/ia64/include/asm/syscall.h
@@ -19,24 +19,35 @@
19static inline long syscall_get_nr(struct task_struct *task, 19static inline long syscall_get_nr(struct task_struct *task,
20 struct pt_regs *regs) 20 struct pt_regs *regs)
21{ 21{
22 BUG_ON(IS_IA32_PROCESS(regs));
23
24 if ((long)regs->cr_ifs < 0) /* Not a syscall */ 22 if ((long)regs->cr_ifs < 0) /* Not a syscall */
25 return -1; 23 return -1;
24
25#ifdef CONFIG_IA32_SUPPORT
26 if (IS_IA32_PROCESS(regs))
27 return regs->r1;
28#endif
29
26 return regs->r15; 30 return regs->r15;
27} 31}
28 32
29static inline void syscall_rollback(struct task_struct *task, 33static inline void syscall_rollback(struct task_struct *task,
30 struct pt_regs *regs) 34 struct pt_regs *regs)
31{ 35{
32 BUG_ON(IS_IA32_PROCESS(regs)); 36#ifdef CONFIG_IA32_SUPPORT
37 if (IS_IA32_PROCESS(regs))
38 regs->r8 = regs->r1;
39#endif
40
33 /* do nothing */ 41 /* do nothing */
34} 42}
35 43
36static inline long syscall_get_error(struct task_struct *task, 44static inline long syscall_get_error(struct task_struct *task,
37 struct pt_regs *regs) 45 struct pt_regs *regs)
38{ 46{
39 BUG_ON(IS_IA32_PROCESS(regs)); 47#ifdef CONFIG_IA32_SUPPORT
48 if (IS_IA32_PROCESS(regs))
49 return regs->r8;
50#endif
40 51
41 return regs->r10 == -1 ? regs->r8:0; 52 return regs->r10 == -1 ? regs->r8:0;
42} 53}
@@ -44,8 +55,6 @@ static inline long syscall_get_error(struct task_struct *task,
44static inline long syscall_get_return_value(struct task_struct *task, 55static inline long syscall_get_return_value(struct task_struct *task,
45 struct pt_regs *regs) 56 struct pt_regs *regs)
46{ 57{
47 BUG_ON(IS_IA32_PROCESS(regs));
48
49 return regs->r8; 58 return regs->r8;
50} 59}
51 60
@@ -53,7 +62,12 @@ static inline void syscall_set_return_value(struct task_struct *task,
53 struct pt_regs *regs, 62 struct pt_regs *regs,
54 int error, long val) 63 int error, long val)
55{ 64{
56 BUG_ON(IS_IA32_PROCESS(regs)); 65#ifdef CONFIG_IA32_SUPPORT
66 if (IS_IA32_PROCESS(regs)) {
67 regs->r8 = (long) error ? error : val;
68 return;
69 }
70#endif
57 71
58 if (error) { 72 if (error) {
59 /* error < 0, but ia64 uses > 0 return value */ 73 /* error < 0, but ia64 uses > 0 return value */
@@ -73,9 +87,39 @@ static inline void syscall_get_arguments(struct task_struct *task,
73 unsigned int i, unsigned int n, 87 unsigned int i, unsigned int n,
74 unsigned long *args) 88 unsigned long *args)
75{ 89{
76 BUG_ON(IS_IA32_PROCESS(regs));
77 BUG_ON(i + n > 6); 90 BUG_ON(i + n > 6);
78 91
92#ifdef CONFIG_IA32_SUPPORT
93 if (IS_IA32_PROCESS(regs)) {
94 switch (i + n) {
95 case 6:
96 if (!n--) break;
97 *args++ = regs->r13;
98 case 5:
99 if (!n--) break;
100 *args++ = regs->r15;
101 case 4:
102 if (!n--) break;
103 *args++ = regs->r14;
104 case 3:
105 if (!n--) break;
106 *args++ = regs->r10;
107 case 2:
108 if (!n--) break;
109 *args++ = regs->r9;
110 case 1:
111 if (!n--) break;
112 *args++ = regs->r11;
113 case 0:
114 if (!n--) break;
115 default:
116 BUG();
117 break;
118 }
119
120 return;
121 }
122#endif
79 ia64_syscall_get_set_arguments(task, regs, i, n, args, 0); 123 ia64_syscall_get_set_arguments(task, regs, i, n, args, 0);
80} 124}
81 125
@@ -84,9 +128,36 @@ static inline void syscall_set_arguments(struct task_struct *task,
84 unsigned int i, unsigned int n, 128 unsigned int i, unsigned int n,
85 unsigned long *args) 129 unsigned long *args)
86{ 130{
87 BUG_ON(IS_IA32_PROCESS(regs));
88 BUG_ON(i + n > 6); 131 BUG_ON(i + n > 6);
89 132
133#ifdef CONFIG_IA32_SUPPORT
134 if (IS_IA32_PROCESS(regs)) {
135 switch (i + n) {
136 case 6:
137 if (!n--) break;
138 regs->r13 = *args++;
139 case 5:
140 if (!n--) break;
141 regs->r15 = *args++;
142 case 4:
143 if (!n--) break;
144 regs->r14 = *args++;
145 case 3:
146 if (!n--) break;
147 regs->r10 = *args++;
148 case 2:
149 if (!n--) break;
150 regs->r9 = *args++;
151 case 1:
152 if (!n--) break;
153 regs->r11 = *args++;
154 case 0:
155 if (!n--) break;
156 }
157
158 return;
159 }
160#endif
90 ia64_syscall_get_set_arguments(task, regs, i, n, args, 1); 161 ia64_syscall_get_set_arguments(task, regs, i, n, args, 1);
91} 162}
92#endif /* _ASM_SYSCALL_H */ 163#endif /* _ASM_SYSCALL_H */