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