1 /* 2 * Copyright (c) 1991, 1992 Paul Kranenburg <pk (at) cs.few.eur.nl> 3 * Copyright (c) 1993 Branko Lankester <branko (at) hacktic.nl> 4 * Copyright (c) 1993, 1994, 1995, 1996 Rick Sladkey <jrs (at) world.std.com> 5 * Copyright (c) 1996-1999 Wichert Akkerman <wichert (at) cistron.nl> 6 * Copyright (c) 1999 IBM Deutschland Entwicklung GmbH, IBM Corporation 7 * Linux for s390 port by D.J. Barrow 8 * <barrow_dj (at) mail.yahoo.com,djbarrow (at) de.ibm.com> 9 * Copyright (c) 2000 PocketPenguins Inc. Linux for Hitachi SuperH 10 * port by Greg Banks <gbanks (at) pocketpenguins.com> 11 * 12 * All rights reserved. 13 * 14 * Redistribution and use in source and binary forms, with or without 15 * modification, are permitted provided that the following conditions 16 * are met: 17 * 1. Redistributions of source code must retain the above copyright 18 * notice, this list of conditions and the following disclaimer. 19 * 2. Redistributions in binary form must reproduce the above copyright 20 * notice, this list of conditions and the following disclaimer in the 21 * documentation and/or other materials provided with the distribution. 22 * 3. The name of the author may not be used to endorse or promote products 23 * derived from this software without specific prior written permission. 24 * 25 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 26 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 27 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 28 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 29 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 30 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 31 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 32 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 33 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 34 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 35 */ 36 37 #include "defs.h" 38 39 #ifdef HAVE_ELF_H 40 # include <elf.h> 41 #endif 42 43 #include "xlat/nt_descriptor_types.h" 44 45 #include "regs.h" 46 #include "ptrace.h" 47 #include "xlat/ptrace_cmds.h" 48 #include "xlat/ptrace_setoptions_flags.h" 49 #include "xlat/ptrace_peeksiginfo_flags.h" 50 51 #define uoff(member) offsetof(struct user, member) 52 #define XLAT_UOFF(member) { uoff(member), "offsetof(struct user, " #member ")" } 53 54 static const struct xlat struct_user_offsets[] = { 55 #include "userent.h" 56 XLAT_END 57 }; 58 59 static void 60 print_user_offset_addr(const kernel_ulong_t addr) 61 { 62 const struct xlat *x; 63 64 for (x = struct_user_offsets; x->str; ++x) { 65 if (x->val >= addr) 66 break; 67 } 68 69 if (!x->str) { 70 printaddr(addr); 71 } else if (x->val > addr) { 72 if (x == struct_user_offsets) { 73 printaddr(addr); 74 } else { 75 --x; 76 tprintf("%s + %" PRI_klu, 77 x->str, addr - (kernel_ulong_t) x->val); 78 } 79 } else { 80 tprints(x->str); 81 } 82 } 83 84 SYS_FUNC(ptrace) 85 { 86 const kernel_ulong_t request = tcp->u_arg[0]; 87 const int pid = tcp->u_arg[1]; 88 const kernel_ulong_t addr = tcp->u_arg[2]; 89 const kernel_ulong_t data = tcp->u_arg[3]; 90 91 if (entering(tcp)) { 92 /* request */ 93 printxval64(ptrace_cmds, request, "PTRACE_???"); 94 95 if (request == PTRACE_TRACEME) { 96 /* pid, addr, and data are ignored. */ 97 return RVAL_DECODED; 98 } 99 100 /* pid */ 101 tprintf(", %d", pid); 102 103 /* addr */ 104 switch (request) { 105 case PTRACE_ATTACH: 106 case PTRACE_INTERRUPT: 107 case PTRACE_KILL: 108 case PTRACE_LISTEN: 109 /* addr and data are ignored */ 110 return RVAL_DECODED; 111 case PTRACE_PEEKUSER: 112 case PTRACE_POKEUSER: 113 tprints(", "); 114 print_user_offset_addr(addr); 115 break; 116 case PTRACE_GETREGSET: 117 case PTRACE_SETREGSET: 118 tprints(", "); 119 printxval(nt_descriptor_types, addr, "NT_???"); 120 break; 121 case PTRACE_GETSIGMASK: 122 case PTRACE_SETSIGMASK: 123 case PTRACE_SECCOMP_GET_FILTER: 124 tprintf(", %" PRI_klu, addr); 125 break; 126 case PTRACE_PEEKSIGINFO: { 127 tprints(", "); 128 struct { 129 uint64_t off; 130 uint32_t flags; 131 uint32_t nr; 132 } psi; 133 if (umove_or_printaddr(tcp, addr, &psi)) { 134 tprints(", "); 135 printaddr(data); 136 return RVAL_DECODED; 137 } 138 tprintf("{off=%" PRIu64 ", flags=", psi.off); 139 printflags(ptrace_peeksiginfo_flags, psi.flags, 140 "PTRACE_PEEKSIGINFO_???"); 141 tprintf(", nr=%u}", psi.nr); 142 break; 143 } 144 default: 145 tprints(", "); 146 printaddr(addr); 147 } 148 149 # if defined IA64 || defined SPARC || defined SPARC64 150 switch (request) { 151 # ifdef IA64 152 case PTRACE_PEEKDATA: 153 case PTRACE_PEEKTEXT: 154 case PTRACE_PEEKUSER: 155 /* data is ignored */ 156 return RVAL_DECODED | RVAL_HEX; 157 # endif /* IA64 */ 158 # if defined SPARC || defined SPARC64 159 case PTRACE_GETREGS: 160 case PTRACE_SETREGS: 161 case PTRACE_GETFPREGS: 162 case PTRACE_SETFPREGS: 163 /* data is ignored */ 164 return RVAL_DECODED; 165 # endif /* SPARC || SPARC64 */ 166 } 167 # endif /* IA64 || SPARC || SPARC64 */ 168 169 tprints(", "); 170 171 /* data */ 172 switch (request) { 173 case PTRACE_CONT: 174 case PTRACE_DETACH: 175 case PTRACE_SYSCALL: 176 #ifdef PTRACE_SINGLESTEP 177 case PTRACE_SINGLESTEP: 178 #endif 179 #ifdef PTRACE_SINGLEBLOCK 180 case PTRACE_SINGLEBLOCK: 181 #endif 182 #ifdef PTRACE_SYSEMU 183 case PTRACE_SYSEMU: 184 #endif 185 #ifdef PTRACE_SYSEMU_SINGLESTEP 186 case PTRACE_SYSEMU_SINGLESTEP: 187 #endif 188 printsignal(data); 189 break; 190 case PTRACE_SEIZE: 191 case PTRACE_SETOPTIONS: 192 #ifdef PTRACE_OLDSETOPTIONS 193 case PTRACE_OLDSETOPTIONS: 194 #endif 195 printflags64(ptrace_setoptions_flags, data, "PTRACE_O_???"); 196 break; 197 case PTRACE_SETSIGINFO: 198 printsiginfo_at(tcp, data); 199 break; 200 case PTRACE_SETSIGMASK: 201 print_sigset_addr_len(tcp, data, addr); 202 break; 203 case PTRACE_SETREGSET: 204 tprint_iov(tcp, /*len:*/ 1, data, IOV_DECODE_ADDR); 205 break; 206 #ifndef IA64 207 case PTRACE_PEEKDATA: 208 case PTRACE_PEEKTEXT: 209 case PTRACE_PEEKUSER: 210 #endif 211 case PTRACE_GETEVENTMSG: 212 case PTRACE_GETREGSET: 213 case PTRACE_GETSIGINFO: 214 case PTRACE_GETSIGMASK: 215 case PTRACE_PEEKSIGINFO: 216 case PTRACE_SECCOMP_GET_FILTER: 217 if (verbose(tcp)) { 218 /* print data on exiting syscall */ 219 return 0; 220 } 221 /* fall through */ 222 default: 223 printaddr(data); 224 break; 225 } 226 227 return RVAL_DECODED; 228 } else { 229 switch (request) { 230 #ifndef IA64 231 case PTRACE_PEEKDATA: 232 case PTRACE_PEEKTEXT: 233 case PTRACE_PEEKUSER: 234 printnum_ptr(tcp, data); 235 break; 236 #endif 237 case PTRACE_GETEVENTMSG: 238 printnum_ulong(tcp, data); 239 break; 240 case PTRACE_GETREGSET: 241 tprint_iov(tcp, /*len:*/ 1, data, IOV_DECODE_ADDR); 242 break; 243 case PTRACE_GETSIGINFO: 244 printsiginfo_at(tcp, data); 245 break; 246 case PTRACE_GETSIGMASK: 247 print_sigset_addr_len(tcp, data, addr); 248 break; 249 case PTRACE_PEEKSIGINFO: 250 print_siginfo_array(tcp, data, tcp->u_rval); 251 break; 252 case PTRACE_SECCOMP_GET_FILTER: 253 print_seccomp_fprog(tcp, data, tcp->u_rval); 254 break; 255 } 256 } 257 return 0; 258 } 259