Changeset View
Changeset View
Standalone View
Standalone View
sys/kern/kern_proc.c
Show First 20 Lines • Show All 3,194 Lines • ▼ Show 20 Lines | if (SV_CURPROC_FLAG(SV_ILP32)) { | ||||
addr32 = addr; | addr32 = addr; | ||||
error = SYSCTL_OUT(req, &addr32, sizeof(addr32)); | error = SYSCTL_OUT(req, &addr32, sizeof(addr32)); | ||||
} else | } else | ||||
#endif | #endif | ||||
error = SYSCTL_OUT(req, &addr, sizeof(addr)); | error = SYSCTL_OUT(req, &addr, sizeof(addr)); | ||||
return (error); | return (error); | ||||
} | } | ||||
static int | |||||
sysctl_kern_proc_vm_layout(SYSCTL_HANDLER_ARGS) | |||||
{ | |||||
struct kinfo_vm_layout kvm; | |||||
struct proc *p; | |||||
struct vmspace *vmspace; | |||||
int error, *name; | |||||
name = (int *)arg1; | |||||
if ((u_int)arg2 != 1) | |||||
return (EINVAL); | |||||
kib: namelen is used only once? | |||||
error = pget((pid_t)name[0], PGET_CANDEBUG, &p); | |||||
if (error != 0) | |||||
return (error); | |||||
#ifdef COMPAT_FREEBSD32 | |||||
if (SV_CURPROC_FLAG(SV_ILP32)) { | |||||
if (!SV_PROC_FLAG(p, SV_ILP32)) { | |||||
PROC_UNLOCK(p); | |||||
return (EINVAL); | |||||
} | |||||
} | |||||
#endif | |||||
vmspace = vmspace_acquire_ref(p); | |||||
PROC_UNLOCK(p); | |||||
memset(&kvm, 0, sizeof(kvm)); | |||||
kvm.kvm_min_user_addr = vm_map_min(&vmspace->vm_map); | |||||
kvm.kvm_max_user_addr = vm_map_max(&vmspace->vm_map); | |||||
kvm.kvm_text_addr = (uintptr_t)vmspace->vm_taddr; | |||||
kvm.kvm_text_size = vmspace->vm_tsize; | |||||
kvm.kvm_data_addr = (uintptr_t)vmspace->vm_daddr; | |||||
Done Inline ActionsWhy not do vm_map_min()/max() instead? sv_*user are only templates, and e.g. map_at_zero changes vm_map_min(). kib: Why not do vm_map_min()/max() instead? sv_*user are only templates, and e.g. map_at_zero… | |||||
kvm.kvm_data_size = vmspace->vm_dsize; | |||||
kvm.kvm_stack_addr = (uintptr_t)vmspace->vm_maxsaddr; | |||||
kvm.kvm_stack_size = vmspace->vm_ssize; | |||||
if ((vmspace->vm_map.flags & MAP_WIREFUTURE) != 0) | |||||
kvm.kvm_map_flags |= KMAP_FLAG_WIREFUTURE; | |||||
if ((vmspace->vm_map.flags & MAP_ASLR) != 0) | |||||
kvm.kvm_map_flags |= KMAP_FLAG_ASLR; | |||||
if ((vmspace->vm_map.flags & MAP_ASLR_IGNSTART) != 0) | |||||
kvm.kvm_map_flags |= KMAP_FLAG_ASLR_IGNSTART; | |||||
Done Inline ActionsI do not like the tie of the kernel-internal flags to the sysctl output, it moves them into ABI. IMO it should be the dedicated flags, translated. kib: I do not like the tie of the kernel-internal flags to the sysctl output, it moves them into ABI. | |||||
if ((vmspace->vm_map.flags & MAP_WXORX) != 0) | |||||
kvm.kvm_map_flags |= KMAP_FLAG_WXORX; | |||||
if ((vmspace->vm_map.flags & MAP_ASLR_STACK) != 0) | |||||
kvm.kvm_map_flags |= KMAP_FLAG_ASLR_STACK; | |||||
#ifdef COMPAT_FREEBSD32 | |||||
if (SV_CURPROC_FLAG(SV_ILP32)) { | |||||
struct kinfo_vm_layout32 kvm32; | |||||
memset(&kvm32, 0, sizeof(kvm32)); | |||||
kvm32.kvm_min_user_addr = (uint32_t)kvm.kvm_min_user_addr; | |||||
kvm32.kvm_max_user_addr = (uint32_t)kvm.kvm_max_user_addr; | |||||
kvm32.kvm_text_addr = (uint32_t)kvm.kvm_text_addr; | |||||
kvm32.kvm_text_size = (uint32_t)kvm.kvm_text_size; | |||||
kvm32.kvm_data_addr = (uint32_t)kvm.kvm_data_addr; | |||||
kvm32.kvm_data_size = (uint32_t)kvm.kvm_data_size; | |||||
kvm32.kvm_stack_addr = (uint32_t)kvm.kvm_stack_addr; | |||||
Done Inline ActionsI copied the handling of 32-bit procs from sysctl_kern_proc_sigfastblk(), but this munging is ugly. Perhaps the compat32 fields should be defined as uint64_t instead, or the native kinfo_vm_layout definition should use uint64_t everywhere. markj: I copied the handling of 32-bit procs from sysctl_kern_proc_sigfastblk(), but this munging is… | |||||
kvm32.kvm_stack_size = (uint32_t)kvm.kvm_stack_size; | |||||
kvm32.kvm_map_flags = kvm.kvm_map_flags; | |||||
vmspace_free(vmspace); | |||||
error = SYSCTL_OUT(req, &kvm32, sizeof(kvm32)); | |||||
goto out; | |||||
} | |||||
#endif | |||||
error = SYSCTL_OUT(req, &kvm, sizeof(kvm)); | |||||
#ifdef COMPAT_FREEBSD32 | |||||
out: | |||||
#endif | |||||
vmspace_free(vmspace); | |||||
return (error); | |||||
} | |||||
SYSCTL_NODE(_kern, KERN_PROC, proc, CTLFLAG_RD | CTLFLAG_MPSAFE, 0, | SYSCTL_NODE(_kern, KERN_PROC, proc, CTLFLAG_RD | CTLFLAG_MPSAFE, 0, | ||||
"Process table"); | "Process table"); | ||||
SYSCTL_PROC(_kern_proc, KERN_PROC_ALL, all, CTLFLAG_RD|CTLTYPE_STRUCT| | SYSCTL_PROC(_kern_proc, KERN_PROC_ALL, all, CTLFLAG_RD|CTLTYPE_STRUCT| | ||||
CTLFLAG_MPSAFE, 0, 0, sysctl_kern_proc, "S,proc", | CTLFLAG_MPSAFE, 0, 0, sysctl_kern_proc, "S,proc", | ||||
"Return entire process table"); | "Return entire process table"); | ||||
static SYSCTL_NODE(_kern_proc, KERN_PROC_GID, gid, CTLFLAG_RD | CTLFLAG_MPSAFE, | static SYSCTL_NODE(_kern_proc, KERN_PROC_GID, gid, CTLFLAG_RD | CTLFLAG_MPSAFE, | ||||
▲ Show 20 Lines • Show All 101 Lines • ▼ Show 20 Lines | |||||
static SYSCTL_NODE(_kern_proc, KERN_PROC_SIGTRAMP, sigtramp, CTLFLAG_RD | | static SYSCTL_NODE(_kern_proc, KERN_PROC_SIGTRAMP, sigtramp, CTLFLAG_RD | | ||||
CTLFLAG_MPSAFE, sysctl_kern_proc_sigtramp, | CTLFLAG_MPSAFE, sysctl_kern_proc_sigtramp, | ||||
"Process signal trampoline location"); | "Process signal trampoline location"); | ||||
static SYSCTL_NODE(_kern_proc, KERN_PROC_SIGFASTBLK, sigfastblk, CTLFLAG_RD | | static SYSCTL_NODE(_kern_proc, KERN_PROC_SIGFASTBLK, sigfastblk, CTLFLAG_RD | | ||||
CTLFLAG_ANYBODY | CTLFLAG_MPSAFE, sysctl_kern_proc_sigfastblk, | CTLFLAG_ANYBODY | CTLFLAG_MPSAFE, sysctl_kern_proc_sigfastblk, | ||||
"Thread sigfastblock address"); | "Thread sigfastblock address"); | ||||
static SYSCTL_NODE(_kern_proc, KERN_PROC_VM_LAYOUT, vm_layout, CTLFLAG_RD | | |||||
CTLFLAG_ANYBODY | CTLFLAG_MPSAFE, sysctl_kern_proc_vm_layout, | |||||
"Process virtual address space layout info"); | |||||
int allproc_gen; | int allproc_gen; | ||||
/* | /* | ||||
* stop_all_proc() purpose is to stop all process which have usermode, | * stop_all_proc() purpose is to stop all process which have usermode, | ||||
* except current process for obvious reasons. This makes it somewhat | * except current process for obvious reasons. This makes it somewhat | ||||
* unreliable when invoked from multithreaded process. The service | * unreliable when invoked from multithreaded process. The service | ||||
* must not be user-callable anyway. | * must not be user-callable anyway. | ||||
▲ Show 20 Lines • Show All 132 Lines • Show Last 20 Lines |
namelen is used only once?