ptrace.c (f45727d52d1581e9ff4df9d1a12a60789ad2d1eb) ptrace.c (347a8dc3b815f0c0fa62a1df075184ffe4cbdcf1)
1/*
2 * arch/s390/kernel/ptrace.c
3 *
4 * S390 version
5 * Copyright (C) 1999,2000 IBM Deutschland Entwicklung GmbH, IBM Corporation
6 * Author(s): Denis Joseph Barrow (djbarrow@de.ibm.com,barrow_dj@yahoo.com),
7 * Martin Schwidefsky (schwidefsky@de.ibm.com)
8 *

--- 28 unchanged lines hidden (view full) ---

37#include <asm/segment.h>
38#include <asm/page.h>
39#include <asm/pgtable.h>
40#include <asm/pgalloc.h>
41#include <asm/system.h>
42#include <asm/uaccess.h>
43#include <asm/unistd.h>
44
1/*
2 * arch/s390/kernel/ptrace.c
3 *
4 * S390 version
5 * Copyright (C) 1999,2000 IBM Deutschland Entwicklung GmbH, IBM Corporation
6 * Author(s): Denis Joseph Barrow (djbarrow@de.ibm.com,barrow_dj@yahoo.com),
7 * Martin Schwidefsky (schwidefsky@de.ibm.com)
8 *

--- 28 unchanged lines hidden (view full) ---

37#include <asm/segment.h>
38#include <asm/page.h>
39#include <asm/pgtable.h>
40#include <asm/pgalloc.h>
41#include <asm/system.h>
42#include <asm/uaccess.h>
43#include <asm/unistd.h>
44
45#ifdef CONFIG_S390_SUPPORT
45#ifdef CONFIG_COMPAT
46#include "compat_ptrace.h"
47#endif
48
49static void
50FixPerRegisters(struct task_struct *task)
51{
52 struct pt_regs *regs;
53 per_struct *per_info;
54
55 regs = __KSTK_PTREGS(task);
56 per_info = (per_struct *) &task->thread.per_info;
57 per_info->control_regs.bits.em_instruction_fetch =
58 per_info->single_step | per_info->instruction_fetch;
59
60 if (per_info->single_step) {
61 per_info->control_regs.bits.starting_addr = 0;
46#include "compat_ptrace.h"
47#endif
48
49static void
50FixPerRegisters(struct task_struct *task)
51{
52 struct pt_regs *regs;
53 per_struct *per_info;
54
55 regs = __KSTK_PTREGS(task);
56 per_info = (per_struct *) &task->thread.per_info;
57 per_info->control_regs.bits.em_instruction_fetch =
58 per_info->single_step | per_info->instruction_fetch;
59
60 if (per_info->single_step) {
61 per_info->control_regs.bits.starting_addr = 0;
62#ifdef CONFIG_S390_SUPPORT
62#ifdef CONFIG_COMPAT
63 if (test_thread_flag(TIF_31BIT))
64 per_info->control_regs.bits.ending_addr = 0x7fffffffUL;
65 else
66#endif
67 per_info->control_regs.bits.ending_addr = PSW_ADDR_INSN;
68 } else {
69 per_info->control_regs.bits.starting_addr =
70 per_info->starting_addr;

--- 36 unchanged lines hidden (view full) ---

107 */
108void
109ptrace_disable(struct task_struct *child)
110{
111 /* make sure the single step bit is not set. */
112 clear_single_step(child);
113}
114
63 if (test_thread_flag(TIF_31BIT))
64 per_info->control_regs.bits.ending_addr = 0x7fffffffUL;
65 else
66#endif
67 per_info->control_regs.bits.ending_addr = PSW_ADDR_INSN;
68 } else {
69 per_info->control_regs.bits.starting_addr =
70 per_info->starting_addr;

--- 36 unchanged lines hidden (view full) ---

107 */
108void
109ptrace_disable(struct task_struct *child)
110{
111 /* make sure the single step bit is not set. */
112 clear_single_step(child);
113}
114
115#ifndef CONFIG_ARCH_S390X
115#ifndef CONFIG_64BIT
116# define __ADDR_MASK 3
117#else
118# define __ADDR_MASK 7
119#endif
120
121/*
122 * Read the word at offset addr from the user area of a process. The
123 * trouble here is that the information is littered over different

--- 9 unchanged lines hidden (view full) ---

133 struct user *dummy = NULL;
134 addr_t offset, tmp, mask;
135
136 /*
137 * Stupid gdb peeks/pokes the access registers in 64 bit with
138 * an alignment of 4. Programmers from hell...
139 */
140 mask = __ADDR_MASK;
116# define __ADDR_MASK 3
117#else
118# define __ADDR_MASK 7
119#endif
120
121/*
122 * Read the word at offset addr from the user area of a process. The
123 * trouble here is that the information is littered over different

--- 9 unchanged lines hidden (view full) ---

133 struct user *dummy = NULL;
134 addr_t offset, tmp, mask;
135
136 /*
137 * Stupid gdb peeks/pokes the access registers in 64 bit with
138 * an alignment of 4. Programmers from hell...
139 */
140 mask = __ADDR_MASK;
141#ifdef CONFIG_ARCH_S390X
141#ifdef CONFIG_64BIT
142 if (addr >= (addr_t) &dummy->regs.acrs &&
143 addr < (addr_t) &dummy->regs.orig_gpr2)
144 mask = 3;
145#endif
146 if ((addr & mask) || addr > sizeof(struct user) - __ADDR_MASK)
147 return -EIO;
148
149 if (addr < (addr_t) &dummy->regs.acrs) {

--- 5 unchanged lines hidden (view full) ---

155 /* Remove per bit from user psw. */
156 tmp &= ~PSW_MASK_PER;
157
158 } else if (addr < (addr_t) &dummy->regs.orig_gpr2) {
159 /*
160 * access registers are stored in the thread structure
161 */
162 offset = addr - (addr_t) &dummy->regs.acrs;
142 if (addr >= (addr_t) &dummy->regs.acrs &&
143 addr < (addr_t) &dummy->regs.orig_gpr2)
144 mask = 3;
145#endif
146 if ((addr & mask) || addr > sizeof(struct user) - __ADDR_MASK)
147 return -EIO;
148
149 if (addr < (addr_t) &dummy->regs.acrs) {

--- 5 unchanged lines hidden (view full) ---

155 /* Remove per bit from user psw. */
156 tmp &= ~PSW_MASK_PER;
157
158 } else if (addr < (addr_t) &dummy->regs.orig_gpr2) {
159 /*
160 * access registers are stored in the thread structure
161 */
162 offset = addr - (addr_t) &dummy->regs.acrs;
163#ifdef CONFIG_ARCH_S390X
163#ifdef CONFIG_64BIT
164 /*
165 * Very special case: old & broken 64 bit gdb reading
166 * from acrs[15]. Result is a 64 bit value. Read the
167 * 32 bit acrs[15] value and shift it by 32. Sick...
168 */
169 if (addr == (addr_t) &dummy->regs.acrs[15])
170 tmp = ((unsigned long) child->thread.acrs[15]) << 32;
171 else

--- 41 unchanged lines hidden (view full) ---

213 struct user *dummy = NULL;
214 addr_t offset, mask;
215
216 /*
217 * Stupid gdb peeks/pokes the access registers in 64 bit with
218 * an alignment of 4. Programmers from hell indeed...
219 */
220 mask = __ADDR_MASK;
164 /*
165 * Very special case: old & broken 64 bit gdb reading
166 * from acrs[15]. Result is a 64 bit value. Read the
167 * 32 bit acrs[15] value and shift it by 32. Sick...
168 */
169 if (addr == (addr_t) &dummy->regs.acrs[15])
170 tmp = ((unsigned long) child->thread.acrs[15]) << 32;
171 else

--- 41 unchanged lines hidden (view full) ---

213 struct user *dummy = NULL;
214 addr_t offset, mask;
215
216 /*
217 * Stupid gdb peeks/pokes the access registers in 64 bit with
218 * an alignment of 4. Programmers from hell indeed...
219 */
220 mask = __ADDR_MASK;
221#ifdef CONFIG_ARCH_S390X
221#ifdef CONFIG_64BIT
222 if (addr >= (addr_t) &dummy->regs.acrs &&
223 addr < (addr_t) &dummy->regs.orig_gpr2)
224 mask = 3;
225#endif
226 if ((addr & mask) || addr > sizeof(struct user) - __ADDR_MASK)
227 return -EIO;
228
229 if (addr < (addr_t) &dummy->regs.acrs) {
230 /*
231 * psw and gprs are stored on the stack
232 */
233 if (addr == (addr_t) &dummy->regs.psw.mask &&
222 if (addr >= (addr_t) &dummy->regs.acrs &&
223 addr < (addr_t) &dummy->regs.orig_gpr2)
224 mask = 3;
225#endif
226 if ((addr & mask) || addr > sizeof(struct user) - __ADDR_MASK)
227 return -EIO;
228
229 if (addr < (addr_t) &dummy->regs.acrs) {
230 /*
231 * psw and gprs are stored on the stack
232 */
233 if (addr == (addr_t) &dummy->regs.psw.mask &&
234#ifdef CONFIG_S390_SUPPORT
234#ifdef CONFIG_COMPAT
235 data != PSW_MASK_MERGE(PSW_USER32_BITS, data) &&
236#endif
237 data != PSW_MASK_MERGE(PSW_USER_BITS, data))
238 /* Invalid psw mask. */
239 return -EINVAL;
235 data != PSW_MASK_MERGE(PSW_USER32_BITS, data) &&
236#endif
237 data != PSW_MASK_MERGE(PSW_USER_BITS, data))
238 /* Invalid psw mask. */
239 return -EINVAL;
240#ifndef CONFIG_ARCH_S390X
240#ifndef CONFIG_64BIT
241 if (addr == (addr_t) &dummy->regs.psw.addr)
242 /* I'd like to reject addresses without the
243 high order bit but older gdb's rely on it */
244 data |= PSW_ADDR_AMODE;
245#endif
246 *(addr_t *)((addr_t) &__KSTK_PTREGS(child)->psw + addr) = data;
247
248 } else if (addr < (addr_t) (&dummy->regs.orig_gpr2)) {
249 /*
250 * access registers are stored in the thread structure
251 */
252 offset = addr - (addr_t) &dummy->regs.acrs;
241 if (addr == (addr_t) &dummy->regs.psw.addr)
242 /* I'd like to reject addresses without the
243 high order bit but older gdb's rely on it */
244 data |= PSW_ADDR_AMODE;
245#endif
246 *(addr_t *)((addr_t) &__KSTK_PTREGS(child)->psw + addr) = data;
247
248 } else if (addr < (addr_t) (&dummy->regs.orig_gpr2)) {
249 /*
250 * access registers are stored in the thread structure
251 */
252 offset = addr - (addr_t) &dummy->regs.acrs;
253#ifdef CONFIG_ARCH_S390X
253#ifdef CONFIG_64BIT
254 /*
255 * Very special case: old & broken 64 bit gdb writing
256 * to acrs[15] with a 64 bit value. Ignore the lower
257 * half of the value and write the upper 32 bit to
258 * acrs[15]. Sick...
259 */
260 if (addr == (addr_t) &dummy->regs.acrs[15])
261 child->thread.acrs[15] = (unsigned int) (data >> 32);

--- 90 unchanged lines hidden (view full) ---

352 data += sizeof(unsigned long);
353 copied += sizeof(unsigned long);
354 }
355 return 0;
356 }
357 return ptrace_request(child, request, addr, data);
358}
359
254 /*
255 * Very special case: old & broken 64 bit gdb writing
256 * to acrs[15] with a 64 bit value. Ignore the lower
257 * half of the value and write the upper 32 bit to
258 * acrs[15]. Sick...
259 */
260 if (addr == (addr_t) &dummy->regs.acrs[15])
261 child->thread.acrs[15] = (unsigned int) (data >> 32);

--- 90 unchanged lines hidden (view full) ---

352 data += sizeof(unsigned long);
353 copied += sizeof(unsigned long);
354 }
355 return 0;
356 }
357 return ptrace_request(child, request, addr, data);
358}
359
360#ifdef CONFIG_S390_SUPPORT
360#ifdef CONFIG_COMPAT
361/*
362 * Now the fun part starts... a 31 bit program running in the
363 * 31 bit emulation tracing another program. PTRACE_PEEKTEXT,
364 * PTRACE_PEEKDATA, PTRACE_POKETEXT and PTRACE_POKEDATA are easy
365 * to handle, the difference to the 64 bit versions of the requests
366 * is that the access is done in multiples of 4 byte instead of
367 * 8 bytes (sizeof(unsigned long) on 31/64 bit).
368 * The ugly part are PTRACE_PEEKUSR, PTRACE_PEEKUSR_AREA,

--- 255 unchanged lines hidden (view full) ---

624 /*
625 * Special cases to get/store the ieee instructions pointer.
626 */
627 if (child == current) {
628 if (request == PTRACE_PEEKUSR && addr == PT_IEEE_IP)
629 return peek_user(child, addr, data);
630 if (request == PTRACE_POKEUSR && addr == PT_IEEE_IP)
631 return poke_user(child, addr, data);
361/*
362 * Now the fun part starts... a 31 bit program running in the
363 * 31 bit emulation tracing another program. PTRACE_PEEKTEXT,
364 * PTRACE_PEEKDATA, PTRACE_POKETEXT and PTRACE_POKEDATA are easy
365 * to handle, the difference to the 64 bit versions of the requests
366 * is that the access is done in multiples of 4 byte instead of
367 * 8 bytes (sizeof(unsigned long) on 31/64 bit).
368 * The ugly part are PTRACE_PEEKUSR, PTRACE_PEEKUSR_AREA,

--- 255 unchanged lines hidden (view full) ---

624 /*
625 * Special cases to get/store the ieee instructions pointer.
626 */
627 if (child == current) {
628 if (request == PTRACE_PEEKUSR && addr == PT_IEEE_IP)
629 return peek_user(child, addr, data);
630 if (request == PTRACE_POKEUSR && addr == PT_IEEE_IP)
631 return poke_user(child, addr, data);
632#ifdef CONFIG_S390_SUPPORT
632#ifdef CONFIG_COMPAT
633 if (request == PTRACE_PEEKUSR &&
634 addr == PT32_IEEE_IP && test_thread_flag(TIF_31BIT))
635 return peek_user_emu31(child, addr, data);
636 if (request == PTRACE_POKEUSR &&
637 addr == PT32_IEEE_IP && test_thread_flag(TIF_31BIT))
638 return poke_user_emu31(child, addr, data);
639#endif
640 }

--- 49 unchanged lines hidden (view full) ---

690
691 case PTRACE_DETACH:
692 /* detach a process that was attached. */
693 return ptrace_detach(child, data);
694
695
696 /* Do requests that differ for 31/64 bit */
697 default:
633 if (request == PTRACE_PEEKUSR &&
634 addr == PT32_IEEE_IP && test_thread_flag(TIF_31BIT))
635 return peek_user_emu31(child, addr, data);
636 if (request == PTRACE_POKEUSR &&
637 addr == PT32_IEEE_IP && test_thread_flag(TIF_31BIT))
638 return poke_user_emu31(child, addr, data);
639#endif
640 }

--- 49 unchanged lines hidden (view full) ---

690
691 case PTRACE_DETACH:
692 /* detach a process that was attached. */
693 return ptrace_detach(child, data);
694
695
696 /* Do requests that differ for 31/64 bit */
697 default:
698#ifdef CONFIG_S390_SUPPORT
698#ifdef CONFIG_COMPAT
699 if (test_thread_flag(TIF_31BIT))
700 return do_ptrace_emu31(child, request, addr, data);
701#endif
702 return do_ptrace_normal(child, request, addr, data);
703 }
704 /* Not reached. */
705 return -EIO;
706}

--- 79 unchanged lines hidden ---
699 if (test_thread_flag(TIF_31BIT))
700 return do_ptrace_emu31(child, request, addr, data);
701#endif
702 return do_ptrace_normal(child, request, addr, data);
703 }
704 /* Not reached. */
705 return -EIO;
706}

--- 79 unchanged lines hidden ---