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 /*
  23  * Copyright (c) 1995, 2010, Oracle and/or its affiliates. All rights reserved.
  24  */
  25 
  26 #include <stdio.h>
  27 #include <stdlib.h>
  28 #include <unistd.h>
  29 #include <sys/uio.h>
  30 #include <fcntl.h>
  31 #include <string.h>
  32 #include <errno.h>
  33 #include <sys/types.h>
  34 #include <sys/signal.h>
  35 #include <sys/fault.h>
  36 #include <sys/syscall.h>
  37 #include <procfs.h>
  38 #include <sys/auxv.h>
  39 #include <sys/stat.h>
  40 #include <sys/mman.h>
  41 #include <libelf.h>
  42 #include <sys/param.h>
  43 #include <sys/machelf.h>
  44 #include <stdarg.h>
  45 
  46 #include <proc_service.h>
  47 
  48 #include "rdb.h"
  49 #include "disasm.h"
  50 
  51 #if     !defined(_LP64)
  52 static void
  53 gelf_sym_to_elf32(GElf_Sym *src, Elf32_Sym *dst)
  54 {
  55         dst->st_name = src->st_name;
  56         dst->st_value        = src->st_value;
  57         dst->st_size = src->st_size;
  58         dst->st_info = ELF32_ST_INFO(GELF_ST_BIND(src->st_info),
  59             GELF_ST_TYPE(src->st_info));
  60         dst->st_other        = src->st_other;
  61         dst->st_shndx        = src->st_shndx;
  62 }
  63 #endif
  64 
  65 #define PROCSIZE        20
  66 
  67 static void
  68 get_ldbase(struct ps_prochandle *procp)
  69 {
  70         int             pauxvfd;
  71         char            pname[PROCSIZE];
  72         struct stat     stbuf;
  73         void            *auxvptr, *auxvtail;
  74         auxv_t          *auxvp;
  75         uint_t          entsize;
  76 
  77         (void) snprintf(pname, PROCSIZE, "/proc/%d/auxv",
  78             EC_SWORD(procp->pp_pid));
  79         if ((pauxvfd = open(pname, O_RDONLY)) == -1)
  80                 perr("open auxv");
  81 
  82         if (fstat(pauxvfd, &stbuf) == -1)
  83                 perr("stat auxv");
  84 
  85         auxvptr = malloc(stbuf.st_size);
  86         if (read(pauxvfd, auxvptr, stbuf.st_size) == -1)
  87                 perr("gldb: reading auxv");
  88 
  89         (void) close(pauxvfd);
  90 
  91         procp->pp_auxvp = auxvptr;
  92         auxvtail = (void *)((uintptr_t)auxvptr + stbuf.st_size);
  93 
  94 #if defined(_LP64)
  95         if (procp->pp_dmodel == PR_MODEL_ILP32)
  96                 entsize = sizeof (auxv32_t);
  97         else
  98 #endif
  99                 entsize = sizeof (auxv_t);
 100 
 101         while (auxvptr < auxvtail) {
 102                 auxvp = auxvptr;
 103                 if (auxvp->a_type == AT_BASE) {
 104 #if defined(_LP64)
 105                         if (procp->pp_dmodel == PR_MODEL_ILP32)
 106                                 procp->pp_ldsobase =
 107                                     ((uintptr_t)((auxv32_t *)auxvp)->
 108                                     a_un.a_val);
 109                         else
 110 #endif
 111                                 procp->pp_ldsobase =  auxvp->a_un.a_val;
 112                 } else if (auxvp->a_type == AT_PHDR) {
 113 #if defined(_LP64)
 114                         if (procp->pp_dmodel == PR_MODEL_ILP32)
 115                                 procp->pp_execphdr =
 116                                     ((uintptr_t)((auxv32_t *)auxvp)->
 117                                     a_un.a_val);
 118                         else
 119 #endif
 120                                 procp->pp_execphdr =  auxvp->a_un.a_val;
 121                 }
 122                 auxvptr = (void *)((uintptr_t)auxvptr + entsize);
 123         }
 124 }
 125 
 126 retc_t
 127 ps_init(int pctlfd, int pstatusfd, pid_t pid, struct ps_prochandle *procp)
 128 {
 129         rd_notify_t     rd_notify;
 130         char            procname[PROCSIZE];
 131         long            oper, pflags;
 132         struct iovec    piov[2];
 133 
 134         procp->pp_pid = pid;
 135         procp->pp_ctlfd = pctlfd;
 136         procp->pp_statusfd = pstatusfd;
 137 
 138         (void) snprintf(procname, PROCSIZE, "/proc/%d/map",
 139             EC_SWORD(procp->pp_pid));
 140         if ((procp->pp_mapfd = open(procname, O_RDONLY)) == -1)
 141                 perr("psi: open of /proc/dpid/map failed");
 142 
 143         (void) snprintf(procname, PROCSIZE, "/proc/%d/as",
 144             EC_SWORD(procp->pp_pid));
 145         if ((procp->pp_asfd = open(procname, O_RDWR)) == -1)
 146                 perr("psi: open of /proc/dpid/as failed");
 147 
 148         if (ps_pdmodel(procp, &procp->pp_dmodel) != PS_OK)
 149                 perr("psi: data model");
 150 
 151 #if     !defined(_LP64)
 152         if (procp->pp_dmodel == PR_MODEL_LP64)
 153                 perr("psi:  run 64-bit rdb to debug a 64-bit process");
 154 #endif
 155         get_ldbase(procp);
 156 
 157         (void) load_map(procp, (caddr_t)procp->pp_ldsobase,
 158             &(procp->pp_ldsomap));
 159         procp->pp_ldsomap.mi_addr += procp->pp_ldsobase;
 160         procp->pp_ldsomap.mi_end += procp->pp_ldsobase;
 161         procp->pp_ldsomap.mi_name = "<procfs: interp>";
 162 
 163         (void) load_map(procp, (caddr_t)procp->pp_execphdr,
 164             &(procp->pp_execmap));
 165         procp->pp_execmap.mi_name = "<procfs: exec>";
 166 
 167         procp->pp_breakpoints = NULL;
 168         procp->pp_flags = FLG_PP_PACT | FLG_PP_PLTSKIP;
 169         procp->pp_lmaplist.ml_head = NULL;
 170         procp->pp_lmaplist.ml_tail = NULL;
 171         if ((procp->pp_rap = rd_new(procp)) == NULL) {
 172                 (void) fprintf(stderr, "rdb: rtld_db: rd_new() call failed\n");
 173                 exit(1);
 174         }
 175         (void) rd_event_enable(procp->pp_rap, 1);
 176 
 177         /*
 178          * For those architectures that increment the PC on
 179          * a breakpoint fault we enable the PR_BPTADJ adjustments.
 180          */
 181         oper = PCSET;
 182         pflags = PR_BPTADJ;
 183         piov[0].iov_base = (caddr_t)(&oper);
 184         piov[0].iov_len = sizeof (oper);
 185         piov[1].iov_base = (caddr_t)(&pflags);
 186         piov[1].iov_len = sizeof (pflags);
 187         if (writev(procp->pp_ctlfd, piov, 2) == -1)
 188                 perr("psinit: PCSET(PR_BTPADJ)");
 189 
 190         /*
 191          * Set breakpoints for special handshakes between librtld_db.so
 192          * and the debugger.  These include:
 193          *      PREINIT         - before .init processing.
 194          *      POSTINIT        - after .init processing
 195          *      DLACTIVITY      - link_maps status has changed
 196          */
 197         if (rd_event_addr(procp->pp_rap, RD_PREINIT, &rd_notify) == RD_OK) {
 198                 if (set_breakpoint(procp, rd_notify.u.bptaddr,
 199                     FLG_BP_RDPREINIT) != RET_OK)
 200                         (void) fprintf(stderr,
 201                             "psi: failed to set BP for preinit at: 0x%lx\n",
 202                             rd_notify.u.bptaddr);
 203         } else
 204                 (void) fprintf(stderr, "psi: no event registered for "
 205                     "preinit\n");
 206 
 207         if (rd_event_addr(procp->pp_rap, RD_POSTINIT, &rd_notify) == RD_OK) {
 208                 if (set_breakpoint(procp, rd_notify.u.bptaddr,
 209                     FLG_BP_RDPOSTINIT) != RET_OK)
 210                         (void) fprintf(stderr,
 211                             "psi: failed to set BP for postinit at: 0x%lx\n",
 212                             rd_notify.u.bptaddr);
 213         } else
 214                 (void) fprintf(stderr, "psi: no event registered for "
 215                     "postinit\n");
 216 
 217         if (rd_event_addr(procp->pp_rap, RD_DLACTIVITY, &rd_notify) == RD_OK) {
 218                 if (set_breakpoint(procp, rd_notify.u.bptaddr,
 219                     FLG_BP_RDDLACT) != RET_OK)
 220                         (void) fprintf(stderr,
 221                             "psi: failed to set BP for dlact at: 0x%lx\n",
 222                             rd_notify.u.bptaddr);
 223         } else
 224                 (void) fprintf(stderr, "psi: no event registered for dlact\n");
 225 
 226         return (RET_OK);
 227 }
 228 
 229 retc_t
 230 ps_close(struct ps_prochandle *ph)
 231 {
 232         (void) delete_all_breakpoints(ph);
 233 
 234         if (ph->pp_auxvp)
 235                 free(ph->pp_auxvp);
 236         free_linkmaps(ph);
 237         return (RET_OK);
 238 }
 239 
 240 ps_err_e
 241 ps_pauxv(struct ps_prochandle *ph, const auxv_t **auxvp)
 242 {
 243         *auxvp = ph->pp_auxvp;
 244         return (PS_OK);
 245 }
 246 
 247 ps_err_e
 248 ps_pdmodel(struct ps_prochandle *ph, int *dm)
 249 {
 250         pstatus_t       pstatus;
 251 
 252         if (pread(ph->pp_statusfd, &pstatus, sizeof (pstatus), 0) == -1)
 253                 return (PS_ERR);
 254 
 255         *dm = (int)pstatus.pr_dmodel;
 256         return (PS_OK);
 257 }
 258 
 259 ps_err_e
 260 ps_pread(struct ps_prochandle *ph, psaddr_t addr, void *buf, size_t size)
 261 {
 262         if (pread(ph->pp_asfd, buf, size, (off_t)addr) != size)
 263                 return (PS_ERR);
 264 
 265         return (PS_OK);
 266 }
 267 
 268 ps_err_e
 269 ps_pwrite(struct ps_prochandle *ph, psaddr_t addr, const void *buf, size_t size)
 270 {
 271         if (pwrite(ph->pp_asfd, buf, size, (off_t)addr) != size)
 272                 return (PS_ERR);
 273 
 274         return (PS_OK);
 275 }
 276 
 277 ps_err_e
 278 ps_pglobal_sym(struct ps_prochandle *ph, const char *object_name,
 279     const char *sym_name, ps_sym_t *symp)
 280 {
 281         map_info_t      *mip;
 282         GElf_Sym        gsym;
 283 
 284         if ((mip = str_to_map(ph, object_name)) == NULL)
 285                 return (PS_ERR);
 286 
 287         if (str_map_sym(sym_name, mip, &gsym, NULL) == RET_FAILED)
 288                 return (PS_ERR);
 289 
 290 #if     defined(_LP64)
 291         *symp = gsym;
 292 #else
 293         gelf_sym_to_elf32(&gsym, (Elf32_Sym *)symp);
 294 #endif
 295 
 296         return (PS_OK);
 297 }
 298 
 299 ps_err_e
 300 ps_pglobal_lookup(struct ps_prochandle *ph, const char *object_name,
 301     const char *sym_name, ulong_t *sym_addr)
 302 {
 303         GElf_Sym        sym;
 304         map_info_t      *mip;
 305 
 306         if ((mip = str_to_map(ph, object_name)) == NULL)
 307                 return (PS_ERR);
 308 
 309         if (str_map_sym(sym_name, mip, &sym, NULL) == RET_FAILED)
 310                 return (PS_ERR);
 311 
 312         *sym_addr = sym.st_value;
 313 
 314         return (PS_OK);
 315 }
 316 
 317 ps_err_e
 318 ps_lgetregs(struct ps_prochandle *ph, lwpid_t lid, prgregset_t gregset)
 319 {
 320         char            procname[MAXPATHLEN];
 321         int             lwpfd;
 322         lwpstatus_t     lwpstatus;
 323 
 324         (void) snprintf(procname, MAXPATHLEN - 1,
 325             "/proc/%d/lwp/%d/lwpstatus", EC_SWORD(ph->pp_pid), EC_SWORD(lid));
 326 
 327         if ((lwpfd = open(procname, O_RDONLY)) == -1)
 328                 return (PS_ERR);
 329 
 330         if (read(lwpfd, &lwpstatus, sizeof (lwpstatus)) == -1)
 331                 return (PS_ERR);
 332 
 333         gregset = lwpstatus.pr_reg;
 334 
 335         (void) close(lwpfd);
 336         return (PS_OK);
 337 }
 338 
 339 void
 340 ps_plog(const char *fmt, ...)
 341 {
 342         va_list         args;
 343         static FILE     *log_fp = NULL;
 344 
 345         if (log_fp == NULL) {
 346                 char            log_fname[256];
 347                 (void) sprintf(log_fname, "/tmp/tdlog.%d", EC_SWORD(getpid()));
 348                 if ((log_fp = fopen(log_fname, "w")) == NULL) {
 349                         /*
 350                          * Unable to open log file - default to stderr.
 351                          */
 352                         (void) fprintf(stderr, "unable to open %s, logging "
 353                             "redirected to stderr", log_fname);
 354                         log_fp = stderr;
 355                 }
 356         }
 357 
 358         va_start(args, fmt);
 359         (void) vfprintf(log_fp, fmt, args);
 360         va_end(args);
 361         (void) fputc('\n', log_fp);
 362         (void) fflush(log_fp);
 363 }
 364 
 365 /* ARGSUSED0 */
 366 ps_err_e
 367 ps_pbrandname(struct ps_prochandle *P, char *buf, size_t len)
 368 {
 369         return (PS_ERR);
 370 }