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.
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.
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.
19 #include <machine/archtypes.h>
20 #include <minix/timers.h>
21 #include "kernel/proc.h"
22 #include "kernel/priv.h"
24 #include "kernel/arch/i386/include/archconst.h" /* for the KTS_ constants */
29 * Working area. By obtaining values from the kernel into these local process
30 * structures, and then returning them, we gain a little robustness against
31 * changes in data types of the fields we need.
33 static struct proc kernel_proc
;
34 static struct priv kernel_priv
;
37 * Check whether our notion of the kernel process structure layout matches that
38 * of the kernel, by comparing magic values. This can be done only once we
39 * have attached to a process. Return TRUE if everything seems alright; FALSE
43 kernel_check(pid_t pid
)
46 if (mem_get_user(pid
, offsetof(struct proc
, p_magic
),
47 &kernel_proc
.p_magic
, sizeof(kernel_proc
.p_magic
)) < 0)
50 return (kernel_proc
.p_magic
== PMAGIC
);
54 * Obtain the kernel name for the given (stopped) process. Return 0 on
55 * success, with the (possibly truncated) name stored in the 'name' buffer
56 * which is of 'size' bytes; the name will be null-terminated. Note that the
57 * name may contain any suffixes as set by the kernel. Return -1 on failure,
58 * with errno set as appropriate.
61 kernel_get_name(pid_t pid
, char * name
, size_t size
)
64 if (mem_get_user(pid
, offsetof(struct proc
, p_name
),
65 kernel_proc
.p_name
, sizeof(kernel_proc
.p_name
)) < 0)
68 strlcpy(name
, kernel_proc
.p_name
, size
);
73 * Check whether the given process, which we have just attached to, is a system
74 * service. PM does not prevent us from attaching to most system services,
75 * even though this utility only supports tracing user programs. Unlike a few
76 * other routines in this file, this function can not use ProcFS to obtain its
77 * result, because the given process may actually be VFS or ProcFS itself!
78 * Return TRUE if the given process is a system service; FALSE if not.
81 kernel_is_service(pid_t pid
)
86 * For T_GETUSER, the priv structure follows the proc structure, but
87 * possibly with padding in between so as to align the priv structure
90 align
= sizeof(long) - 1;
91 off
= (sizeof(struct proc
) + align
) & ~align
;
93 if (mem_get_user(pid
, off
+ offsetof(struct priv
, s_id
),
94 &kernel_priv
.s_id
, sizeof(kernel_priv
.s_id
)) < 0)
95 return FALSE
; /* process may have disappeared, so no danger */
97 return (kernel_priv
.s_id
!= USER_PRIV_ID
);
101 * For the given process, which must be stopped on entering a system call,
102 * retrieve the three register values describing the system call. Return 0 on
103 * success, or -1 on failure with errno set as appropriate.
106 kernel_get_syscall(pid_t pid
, reg_t reg
[3])
109 assert(sizeof(kernel_proc
.p_defer
) == sizeof(reg_t
) * 3);
111 if (mem_get_user(pid
, offsetof(struct proc
, p_defer
),
112 &kernel_proc
.p_defer
, sizeof(kernel_proc
.p_defer
)) < 0)
115 reg
[0] = kernel_proc
.p_defer
.r1
;
116 reg
[1] = kernel_proc
.p_defer
.r2
;
117 reg
[2] = kernel_proc
.p_defer
.r3
;
122 * Retrieve the value of the primary return register for the given process,
123 * which must be stopped on leaving a system call. This register contains the
124 * IPC-level result of the system call. Return 0 on success, or -1 on failure
125 * with errno set as appropriate.
128 kernel_get_retreg(pid_t pid
, reg_t
* retreg
)
133 * Historically p_reg had to be the first field in the proc structure,
134 * but since this is no longer a hard requirement, getting its actual
135 * offset into the proc structure certainly doesn't hurt.
137 off
= offsetof(struct proc
, p_reg
);
139 if (mem_get_user(pid
, off
+ offsetof(struct stackframe_s
, retreg
),
140 &kernel_proc
.p_reg
.retreg
, sizeof(kernel_proc
.p_reg
.retreg
)) < 0)
143 *retreg
= kernel_proc
.p_reg
.retreg
;
148 * Return the stack top for user processes. This is needed for execve(), since
149 * the supplied frame contains pointers prepared for the new location of the
150 * frame, which is at the stack top of the process after the execve().
153 kernel_get_stacktop(void)
156 return minix_get_user_sp();
160 * For the given stopped process, get its program counter (pc), stack pointer
161 * (sp), and optionally its frame pointer (fp). The given fp pointer may be
162 * NULL, in which case the frame pointer is not obtained. The given pc and sp
163 * pointers must not be NULL, and this is intentional: obtaining fp may require
164 * obtaining sp first. Return 0 on success, or -1 on failure with errno set
165 * as appropriate. This functionality is not essential for tracing processes,
166 * and may not be supported on all platforms, in part or full. In particular,
167 * on some platforms, a zero (= invalid) frame pointer may be returned on
168 * success, indicating that obtaining frame pointers is not supported.
171 kernel_get_context(pid_t pid
, reg_t
* pc
, reg_t
* sp
, reg_t
* fp
)
175 off
= offsetof(struct proc
, p_reg
); /* as above */
177 if (mem_get_user(pid
, off
+ offsetof(struct stackframe_s
, pc
),
178 &kernel_proc
.p_reg
.pc
, sizeof(kernel_proc
.p_reg
.pc
)) < 0)
180 if (mem_get_user(pid
, off
+ offsetof(struct stackframe_s
, sp
),
181 &kernel_proc
.p_reg
.sp
, sizeof(kernel_proc
.p_reg
.sp
)) < 0)
184 *pc
= kernel_proc
.p_reg
.pc
;
185 *sp
= kernel_proc
.p_reg
.sp
;
190 #if defined(__i386__)
191 if (mem_get_user(pid
, offsetof(struct proc
, p_seg
) +
192 offsetof(struct segframe
, p_kern_trap_style
),
193 &kernel_proc
.p_seg
.p_kern_trap_style
,
194 sizeof(kernel_proc
.p_seg
.p_kern_trap_style
)) < 0)
197 /* This is taken from the kernel i386 exception code. */
198 switch (kernel_proc
.p_seg
.p_kern_trap_style
) {
201 if (mem_get_data(pid
, *sp
+ 16, fp
, sizeof(fp
)) < 0)
206 if (mem_get_user(pid
, off
+ offsetof(struct stackframe_s
, fp
),
207 &kernel_proc
.p_reg
.fp
, sizeof(kernel_proc
.p_reg
.fp
)) < 0)
210 *fp
= kernel_proc
.p_reg
.fp
;
213 *fp
= 0; /* not supported; this is not a failure (*pc is valid) */
219 * Given a frame pointer, obtain the next program counter and frame pointer.
220 * Return 0 if successful, or -1 on failure with errno set appropriately. The
221 * functionality is not essential for tracing processes, and may not be
222 * supported on all platforms. Thus, on some platforms, this function may
226 kernel_get_nextframe(pid_t pid
, reg_t fp
, reg_t
* next_pc
, reg_t
* next_fp
)
228 #if defined(__i386__)
231 if (mem_get_data(pid
, (vir_bytes
)fp
, &p
, sizeof(p
)) < 0)
234 *next_pc
= (reg_t
)p
[1];
235 *next_fp
= (reg_t
)p
[0];
238 /* Not supported (yet). */
245 * Print a stack trace for the given process, which is known to be stopped on
246 * entering a system call. This function does not really belong here, but
247 * without a doubt it is going to have to be fully rewritten to support
248 * anything other than i386.
250 * Getting symbol names is currently an absolute nightmare. Not just because
251 * of shared libraries, but also since ProcFS does not offer a /proc/NNN/exe,
252 * so that we cannot reliably determine the binary being executed: not for
253 * processes being attached to, and not for exec calls using a relative path.
256 kernel_put_stacktrace(struct trace_proc
* procp
)
258 unsigned int count
, max
;
259 reg_t pc
, sp
, fp
, low
, high
;
261 if (kernel_get_context(procp
->pid
, &pc
, &sp
, &fp
) < 0)
265 * A low default limit such as 6 looks much prettier, but is simply not
266 * useful enough for moderately-sized programs in practice. Right now,
267 * 15 is about two lines on a 80-column terminal.
269 if (verbose
== 0) max
= 15;
270 else if (verbose
== 1) max
= 31;
274 * We keep formatting to an absolute minimum, to facilitate passing
275 * the lines straight into tools such as addr2line.
278 put_fmt(procp
, " 0x%x", pc
);
282 for (count
= 1; count
< max
&& fp
!= 0; count
++) {
283 if (kernel_get_nextframe(procp
->pid
, fp
, &pc
, &fp
) < 0)
286 put_fmt(procp
, " 0x%x", pc
);
289 * Stop if we see a frame pointer that falls within the range
290 * of the frame pointers we have seen so far. This also
291 * prevents getting stuck in a loop on the same frame pointer.
293 if (fp
>= low
&& fp
<= high
)
302 put_text(procp
, " ..");