4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License"). You may not use this file except in compliance
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
23 * Copyright (c) 1996-1998 by Sun Microsystems, Inc.
24 * All rights reserved.
27 #pragma ident "%Z%%M% %I% %E% SMI"
38 #include <sys/thread.h>
39 #include <sys/fcntl.h>
40 #include <sys/param.h>
49 struct proc
*tst_getproc(pid_t
);
50 struct proc
*tst_nextproc(void);
51 struct user
*tst_getu(struct proc
*);
52 int tst_setproc(void);
53 int tst_getcmd(struct proc
*, struct user
*);
55 void tst_nlist(struct nlist nl
[]);
56 void tst_open(char *, char *, char *, int);
58 ssize_t
tst_read(uintptr_t, void *, size_t);
59 ssize_t
tst_write(uintptr_t, void *, size_t);
60 int tst_getcmd(struct proc
*, struct user
*);
61 void tst_segkvp(void);
79 main(int argc
, char *argv
[], char *envp
[])
88 for (envc
= 0; *envp
++ != NULL
; envc
++)
91 ccnt
= (*envp
- *argv
) + strlen(*envp
) + 1;
92 printf("pid %d:: %d args; %d envs; %d chars (%p - %p)\n",
93 getpid(), argc
, envc
, ccnt
,
94 &argv
[0], *envp
+ strlen(*envp
));
96 while ((c
= getopt(argc
, argv
, "w")) != EOF
)
105 fprintf(stderr
, "usage: %s [-w] [name] [core] [swap]\n",
110 name
= argv
[optind
++];
116 core
= argv
[optind
++];
122 swap
= argv
[optind
++];
128 tst_open(name
, core
, swap
, (wflag
? O_RDWR
: O_RDONLY
));
134 for (nlp
= nl
; nlp
[0].n_type
!= 0; nlp
++)
135 tst_read(nlp
[0].n_value
, &xx
, sizeof (xx
));
137 while ((proc
= tst_nextproc()) != NULL
) {
139 if (kvm_read(cookie
, (uintptr_t)proc
->p_pidp
, &pid
,
140 sizeof (pid
)) != sizeof (pid
)) {
141 printf("ERROR: couldn't get pid\n");
144 tst_getproc(pid
.pid_id
);
149 while ((proc
= tst_nextproc()) != NULL
) {
150 if ((u
= tst_getu(proc
)) != NULL
)
151 (void) tst_getcmd(proc
, u
);
161 tst_open(char *namelist
, char *corefile
, char *swapfile
, int flag
)
163 printf("kvm_open(%s, %s, %s, %s)\n",
164 (namelist
== NULL
) ? "LIVE_KERNEL" : namelist
,
165 (corefile
== NULL
) ? "LIVE_KERNEL" : corefile
,
167 ((corefile
== NULL
) ? "LIVE_KERNEL" : "(none)") : swapfile
,
168 (flag
== O_RDONLY
) ? "O_RDONLY" : ((flag
== O_RDWR
) ?
171 if ((cookie
= kvm_open(namelist
, corefile
,
172 swapfile
, flag
, "libkvm test")) == NULL
)
173 printf("ERROR: kvm_open returned %p\n", cookie
);
181 printf("kvm_close()\n");
182 if ((i
= kvm_close(cookie
)) != 0)
183 printf("ERROR: kvm_close returned %d\n", i
);
187 tst_nlist(struct nlist nl
[])
192 printf("kvm_nlist([nl])\n");
193 if ((i
= kvm_nlist(cookie
, nl
)) != 0)
194 printf("ERROR: kvm_nlist returned %d\n", i
);
195 for (i
= 0; nl
[i
].n_name
!= 0 && nl
[i
].n_name
[0] != '\0'; i
++) {
198 * n_value gets filled in with st_value,
199 * n_type gets filled in w/ELF32_ST_TYPE(sym->st_info)
200 * n_scnum gets filled in w/st_shndx
202 switch (nl
[i
].n_type
) {
225 switch ((unsigned)nl
[i
].n_scnum
) {
226 static char strbuf
[40];
244 (void) sprintf(strbuf
, "unknown (%d)", nl
[i
].n_scnum
);
249 printf("%s: %lx (%s, %s)\n",
250 nl
[i
].n_name
, nl
[i
].n_value
, s
, t
);
255 tst_read(uintptr_t addr
, void *buf
, size_t nbytes
)
261 printf("kvm_read(%lx, [buf], %lu)\n", addr
, nbytes
);
262 if ((e
= kvm_read(cookie
, addr
, buf
, nbytes
)) != nbytes
)
263 printf("ERROR: kvm_read returned %ld instead of %lu\n",
265 for (b
= buf
, i
= 0; i
< nbytes
; b
++, i
++)
266 printf("%lx: %02x (%04o)\n", addr
+ i
,
267 *b
& 0xff, *b
& 0xff);
273 tst_write(uintptr_t addr
, void *buf
, size_t nbytes
)
279 printf("kvm_write(%lx, [buf], %lu)\n", addr
, nbytes
);
280 if ((e
= kvm_write(cookie
, addr
, buf
, nbytes
)) != nbytes
)
281 printf("ERROR: kvm_write returned %ld instead of %lu\n",
283 if ((b
= malloc(nbytes
)) == 0)
284 printf("ERROR: malloc for readback failed\n");
286 if ((i
= kvm_read(cookie
, addr
, b
, nbytes
)) != nbytes
)
287 printf("ERROR: readback returned %ld\n", i
);
288 else if (memcmp(b
, buf
, nbytes
))
289 printf("ERROR: write check failed!\n");
296 tst_getproc(pid_t pid
)
301 printf("kvm_getproc(%d)\n", pid
);
302 if ((proc
= kvm_getproc(cookie
, pid
)) == NULL
) {
303 printf("ERROR: kvm_getproc returned NULL\n");
307 if (kvm_read(cookie
, (uintptr_t)proc
->p_pidp
, &pidbuf
,
308 sizeof (pidbuf
)) != sizeof (pidbuf
)) {
309 printf("ERROR: couldn't get pid\n");
313 printf("p_pid: %d\n", pidbuf
.pid_id
);
323 printf("kvm_nextproc()\n");
324 if ((proc
= kvm_nextproc(cookie
)) == NULL
) {
325 printf("kvm_nextproc returned NULL\n");
330 * p_pid is now a macro which turns into a ptr dereference;
331 * must do a kvm_read to get contents.
333 if (kvm_read(cookie
, (u_long
)proc
->p_pidp
, (char *)&pidbuf
,
334 sizeof (struct pid
)) != sizeof (struct pid
)) {
335 printf("ERROR: couldn't get pid\n");
337 printf("p_pid: %d\n", pidbuf
.pid_id
);
347 printf("kvm_setproc()\n");
348 if ((i
= kvm_setproc(cookie
)) != 0)
349 printf("ERROR: kvm_setproc returned %d\n", i
);
354 tst_getu(struct proc
*proc
)
361 if (kvm_read(cookie
, (uintptr_t)proc
->p_pidp
, &pidbuf
,
362 sizeof (pidbuf
)) != sizeof (pidbuf
))
363 printf("ERROR: couldn't get pid\n");
365 printf("kvm_getu(pid:%d)\n", pidbuf
.pid_id
);
366 if ((u
= kvm_getu(cookie
, proc
)) == NULL
)
367 printf("ERROR: kvm_getu returned NULL\n");
372 safe_printf(const char *s
)
374 char buf
[BUFSIZ
], *p
;
376 (void) strncpy(buf
, s
, BUFSIZ
- 1);
377 buf
[BUFSIZ
- 1] = '\0';
379 for (p
= buf
; *p
!= '\0'; p
++) {
384 (void) printf("\"%s\"\n", buf
);
388 tst_getcmd(struct proc
*proc
, struct user
*u
)
396 if (kvm_kread(cookie
, (uintptr_t)proc
->p_pidp
, &pidbuf
,
397 sizeof (pidbuf
)) != sizeof (pidbuf
)) {
398 printf("ERROR: couldn't get pid\n");
402 printf("kvm_getcmd(pid:%d, [u], arg, env)\n", pidbuf
.pid_id
);
403 if ((i
= kvm_getcmd(cookie
, proc
, u
, &arg
, &env
)) != 0) {
404 printf("kvm_getcmd returned %d\n", i
);
409 for (p
= arg
; *p
!= NULL
; p
++)
412 for (p
= env
; *p
!= NULL
; p
++)
429 if (kvm_read(cookie
, nl
[3].n_value
, &alltp
, sizeof (alltp
))
431 printf("ERROR: couldn't read allthread, addr 0x%lx\n",
435 printf("allthreads 0x%lx\n", nl
[3].n_value
);
436 printf("next offset 0x%lx\n",
437 (uintptr_t)&(t
.t_next
) - (uintptr_t)&t
);
439 for (tp
= alltp
; tp
; tp
= (caddr_t
)(t
.t_next
)) {
441 (uintptr_t)tp
, &t
, sizeof (t
)) != sizeof (t
)) {
442 printf("ERROR: couldn't read thread, addr 0x%p\n", tp
);
446 printf("thread 0x%p\n", tp
);
447 printf("\tstk 0x%p sp 0x%lx tid %d next 0x%p prev 0x%p\n",
448 tp
, t
.t_stk
, t
.t_pcb
.val
[1], t
.t_tid
, t
.t_next
, t
.t_prev
);
450 if (kvm_read(cookie
, t
.t_pcb
.val
[1] + STACK_BIAS
, stk
,
451 sizeof (stk
)) != sizeof (stk
)) {
452 printf("ERROR: couldn't read stack, taddr 0x%p\n", tp
);
455 for (i
= 0; i
< 16; i
++) {
456 printf("%-16lx ", stk
[i
]);
457 if (((i
+ 1) % 4) == 0)
461 if ((caddr_t
)(t
.t_next
) == alltp
)