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