sys_process.c (a5d8944a83ff8a3aad14197b7aa0800ff9bda95e) sys_process.c (711fbd17ecb5c73100aeb4991e158efcd50b8e7b)
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

--- 238 unchanged lines hidden (view full) ---

247 int error, fault_flags, page_offset, writing;
248
249 /*
250 * Assert that someone has locked this vmspace. (Should be
251 * curthread but we can't assert that.) This keeps the process
252 * from exiting out from under us until this operation completes.
253 */
254 PROC_ASSERT_HELD(p);
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

--- 238 unchanged lines hidden (view full) ---

247 int error, fault_flags, page_offset, writing;
248
249 /*
250 * Assert that someone has locked this vmspace. (Should be
251 * curthread but we can't assert that.) This keeps the process
252 * from exiting out from under us until this operation completes.
253 */
254 PROC_ASSERT_HELD(p);
255 PROC_LOCK_ASSERT(p, MA_NOTOWNED);
255
256 /*
257 * The map we want...
258 */
259 map = &p->p_vmspace->vm_map;
260
261 /*
262 * If we are writing, then we request vm_fault() to create a private

--- 59 unchanged lines hidden (view full) ---

322 vm_page_unhold(m);
323 vm_page_unlock(m);
324
325 } while (error == 0 && uio->uio_resid > 0);
326
327 return (error);
328}
329
256
257 /*
258 * The map we want...
259 */
260 map = &p->p_vmspace->vm_map;
261
262 /*
263 * If we are writing, then we request vm_fault() to create a private

--- 59 unchanged lines hidden (view full) ---

323 vm_page_unhold(m);
324 vm_page_unlock(m);
325
326 } while (error == 0 && uio->uio_resid > 0);
327
328 return (error);
329}
330
331static ssize_t
332proc_iop(struct thread *td, struct proc *p, vm_offset_t va, void *buf,
333 size_t len, enum uio_rw rw)
334{
335 struct iovec iov;
336 struct uio uio;
337 ssize_t slen;
338 int error;
339
340 MPASS(len < SSIZE_MAX);
341 slen = (ssize_t)len;
342
343 iov.iov_base = (caddr_t)buf;
344 iov.iov_len = len;
345 uio.uio_iov = &iov;
346 uio.uio_iovcnt = 1;
347 uio.uio_offset = va;
348 uio.uio_resid = slen;
349 uio.uio_segflg = UIO_SYSSPACE;
350 uio.uio_rw = rw;
351 uio.uio_td = td;
352 error = proc_rwmem(p, &uio);
353 if (uio.uio_resid == slen)
354 return (-1);
355 return (slen - uio.uio_resid);
356}
357
358ssize_t
359proc_readmem(struct thread *td, struct proc *p, vm_offset_t va, void *buf,
360 size_t len)
361{
362
363 return (proc_iop(td, p, va, buf, len, UIO_READ));
364}
365
366ssize_t
367proc_writemem(struct thread *td, struct proc *p, vm_offset_t va, void *buf,
368 size_t len)
369{
370
371 return (proc_iop(td, p, va, buf, len, UIO_WRITE));
372}
373
330static int
331ptrace_vm_entry(struct thread *td, struct proc *p, struct ptrace_vm_entry *pve)
332{
333 struct vattr vattr;
334 vm_map_t map;
335 vm_map_entry_t entry;
336 vm_object_t obj, tobj, lobj;
337 struct vmspace *vm;

--- 301 unchanged lines hidden (view full) ---

639kern_ptrace(struct thread *td, int req, pid_t pid, void *addr, int data)
640{
641 struct iovec iov;
642 struct uio uio;
643 struct proc *curp, *p, *pp;
644 struct thread *td2 = NULL, *td3;
645 struct ptrace_io_desc *piod = NULL;
646 struct ptrace_lwpinfo *pl;
374static int
375ptrace_vm_entry(struct thread *td, struct proc *p, struct ptrace_vm_entry *pve)
376{
377 struct vattr vattr;
378 vm_map_t map;
379 vm_map_entry_t entry;
380 vm_object_t obj, tobj, lobj;
381 struct vmspace *vm;

--- 301 unchanged lines hidden (view full) ---

683kern_ptrace(struct thread *td, int req, pid_t pid, void *addr, int data)
684{
685 struct iovec iov;
686 struct uio uio;
687 struct proc *curp, *p, *pp;
688 struct thread *td2 = NULL, *td3;
689 struct ptrace_io_desc *piod = NULL;
690 struct ptrace_lwpinfo *pl;
647 int error, write, tmp, num;
691 int error, num, tmp;
648 int proctree_locked = 0;
649 lwpid_t tid = 0, *buf;
650#ifdef COMPAT_FREEBSD32
651 int wrap32 = 0, safe = 0;
652 struct ptrace_io_desc32 *piod32 = NULL;
653 struct ptrace_lwpinfo32 *pl32 = NULL;
654 struct ptrace_lwpinfo plr;
655#endif

--- 13 unchanged lines hidden (view full) ---

669 case PT_DETACH:
670 sx_xlock(&proctree_lock);
671 proctree_locked = 1;
672 break;
673 default:
674 break;
675 }
676
692 int proctree_locked = 0;
693 lwpid_t tid = 0, *buf;
694#ifdef COMPAT_FREEBSD32
695 int wrap32 = 0, safe = 0;
696 struct ptrace_io_desc32 *piod32 = NULL;
697 struct ptrace_lwpinfo32 *pl32 = NULL;
698 struct ptrace_lwpinfo plr;
699#endif

--- 13 unchanged lines hidden (view full) ---

713 case PT_DETACH:
714 sx_xlock(&proctree_lock);
715 proctree_locked = 1;
716 break;
717 default:
718 break;
719 }
720
677 write = 0;
678 if (req == PT_TRACE_ME) {
679 p = td->td_proc;
680 PROC_LOCK(p);
681 } else {
682 if (pid <= PID_MAX) {
683 if ((p = pfind(pid)) == NULL) {
684 if (proctree_locked)
685 sx_xunlock(&proctree_lock);

--- 342 unchanged lines hidden (view full) ---

1028 if (data)
1029 kern_psignal(p, data);
1030 }
1031 break;
1032
1033 case PT_WRITE_I:
1034 case PT_WRITE_D:
1035 td2->td_dbgflags |= TDB_USERWR;
721 if (req == PT_TRACE_ME) {
722 p = td->td_proc;
723 PROC_LOCK(p);
724 } else {
725 if (pid <= PID_MAX) {
726 if ((p = pfind(pid)) == NULL) {
727 if (proctree_locked)
728 sx_xunlock(&proctree_lock);

--- 342 unchanged lines hidden (view full) ---

1071 if (data)
1072 kern_psignal(p, data);
1073 }
1074 break;
1075
1076 case PT_WRITE_I:
1077 case PT_WRITE_D:
1078 td2->td_dbgflags |= TDB_USERWR;
1036 write = 1;
1037 /* FALLTHROUGH */
1079 PROC_UNLOCK(p);
1080 error = 0;
1081 if (proc_writemem(td, p, (off_t)(uintptr_t)addr, &data,
1082 sizeof(int)) != sizeof(int))
1083 error = ENOMEM;
1084 else
1085 CTR3(KTR_PTRACE, "PT_WRITE: pid %d: %p <= %#x",
1086 p->p_pid, addr, data);
1087 PROC_LOCK(p);
1088 break;
1089
1038 case PT_READ_I:
1039 case PT_READ_D:
1040 PROC_UNLOCK(p);
1090 case PT_READ_I:
1091 case PT_READ_D:
1092 PROC_UNLOCK(p);
1041 tmp = 0;
1042 /* write = 0 set above */
1043 iov.iov_base = write ? (caddr_t)&data : (caddr_t)&tmp;
1044 iov.iov_len = sizeof(int);
1045 uio.uio_iov = &iov;
1046 uio.uio_iovcnt = 1;
1047 uio.uio_offset = (off_t)(uintptr_t)addr;
1048 uio.uio_resid = sizeof(int);
1049 uio.uio_segflg = UIO_SYSSPACE; /* i.e.: the uap */
1050 uio.uio_rw = write ? UIO_WRITE : UIO_READ;
1051 uio.uio_td = td;
1052 error = proc_rwmem(p, &uio);
1053 if (uio.uio_resid != 0) {
1054 /*
1055 * XXX proc_rwmem() doesn't currently return ENOSPC,
1056 * so I think write() can bogusly return 0.
1057 * XXX what happens for short writes? We don't want
1058 * to write partial data.
1059 * XXX proc_rwmem() returns EPERM for other invalid
1060 * addresses. Convert this to EINVAL. Does this
1061 * clobber returns of EPERM for other reasons?
1062 */
1063 if (error == 0 || error == ENOSPC || error == EPERM)
1064 error = EINVAL; /* EOF */
1065 }
1066 if (!write)
1067 td->td_retval[0] = tmp;
1068 if (error == 0) {
1069 if (write)
1070 CTR3(KTR_PTRACE, "PT_WRITE: pid %d: %p <= %#x",
1071 p->p_pid, addr, data);
1072 else
1073 CTR3(KTR_PTRACE, "PT_READ: pid %d: %p >= %#x",
1074 p->p_pid, addr, tmp);
1075 }
1093 error = tmp = 0;
1094 if (proc_readmem(td, p, (off_t)(uintptr_t)addr, &tmp,
1095 sizeof(int)) != sizeof(int))
1096 error = ENOMEM;
1097 else
1098 CTR3(KTR_PTRACE, "PT_READ: pid %d: %p >= %#x",
1099 p->p_pid, addr, tmp);
1100 td->td_retval[0] = tmp;
1076 PROC_LOCK(p);
1077 break;
1078
1079 case PT_IO:
1080#ifdef COMPAT_FREEBSD32
1081 if (wrap32) {
1082 piod32 = addr;
1083 iov.iov_base = (void *)(uintptr_t)piod32->piod_addr;

--- 261 unchanged lines hidden ---
1101 PROC_LOCK(p);
1102 break;
1103
1104 case PT_IO:
1105#ifdef COMPAT_FREEBSD32
1106 if (wrap32) {
1107 piod32 = addr;
1108 iov.iov_base = (void *)(uintptr_t)piod32->piod_addr;

--- 261 unchanged lines hidden ---