Print this page
| Split |
Close |
| Expand all |
| Collapse all |
--- old/usr/src/cmd/sgs/librtld_db/common/rd_elf.c
+++ new/usr/src/cmd/sgs/librtld_db/common/rd_elf.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 2010 Sun Microsystems, Inc. All rights reserved.
23 23 * Use is subject to license terms.
24 24 */
25 25
26 26 /*
27 27 * Copyright (c) 2014 Joyent, Inc. All rights reserved.
28 28 */
29 29
30 30 #include <stdlib.h>
31 31 #include <stdio.h>
32 32 #include <proc_service.h>
33 33 #include <link.h>
34 34 #include <rtld_db.h>
35 35 #include <rtld.h>
36 36 #include <alist.h>
37 37 #include <list.h>
38 38 #include <_rtld_db.h>
39 39 #include <msg.h>
40 40 #include <limits.h>
41 41 #include <string.h>
42 42 #include <sys/param.h>
43 43
44 44 /*
45 45 * We want to include zone.h to pull in the prototype for zone_get_nroot(),
46 46 * but we need to avoid pulling in <sys/stream.h>, which has a definition
47 47 * of M_DATA that conflicts with the ELF-related definition in machdep_*.h.
48 48 */
49 49 #define _SYS_STREAM_H
50 50 #include <zone.h>
51 51
52 52 /*
53 53 * 64-bit builds are going to compile this module twice, the
54 54 * second time with _ELF64 defined. These defines should make
55 55 * all the necessary adjustments to the code.
56 56 */
57 57 #ifdef _LP64
58 58 #ifdef _ELF64
59 59 #define _rd_event_enable32 _rd_event_enable64
60 60 #define _rd_event_getmsg32 _rd_event_getmsg64
61 61 #define _rd_get_dyns32 _rd_get_dyns64
62 62 #define _rd_get_ehdr32 _rd_get_ehdr64
63 63 #define _rd_objpad_enable32 _rd_objpad_enable64
64 64 #define _rd_loadobj_iter32 _rd_loadobj_iter64
65 65 #define _rd_reset32 _rd_reset64
66 66 #define find_dynamic_ent32 find_dynamic_ent64
67 67 #define validate_rdebug32 validate_rdebug64
68 68 #define TAPlist APlist
69 69 #define TLm_list Lm_list
70 70 #define TList List
71 71 #define TListnode Listnode
72 72 #define MSG_SYM_BRANDOPS MSG_SYM_BRANDOPS_64
73 73 #else /* ELF32 */
74 74 #define Rt_map Rt_map32
75 75 #define Rtld_db_priv Rtld_db_priv32
76 76 #define TAPlist APlist32
77 77 #define TLm_list Lm_list32
78 78 #define TList List32
79 79 #define TListnode Listnode32
80 80 #define Lm_list Lm_list32
81 81 #define MSG_SYM_BRANDOPS MSG_SYM_BRANDOPS_32
82 82 #endif /* _ELF64 */
83 83 #else /* _LP64 */
84 84 #define TAPlist APlist
85 85 #define TLm_list Lm_list
86 86 #define TList List
87 87 #define TListnode Listnode
88 88 #define MSG_SYM_BRANDOPS MSG_SYM_BRANDOPS_32
89 89 #endif /* _LP64 */
90 90
91 91 /*
92 92 * BrandZ added ps_pbrandname(). Many debuggers that link directly
93 93 * against librtld_db.so may not implement this interface. Hence
94 94 * we won't call the function directly, instead we'll try to look it
95 95 * up using the linker first and only invoke it if we find it.
96 96 */
97 97 typedef ps_err_e (*ps_pbrandname_fp_t)(struct ps_prochandle *,
98 98 char *, size_t);
99 99
100 100 rd_err_e
101 101 validate_rdebug32(struct rd_agent *rap)
102 102 {
103 103 struct ps_prochandle *php = rap->rd_psp;
104 104 psaddr_t db_privp;
105 105 Rtld_db_priv db_priv;
106 106
107 107 if (rap->rd_rdebug == 0)
108 108 return (RD_ERR);
109 109
110 110 /*
111 111 * The rtld_db_priv structure contains both the traditional (exposed)
112 112 * r_debug structure as well as private data only available to
113 113 * this library.
114 114 */
115 115 db_privp = rap->rd_rdebug;
116 116
117 117 /*
118 118 * Verify that librtld_db & rtld are at the proper revision
119 119 * levels.
120 120 */
121 121 if (ps_pread(php, db_privp, (char *)&db_priv,
122 122 sizeof (Rtld_db_priv)) != PS_OK) {
123 123 LOG(ps_plog(MSG_ORIG(MSG_DB_READPRIVFAIL_1),
124 124 EC_ADDR(db_privp)));
125 125 return (RD_DBERR);
126 126 }
127 127
128 128 if ((db_priv.rtd_version < R_RTLDDB_VERSION1) ||
129 129 (db_priv.rtd_version > R_RTLDDB_VERSION)) {
130 130 LOG(ps_plog(MSG_ORIG(MSG_DB_BADPVERS),
131 131 db_priv.rtd_version, R_RTLDDB_VERSION));
132 132 return (RD_NOCAPAB);
133 133 }
134 134
135 135 /*
136 136 * Is the image being examined from a core file or not.
137 137 * If it is a core file then the following write will fail.
138 138 */
139 139 if (ps_pwrite(php, db_privp, (char *)&db_priv,
140 140 sizeof (Rtld_db_priv)) != PS_OK)
141 141 rap->rd_flags |= RDF_FL_COREFILE;
142 142
143 143 rap->rd_rdebugvers = db_priv.rtd_version;
144 144 rap->rd_rtlddbpriv = db_privp;
145 145
146 146 LOG(ps_plog(MSG_ORIG(MSG_DB_VALIDRDEBUG), EC_ADDR(rap->rd_rdebug),
147 147 R_RTLDDB_VERSION, rap->rd_rdebugvers,
148 148 rap->rd_flags & RDF_FL_COREFILE));
149 149 return (RD_OK);
150 150 }
151 151
152 152
153 153 rd_err_e
154 154 find_dynamic_ent32(struct rd_agent *rap, psaddr_t dynaddr,
155 155 Xword dyntag, Dyn *dyn)
156 156 {
157 157 struct ps_prochandle *php = rap->rd_psp;
158 158 Dyn d;
159 159
160 160 d.d_tag = DT_NULL;
161 161 do {
162 162 if (ps_pread(php, dynaddr, (void *)(&d), sizeof (d)) !=
163 163 PS_OK) {
164 164 LOG(ps_plog(MSG_ORIG(MSG_DB_READFAIL_4),
165 165 EC_ADDR(dynaddr)));
166 166 return (RD_DBERR);
167 167 }
168 168 dynaddr += sizeof (d);
169 169 if (d.d_tag == dyntag)
170 170 break;
171 171 } while (d.d_tag != DT_NULL);
172 172 if (d.d_tag == dyntag) {
173 173 *dyn = d;
174 174 LOG(ps_plog(MSG_ORIG(MSG_DB_FINDDYNAMIC), EC_ADDR(dyntag),
175 175 EC_ADDR(d.d_un.d_val)));
176 176 return (RD_OK);
177 177 }
178 178 LOG(ps_plog(MSG_ORIG(MSG_DB_NODYNDEBUG), EC_ADDR(dyntag)));
179 179 return (RD_DBERR);
180 180 }
181 181
182 182 extern char rtld_db_helper_path[MAXPATHLEN];
183 183
184 184 rd_err_e
185 185 _rd_reset32(struct rd_agent *rap)
186 186 {
187 187 psaddr_t symaddr;
188 188 struct ps_prochandle *php = rap->rd_psp;
189 189 const auxv_t *auxvp = NULL;
190 190 rd_err_e rc = RD_OK;
191 191 char brandname[MAXPATHLEN];
192 192 char brandlib[MAXPATHLEN];
193 193 ps_pbrandname_fp_t ps_pbrandname;
194 194
195 195 /*
196 196 * librtld_db attempts three different methods to find
197 197 * the r_debug structure which is required to
198 198 * initialize itself. The methods are:
199 199 * method1:
200 200 * entirely independent of any text segment
201 201 * and relies on the AT_SUN_LDDATA auxvector
202 202 * to find the ld.so.1::rdebug structure.
203 203 * method2:
204 204 * lookup symbols in ld.so.1's symbol table
205 205 * to find the r_debug symbol.
206 206 * method3:
207 207 * (old dbx method) dependent upon the
208 208 * text segment/symbol table of the
209 209 * executable and not ld.so.1. We lookup the
210 210 * _DYNAMIC symbol in the executable and look for
211 211 * the DT_DEBUG entry in the .dynamic table. This
212 212 * points to rdebug.
213 213 *
214 214 * If none of that works - we fail.
215 215 */
216 216 LOG(ps_plog(MSG_ORIG(MSG_DB_RDRESET), rap->rd_dmodel));
217 217 /*
218 218 * Method1
219 219 *
220 220 * Scan the aux vector looking for AT_BASE & AT_SUN_LDDATA
221 221 */
222 222
223 223 if (ps_pauxv(php, &auxvp) != PS_OK) {
224 224 LOG(ps_plog(MSG_ORIG(MSG_DB_NOAUXV)));
225 225 rc = RD_ERR;
226 226 }
227 227
228 228 rap->rd_rdebug = 0;
229 229
230 230 if (auxvp != NULL) {
231 231 rc = RD_ERR;
232 232 while (auxvp->a_type != AT_NULL) {
233 233 if (auxvp->a_type == AT_SUN_LDDATA) {
234 234 /* LINTED */
235 235 rap->rd_rdebug = (uintptr_t)auxvp->a_un.a_ptr;
236 236 LOG(ps_plog(MSG_ORIG(MSG_DB_FLDDATA),
237 237 rap->rd_rdebug));
238 238 rc = validate_rdebug32(rap);
239 239 break;
240 240 }
241 241 auxvp++;
242 242 }
243 243 }
244 244
245 245 /*
246 246 * method2 - look for r_rdebug symbol in ld.so.1
247 247 */
248 248 if (rc != RD_OK) {
249 249 /*
250 250 * If the AT_SUN_LDDATA auxv vector is not present
251 251 * fall back on doing a symlookup of
252 252 * the r_debug symbol. This is for backward
253 253 * compatiblity with older OS's
254 254 */
255 255 LOG(ps_plog(MSG_ORIG(MSG_DB_NOLDDATA)));
256 256 if (ps_pglobal_lookup(php, PS_OBJ_LDSO, MSG_ORIG(MSG_SYM_DEBUG),
257 257 &symaddr) != PS_OK) {
258 258 LOG(ps_plog(MSG_ORIG(MSG_DB_LOOKFAIL),
259 259 MSG_ORIG(MSG_SYM_DEBUG)));
260 260 rc = RD_DBERR;
261 261 } else {
262 262 rap->rd_rdebug = symaddr;
263 263 LOG(ps_plog(MSG_ORIG(MSG_DB_SYMRDEBUG),
264 264 EC_ADDR(symaddr)));
265 265 rc = validate_rdebug32(rap);
266 266 }
267 267 }
268 268
269 269
270 270 /*
271 271 * method3 - find DT_DEBUG in the executables .dynamic section.
272 272 */
273 273 if (rc != RD_OK) {
274 274 Dyn dyn;
275 275 if (ps_pglobal_lookup(php, PS_OBJ_EXEC,
276 276 MSG_ORIG(MSG_SYM_DYNAMIC), &symaddr) != PS_OK) {
277 277 LOG(ps_plog(MSG_ORIG(MSG_DB_NODYNAMIC)));
278 278 LOG(ps_plog(MSG_ORIG(MSG_DB_INITFAILED)));
279 279 return (rc);
280 280 }
281 281 rc = find_dynamic_ent32(rap, symaddr, DT_DEBUG, &dyn);
282 282 if (rc != RD_OK) {
283 283 LOG(ps_plog(MSG_ORIG(MSG_DB_INITFAILED)));
284 284 return (rc);
285 285 }
286 286 rap->rd_rdebug = dyn.d_un.d_ptr;
287 287 rc = validate_rdebug32(rap);
288 288 if (rc != RD_OK) {
289 289 LOG(ps_plog(MSG_ORIG(MSG_DB_INITFAILED)));
290 290 return (rc);
291 291 }
292 292 }
293 293
294 294 /*
295 295 * If we are debugging a branded executable, load the appropriate
296 296 * helper library, and call its initialization routine. Being unable
297 297 * to load the helper library is not a critical error. (Hopefully
298 298 * we'll still be able to access some objects in the target.) Note
299 299 * that we pull in the native root here to allow for helper libraries
300 300 * to be properly found from within the branded zone.
301 301 */
302 302 ps_pbrandname = (ps_pbrandname_fp_t)dlsym(RTLD_PROBE, "ps_pbrandname");
303 303 while ((ps_pbrandname != NULL) &&
304 304 (ps_pbrandname(php, brandname, MAXPATHLEN) == PS_OK)) {
305 305 const char *isa = "";
306 306
307 307 #ifdef _LP64
308 308 isa = MSG_ORIG(MSG_DB_64BIT_PREFIX);
309 309 #endif /* _LP64 */
310 310
311 311 if (rtld_db_helper_path[0] != '\0') {
312 312 (void) snprintf(brandlib, MAXPATHLEN,
313 313 MSG_ORIG(MSG_DB_BRAND_HELPERPATH_PREFIX),
314 314 rtld_db_helper_path,
315 315 MSG_ORIG(MSG_DB_HELPER_PREFIX), brandname, isa,
316 316 brandname);
317 317 } else {
318 318 const char *nroot = zone_get_nroot();
319 319
320 320 if (nroot == NULL)
321 321 nroot = "";
322 322
323 323 (void) snprintf(brandlib, MAXPATHLEN,
324 324 MSG_ORIG(MSG_DB_BRAND_HELPERPATH), nroot,
325 325 MSG_ORIG(MSG_DB_HELPER_PREFIX), brandname, isa,
326 326 brandname);
327 327 }
328 328
329 329 rap->rd_helper.rh_dlhandle = dlopen(brandlib,
330 330 RTLD_LAZY | RTLD_LOCAL);
331 331 if (rap->rd_helper.rh_dlhandle == NULL) {
332 332 LOG(ps_plog(MSG_ORIG(MSG_DB_HELPERLOADFAILED),
333 333 brandlib));
334 334 break;
335 335 }
336 336
337 337 rap->rd_helper.rh_ops = dlsym(rap->rd_helper.rh_dlhandle,
338 338 MSG_ORIG(MSG_SYM_BRANDOPS));
339 339 if (rap->rd_helper.rh_ops == NULL) {
340 340 LOG(ps_plog(MSG_ORIG(MSG_DB_HELPERNOOPS),
341 341 brandlib));
342 342 (void) dlclose(rap->rd_helper.rh_dlhandle);
343 343 rap->rd_helper.rh_dlhandle = NULL;
344 344 break;
345 345 }
346 346
347 347 rap->rd_helper.rh_data = rap->rd_helper.rh_ops->rho_init(rap,
348 348 php);
349 349 if (rap->rd_helper.rh_data == NULL) {
350 350 LOG(ps_plog(MSG_ORIG(MSG_DB_HELPERINITFAILED)));
351 351 (void) dlclose(rap->rd_helper.rh_dlhandle);
352 352 rap->rd_helper.rh_dlhandle = NULL;
353 353 rap->rd_helper.rh_ops = NULL;
354 354 break;
355 355 }
356 356
357 357 LOG(ps_plog(MSG_ORIG(MSG_DB_HELPERLOADED), brandname));
358 358 break;
359 359
360 360 /* NOTREACHED */
361 361 }
362 362
363 363 if ((rap->rd_flags & RDF_FL_COREFILE) == 0) {
364 364 if (ps_pglobal_lookup(php, PS_OBJ_LDSO,
365 365 MSG_ORIG(MSG_SYM_PREINIT), &symaddr) != PS_OK) {
366 366 LOG(ps_plog(MSG_ORIG(MSG_DB_LOOKFAIL),
367 367 MSG_ORIG(MSG_SYM_PREINIT)));
368 368 return (RD_DBERR);
369 369 }
370 370 rap->rd_preinit = symaddr;
371 371
372 372 if (ps_pglobal_lookup(php, PS_OBJ_LDSO,
373 373 MSG_ORIG(MSG_SYM_POSTINIT), &symaddr) != PS_OK) {
374 374 LOG(ps_plog(MSG_ORIG(MSG_DB_LOOKFAIL),
375 375 MSG_ORIG(MSG_SYM_POSTINIT)));
376 376 return (RD_DBERR);
377 377 }
378 378 rap->rd_postinit = symaddr;
379 379
380 380 if (ps_pglobal_lookup(php, PS_OBJ_LDSO,
381 381 MSG_ORIG(MSG_SYM_DLACT), &symaddr) != PS_OK) {
382 382 LOG(ps_plog(MSG_ORIG(MSG_DB_LOOKFAIL),
383 383 MSG_ORIG(MSG_SYM_DLACT)));
384 384 return (RD_DBERR);
385 385 }
386 386 rap->rd_dlact = symaddr;
387 387 rap->rd_tbinder = 0;
388 388 }
389 389
390 390 return (RD_OK);
391 391 }
392 392
393 393 rd_err_e
394 394 _rd_get_ehdr32(struct rd_agent *rap,
395 395 psaddr_t addr, Ehdr *ehdr, uint_t *phnum)
396 396 {
397 397 struct ps_prochandle *php = rap->rd_psp;
398 398 Shdr shdr;
399 399
400 400 if (ps_pread(php, addr, ehdr, sizeof (*ehdr)) != PS_OK) {
401 401 LOG(ps_plog(MSG_ORIG(MSG_DB_READFAIL_5), EC_ADDR(addr)));
402 402 return (RD_ERR);
403 403 }
404 404 if (phnum == NULL)
405 405 return (RD_OK);
406 406
407 407 if (ehdr->e_phnum != PN_XNUM) {
408 408 *phnum = ehdr->e_phnum;
409 409 return (RD_OK);
410 410 }
411 411
412 412 /* deal with elf extended program headers */
413 413 if ((ehdr->e_shoff == 0) || (ehdr->e_shentsize < sizeof (shdr)))
414 414 return (RD_ERR);
415 415
416 416 addr += ehdr->e_shoff;
417 417 if (ps_pread(php, addr, &shdr, sizeof (shdr)) != PS_OK) {
418 418 LOG(ps_plog(MSG_ORIG(MSG_DB_READFAIL_5), EC_ADDR(addr)));
419 419 return (RD_ERR);
420 420 }
421 421
422 422 if (shdr.sh_info == 0)
423 423 return (RD_ERR);
424 424
425 425 *phnum = shdr.sh_info;
426 426 return (RD_OK);
427 427 }
428 428
429 429 rd_err_e
430 430 _rd_get_dyns32(rd_agent_t *rap, psaddr_t addr, Dyn **dynpp, size_t *dynpp_sz)
431 431 {
432 432 struct ps_prochandle *php = rap->rd_psp;
433 433 rd_err_e err;
434 434 uint_t phnum;
435 435 Ehdr ehdr;
436 436 Phdr phdr;
437 437 Dyn *dynp;
438 438 int i;
439 439
440 440 /* We only need to muck with dyn elements for ET_DYN objects */
441 441 if ((err = _rd_get_ehdr32(rap, addr, &ehdr, &phnum)) != RD_OK)
442 442 return (err);
443 443
444 444 for (i = 0; i < phnum; i++) {
445 445 psaddr_t a = addr + ehdr.e_phoff + (i * ehdr.e_phentsize);
446 446 if (ps_pread(php, a, &phdr, sizeof (phdr)) != PS_OK) {
447 447 LOG(ps_plog(MSG_ORIG(MSG_DB_READFAIL_6), EC_ADDR(a)));
448 448 return (RD_ERR);
449 449 }
450 450 if (phdr.p_type == PT_DYNAMIC)
451 451 break;
452 452 }
453 453 if (i == phnum)
454 454 return (RD_ERR);
455 455
456 456 if ((dynp = malloc(phdr.p_filesz)) == NULL)
457 457 return (RD_ERR);
458 458 if (ehdr.e_type == ET_DYN)
459 459 phdr.p_vaddr += addr;
460 460 if (ps_pread(php, phdr.p_vaddr, dynp, phdr.p_filesz) != PS_OK) {
461 461 free(dynp);
462 462 LOG(ps_plog(MSG_ORIG(MSG_DB_READFAIL_6),
463 463 EC_ADDR(phdr.p_vaddr)));
464 464 return (RD_ERR);
465 465 }
466 466
467 467 *dynpp = dynp;
468 468 if (dynpp_sz != NULL)
469 469 *dynpp_sz = phdr.p_filesz;
470 470 return (RD_OK);
471 471 }
472 472
473 473 rd_err_e
474 474 _rd_event_enable32(rd_agent_t *rap, int onoff)
475 475 {
476 476 struct ps_prochandle *php = rap->rd_psp;
477 477 Rtld_db_priv rdb;
478 478
479 479 LOG(ps_plog(MSG_ORIG(MSG_DB_RDEVENTENABLE), rap->rd_dmodel, onoff));
480 480 /*
481 481 * Tell the debugged process that debugging is occuring
482 482 * This will enable the storing of event messages so that
483 483 * the can be gathered by the debugger.
484 484 */
485 485 if (ps_pread(php, rap->rd_rdebug, (char *)&rdb,
486 486 sizeof (Rtld_db_priv)) != PS_OK) {
487 487 LOG(ps_plog(MSG_ORIG(MSG_DB_READFAIL_1),
488 488 EC_ADDR((uintptr_t)&rdb)));
489 489 return (RD_DBERR);
490 490 }
491 491
492 492 if (onoff)
493 493 rdb.rtd_rdebug.r_flags |= RD_FL_DBG;
494 494 else
495 495 rdb.rtd_rdebug.r_flags &= ~RD_FL_DBG;
496 496
497 497 if (ps_pwrite(php, rap->rd_rdebug, (char *)&rdb,
498 498 sizeof (Rtld_db_priv)) != PS_OK) {
499 499 LOG(ps_plog(MSG_ORIG(MSG_DB_WRITEFAIL_1),
500 500 EC_ADDR((uintptr_t)&rdb)));
501 501 return (RD_DBERR);
502 502 }
503 503
504 504 return (RD_OK);
505 505 }
506 506
507 507
508 508 rd_err_e
509 509 _rd_event_getmsg32(rd_agent_t *rap, rd_event_msg_t *emsg)
510 510 {
511 511 Rtld_db_priv rdb;
512 512
513 513 if (ps_pread(rap->rd_psp, rap->rd_rdebug, (char *)&rdb,
514 514 sizeof (Rtld_db_priv)) != PS_OK) {
515 515 LOG(ps_plog(MSG_ORIG(MSG_DB_READDBGFAIL_2),
516 516 EC_ADDR(rap->rd_rdebug)));
517 517 return (RD_DBERR);
518 518 }
519 519 emsg->type = rdb.rtd_rdebug.r_rdevent;
520 520 if (emsg->type == RD_DLACTIVITY) {
521 521 switch (rdb.rtd_rdebug.r_state) {
522 522 case RT_CONSISTENT:
523 523 emsg->u.state = RD_CONSISTENT;
524 524 break;
525 525 case RT_ADD:
526 526 emsg->u.state = RD_ADD;
527 527 break;
528 528 case RT_DELETE:
529 529 emsg->u.state = RD_DELETE;
530 530 break;
531 531 }
532 532 } else
533 533 emsg->u.state = RD_NOSTATE;
534 534
535 535 LOG(ps_plog(MSG_ORIG(MSG_DB_RDEVENTGETMSG), rap->rd_dmodel,
536 536 emsg->type, emsg->u.state));
537 537
538 538 return (RD_OK);
539 539 }
540 540
541 541
542 542 rd_err_e
543 543 _rd_objpad_enable32(struct rd_agent *rap, size_t padsize)
544 544 {
545 545 Rtld_db_priv db_priv;
546 546 struct ps_prochandle *php = rap->rd_psp;
547 547
548 548 LOG(ps_plog(MSG_ORIG(MSG_DB_RDOBJPADE), EC_ADDR(padsize)));
549 549
550 550 if (ps_pread(php, rap->rd_rtlddbpriv, (char *)&db_priv,
551 551 sizeof (Rtld_db_priv)) != PS_OK) {
552 552 LOG(ps_plog(MSG_ORIG(MSG_DB_READFAIL_3),
553 553 EC_ADDR(rap->rd_rtlddbpriv)));
554 554 return (RD_DBERR);
555 555 }
556 556 #if defined(_LP64) && !defined(_ELF64)
557 557 /*LINTED*/
558 558 db_priv.rtd_objpad = (uint32_t)padsize;
559 559 #else
560 560 db_priv.rtd_objpad = padsize;
561 561 #endif
562 562 if (ps_pwrite(php, rap->rd_rtlddbpriv, (char *)&db_priv,
563 563 sizeof (Rtld_db_priv)) != PS_OK) {
564 564 LOG(ps_plog(MSG_ORIG(MSG_DB_WRITEFAIL_2),
565 565 EC_ADDR(rap->rd_rtlddbpriv)));
566 566 return (RD_DBERR);
567 567 }
568 568 return (RD_OK);
569 569 }
570 570
571 571 static rd_err_e
572 572 iter_map(rd_agent_t *rap, unsigned long ident, psaddr_t lmaddr,
573 573 rl_iter_f *cb, void *client_data, uint_t *abort_iterp)
574 574 {
575 575 while (lmaddr) {
576 576 Rt_map rmap;
577 577 rd_loadobj_t lobj;
578 578 int i;
579 579 ulong_t off;
580 580 Ehdr ehdr;
581 581 Phdr phdr;
582 582
583 583 if (ps_pread(rap->rd_psp, lmaddr, (char *)&rmap,
584 584 sizeof (Rt_map)) != PS_OK) {
585 585 LOG(ps_plog(MSG_ORIG(MSG_DB_LKMAPFAIL)));
586 586 return (RD_DBERR);
587 587 }
588 588
589 589 /*
590 590 * As of 'VERSION5' we only report objects
591 591 * which have been fully relocated. While the maps
592 592 * might be in a consistent state - if a object hasn't
593 593 * been relocated - it's not really ready for the debuggers
594 594 * to examine. This is mostly due to the fact that we
595 595 * might still be mucking with the text-segment, if
596 596 * we are - we could conflict with any break-points
597 597 * the debuggers might have set.
598 598 */
599 599 if (rap->rd_rdebugvers >= R_RTLDDB_VERSION5) {
600 600 if ((FLAGS(&rmap) & FLG_RT_RELOCED) == 0) {
601 601 lmaddr = (psaddr_t)NEXT(&rmap);
602 602 continue;
603 603 }
604 604 }
605 605
606 606 lobj.rl_base = (psaddr_t)ADDR(&rmap);
607 607 lobj.rl_flags = 0;
608 608 lobj.rl_refnameaddr = (psaddr_t)REFNAME(&rmap);
609 609 if ((rap->rd_helper.rh_ops != NULL) &&
610 610 (rap->rd_helper.rh_ops->rho_lmid != LM_ID_NONE))
611 611 lobj.rl_lmident =
612 612 rap->rd_helper.rh_ops->rho_lmid;
613 613 else
614 614 lobj.rl_lmident = ident;
615 615
616 616 /*
617 617 * refnameaddr is only valid from a core file
618 618 * which is VERSION3 or greater.
619 619 */
620 620 if (rap->rd_rdebugvers < R_RTLDDB_VERSION3) {
621 621 lobj.rl_nameaddr = (psaddr_t)NAME(&rmap);
622 622 lobj.rl_bend = 0;
623 623 lobj.rl_padstart = 0;
624 624 lobj.rl_padend = 0;
625 625 } else {
626 626 lobj.rl_nameaddr = (psaddr_t)PATHNAME(&rmap);
627 627 lobj.rl_bend = ADDR(&rmap) + MSIZE(&rmap);
628 628 lobj.rl_padstart = PADSTART(&rmap);
629 629 lobj.rl_padend = PADSTART(&rmap) + PADIMLEN(&rmap);
630 630
631 631 }
632 632
633 633 if (rtld_db_version >= RD_VERSION2)
634 634 if (FLAGS(&rmap) & FLG_RT_IMGALLOC)
635 635 lobj.rl_flags |= RD_FLG_MEM_OBJECT;
636 636 if (rtld_db_version >= RD_VERSION2) {
637 637 lobj.rl_dynamic = (psaddr_t)DYN(&rmap);
638 638 }
639 639
640 640 if (rtld_db_version >= RD_VERSION4)
641 641 lobj.rl_tlsmodid = TLSMODID(&rmap);
642 642
643 643 /*
644 644 * Look for beginning of data segment.
645 645 *
646 646 * NOTE: the data segment can only be found for full
647 647 * processes and not from core images.
648 648 */
649 649 lobj.rl_data_base = 0;
650 650 if (rap->rd_flags & RDF_FL_COREFILE)
651 651 lobj.rl_data_base = 0;
652 652 else {
653 653 off = ADDR(&rmap);
654 654 if (ps_pread(rap->rd_psp, off, (char *)&ehdr,
655 655 sizeof (Ehdr)) != PS_OK) {
656 656 LOG(ps_plog(MSG_ORIG(MSG_DB_LKMAPFAIL)));
657 657 return (RD_DBERR);
658 658 }
659 659 off += sizeof (Ehdr);
660 660 for (i = 0; i < ehdr.e_phnum; i++) {
661 661 if (ps_pread(rap->rd_psp, off, (char *)&phdr,
662 662 sizeof (Phdr)) != PS_OK) {
663 663 LOG(ps_plog(MSG_ORIG(
664 664 MSG_DB_LKMAPFAIL)));
665 665 return (RD_DBERR);
666 666 }
667 667 if ((phdr.p_type == PT_LOAD) &&
668 668 (phdr.p_flags & PF_W)) {
669 669 lobj.rl_data_base = phdr.p_vaddr;
670 670 if (ehdr.e_type == ET_DYN)
671 671 lobj.rl_data_base +=
672 672 ADDR(&rmap);
673 673 break;
674 674 }
675 675 off += ehdr.e_phentsize;
676 676 }
677 677 }
678 678
679 679 /*
680 680 * When we transfer control to the client we free the
681 681 * lock and re-atain it after we've returned from the
682 682 * client. This is to avoid any deadlock situations.
683 683 */
684 684 LOG(ps_plog(MSG_ORIG(MSG_DB_ITERMAP), cb, client_data,
685 685 EC_ADDR(lobj.rl_base), EC_ADDR(lobj.rl_lmident)));
686 686 RDAGUNLOCK(rap);
687 687 if ((*cb)(&lobj, client_data) == 0) {
688 688 LOG(ps_plog(MSG_ORIG(MSG_DB_CALLBACKR0)));
689 689 RDAGLOCK(rap);
690 690 *abort_iterp = 1;
691 691 break;
692 692 }
693 693 RDAGLOCK(rap);
694 694 lmaddr = (psaddr_t)NEXT(&rmap);
695 695 }
696 696 return (RD_OK);
697 697 }
698 698
699 699
700 700 static rd_err_e
701 701 _rd_loadobj_iter32_native(rd_agent_t *rap, rl_iter_f *cb, void *client_data,
702 702 uint_t *abort_iterp)
703 703 {
704 704 Rtld_db_priv db_priv;
705 705 TAPlist apl;
706 706 uintptr_t datap, nitems;
707 707 Addr addr;
708 708 rd_err_e rc;
709 709
710 710 LOG(ps_plog(MSG_ORIG(MSG_DB_LOADOBJITER), rap->rd_dmodel, cb,
711 711 client_data));
712 712
713 713 /*
714 714 * First, determine whether the link-map information has been
715 715 * established. Some debuggers have made an initial call to this
716 716 * function with a null call back function (cb), but expect a
717 717 * RD_NOMAPS error return rather than a RD_ERR return when the
718 718 * link-maps aren't available.
719 719 */
720 720 if (ps_pread(rap->rd_psp, rap->rd_rtlddbpriv, (char *)&db_priv,
721 721 sizeof (Rtld_db_priv)) != PS_OK) {
722 722 LOG(ps_plog(MSG_ORIG(MSG_DB_READDBGFAIL_1),
723 723 EC_ADDR(rap->rd_rtlddbpriv)));
724 724 return (RD_DBERR);
725 725 }
726 726
727 727 if (db_priv.rtd_dynlmlst == NULL) {
728 728 LOG(ps_plog(MSG_ORIG(MSG_DB_LKMAPNOINIT),
729 729 EC_ADDR((uintptr_t)db_priv.rtd_dynlmlst)));
730 730 return (RD_NOMAPS);
731 731 }
732 732
733 733 if (ps_pread(rap->rd_psp, (psaddr_t)db_priv.rtd_dynlmlst, (char *)&addr,
734 734 sizeof (Addr)) != PS_OK) {
735 735 LOG(ps_plog(MSG_ORIG(MSG_DB_READDBGFAIL_3),
736 736 EC_ADDR((uintptr_t)db_priv.rtd_dynlmlst)));
737 737 return (RD_DBERR);
738 738 }
739 739
740 740 if (addr == NULL) {
741 741 LOG(ps_plog(MSG_ORIG(MSG_DB_LKMAPNOINIT_1),
742 742 EC_ADDR((uintptr_t)db_priv.rtd_dynlmlst)));
743 743 return (RD_NOMAPS);
744 744 }
745 745
746 746 /*
747 747 * Having determined we have link-maps, ensure we have an iterator
748 748 * call back function.
749 749 */
750 750 if (cb == NULL) {
751 751 LOG(ps_plog(MSG_ORIG(MSG_DB_NULLITER)));
752 752 return (RD_ERR);
753 753 }
754 754
755 755 /*
756 756 * As of VERSION6, rtd_dynlmlst points to an APlist. Prior to VERSION6
757 757 * rtd_dynlmlst pointed to a List. But, there was a window where the
758 758 * version was not incremented, and this must be worked around by
759 759 * interpreting the APlist data. Read the initial APlist information.
760 760 */
761 761 if (ps_pread(rap->rd_psp, (psaddr_t)addr, (char *)&apl,
762 762 sizeof (TAPlist)) != PS_OK) {
763 763 LOG(ps_plog(MSG_ORIG(MSG_DB_READDBGFAIL_4),
764 764 EC_ADDR((uintptr_t)addr)));
765 765 return (RD_DBERR);
766 766 }
767 767
768 768 /*
769 769 * The rtd_dynlmlst change from a List to an APlist occurred under
770 770 * 6801536 in snv_112. However, this change neglected to preserve
771 771 * backward compatibility by maintaining List processing and using a
772 772 * version increment to detect the change. 6862967, intergrated in
773 773 * snv_121 corrects the version detection. However, to catch objects
774 774 * built between these releases, we look at the first element of the
775 775 * APlist. apl_arritems indicates the number of APlist items that are
776 776 * available. This was originally initialized with a AL_CNT_DYNLIST
777 777 * value of 2 (one entry for LM_ID_BASE and one entry for LM_ID_LDSO).
778 778 * It is possible that the use of an auditor results in an additional
779 779 * link-map list, in which case the original apl_arritems would have
780 780 * been doubled.
781 781 *
782 782 * Therefore, if the debugging verion is VERSION6, or the apl_arritems
783 783 * entry has a value less than or equal to 4 and the debugging version
784 784 * is VERSION5, then we process APlists. Otherwise, fall back to List
785 785 * processing.
786 786 */
787 787 if ((rap->rd_rdebugvers >= R_RTLDDB_VERSION6) ||
788 788 ((rap->rd_rdebugvers == R_RTLDDB_VERSION5) &&
789 789 (apl.apl_arritems <= 4))) {
790 790 /*
791 791 * Iterate through each apl.ap_data[] entry.
792 792 */
793 793 for (datap = (uintptr_t)((char *)(uintptr_t)addr +
794 794 ((size_t)(((TAPlist *)0)->apl_data))), nitems = 0;
795 795 nitems < apl.apl_nitems; nitems++, datap += sizeof (Addr)) {
796 796 TLm_list lm;
797 797 ulong_t ident;
798 798
799 799 /*
800 800 * Obtain the Lm_list address for this apl.ap_data[]
801 801 * entry.
802 802 */
803 803 if (ps_pread(rap->rd_psp, (psaddr_t)datap,
804 804 (char *)&addr, sizeof (Addr)) != PS_OK) {
805 805 LOG(ps_plog(MSG_ORIG(MSG_DB_READDBGFAIL_5),
806 806 EC_ADDR(datap)));
807 807 return (RD_DBERR);
808 808 }
809 809
810 810 /*
811 811 * Obtain the Lm_list data for this Lm_list address.
812 812 */
813 813 if (ps_pread(rap->rd_psp, (psaddr_t)addr, (char *)&lm,
814 814 sizeof (TLm_list)) != PS_OK) {
815 815 LOG(ps_plog(MSG_ORIG(MSG_DB_READDBGFAIL_6),
816 816 EC_ADDR((uintptr_t)addr)));
817 817 return (RD_DBERR);
818 818 }
819 819
820 820 /*
821 821 * Determine IDENT of current LM_LIST
822 822 */
823 823 if (lm.lm_flags & LML_FLG_BASELM)
824 824 ident = LM_ID_BASE;
825 825 else if (lm.lm_flags & LML_FLG_RTLDLM)
826 826 ident = LM_ID_LDSO;
827 827 else
828 828 ident = (ulong_t)addr;
829 829
830 830 if ((rc = iter_map(rap, ident, (psaddr_t)lm.lm_head,
831 831 cb, client_data, abort_iterp)) != RD_OK)
832 832 return (rc);
833 833
834 834 if (*abort_iterp != 0)
835 835 break;
836 836 }
837 837 } else {
838 838 TList list;
839 839 TListnode lnode;
840 840 Addr lnp;
841 841
842 842 /*
843 843 * Re-read the dynlmlst address to obtain a List structure.
844 844 */
845 845 if (ps_pread(rap->rd_psp, (psaddr_t)db_priv.rtd_dynlmlst,
846 846 (char *)&list, sizeof (TList)) != PS_OK) {
847 847 LOG(ps_plog(MSG_ORIG(MSG_DB_READDBGFAIL_3),
848 848 EC_ADDR((uintptr_t)db_priv.rtd_dynlmlst)));
849 849 return (RD_DBERR);
850 850 }
851 851
852 852 /*
853 853 * Iterate through the link-map list.
854 854 */
855 855 for (lnp = (Addr)list.head; lnp; lnp = (Addr)lnode.next) {
856 856 Lm_list lml;
857 857 ulong_t ident;
858 858
859 859 /*
860 860 * Iterate through the List of Lm_list's.
861 861 */
862 862 if (ps_pread(rap->rd_psp, (psaddr_t)lnp, (char *)&lnode,
863 863 sizeof (TListnode)) != PS_OK) {
864 864 LOG(ps_plog(MSG_ORIG(MSG_DB_READDBGFAIL_4),
865 865 EC_ADDR(lnp)));
866 866 return (RD_DBERR);
867 867 }
868 868
869 869 if (ps_pread(rap->rd_psp, (psaddr_t)lnode.data,
870 870 (char *)&lml, sizeof (Lm_list)) != PS_OK) {
871 871 LOG(ps_plog(MSG_ORIG(MSG_DB_READDBGFAIL_5),
872 872 EC_ADDR((uintptr_t)lnode.data)));
873 873 return (RD_DBERR);
874 874 }
875 875
876 876 /*
877 877 * Determine IDENT of current LM_LIST
878 878 */
879 879 if (lml.lm_flags & LML_FLG_BASELM)
880 880 ident = LM_ID_BASE;
881 881 else if (lml.lm_flags & LML_FLG_RTLDLM)
882 882 ident = LM_ID_LDSO;
883 883 else
884 884 ident = (unsigned long)lnode.data;
885 885
886 886 if ((rc = iter_map(rap, ident, (psaddr_t)lml.lm_head,
887 887 cb, client_data, abort_iterp)) != RD_OK)
888 888 return (rc);
889 889
890 890 if (*abort_iterp != 0)
891 891 break;
892 892 }
893 893 }
894 894
895 895 return (rc);
896 896 }
897 897
898 898 rd_err_e
899 899 _rd_loadobj_iter32(rd_agent_t *rap, rl_iter_f *cb, void *client_data)
900 900 {
901 901 rd_err_e rc, rc_brand = RD_OK;
902 902 uint_t abort_iter = 0;
903 903
904 904 /* First iterate over the native target objects */
905 905 rc = _rd_loadobj_iter32_native(rap, cb, client_data, &abort_iter);
906 906 if (abort_iter != 0)
907 907 return (rc);
908 908
909 909 /* Then iterate over any branded objects. */
910 910 if ((rap->rd_helper.rh_ops != NULL) &&
911 911 (rap->rd_helper.rh_ops->rho_loadobj_iter != NULL))
912 912 rc_brand = rap->rd_helper.rh_ops->rho_loadobj_iter(
913 913 rap->rd_helper.rh_data, cb, client_data);
914 914
915 915 rc = (rc != RD_OK) ? rc : rc_brand;
916 916 return (rc);
917 917 }
|
↓ open down ↓ |
917 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX