Print this page
27908 ::gcore breaks sparc build
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/lib/libproc/common/Pservice.c
+++ new/usr/src/lib/libproc/common/Pservice.c
1 1 /*
2 2 * CDDL HEADER START
3 3 *
4 4 * The contents of this file are subject to the terms of the
5 5 * Common Development and Distribution License (the "License").
6 6 * You may not use this file except in compliance with the License.
7 7 *
8 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 9 * or http://www.opensolaris.org/os/licensing.
10 10 * See the License for the specific language governing permissions
11 11 * and limitations under the License.
12 12 *
13 13 * When distributing Covered Code, include this CDDL HEADER in each
14 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 15 * If applicable, add the following below this CDDL HEADER, with the
16 16 * fields enclosed by brackets "[]" replaced with your own identifying
17 17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 18 *
19 19 * CDDL HEADER END
20 20 */
21 21 /*
22 22 * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
23 23 * Use is subject to license terms.
24 24 */
25 25 /*
26 26 * Copyright (c) 2013 by Delphix. All rights reserved.
27 27 */
28 28
29 29 #include <stdarg.h>
30 30 #include <string.h>
31 31 #include "Pcontrol.h"
32 32
33 33 /*
34 34 * This file implements the process services declared in <proc_service.h>.
35 35 * This enables libproc to be used in conjunction with libc_db and
36 36 * librtld_db. As most of these facilities are already provided by
37 37 * (more elegant) interfaces in <libproc.h>, we can just call those.
38 38 *
39 39 * NOTE: We explicitly do *not* implement the functions ps_kill() and
40 40 * ps_lrolltoaddr() in this library. The very existence of these functions
41 41 * causes libc_db to create an "agent thread" in the target process.
42 42 * The only way to turn off this behavior is to omit these functions.
43 43 */
44 44
45 45 #pragma weak ps_pdread = ps_pread
46 46 #pragma weak ps_ptread = ps_pread
47 47 #pragma weak ps_pdwrite = ps_pwrite
48 48 #pragma weak ps_ptwrite = ps_pwrite
49 49
50 50 ps_err_e
51 51 ps_pdmodel(struct ps_prochandle *P, int *modelp)
52 52 {
53 53 *modelp = P->status.pr_dmodel;
54 54 return (PS_OK);
55 55 }
56 56
57 57 ps_err_e
58 58 ps_pread(struct ps_prochandle *P, psaddr_t addr, void *buf, size_t size)
59 59 {
60 60 if (P->ops.pop_pread(P, buf, size, addr, P->data) != size)
61 61 return (PS_BADADDR);
62 62 return (PS_OK);
63 63 }
64 64
65 65 ps_err_e
66 66 ps_pwrite(struct ps_prochandle *P, psaddr_t addr, const void *buf, size_t size)
67 67 {
68 68 if (P->ops.pop_pwrite(P, buf, size, addr, P->data) != size)
69 69 return (PS_BADADDR);
70 70 return (PS_OK);
71 71 }
72 72
73 73 /*
74 74 * libc_db calls matched pairs of ps_pstop()/ps_pcontinue()
75 75 * in the belief that the client may have left the process
76 76 * running while calling in to the libc_db interfaces.
77 77 *
78 78 * We interpret the meaning of these functions to be an inquiry
79 79 * as to whether the process is stopped, not an action to be
80 80 * performed to make it stopped. For similar reasons, we also
81 81 * return PS_OK for core files in order to allow libc_db to
82 82 * operate on these as well.
83 83 */
84 84 ps_err_e
85 85 ps_pstop(struct ps_prochandle *P)
86 86 {
87 87 if (P->state != PS_STOP && P->state != PS_DEAD)
88 88 return (PS_ERR);
89 89 return (PS_OK);
90 90 }
91 91
92 92 ps_err_e
93 93 ps_pcontinue(struct ps_prochandle *P)
94 94 {
95 95 if (P->state != PS_STOP && P->state != PS_DEAD)
96 96 return (PS_ERR);
97 97 return (PS_OK);
98 98 }
99 99
100 100 /*
101 101 * ps_lstop() and ps_lcontinue() are not called by any code in libc_db
102 102 * or librtld_db. We make them behave like ps_pstop() and ps_pcontinue().
103 103 */
104 104 /* ARGSUSED1 */
105 105 ps_err_e
106 106 ps_lstop(struct ps_prochandle *P, lwpid_t lwpid)
107 107 {
108 108 if (P->state != PS_STOP && P->state != PS_DEAD)
109 109 return (PS_ERR);
110 110 return (PS_OK);
111 111 }
112 112
113 113 /* ARGSUSED1 */
114 114 ps_err_e
115 115 ps_lcontinue(struct ps_prochandle *P, lwpid_t lwpid)
116 116 {
117 117 if (P->state != PS_STOP && P->state != PS_DEAD)
118 118 return (PS_ERR);
119 119 return (PS_OK);
120 120 }
121 121
122 122 ps_err_e
123 123 ps_lgetregs(struct ps_prochandle *P, lwpid_t lwpid, prgregset_t regs)
124 124 {
125 125 if (P->state != PS_STOP && P->state != PS_DEAD)
126 126 return (PS_ERR);
127 127
128 128 if (Plwp_getregs(P, lwpid, regs) == 0)
129 129 return (PS_OK);
130 130
131 131 return (PS_BADLID);
132 132 }
133 133
134 134 ps_err_e
135 135 ps_lsetregs(struct ps_prochandle *P, lwpid_t lwpid, const prgregset_t regs)
136 136 {
137 137 if (P->state != PS_STOP)
138 138 return (PS_ERR);
139 139
140 140 if (Plwp_setregs(P, lwpid, regs) == 0)
141 141 return (PS_OK);
142 142
143 143 return (PS_BADLID);
144 144 }
145 145
146 146 ps_err_e
147 147 ps_lgetfpregs(struct ps_prochandle *P, lwpid_t lwpid, prfpregset_t *regs)
148 148 {
149 149 if (P->state != PS_STOP && P->state != PS_DEAD)
150 150 return (PS_ERR);
151 151
152 152 if (Plwp_getfpregs(P, lwpid, regs) == 0)
153 153 return (PS_OK);
154 154
155 155 return (PS_BADLID);
156 156 }
157 157
158 158 ps_err_e
159 159 ps_lsetfpregs(struct ps_prochandle *P, lwpid_t lwpid, const prfpregset_t *regs)
160 160 {
161 161 if (P->state != PS_STOP)
162 162 return (PS_ERR);
163 163
164 164 if (Plwp_setfpregs(P, lwpid, regs) == 0)
165 165 return (PS_OK);
166 166
167 167 return (PS_BADLID);
168 168 }
↓ open down ↓ |
168 lines elided |
↑ open up ↑ |
169 169
170 170 #if defined(sparc) || defined(__sparc)
171 171
172 172 ps_err_e
173 173 ps_lgetxregsize(struct ps_prochandle *P, lwpid_t lwpid, int *xrsize)
174 174 {
175 175 char fname[PATH_MAX];
176 176 struct stat statb;
177 177
178 178 if (P->state == PS_DEAD) {
179 - lwp_info_t *lwp = list_next(&P->core->core_lwp_head);
179 + core_info_t *core = P->data;
180 + lwp_info_t *lwp = list_next(&core->core_lwp_head);
180 181 uint_t i;
181 182
182 - for (i = 0; i < P->core->core_nlwp; i++, lwp = list_next(lwp)) {
183 + for (i = 0; i < core->core_nlwp; i++, lwp = list_next(lwp)) {
183 184 if (lwp->lwp_id == lwpid) {
184 185 if (lwp->lwp_xregs != NULL)
185 186 *xrsize = sizeof (prxregset_t);
186 187 else
187 188 *xrsize = 0;
188 189 return (PS_OK);
189 190 }
190 191 }
191 192
192 193 return (PS_BADLID);
193 194 }
194 195
195 196 (void) snprintf(fname, sizeof (fname), "%s/%d/lwp/%d/xregs",
196 197 procfs_path, (int)P->status.pr_pid, (int)lwpid);
197 198
198 199 if (stat(fname, &statb) != 0)
199 200 return (PS_BADLID);
200 201
201 202 *xrsize = (int)statb.st_size;
202 203 return (PS_OK);
203 204 }
204 205
205 206 ps_err_e
206 207 ps_lgetxregs(struct ps_prochandle *P, lwpid_t lwpid, caddr_t xregs)
207 208 {
208 209 if (P->state != PS_STOP && P->state != PS_DEAD)
209 210 return (PS_ERR);
210 211
211 212 /* LINTED - alignment */
212 213 if (Plwp_getxregs(P, lwpid, (prxregset_t *)xregs) == 0)
213 214 return (PS_OK);
214 215
215 216 return (PS_BADLID);
216 217 }
217 218
218 219 ps_err_e
219 220 ps_lsetxregs(struct ps_prochandle *P, lwpid_t lwpid, caddr_t xregs)
220 221 {
221 222 if (P->state != PS_STOP)
222 223 return (PS_ERR);
223 224
224 225 /* LINTED - alignment */
225 226 if (Plwp_setxregs(P, lwpid, (prxregset_t *)xregs) == 0)
226 227 return (PS_OK);
227 228
228 229 return (PS_BADLID);
229 230 }
230 231
231 232 #endif /* sparc */
232 233
233 234 #if defined(__i386) || defined(__amd64)
234 235
235 236 ps_err_e
236 237 ps_lgetLDT(struct ps_prochandle *P, lwpid_t lwpid, struct ssd *ldt)
237 238 {
238 239 #if defined(__amd64) && defined(_LP64)
239 240 if (P->status.pr_dmodel != PR_MODEL_NATIVE) {
240 241 #endif
241 242 prgregset_t regs;
242 243 struct ssd *ldtarray;
243 244 ps_err_e error;
244 245 uint_t gs;
245 246 int nldt;
246 247 int i;
247 248
248 249 if (P->state != PS_STOP && P->state != PS_DEAD)
249 250 return (PS_ERR);
250 251
251 252 /*
252 253 * We need to get the ldt entry that matches the
253 254 * value in the lwp's GS register.
254 255 */
255 256 if ((error = ps_lgetregs(P, lwpid, regs)) != PS_OK)
256 257 return (error);
257 258
258 259 gs = regs[GS];
259 260
260 261 if ((nldt = Pldt(P, NULL, 0)) <= 0 ||
261 262 (ldtarray = malloc(nldt * sizeof (struct ssd))) == NULL)
262 263 return (PS_ERR);
263 264 if ((nldt = Pldt(P, ldtarray, nldt)) <= 0) {
264 265 free(ldtarray);
265 266 return (PS_ERR);
266 267 }
267 268
268 269 for (i = 0; i < nldt; i++) {
269 270 if (gs == ldtarray[i].sel) {
270 271 *ldt = ldtarray[i];
271 272 break;
272 273 }
273 274 }
274 275 free(ldtarray);
275 276
276 277 if (i < nldt)
277 278 return (PS_OK);
278 279 #if defined(__amd64) && defined(_LP64)
279 280 }
280 281 #endif
281 282
282 283 return (PS_ERR);
283 284 }
284 285
285 286 #endif /* __i386 || __amd64 */
286 287
287 288 /*
288 289 * Libthread_db doesn't use this function currently, but librtld_db uses
289 290 * it for its debugging output. We turn this on via rd_log if our debugging
290 291 * switch is on, and then echo the messages sent to ps_plog to stderr.
291 292 */
292 293 void
293 294 ps_plog(const char *fmt, ...)
294 295 {
295 296 va_list ap;
296 297
297 298 if (_libproc_debug && fmt != NULL && *fmt != '\0') {
298 299 va_start(ap, fmt);
299 300 (void) vfprintf(stderr, fmt, ap);
300 301 va_end(ap);
301 302 if (fmt[strlen(fmt) - 1] != '\n')
302 303 (void) fputc('\n', stderr);
303 304 }
304 305 }
305 306
306 307 /*
307 308 * Store a pointer to our internal copy of the aux vector at the address
308 309 * specified by the caller. It should not hold on to this data for too long.
309 310 */
310 311 ps_err_e
311 312 ps_pauxv(struct ps_prochandle *P, const auxv_t **aux)
312 313 {
313 314 if (P->auxv == NULL)
314 315 Preadauxvec(P);
315 316
316 317 if (P->auxv == NULL)
317 318 return (PS_ERR);
318 319
319 320 *aux = (const auxv_t *)P->auxv;
320 321 return (PS_OK);
321 322 }
322 323
323 324 ps_err_e
324 325 ps_pbrandname(struct ps_prochandle *P, char *buf, size_t len)
325 326 {
326 327 return (Pbrandname(P, buf, len) ? PS_OK : PS_ERR);
327 328 }
328 329
329 330 /*
330 331 * Search for a symbol by name and return the corresponding address.
331 332 */
332 333 ps_err_e
333 334 ps_pglobal_lookup(struct ps_prochandle *P, const char *object_name,
334 335 const char *sym_name, psaddr_t *sym_addr)
335 336 {
336 337 GElf_Sym sym;
337 338
338 339 if (Plookup_by_name(P, object_name, sym_name, &sym) == 0) {
339 340 dprintf("pglobal_lookup <%s> -> %p\n",
340 341 sym_name, (void *)(uintptr_t)sym.st_value);
341 342 *sym_addr = (psaddr_t)sym.st_value;
342 343 return (PS_OK);
343 344 }
344 345
345 346 return (PS_NOSYM);
346 347 }
347 348
348 349 /*
349 350 * Search for a symbol by name and return the corresponding symbol
350 351 * information. If we're compiled _LP64, we just call Plookup_by_name
351 352 * and return because ps_sym_t is defined to be an Elf64_Sym, which
352 353 * is the same as a GElf_Sym. In the _ILP32 case, we have to convert
353 354 * Plookup_by_name's result back to a ps_sym_t (which is an Elf32_Sym).
354 355 */
355 356 ps_err_e
356 357 ps_pglobal_sym(struct ps_prochandle *P, const char *object_name,
357 358 const char *sym_name, ps_sym_t *symp)
358 359 {
359 360 #if defined(_ILP32)
360 361 GElf_Sym sym;
361 362
362 363 if (Plookup_by_name(P, object_name, sym_name, &sym) == 0) {
363 364 symp->st_name = (Elf32_Word)sym.st_name;
364 365 symp->st_value = (Elf32_Addr)sym.st_value;
365 366 symp->st_size = (Elf32_Word)sym.st_size;
366 367 symp->st_info = ELF32_ST_INFO(
367 368 GELF_ST_BIND(sym.st_info), GELF_ST_TYPE(sym.st_info));
368 369 symp->st_other = sym.st_other;
369 370 symp->st_shndx = sym.st_shndx;
370 371 return (PS_OK);
371 372 }
372 373
373 374 #elif defined(_LP64)
374 375 if (Plookup_by_name(P, object_name, sym_name, symp) == 0)
375 376 return (PS_OK);
376 377 #endif
377 378 return (PS_NOSYM);
378 379 }
↓ open down ↓ |
186 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX