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