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