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 == NULL) {
 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 == NULL) {
 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 }