1 /*
   2  * CDDL HEADER START
   3  *
   4  * The contents of this file are subject to the terms of the
   5  * Common Development and Distribution License (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 /*
  22  * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
  23  * Use is subject to license terms.
  24  */
  25 
  26 /*
  27  * Copyright (c) 2013, Joyent, Inc. All rights reserved.
  28  */
  29 
  30 #include <sys/types.h>
  31 #include <sys/uio.h>
  32 #include <string.h>
  33 #include <errno.h>
  34 #include <limits.h>
  35 
  36 #include "Pcontrol.h"
  37 #include "P32ton.h"
  38 
  39 /*
  40  * This file implements the routines to read and write per-lwp register
  41  * information from either a live process or core file opened with libproc.
  42  * We build up a few common routines for reading and writing register
  43  * information, and then the public functions are all trivial calls to these.
  44  */
  45 
  46 /*
  47  * Utility function to return a pointer to the structure of cached information
  48  * about an lwp in the core file, given its lwpid.
  49  */
  50 static lwp_info_t *
  51 getlwpcore(struct ps_prochandle *P, lwpid_t lwpid)
  52 {
  53         lwp_info_t *lwp = list_next(&P->core->core_lwp_head);
  54         uint_t i;
  55 
  56         for (i = 0; i < P->core->core_nlwp; i++, lwp = list_next(lwp)) {
  57                 if (lwp->lwp_id == lwpid)
  58                         return (lwp);
  59         }
  60 
  61         errno = EINVAL;
  62         return (NULL);
  63 }
  64 
  65 /*
  66  * Utility function to open and read the contents of a per-lwp /proc file.
  67  * This function is used to slurp in lwpstatus, xregs, and asrs.
  68  */
  69 static int
  70 getlwpfile(struct ps_prochandle *P, lwpid_t lwpid,
  71     const char *fbase, void *rp, size_t n)
  72 {
  73         char fname[PATH_MAX];
  74         int fd;
  75 
  76         (void) snprintf(fname, sizeof (fname), "%s/%d/lwp/%d/%s",
  77             procfs_path, (int)P->status.pr_pid, (int)lwpid, fbase);
  78 
  79         if ((fd = open(fname, O_RDONLY)) >= 0) {
  80                 if (read(fd, rp, n) > 0) {
  81                         (void) close(fd);
  82                         return (0);
  83                 }
  84                 (void) close(fd);
  85         }
  86         return (-1);
  87 }
  88 
  89 /*
  90  * Get the lwpstatus_t for an lwp from either the live process or our
  91  * cached information from the core file.  This is used to get the
  92  * general-purpose registers or floating point registers.
  93  */
  94 int
  95 getlwpstatus(struct ps_prochandle *P, lwpid_t lwpid, lwpstatus_t *lps)
  96 {
  97         lwp_info_t *lwp;
  98 
  99         /*
 100          * For both live processes and cores, our job is easy if the lwpid
 101          * matches that of the representative lwp:
 102          */
 103         if (P->status.pr_lwp.pr_lwpid == lwpid) {
 104                 (void) memcpy(lps, &P->status.pr_lwp, sizeof (lwpstatus_t));
 105                 return (0);
 106         }
 107 
 108         /*
 109          * If this is a live process, then just read the information out
 110          * of the per-lwp status file:
 111          */
 112         if (P->state != PS_DEAD) {
 113                 return (getlwpfile(P, lwpid, "lwpstatus",
 114                     lps, sizeof (lwpstatus_t)));
 115         }
 116 
 117         /*
 118          * If this is a core file, we need to iterate through our list of
 119          * cached lwp information and then copy out the status.
 120          */
 121         if (P->core != NULL && (lwp = getlwpcore(P, lwpid)) != NULL) {
 122                 (void) memcpy(lps, &lwp->lwp_status, sizeof (lwpstatus_t));
 123                 return (0);
 124         }
 125 
 126         return (-1);
 127 }
 128 
 129 /*
 130  * Utility function to modify lwp registers.  This is done using either the
 131  * process control file or per-lwp control file as necessary.
 132  */
 133 static int
 134 setlwpregs(struct ps_prochandle *P, lwpid_t lwpid, long cmd,
 135     const void *rp, size_t n)
 136 {
 137         iovec_t iov[2];
 138         char fname[PATH_MAX];
 139         int fd;
 140 
 141         if (P->state != PS_STOP) {
 142                 errno = EBUSY;
 143                 return (-1);
 144         }
 145 
 146         iov[0].iov_base = (caddr_t)&cmd;
 147         iov[0].iov_len = sizeof (long);
 148         iov[1].iov_base = (caddr_t)rp;
 149         iov[1].iov_len = n;
 150 
 151         /*
 152          * Writing the process control file writes the representative lwp.
 153          * Psync before we write to make sure we are consistent with the
 154          * primary interfaces.  Similarly, make sure to update P->status
 155          * afterward if we are modifying one of its register sets.
 156          */
 157         if (P->status.pr_lwp.pr_lwpid == lwpid) {
 158                 Psync(P);
 159 
 160                 if (writev(P->ctlfd, iov, 2) == -1)
 161                         return (-1);
 162 
 163                 if (cmd == PCSREG)
 164                         (void) memcpy(P->status.pr_lwp.pr_reg, rp, n);
 165                 else if (cmd == PCSFPREG)
 166                         (void) memcpy(&P->status.pr_lwp.pr_fpreg, rp, n);
 167 
 168                 return (0);
 169         }
 170 
 171         /*
 172          * If the lwp we want is not the representative lwp, we need to
 173          * open the ctl file for that specific lwp.
 174          */
 175         (void) snprintf(fname, sizeof (fname), "%s/%d/lwp/%d/lwpctl",
 176             procfs_path, (int)P->status.pr_pid, (int)lwpid);
 177 
 178         if ((fd = open(fname, O_WRONLY)) >= 0) {
 179                 if (writev(fd, iov, 2) > 0) {
 180                         (void) close(fd);
 181                         return (0);
 182                 }
 183                 (void) close(fd);
 184         }
 185         return (-1);
 186 }
 187 
 188 int
 189 Plwp_getregs(struct ps_prochandle *P, lwpid_t lwpid, prgregset_t gregs)
 190 {
 191         lwpstatus_t lps;
 192 
 193         if (getlwpstatus(P, lwpid, &lps) == -1)
 194                 return (-1);
 195 
 196         (void) memcpy(gregs, lps.pr_reg, sizeof (prgregset_t));
 197         return (0);
 198 }
 199 
 200 int
 201 Plwp_setregs(struct ps_prochandle *P, lwpid_t lwpid, const prgregset_t gregs)
 202 {
 203         return (setlwpregs(P, lwpid, PCSREG, gregs, sizeof (prgregset_t)));
 204 }
 205 
 206 int
 207 Plwp_getfpregs(struct ps_prochandle *P, lwpid_t lwpid, prfpregset_t *fpregs)
 208 {
 209         lwpstatus_t lps;
 210 
 211         if (getlwpstatus(P, lwpid, &lps) == -1)
 212                 return (-1);
 213 
 214         (void) memcpy(fpregs, &lps.pr_fpreg, sizeof (prfpregset_t));
 215         return (0);
 216 }
 217 
 218 int Plwp_setfpregs(struct ps_prochandle *P, lwpid_t lwpid,
 219     const prfpregset_t *fpregs)
 220 {
 221         return (setlwpregs(P, lwpid, PCSFPREG, fpregs, sizeof (prfpregset_t)));
 222 }
 223 
 224 #if defined(sparc) || defined(__sparc)
 225 int
 226 Plwp_getxregs(struct ps_prochandle *P, lwpid_t lwpid, prxregset_t *xregs)
 227 {
 228         lwp_info_t *lwp;
 229 
 230         if (P->state == PS_IDLE) {
 231                 errno = ENODATA;
 232                 return (-1);
 233         }
 234 
 235         if (P->state != PS_DEAD) {
 236                 if (P->state != PS_STOP) {
 237                         errno = EBUSY;
 238                         return (-1);
 239                 }
 240 
 241                 return (getlwpfile(P, lwpid, "xregs",
 242                     xregs, sizeof (prxregset_t)));
 243         }
 244 
 245         if ((lwp = getlwpcore(P, lwpid)) != NULL && lwp->lwp_xregs != NULL) {
 246                 (void) memcpy(xregs, lwp->lwp_xregs, sizeof (prxregset_t));
 247                 return (0);
 248         }
 249 
 250         if (lwp != NULL)
 251                 errno = ENODATA;
 252         return (-1);
 253 }
 254 
 255 int
 256 Plwp_setxregs(struct ps_prochandle *P, lwpid_t lwpid, const prxregset_t *xregs)
 257 {
 258         return (setlwpregs(P, lwpid, PCSXREG, xregs, sizeof (prxregset_t)));
 259 }
 260 
 261 int
 262 Plwp_getgwindows(struct ps_prochandle *P, lwpid_t lwpid, gwindows_t *gwins)
 263 {
 264         lwp_info_t *lwp;
 265 
 266         if (P->state == PS_IDLE) {
 267                 errno = ENODATA;
 268                 return (-1);
 269         }
 270 
 271         if (P->state != PS_DEAD) {
 272                 if (P->state != PS_STOP) {
 273                         errno = EBUSY;
 274                         return (-1);
 275                 }
 276 
 277                 return (getlwpfile(P, lwpid, "gwindows",
 278                     gwins, sizeof (gwindows_t)));
 279         }
 280 
 281         if ((lwp = getlwpcore(P, lwpid)) != NULL && lwp->lwp_gwins != NULL) {
 282                 *gwins = *lwp->lwp_gwins;
 283                 return (0);
 284         }
 285 
 286         if (lwp != NULL)
 287                 errno = ENODATA;
 288         return (-1);
 289 }
 290 
 291 #if defined(__sparcv9)
 292 int
 293 Plwp_getasrs(struct ps_prochandle *P, lwpid_t lwpid, asrset_t asrs)
 294 {
 295         lwp_info_t *lwp;
 296 
 297         if (P->state == PS_IDLE) {
 298                 errno = ENODATA;
 299                 return (-1);
 300         }
 301 
 302         if (P->state != PS_DEAD) {
 303                 if (P->state != PS_STOP) {
 304                         errno = EBUSY;
 305                         return (-1);
 306                 }
 307 
 308                 return (getlwpfile(P, lwpid, "asrs", asrs, sizeof (asrset_t)));
 309         }
 310 
 311         if ((lwp = getlwpcore(P, lwpid)) != NULL && lwp->lwp_asrs != NULL) {
 312                 (void) memcpy(asrs, lwp->lwp_asrs, sizeof (asrset_t));
 313                 return (0);
 314         }
 315 
 316         if (lwp != NULL)
 317                 errno = ENODATA;
 318         return (-1);
 319 
 320 }
 321 
 322 int
 323 Plwp_setasrs(struct ps_prochandle *P, lwpid_t lwpid, const asrset_t asrs)
 324 {
 325         return (setlwpregs(P, lwpid, PCSASRS, asrs, sizeof (asrset_t)));
 326 }
 327 #endif  /* __sparcv9 */
 328 #endif  /* __sparc */
 329 
 330 int
 331 Plwp_getpsinfo(struct ps_prochandle *P, lwpid_t lwpid, lwpsinfo_t *lps)
 332 {
 333         lwp_info_t *lwp;
 334 
 335         if (P->state == PS_IDLE) {
 336                 errno = ENODATA;
 337                 return (-1);
 338         }
 339 
 340         if (P->state != PS_DEAD) {
 341                 return (getlwpfile(P, lwpid, "lwpsinfo",
 342                     lps, sizeof (lwpsinfo_t)));
 343         }
 344 
 345         if ((lwp = getlwpcore(P, lwpid)) != NULL) {
 346                 (void) memcpy(lps, &lwp->lwp_psinfo, sizeof (lwpsinfo_t));
 347                 return (0);
 348         }
 349 
 350         return (-1);
 351 }
 352 
 353 int
 354 Plwp_getspymaster(struct ps_prochandle *P, lwpid_t lwpid, psinfo_t *ps)
 355 {
 356         lwpstatus_t lps;
 357 
 358         if (P->state == PS_IDLE) {
 359                 errno = ENODATA;
 360                 return (-1);
 361         }
 362 
 363         if (getlwpstatus(P, lwpid, &lps) != 0)
 364                 return (-1);
 365 
 366         if (!(lps.pr_flags & PR_AGENT)) {
 367                 errno = EINVAL;
 368                 return (-1);
 369         }
 370 
 371         if (P->state != PS_DEAD) {
 372                 return (getlwpfile(P, lwpid, "spymaster",
 373                     ps, sizeof (psinfo_t)));
 374         }
 375 
 376         if (P->spymaster.pr_nlwp != 0) {
 377                 (void) memcpy(ps, &P->spymaster, sizeof (psinfo_t));
 378                 return (0);
 379         }
 380 
 381         errno = ENODATA;
 382 
 383         return (-1);
 384 }
 385 
 386 int
 387 Plwp_stack(struct ps_prochandle *P, lwpid_t lwpid, stack_t *stkp)
 388 {
 389         uintptr_t addr;
 390 
 391         if (P->state == PS_IDLE) {
 392                 errno = ENODATA;
 393                 return (-1);
 394         }
 395 
 396         if (P->state != PS_DEAD) {
 397                 lwpstatus_t ls;
 398                 if (getlwpfile(P, lwpid, "lwpstatus", &ls, sizeof (ls)) != 0)
 399                         return (-1);
 400                 addr = ls.pr_ustack;
 401         } else {
 402                 lwp_info_t *lwp;
 403                 if ((lwp = getlwpcore(P, lwpid)) == NULL)
 404                         return (-1);
 405                 addr = lwp->lwp_status.pr_ustack;
 406         }
 407 
 408 
 409         if (P->status.pr_dmodel == PR_MODEL_NATIVE) {
 410                 if (Pread(P, stkp, sizeof (*stkp), addr) != sizeof (*stkp))
 411                         return (-1);
 412 #ifdef _LP64
 413         } else {
 414                 stack32_t stk32;
 415 
 416                 if (Pread(P, &stk32, sizeof (stk32), addr) != sizeof (stk32))
 417                         return (-1);
 418 
 419                 stack_32_to_n(&stk32, stkp);
 420 #endif
 421         }
 422 
 423         return (0);
 424 }
 425 
 426 int
 427 Plwp_main_stack(struct ps_prochandle *P, lwpid_t lwpid, stack_t *stkp)
 428 {
 429         uintptr_t addr;
 430         lwpstatus_t ls;
 431 
 432         if (P->state == PS_IDLE) {
 433                 errno = ENODATA;
 434                 return (-1);
 435         }
 436 
 437         if (P->state != PS_DEAD) {
 438                 if (getlwpfile(P, lwpid, "lwpstatus", &ls, sizeof (ls)) != 0)
 439                         return (-1);
 440         } else {
 441                 lwp_info_t *lwp;
 442                 if ((lwp = getlwpcore(P, lwpid)) == NULL)
 443                         return (-1);
 444                 ls = lwp->lwp_status;
 445         }
 446 
 447         addr = ls.pr_ustack;
 448 
 449         /*
 450          * Read out the current stack; if the SS_ONSTACK flag is set then
 451          * this LWP is operating on the alternate signal stack. We can
 452          * recover the original stack from pr_oldcontext.
 453          */
 454         if (P->status.pr_dmodel == PR_MODEL_NATIVE) {
 455                 if (Pread(P, stkp, sizeof (*stkp), addr) != sizeof (*stkp))
 456                         return (-1);
 457 
 458                 if (stkp->ss_flags & SS_ONSTACK)
 459                         goto on_altstack;
 460 #ifdef _LP64
 461         } else {
 462                 stack32_t stk32;
 463 
 464                 if (Pread(P, &stk32, sizeof (stk32), addr) != sizeof (stk32))
 465                         return (-1);
 466 
 467                 if (stk32.ss_flags & SS_ONSTACK)
 468                         goto on_altstack;
 469 
 470                 stack_32_to_n(&stk32, stkp);
 471 #endif
 472         }
 473 
 474         return (0);
 475 
 476 on_altstack:
 477 
 478         if (P->status.pr_dmodel == PR_MODEL_NATIVE) {
 479                 ucontext_t *ctxp = (void *)ls.pr_oldcontext;
 480 
 481                 if (Pread(P, stkp, sizeof (*stkp),
 482                     (uintptr_t)&ctxp->uc_stack) != sizeof (*stkp))
 483                         return (-1);
 484 #ifdef _LP64
 485         } else {
 486                 ucontext32_t *ctxp = (void *)ls.pr_oldcontext;
 487                 stack32_t stk32;
 488 
 489                 if (Pread(P, &stk32, sizeof (stk32),
 490                     (uintptr_t)&ctxp->uc_stack) != sizeof (stk32))
 491                         return (-1);
 492 
 493                 stack_32_to_n(&stk32, stkp);
 494 #endif
 495         }
 496 
 497         return (0);
 498 }
 499 
 500 int
 501 Plwp_alt_stack(struct ps_prochandle *P, lwpid_t lwpid, stack_t *stkp)
 502 {
 503         if (P->state == PS_IDLE) {
 504                 errno = ENODATA;
 505                 return (-1);
 506         }
 507 
 508         if (P->state != PS_DEAD) {
 509                 lwpstatus_t ls;
 510 
 511                 if (getlwpfile(P, lwpid, "lwpstatus", &ls, sizeof (ls)) != 0)
 512                         return (-1);
 513 
 514                 if (ls.pr_altstack.ss_flags & SS_DISABLE) {
 515                         errno = ENODATA;
 516                         return (-1);
 517                 }
 518 
 519                 *stkp = ls.pr_altstack;
 520         } else {
 521                 lwp_info_t *lwp;
 522 
 523                 if ((lwp = getlwpcore(P, lwpid)) == NULL)
 524                         return (-1);
 525 
 526                 if (lwp->lwp_status.pr_altstack.ss_flags & SS_DISABLE) {
 527                         errno = ENODATA;
 528                         return (-1);
 529                 }
 530 
 531                 *stkp = lwp->lwp_status.pr_altstack;
 532         }
 533 
 534         return (0);
 535 }