1 /* 2 * This file, and only this file, should contain all the ugliness needed to 3 * obtain values from the kernel. It has to be recompiled every time the 4 * layout of the kernel "struct proc" and/or "struct priv" structures changes. 5 * In addition, this file contains the platform-dependent code related to 6 * interpreting the registers exposed by the kernel. 7 * 8 * As a quick note, some functions return TRUE/FALSE, and some return 0/-1. 9 * The former convention is used for functions that return a boolean value; 10 * the latter is used for functions that set errno in all cases of failure, 11 * and where the caller may conceivably use errno as a result. 12 * 13 * On a related note, relevant here and elsewhere: we define _MINIX_SYSTEM but 14 * not _SYSTEM, which means that we should not get negative error numbers. 15 */ 16 17 #include "inc.h" 18 19 #include <machine/archtypes.h> 20 #include <minix/timers.h> 21 #include "kernel/proc.h" 22 #include "kernel/priv.h" 23 #if defined(__i386__) 24 #include "kernel/arch/i386/include/archconst.h" /* for the KTS_ constants */ 25 #endif 26 27 #include <minix/param.h> 28 29 extern struct minix_kerninfo *_minix_kerninfo; 30 31 /* 32 * Working area. By obtaining values from the kernel into these local process 33 * structures, and then returning them, we gain a little robustness against 34 * changes in data types of the fields we need. 35 */ 36 static struct proc kernel_proc; 37 static struct priv kernel_priv; 38 39 /* 40 * Check whether our notion of the kernel process structure layout matches that 41 * of the kernel, by comparing magic values. This can be done only once we 42 * have attached to a process. Return TRUE if everything seems alright; FALSE 43 * otherwise. 44 */ 45 int 46 kernel_check(pid_t pid) 47 { 48 49 if (mem_get_user(pid, offsetof(struct proc, p_magic), 50 &kernel_proc.p_magic, sizeof(kernel_proc.p_magic)) < 0) 51 return FALSE; 52 53 return (kernel_proc.p_magic == PMAGIC); 54 } 55 56 /* 57 * Obtain the kernel name for the given (stopped) process. Return 0 on 58 * success, with the (possibly truncated) name stored in the 'name' buffer 59 * which is of 'size' bytes; the name will be null-terminated. Note that the 60 * name may contain any suffixes as set by the kernel. Return -1 on failure, 61 * with errno set as appropriate. 62 */ 63 int 64 kernel_get_name(pid_t pid, char * name, size_t size) 65 { 66 67 if (mem_get_user(pid, offsetof(struct proc, p_name), 68 kernel_proc.p_name, sizeof(kernel_proc.p_name)) < 0) 69 return -1; 70 71 strlcpy(name, kernel_proc.p_name, size); 72 return 0; 73 } 74 75 /* 76 * Check whether the given process, which we have just attached to, is a system 77 * service. PM does not prevent us from attaching to most system services, 78 * even though this utility only supports tracing user programs. Unlike a few 79 * other routines in this file, this function can not use ProcFS to obtain its 80 * result, because the given process may actually be VFS or ProcFS itself! 81 * Return TRUE if the given process is a system service; FALSE if not. 82 */ 83 int 84 kernel_is_service(pid_t pid) 85 { 86 size_t align, off; 87 88 /* 89 * For T_GETUSER, the priv structure follows the proc structure, but 90 * possibly with padding in between so as to align the priv structure 91 * to long boundary. 92 */ 93 align = sizeof(long) - 1; 94 off = (sizeof(struct proc) + align) & ~align; 95 96 if (mem_get_user(pid, off + offsetof(struct priv, s_id), 97 &kernel_priv.s_id, sizeof(kernel_priv.s_id)) < 0) 98 return FALSE; /* process may have disappeared, so no danger */ 99 100 return (kernel_priv.s_id != USER_PRIV_ID); 101 } 102 103 /* 104 * For the given process, which must be stopped on entering a system call, 105 * retrieve the three register values describing the system call. Return 0 on 106 * success, or -1 on failure with errno set as appropriate. 107 */ 108 int 109 kernel_get_syscall(pid_t pid, reg_t reg[3]) 110 { 111 112 assert(sizeof(kernel_proc.p_defer) == sizeof(reg_t) * 3); 113 114 if (mem_get_user(pid, offsetof(struct proc, p_defer), 115 &kernel_proc.p_defer, sizeof(kernel_proc.p_defer)) < 0) 116 return -1; 117 118 reg[0] = kernel_proc.p_defer.r1; 119 reg[1] = kernel_proc.p_defer.r2; 120 reg[2] = kernel_proc.p_defer.r3; 121 return 0; 122 } 123 124 /* 125 * Retrieve the value of the primary return register for the given process, 126 * which must be stopped on leaving a system call. This register contains the 127 * IPC-level result of the system call. Return 0 on success, or -1 on failure 128 * with errno set as appropriate. 129 */ 130 int 131 kernel_get_retreg(pid_t pid, reg_t * retreg) 132 { 133 size_t off; 134 135 /* 136 * Historically p_reg had to be the first field in the proc structure, 137 * but since this is no longer a hard requirement, getting its actual 138 * offset into the proc structure certainly doesn't hurt. 139 */ 140 off = offsetof(struct proc, p_reg); 141 142 if (mem_get_user(pid, off + offsetof(struct stackframe_s, retreg), 143 &kernel_proc.p_reg.retreg, sizeof(kernel_proc.p_reg.retreg)) < 0) 144 return -1; 145 146 *retreg = kernel_proc.p_reg.retreg; 147 return 0; 148 } 149 150 /* 151 * Return the stack top for user processes. This is needed for execve(), since 152 * the supplied frame contains pointers prepared for the new location of the 153 * frame, which is at the stack top of the process after the execve(). 154 */ 155 vir_bytes 156 kernel_get_stacktop(void) 157 { 158 159 return _minix_kerninfo->kinfo->user_sp; 160 } 161 162 /* 163 * For the given stopped process, get its program counter (pc), stack pointer 164 * (sp), and optionally its frame pointer (fp). The given fp pointer may be 165 * NULL, in which case the frame pointer is not obtained. The given pc and sp 166 * pointers must not be NULL, and this is intentional: obtaining fp may require 167 * obtaining sp first. Return 0 on success, or -1 on failure with errno set 168 * as appropriate. This functionality is not essential for tracing processes, 169 * and may not be supported on all platforms, in part or full. In particular, 170 * on some platforms, a zero (= invalid) frame pointer may be returned on 171 * success, indicating that obtaining frame pointers is not supported. 172 */ 173 int 174 kernel_get_context(pid_t pid, reg_t * pc, reg_t * sp, reg_t * fp) 175 { 176 size_t off; 177 178 off = offsetof(struct proc, p_reg); /* as above */ 179 180 if (mem_get_user(pid, off + offsetof(struct stackframe_s, pc), 181 &kernel_proc.p_reg.pc, sizeof(kernel_proc.p_reg.pc)) < 0) 182 return -1; 183 if (mem_get_user(pid, off + offsetof(struct stackframe_s, sp), 184 &kernel_proc.p_reg.sp, sizeof(kernel_proc.p_reg.sp)) < 0) 185 return -1; 186 187 *pc = kernel_proc.p_reg.pc; 188 *sp = kernel_proc.p_reg.sp; 189 190 if (fp == NULL) 191 return 0; 192 193 #if defined(__i386__) 194 if (mem_get_user(pid, offsetof(struct proc, p_seg) + 195 offsetof(struct segframe, p_kern_trap_style), 196 &kernel_proc.p_seg.p_kern_trap_style, 197 sizeof(kernel_proc.p_seg.p_kern_trap_style)) < 0) 198 return -1; 199 200 /* This is taken from the kernel i386 exception code. */ 201 switch (kernel_proc.p_seg.p_kern_trap_style) { 202 case KTS_SYSENTER: 203 case KTS_SYSCALL: 204 if (mem_get_data(pid, *sp + 16, fp, sizeof(fp)) < 0) 205 return -1; 206 break; 207 208 default: 209 if (mem_get_user(pid, off + offsetof(struct stackframe_s, fp), 210 &kernel_proc.p_reg.fp, sizeof(kernel_proc.p_reg.fp)) < 0) 211 return -1; 212 213 *fp = kernel_proc.p_reg.fp; 214 } 215 #else 216 *fp = 0; /* not supported; this is not a failure (*pc is valid) */ 217 #endif 218 return 0; 219 } 220 221 /* 222 * Given a frame pointer, obtain the next program counter and frame pointer. 223 * Return 0 if successful, or -1 on failure with errno set appropriately. The 224 * functionality is not essential for tracing processes, and may not be 225 * supported on all platforms. Thus, on some platforms, this function may 226 * always fail. 227 */ 228 static int 229 kernel_get_nextframe(pid_t pid, reg_t fp, reg_t * next_pc, reg_t * next_fp) 230 { 231 #if defined(__i386__) 232 void *p[2]; 233 234 if (mem_get_data(pid, (vir_bytes)fp, &p, sizeof(p)) < 0) 235 return -1; 236 237 *next_pc = (reg_t)p[1]; 238 *next_fp = (reg_t)p[0]; 239 return 0; 240 #else 241 /* Not supported (yet). */ 242 errno = ENOSYS; 243 return -1; 244 #endif 245 } 246 247 /* 248 * Print a stack trace for the given process, which is known to be stopped on 249 * entering a system call. This function does not really belong here, but 250 * without a doubt it is going to have to be fully rewritten to support 251 * anything other than i386. 252 * 253 * Getting symbol names is currently an absolute nightmare. Not just because 254 * of shared libraries, but also since ProcFS does not offer a /proc/NNN/exe, 255 * so that we cannot reliably determine the binary being executed: not for 256 * processes being attached to, and not for exec calls using a relative path. 257 */ 258 void 259 kernel_put_stacktrace(struct trace_proc * proc) 260 { 261 unsigned int count, max; 262 reg_t pc, sp, fp, low, high; 263 264 if (kernel_get_context(proc->pid, &pc, &sp, &fp) < 0) 265 return; 266 267 /* 268 * A low default limit such as 6 looks much prettier, but is simply not 269 * useful enough for moderately-sized programs in practice. Right now, 270 * 15 is about two lines on a 80-column terminal. 271 */ 272 if (verbose == 0) max = 15; 273 else if (verbose == 1) max = 31; 274 else max = UINT_MAX; 275 276 /* 277 * We keep formatting to an absolute minimum, to facilitate passing 278 * the lines straight into tools such as addr2line. 279 */ 280 put_newline(); 281 put_fmt(proc, " 0x%x", pc); 282 283 low = high = fp; 284 285 for (count = 1; count < max && fp != 0; count++) { 286 if (kernel_get_nextframe(proc->pid, fp, &pc, &fp) < 0) 287 break; 288 289 put_fmt(proc, " 0x%x", pc); 290 291 /* 292 * Stop if we see a frame pointer that falls within the range 293 * of the frame pointers we have seen so far. This also 294 * prevents getting stuck in a loop on the same frame pointer. 295 */ 296 if (fp >= low && fp <= high) 297 break; 298 if (low > fp) 299 low = fp; 300 if (high < fp) 301 high = fp; 302 } 303 304 if (fp != 0) 305 put_text(proc, " .."); 306 put_newline(); 307 } 308