The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/kern/sys_process.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*
    2  * Copyright (c) 1994, Sean Eric Fagan
    3  * All rights reserved.
    4  *
    5  * Redistribution and use in source and binary forms, with or without
    6  * modification, are permitted provided that the following conditions
    7  * are met:
    8  * 1. Redistributions of source code must retain the above copyright
    9  *    notice, this list of conditions and the following disclaimer.
   10  * 2. Redistributions in binary form must reproduce the above copyright
   11  *    notice, this list of conditions and the following disclaimer in the
   12  *    documentation and/or other materials provided with the distribution.
   13  * 3. All advertising materials mentioning features or use of this software
   14  *    must display the following acknowledgement:
   15  *      This product includes software developed by Sean Eric Fagan.
   16  * 4. The name of the author may not be used to endorse or promote products
   17  *    derived from this software without specific prior written permission.
   18  *
   19  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
   20  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   21  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   22  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
   23  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   24  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   25  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   26  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   27  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   28  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   29  * SUCH DAMAGE.
   30  *
   31  * $FreeBSD: releng/5.0/sys/kern/sys_process.c 118752 2003-08-10 23:17:49Z nectar $
   32  */
   33 
   34 #include <sys/param.h>
   35 #include <sys/systm.h>
   36 #include <sys/lock.h>
   37 #include <sys/mutex.h>
   38 #include <sys/syscallsubr.h>
   39 #include <sys/sysproto.h>
   40 #include <sys/proc.h>
   41 #include <sys/vnode.h>
   42 #include <sys/ptrace.h>
   43 #include <sys/sx.h>
   44 #include <sys/user.h>
   45 
   46 #include <machine/reg.h>
   47 
   48 #include <vm/vm.h>
   49 #include <vm/pmap.h>
   50 #include <vm/vm_extern.h>
   51 #include <vm/vm_map.h>
   52 #include <vm/vm_kern.h>
   53 #include <vm/vm_object.h>
   54 #include <vm/vm_page.h>
   55 
   56 /*
   57  * Functions implemented using PROC_ACTION():
   58  *
   59  * proc_read_regs(proc, regs)
   60  *      Get the current user-visible register set from the process
   61  *      and copy it into the regs structure (<machine/reg.h>).
   62  *      The process is stopped at the time read_regs is called.
   63  *
   64  * proc_write_regs(proc, regs)
   65  *      Update the current register set from the passed in regs
   66  *      structure.  Take care to avoid clobbering special CPU
   67  *      registers or privileged bits in the PSL.
   68  *      Depending on the architecture this may have fix-up work to do,
   69  *      especially if the IAR or PCW are modified.
   70  *      The process is stopped at the time write_regs is called.
   71  *
   72  * proc_read_fpregs, proc_write_fpregs
   73  *      deal with the floating point register set, otherwise as above.
   74  *
   75  * proc_read_dbregs, proc_write_dbregs
   76  *      deal with the processor debug register set, otherwise as above.
   77  *
   78  * proc_sstep(proc)
   79  *      Arrange for the process to trap after executing a single instruction.
   80  */
   81 
   82 #define PROC_ACTION(action) do {                                        \
   83         int error;                                                      \
   84                                                                         \
   85         mtx_lock_spin(&sched_lock);                                     \
   86         if ((td->td_proc->p_sflag & PS_INMEM) == 0)                     \
   87                 error = EIO;                                            \
   88         else                                                            \
   89                 error = (action);                                       \
   90         mtx_unlock_spin(&sched_lock);                                   \
   91         return (error);                                                 \
   92 } while(0)
   93         
   94 int
   95 proc_read_regs(struct thread *td, struct reg *regs)
   96 {
   97 
   98         PROC_ACTION(fill_regs(td, regs));
   99 }
  100 
  101 int
  102 proc_write_regs(struct thread *td, struct reg *regs)
  103 {
  104 
  105         PROC_ACTION(set_regs(td, regs));
  106 }
  107 
  108 int
  109 proc_read_dbregs(struct thread *td, struct dbreg *dbregs)
  110 {
  111 
  112         PROC_ACTION(fill_dbregs(td, dbregs));
  113 }
  114 
  115 int
  116 proc_write_dbregs(struct thread *td, struct dbreg *dbregs)
  117 {
  118 
  119         PROC_ACTION(set_dbregs(td, dbregs));
  120 }
  121 
  122 /*
  123  * Ptrace doesn't support fpregs at all, and there are no security holes
  124  * or translations for fpregs, so we can just copy them.
  125  */
  126 int
  127 proc_read_fpregs(struct thread *td, struct fpreg *fpregs)
  128 {
  129 
  130         PROC_ACTION(fill_fpregs(td, fpregs));
  131 }
  132 
  133 int
  134 proc_write_fpregs(struct thread *td, struct fpreg *fpregs)
  135 {
  136 
  137         PROC_ACTION(set_fpregs(td, fpregs));
  138 }
  139 
  140 int
  141 proc_sstep(struct thread *td)
  142 {
  143 
  144         PROC_ACTION(ptrace_single_step(td));
  145 }
  146 
  147 int
  148 proc_rwmem(struct proc *p, struct uio *uio)
  149 {
  150         struct vmspace *vm;
  151         vm_map_t map;
  152         vm_object_t object = NULL;
  153         vm_offset_t pageno = 0;         /* page number */
  154         vm_prot_t reqprot;
  155         vm_offset_t kva;
  156         int error, writing;
  157 
  158         GIANT_REQUIRED;
  159 
  160         /*
  161          * if the vmspace is in the midst of being deallocated or the
  162          * process is exiting, don't try to grab anything.  The page table
  163          * usage in that process can be messed up.
  164          */
  165         vm = p->p_vmspace;
  166         if ((p->p_flag & P_WEXIT))
  167                 return (EFAULT);
  168         if (vm->vm_refcnt < 1)
  169                 return (EFAULT);
  170         ++vm->vm_refcnt;
  171         /*
  172          * The map we want...
  173          */
  174         map = &vm->vm_map;
  175 
  176         writing = uio->uio_rw == UIO_WRITE;
  177         reqprot = writing ? (VM_PROT_WRITE | VM_PROT_OVERRIDE_WRITE) :
  178             VM_PROT_READ;
  179 
  180         kva = kmem_alloc_pageable(kernel_map, PAGE_SIZE);
  181 
  182         /*
  183          * Only map in one page at a time.  We don't have to, but it
  184          * makes things easier.  This way is trivial - right?
  185          */
  186         do {
  187                 vm_map_t tmap;
  188                 vm_offset_t uva;
  189                 int page_offset;                /* offset into page */
  190                 vm_map_entry_t out_entry;
  191                 vm_prot_t out_prot;
  192                 boolean_t wired;
  193                 vm_pindex_t pindex;
  194                 u_int len;
  195                 vm_page_t m;
  196 
  197                 object = NULL;
  198 
  199                 uva = (vm_offset_t)uio->uio_offset;
  200 
  201                 /*
  202                  * Get the page number of this segment.
  203                  */
  204                 pageno = trunc_page(uva);
  205                 page_offset = uva - pageno;
  206 
  207                 /*
  208                  * How many bytes to copy
  209                  */
  210                 len = min(PAGE_SIZE - page_offset, uio->uio_resid);
  211 
  212                 /*
  213                  * Fault the page on behalf of the process
  214                  */
  215                 error = vm_fault(map, pageno, reqprot, VM_FAULT_NORMAL);
  216                 if (error) {
  217                         error = EFAULT;
  218                         break;
  219                 }
  220 
  221                 /*
  222                  * Now we need to get the page.  out_entry, out_prot, wired,
  223                  * and single_use aren't used.  One would think the vm code
  224                  * would be a *bit* nicer...  We use tmap because
  225                  * vm_map_lookup() can change the map argument.
  226                  */
  227                 tmap = map;
  228                 error = vm_map_lookup(&tmap, pageno, reqprot, &out_entry,
  229                     &object, &pindex, &out_prot, &wired);
  230 
  231                 if (error) {
  232                         error = EFAULT;
  233 
  234                         /*
  235                          * Make sure that there is no residue in 'object' from
  236                          * an error return on vm_map_lookup.
  237                          */
  238                         object = NULL;
  239 
  240                         break;
  241                 }
  242 
  243                 m = vm_page_lookup(object, pindex);
  244 
  245                 /* Allow fallback to backing objects if we are reading */
  246 
  247                 while (m == NULL && !writing && object->backing_object) {
  248 
  249                         pindex += OFF_TO_IDX(object->backing_object_offset);
  250                         object = object->backing_object;
  251                         
  252                         m = vm_page_lookup(object, pindex);
  253                 }
  254 
  255                 if (m == NULL) {
  256                         error = EFAULT;
  257 
  258                         /*
  259                          * Make sure that there is no residue in 'object' from
  260                          * an error return on vm_map_lookup.
  261                          */
  262                         object = NULL;
  263 
  264                         vm_map_lookup_done(tmap, out_entry);
  265 
  266                         break;
  267                 }
  268 
  269                 /*
  270                  * Wire the page into memory
  271                  */
  272                 vm_page_lock_queues();
  273                 vm_page_wire(m);
  274                 vm_page_unlock_queues();
  275 
  276                 /*
  277                  * We're done with tmap now.
  278                  * But reference the object first, so that we won't loose
  279                  * it.
  280                  */
  281                 vm_object_reference(object);
  282                 vm_map_lookup_done(tmap, out_entry);
  283 
  284                 pmap_qenter(kva, &m, 1);
  285 
  286                 /*
  287                  * Now do the i/o move.
  288                  */
  289                 error = uiomove((caddr_t)(kva + page_offset), len, uio);
  290 
  291                 pmap_qremove(kva, 1);
  292 
  293                 /*
  294                  * release the page and the object
  295                  */
  296                 vm_page_lock_queues();
  297                 vm_page_unwire(m, 1);
  298                 vm_page_unlock_queues();
  299                 vm_object_deallocate(object);
  300 
  301                 object = NULL;
  302 
  303         } while (error == 0 && uio->uio_resid > 0);
  304 
  305         if (object)
  306                 vm_object_deallocate(object);
  307 
  308         kmem_free(kernel_map, kva, PAGE_SIZE);
  309         vmspace_free(vm);
  310         return (error);
  311 }
  312 
  313 /*
  314  * Process debugging system call.
  315  */
  316 #ifndef _SYS_SYSPROTO_H_
  317 struct ptrace_args {
  318         int     req;
  319         pid_t   pid;
  320         caddr_t addr;
  321         int     data;
  322 };
  323 #endif
  324 
  325 int
  326 ptrace(struct thread *td, struct ptrace_args *uap)
  327 {
  328         /*
  329          * XXX this obfuscation is to reduce stack usage, but the register
  330          * structs may be too large to put on the stack anyway.
  331          */
  332         union {
  333                 struct ptrace_io_desc piod;
  334                 struct dbreg dbreg;
  335                 struct fpreg fpreg;
  336                 struct reg reg;
  337         } r;
  338         void *addr;
  339         int error = 0;
  340 
  341         addr = &r;
  342         switch (uap->req) {
  343         case PT_GETREGS:
  344         case PT_GETFPREGS:
  345         case PT_GETDBREGS:
  346                 break;
  347         case PT_SETREGS:
  348                 error = copyin(uap->addr, &r.reg, sizeof r.reg);
  349                 break;
  350         case PT_SETFPREGS:
  351                 error = copyin(uap->addr, &r.fpreg, sizeof r.fpreg);
  352                 break;
  353         case PT_SETDBREGS:
  354                 error = copyin(uap->addr, &r.dbreg, sizeof r.dbreg);
  355                 break;
  356         case PT_IO:
  357                 error = copyin(uap->addr, &r.piod, sizeof r.piod);
  358                 break;
  359         default:
  360                 addr = uap->addr;
  361         }
  362         if (error)
  363                 return (error);
  364 
  365         error = kern_ptrace(td, uap->req, uap->pid, addr, uap->data);
  366         if (error)
  367                 return (error);
  368 
  369         switch (uap->req) {
  370         case PT_IO:
  371                 (void)copyout(&r.piod, uap->addr, sizeof r.piod);
  372                 break;
  373         case PT_GETREGS:
  374                 error = copyout(&r.reg, uap->addr, sizeof r.reg);
  375                 break;
  376         case PT_GETFPREGS:
  377                 error = copyout(&r.fpreg, uap->addr, sizeof r.fpreg);
  378                 break;
  379         case PT_GETDBREGS:
  380                 error = copyout(&r.dbreg, uap->addr, sizeof r.dbreg);
  381                 break;
  382         }
  383 
  384         return (error);
  385 }
  386 
  387 int
  388 kern_ptrace(struct thread *td, int req, pid_t pid, void *addr, int data)
  389 {
  390         struct iovec iov;
  391         struct uio uio;
  392         struct proc *curp, *p, *pp;
  393         struct thread *td2;
  394         struct ptrace_io_desc *piod;
  395         int error, write, tmp;
  396         int proctree_locked = 0;
  397 
  398         curp = td->td_proc;
  399 
  400         /* Lock proctree before locking the process. */
  401         switch (req) {
  402         case PT_TRACE_ME:
  403         case PT_ATTACH:
  404         case PT_STEP:
  405         case PT_CONTINUE:
  406         case PT_DETACH:
  407                 sx_xlock(&proctree_lock);
  408                 proctree_locked = 1;
  409                 break;
  410         default:
  411                 break;
  412         }
  413                 
  414         write = 0;
  415         if (req == PT_TRACE_ME) {
  416                 p = td->td_proc;
  417                 PROC_LOCK(p);
  418         } else {
  419                 if ((p = pfind(pid)) == NULL) {
  420                         if (proctree_locked)
  421                                 sx_xunlock(&proctree_lock);
  422                         return (ESRCH);
  423                 }
  424         }
  425         if ((error = p_cansee(td, p)) != 0)
  426                 goto fail;
  427 
  428         if ((error = p_candebug(td, p)) != 0)
  429                 goto fail;
  430 
  431         /*
  432          * System processes can't be debugged.
  433          */
  434         if ((p->p_flag & P_SYSTEM) != 0) {
  435                 error = EINVAL;
  436                 goto fail;
  437         }
  438         
  439         /*
  440          * Permissions check
  441          */
  442         switch (req) {
  443         case PT_TRACE_ME:
  444                 /* Always legal. */
  445                 break;
  446 
  447         case PT_ATTACH:
  448                 /* Self */
  449                 if (p->p_pid == td->td_proc->p_pid) {
  450                         error = EINVAL;
  451                         goto fail;
  452                 }
  453 
  454                 /* Already traced */
  455                 if (p->p_flag & P_TRACED) {
  456                         error = EBUSY;
  457                         goto fail;
  458                 }
  459 
  460                 /* Can't trace an ancestor if you're being traced. */
  461                 if (curp->p_flag & P_TRACED) {
  462                         for (pp = curp->p_pptr; pp != NULL; pp = pp->p_pptr) {
  463                                 if (pp == p) {
  464                                         error = EINVAL;
  465                                         goto fail;
  466                                 }
  467                         }
  468                 }
  469 
  470 
  471                 /* OK */
  472                 break;
  473 
  474         case PT_READ_I:
  475         case PT_READ_D:
  476         case PT_WRITE_I:
  477         case PT_WRITE_D:
  478         case PT_IO:
  479         case PT_CONTINUE:
  480         case PT_KILL:
  481         case PT_STEP:
  482         case PT_DETACH:
  483         case PT_GETREGS:
  484         case PT_SETREGS:
  485         case PT_GETFPREGS:
  486         case PT_SETFPREGS:
  487         case PT_GETDBREGS:
  488         case PT_SETDBREGS:
  489                 /* not being traced... */
  490                 if ((p->p_flag & P_TRACED) == 0) {
  491                         error = EPERM;
  492                         goto fail;
  493                 }
  494 
  495                 /* not being traced by YOU */
  496                 if (p->p_pptr != td->td_proc) {
  497                         error = EBUSY;
  498                         goto fail;
  499                 }
  500 
  501                 /* not currently stopped */
  502                 if (!P_SHOULDSTOP(p) || (p->p_flag & P_WAITED) == 0) {
  503                         error = EBUSY;
  504                         goto fail;
  505                 }
  506 
  507                 /* OK */
  508                 break;
  509 
  510         default:
  511                 error = EINVAL;
  512                 goto fail;
  513         }
  514 
  515         td2 = FIRST_THREAD_IN_PROC(p);
  516 #ifdef FIX_SSTEP
  517         /*
  518          * Single step fixup ala procfs
  519          */
  520         FIX_SSTEP(td2);                 /* XXXKSE */
  521 #endif
  522 
  523         /*
  524          * Actually do the requests
  525          */
  526 
  527         td->td_retval[0] = 0;
  528 
  529         switch (req) {
  530         case PT_TRACE_ME:
  531                 /* set my trace flag and "owner" so it can read/write me */
  532                 p->p_flag |= P_TRACED;
  533                 p->p_oppid = p->p_pptr->p_pid;
  534                 PROC_UNLOCK(p);
  535                 sx_xunlock(&proctree_lock);
  536                 return (0);
  537 
  538         case PT_ATTACH:
  539                 /* security check done above */
  540                 p->p_flag |= P_TRACED;
  541                 p->p_oppid = p->p_pptr->p_pid;
  542                 if (p->p_pptr != td->td_proc)
  543                         proc_reparent(p, td->td_proc);
  544                 data = SIGSTOP;
  545                 goto sendsig;   /* in PT_CONTINUE below */
  546 
  547         case PT_STEP:
  548         case PT_CONTINUE:
  549         case PT_DETACH:
  550                 /* Zero means do not send any signal */
  551                 if (data < 0 || data > _SIG_MAXSIG) {
  552                         error = EINVAL;
  553                         goto fail;
  554                 }
  555 
  556                 _PHOLD(p);
  557 
  558                 if (req == PT_STEP) {
  559                         error = ptrace_single_step(td2);
  560                         if (error) {
  561                                 _PRELE(p);
  562                                 goto fail;
  563                         }
  564                 }
  565 
  566                 if (addr != (void *)1) {
  567                         error = ptrace_set_pc(td2, (u_long)(uintfptr_t)addr);
  568                         if (error) {
  569                                 _PRELE(p);
  570                                 goto fail;
  571                         }
  572                 }
  573                 _PRELE(p);
  574 
  575                 if (req == PT_DETACH) {
  576                         /* reset process parent */
  577                         if (p->p_oppid != p->p_pptr->p_pid) {
  578                                 struct proc *pp;
  579 
  580                                 PROC_UNLOCK(p);
  581                                 pp = pfind(p->p_oppid);
  582                                 if (pp == NULL)
  583                                         pp = initproc;
  584                                 else
  585                                         PROC_UNLOCK(pp);
  586                                 PROC_LOCK(p);
  587                                 proc_reparent(p, pp);
  588                         }
  589                         p->p_flag &= ~(P_TRACED | P_WAITED);
  590                         p->p_oppid = 0;
  591 
  592                         /* should we send SIGCHLD? */
  593                 }
  594 
  595         sendsig:
  596                 if (proctree_locked)
  597                         sx_xunlock(&proctree_lock);
  598                 /* deliver or queue signal */
  599                 if (P_SHOULDSTOP(p)) {
  600                         p->p_xstat = data;
  601                         mtx_lock_spin(&sched_lock);
  602                         p->p_flag &= ~(P_STOPPED_TRACE|P_STOPPED_SIG);
  603                         thread_unsuspend(p);
  604                         setrunnable(td2);       /* XXXKSE */
  605                         /* Need foreach kse in proc, ... make_kse_queued(). */
  606                         mtx_unlock_spin(&sched_lock);
  607                 } else if (data)
  608                         psignal(p, data);
  609                 PROC_UNLOCK(p);
  610                 
  611                 return (0);
  612 
  613         case PT_WRITE_I:
  614         case PT_WRITE_D:
  615                 write = 1;
  616                 /* FALLTHROUGH */
  617         case PT_READ_I:
  618         case PT_READ_D:
  619                 PROC_UNLOCK(p);
  620                 tmp = 0;
  621                 /* write = 0 set above */
  622                 iov.iov_base = write ? (caddr_t)&data : (caddr_t)&tmp;
  623                 iov.iov_len = sizeof(int);
  624                 uio.uio_iov = &iov;
  625                 uio.uio_iovcnt = 1;
  626                 uio.uio_offset = (off_t)(uintptr_t)addr;
  627                 uio.uio_resid = sizeof(int);
  628                 uio.uio_segflg = UIO_SYSSPACE;  /* i.e.: the uap */
  629                 uio.uio_rw = write ? UIO_WRITE : UIO_READ;
  630                 uio.uio_td = td;
  631                 error = proc_rwmem(p, &uio);
  632                 if (uio.uio_resid != 0) {
  633                         /*
  634                          * XXX proc_rwmem() doesn't currently return ENOSPC,
  635                          * so I think write() can bogusly return 0.
  636                          * XXX what happens for short writes?  We don't want
  637                          * to write partial data.
  638                          * XXX proc_rwmem() returns EPERM for other invalid
  639                          * addresses.  Convert this to EINVAL.  Does this
  640                          * clobber returns of EPERM for other reasons?
  641                          */
  642                         if (error == 0 || error == ENOSPC || error == EPERM)
  643                                 error = EINVAL; /* EOF */
  644                 }
  645                 if (!write)
  646                         td->td_retval[0] = tmp;
  647                 return (error);
  648 
  649         case PT_IO:
  650                 PROC_UNLOCK(p);
  651                 piod = addr;
  652                 iov.iov_base = piod->piod_addr;
  653                 iov.iov_len = piod->piod_len;
  654                 uio.uio_iov = &iov;
  655                 uio.uio_iovcnt = 1;
  656                 uio.uio_offset = (off_t)(uintptr_t)piod->piod_offs;
  657                 uio.uio_resid = piod->piod_len;
  658                 uio.uio_segflg = UIO_USERSPACE;
  659                 uio.uio_td = td;
  660                 switch (piod->piod_op) {
  661                 case PIOD_READ_D:
  662                 case PIOD_READ_I:
  663                         uio.uio_rw = UIO_READ;
  664                         break;
  665                 case PIOD_WRITE_D:
  666                 case PIOD_WRITE_I:
  667                         uio.uio_rw = UIO_WRITE;
  668                         break;
  669                 default:
  670                         return (EINVAL);
  671                 }
  672                 error = proc_rwmem(p, &uio);
  673                 piod->piod_len -= uio.uio_resid;
  674                 return (error);
  675 
  676         case PT_KILL:
  677                 data = SIGKILL;
  678                 goto sendsig;   /* in PT_CONTINUE above */
  679 
  680         case PT_SETREGS:
  681                 _PHOLD(p);
  682                 error = proc_write_regs(td2, addr);
  683                 _PRELE(p);
  684                 PROC_UNLOCK(p);
  685                 return (error);
  686 
  687         case PT_GETREGS:
  688                 _PHOLD(p);
  689                 error = proc_read_regs(td2, addr);
  690                 _PRELE(p);
  691                 PROC_UNLOCK(p);
  692                 return (error);
  693 
  694         case PT_SETFPREGS:
  695                 _PHOLD(p);
  696                 error = proc_write_fpregs(td2, addr);
  697                 _PRELE(p);
  698                 PROC_UNLOCK(p);
  699                 return (error);
  700 
  701         case PT_GETFPREGS:
  702                 _PHOLD(p);
  703                 error = proc_read_fpregs(td2, addr);
  704                 _PRELE(p);
  705                 PROC_UNLOCK(p);
  706                 return (error);
  707 
  708         case PT_SETDBREGS:
  709                 _PHOLD(p);
  710                 error = proc_write_dbregs(td2, addr);
  711                 _PRELE(p);
  712                 PROC_UNLOCK(p);
  713                 return (error);
  714 
  715         case PT_GETDBREGS:
  716                 _PHOLD(p);
  717                 error = proc_read_dbregs(td2, addr);
  718                 _PRELE(p);
  719                 PROC_UNLOCK(p);
  720                 return (error);
  721 
  722         default:
  723                 KASSERT(0, ("unreachable code\n"));
  724                 break;
  725         }
  726 
  727         KASSERT(0, ("unreachable code\n"));
  728         return (0);
  729 
  730 fail:
  731         PROC_UNLOCK(p);
  732         if (proctree_locked)
  733                 sx_xunlock(&proctree_lock);
  734         return (error);
  735 }
  736 
  737 /*
  738  * Stop a process because of a debugging event;
  739  * stay stopped until p->p_step is cleared
  740  * (cleared by PIOCCONT in procfs).
  741  */
  742 void
  743 stopevent(struct proc *p, unsigned int event, unsigned int val)
  744 {
  745 
  746         PROC_LOCK_ASSERT(p, MA_OWNED | MA_NOTRECURSED);
  747         p->p_step = 1;
  748 
  749         do {
  750                 p->p_xstat = val;
  751                 p->p_stype = event;     /* Which event caused the stop? */
  752                 wakeup(&p->p_stype);    /* Wake up any PIOCWAIT'ing procs */
  753                 msleep(&p->p_step, &p->p_mtx, PWAIT, "stopevent", 0);
  754         } while (p->p_step);
  755 }

Cache object: be59c44c678ef6ae85899201c554bfb0


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.