diff options
Diffstat (limited to 'arch/ia64')
-rw-r--r-- | arch/ia64/ia32/ia32_entry.S | 2 | ||||
-rw-r--r-- | arch/ia64/ia32/sys_ia32.c | 83 | ||||
-rw-r--r-- | arch/ia64/include/asm/ptrace.h | 2 | ||||
-rw-r--r-- | arch/ia64/include/asm/syscall.h | 89 |
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 | ||
1303 | static unsigned int | ||
1304 | ia32_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 | |||
1313 | static unsigned int | ||
1314 | ia32_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 | ||
1619 | asmlinkage long | 1600 | long compat_arch_ptrace(struct task_struct *child, compat_long_t request, |
1620 | sys32_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 @@ | |||
19 | static inline long syscall_get_nr(struct task_struct *task, | 19 | static 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 | ||
29 | static inline void syscall_rollback(struct task_struct *task, | 33 | static 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 | ||
36 | static inline long syscall_get_error(struct task_struct *task, | 44 | static 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, | |||
44 | static inline long syscall_get_return_value(struct task_struct *task, | 55 | static 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 */ |