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