8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21 /*
22 * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
24 */
25
26 /*
27 * Copyright (c) 2013, Joyent, Inc. All rights reserved.
28 */
29
30 #include <sys/types.h>
31 #include <sys/uio.h>
32 #include <string.h>
33 #include <errno.h>
34 #include <limits.h>
35
36 #include "Pcontrol.h"
37 #include "P32ton.h"
38
39 /*
40 * This file implements the routines to read and write per-lwp register
41 * information from either a live process or core file opened with libproc.
42 * We build up a few common routines for reading and writing register
43 * information, and then the public functions are all trivial calls to these.
44 */
45
46 /*
47 * Utility function to return a pointer to the structure of cached information
48 * about an lwp in the core file, given its lwpid.
49 */
50 static lwp_info_t *
51 getlwpcore(struct ps_prochandle *P, lwpid_t lwpid)
52 {
53 lwp_info_t *lwp = list_next(&P->core->core_lwp_head);
54 uint_t i;
55
56 for (i = 0; i < P->core->core_nlwp; i++, lwp = list_next(lwp)) {
57 if (lwp->lwp_id == lwpid)
58 return (lwp);
59 }
60
61 errno = EINVAL;
62 return (NULL);
63 }
64
65 /*
66 * Utility function to open and read the contents of a per-lwp /proc file.
67 * This function is used to slurp in lwpstatus, xregs, and asrs.
68 */
69 static int
70 getlwpfile(struct ps_prochandle *P, lwpid_t lwpid,
71 const char *fbase, void *rp, size_t n)
72 {
73 char fname[PATH_MAX];
74 int fd;
75
76 (void) snprintf(fname, sizeof (fname), "%s/%d/lwp/%d/%s",
101 * matches that of the representative lwp:
102 */
103 if (P->status.pr_lwp.pr_lwpid == lwpid) {
104 (void) memcpy(lps, &P->status.pr_lwp, sizeof (lwpstatus_t));
105 return (0);
106 }
107
108 /*
109 * If this is a live process, then just read the information out
110 * of the per-lwp status file:
111 */
112 if (P->state != PS_DEAD) {
113 return (getlwpfile(P, lwpid, "lwpstatus",
114 lps, sizeof (lwpstatus_t)));
115 }
116
117 /*
118 * If this is a core file, we need to iterate through our list of
119 * cached lwp information and then copy out the status.
120 */
121 if (P->core != NULL && (lwp = getlwpcore(P, lwpid)) != NULL) {
122 (void) memcpy(lps, &lwp->lwp_status, sizeof (lwpstatus_t));
123 return (0);
124 }
125
126 return (-1);
127 }
128
129 /*
130 * Utility function to modify lwp registers. This is done using either the
131 * process control file or per-lwp control file as necessary.
132 */
133 static int
134 setlwpregs(struct ps_prochandle *P, lwpid_t lwpid, long cmd,
135 const void *rp, size_t n)
136 {
137 iovec_t iov[2];
138 char fname[PATH_MAX];
139 int fd;
140
141 if (P->state != PS_STOP) {
|
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21 /*
22 * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
24 */
25
26 /*
27 * Copyright (c) 2013, Joyent, Inc. All rights reserved.
28 * Copyright (c) 2013 by Delphix. All rights reserved.
29 */
30
31 #include <sys/types.h>
32 #include <sys/uio.h>
33 #include <string.h>
34 #include <errno.h>
35 #include <limits.h>
36
37 #include "Pcontrol.h"
38 #include "P32ton.h"
39
40 /*
41 * This file implements the routines to read and write per-lwp register
42 * information from either a live process or core file opened with libproc.
43 * We build up a few common routines for reading and writing register
44 * information, and then the public functions are all trivial calls to these.
45 */
46
47 /*
48 * Utility function to return a pointer to the structure of cached information
49 * about an lwp in the core file, given its lwpid.
50 */
51 static lwp_info_t *
52 getlwpcore(struct ps_prochandle *P, lwpid_t lwpid)
53 {
54 core_info_t *core = P->data;
55 lwp_info_t *lwp = list_next(&core->core_lwp_head);
56 uint_t i;
57
58 for (i = 0; i < core->core_nlwp; i++, lwp = list_next(lwp)) {
59 if (lwp->lwp_id == lwpid)
60 return (lwp);
61 }
62
63 errno = EINVAL;
64 return (NULL);
65 }
66
67 /*
68 * Utility function to open and read the contents of a per-lwp /proc file.
69 * This function is used to slurp in lwpstatus, xregs, and asrs.
70 */
71 static int
72 getlwpfile(struct ps_prochandle *P, lwpid_t lwpid,
73 const char *fbase, void *rp, size_t n)
74 {
75 char fname[PATH_MAX];
76 int fd;
77
78 (void) snprintf(fname, sizeof (fname), "%s/%d/lwp/%d/%s",
103 * matches that of the representative lwp:
104 */
105 if (P->status.pr_lwp.pr_lwpid == lwpid) {
106 (void) memcpy(lps, &P->status.pr_lwp, sizeof (lwpstatus_t));
107 return (0);
108 }
109
110 /*
111 * If this is a live process, then just read the information out
112 * of the per-lwp status file:
113 */
114 if (P->state != PS_DEAD) {
115 return (getlwpfile(P, lwpid, "lwpstatus",
116 lps, sizeof (lwpstatus_t)));
117 }
118
119 /*
120 * If this is a core file, we need to iterate through our list of
121 * cached lwp information and then copy out the status.
122 */
123 if (P->data != NULL && (lwp = getlwpcore(P, lwpid)) != NULL) {
124 (void) memcpy(lps, &lwp->lwp_status, sizeof (lwpstatus_t));
125 return (0);
126 }
127
128 return (-1);
129 }
130
131 /*
132 * Utility function to modify lwp registers. This is done using either the
133 * process control file or per-lwp control file as necessary.
134 */
135 static int
136 setlwpregs(struct ps_prochandle *P, lwpid_t lwpid, long cmd,
137 const void *rp, size_t n)
138 {
139 iovec_t iov[2];
140 char fname[PATH_MAX];
141 int fd;
142
143 if (P->state != PS_STOP) {
|