? o
Index: procfs_vnops.c
===================================================================
RCS file: /cvsroot/src/sys/miscfs/procfs/procfs_vnops.c,v
retrieving revision 1.198
diff -u -p -u -r1.198 procfs_vnops.c
--- procfs_vnops.c	28 Aug 2017 00:46:07 -0000	1.198
+++ procfs_vnops.c	6 Nov 2017 22:09:02 -0000
@@ -569,9 +569,6 @@ procfs_dir(pfstype t, struct lwp *caller
 	case PFSchroot:
 		vp = target->p_cwdi->cwdi_rdir;
 		break;
-	case PFSexe:
-		vp = target->p_textvp;
-		break;
 	default:
 		rw_exit(&cwdi->cwdi_lock);
 		return;
@@ -596,14 +593,8 @@ procfs_dir(pfstype t, struct lwp *caller
 	    len / 2, 0, caller) != 0) {
 		vp = NULL;
 		if (bpp) {
-/* 
-			if (t == PFSexe) {
-				snprintf(path, len, "%s/%d/file"
-				    mp->mnt_stat.f_mntonname, pfs->pfs_pid);
-			} else */ {
-				bp = *bpp;
-				*--bp = '/';
-			}
+			bp = *bpp;
+			*--bp = '/';
 		}
 	}
 
@@ -660,7 +651,6 @@ procfs_getattr(void *v)
 		/*FALLTHROUGH*/
 	case PFScwd:
 	case PFSchroot:
-	case PFSexe:
 		path = malloc(MAXPATHLEN + 4, M_TEMP, M_WAITOK|M_CANFAIL);
 		if (path == NULL && procp != NULL) {
 			procfs_proc_unlock(procp);
@@ -903,8 +893,7 @@ procfs_getattr(void *v)
 		break;
 
 	case PFScwd:
-	case PFSchroot:
-	case PFSexe: {
+	case PFSchroot: {
 		char *bp;
 
 		vap->va_nlink = 1;
@@ -918,6 +907,10 @@ procfs_getattr(void *v)
 		break;
 	}
 
+	case PFSexe:
+		vap->va_bytes = vap->va_size = strlen(procp->p_path);
+		break;
+
 	case PFSemul:
 		vap->va_bytes = vap->va_size = strlen(procp->p_emul->e_name);
 		break;
@@ -1631,9 +1624,13 @@ procfs_readlink(void *v)
 		len = snprintf(bf, sizeof(bf), "%s", "curproc");
 	else if (pfs->pfs_fileno == PROCFS_FILENO(pfs->pfs_pid, PFStask, 0))
 		len = snprintf(bf, sizeof(bf), "..");
-	else if (pfs->pfs_fileno == PROCFS_FILENO(pfs->pfs_pid, PFScwd, -1) ||
-	    pfs->pfs_fileno == PROCFS_FILENO(pfs->pfs_pid, PFSchroot, -1) ||
-	    pfs->pfs_fileno == PROCFS_FILENO(pfs->pfs_pid, PFSexe, -1)) {
+	else if (pfs->pfs_fileno == PROCFS_FILENO(pfs->pfs_pid, PFSexe, -1)) {
+		if ((error = procfs_proc_lock(pfs->pfs_pid, &pown, ESRCH)) != 0)
+			return error;
+		len = snprintf(bf, sizeof(bf), "%s", pown->p_path);
+		procfs_proc_unlock(pown);
+	} else if (pfs->pfs_fileno == PROCFS_FILENO(pfs->pfs_pid, PFScwd, -1) ||
+	    pfs->pfs_fileno == PROCFS_FILENO(pfs->pfs_pid, PFSchroot, -1)) {
 		if ((error = procfs_proc_lock(pfs->pfs_pid, &pown, ESRCH)) != 0)
 			return error;
 		path = malloc(MAXPATHLEN + 4, M_TEMP, M_WAITOK|M_CANFAIL);
Index: sys/proc.h
===================================================================
RCS file: /cvsroot/src/sys/sys/proc.h,v
retrieving revision 1.342
diff -u -p -r1.342 proc.h
--- sys/proc.h	28 Aug 2017 00:46:07 -0000	1.342
+++ sys/proc.h	6 Nov 2017 22:09:31 -0000
@@ -315,6 +315,7 @@ struct proc {
 	lwpid_t		p_lwp_created;	/* :: lwp created */
 	lwpid_t		p_lwp_exited;	/* :: lwp exited */
 	u_int		p_nsems;	/* Count of semaphores */
+	char		*p_path;	/* :: full pathname of executable */
 
 /*
  * End area that is zeroed on creation
Index: kern/exec_elf.c
===================================================================
RCS file: /cvsroot/src/sys/kern/exec_elf.c,v
retrieving revision 1.92
diff -u -p -r1.92 exec_elf.c
--- kern/exec_elf.c	16 Oct 2017 01:50:55 -0000	1.92
+++ kern/exec_elf.c	6 Nov 2017 22:09:31 -0000
@@ -226,11 +230,9 @@ elf_copyargs(struct lwp *l, struct exec_
 		a->a_v = l->l_proc->p_stackbase;
 		a++;
 
-		if (pack->ep_path) {
-			execname = a;
-			a->a_type = AT_SUN_EXECNAME;
-			a++;
-		}
+		execname = a;
+		a->a_type = AT_SUN_EXECNAME;
+		a++;
 
 		exec_free_emul_arg(pack);
 	}
@@ -243,15 +245,12 @@ elf_copyargs(struct lwp *l, struct exec_
 
 	KASSERT(vlen <= sizeof(ai));
 
-	if (execname) {
-		char *path = pack->ep_path;
-		execname->a_v = (uintptr_t)(*stackp + vlen);
-		len = strlen(path) + 1;
-		if ((error = copyout(path, (*stackp + vlen), len)) != 0)
-			return error;
-		len = ALIGN(len);
-	} else
-		len = 0;
+	char *path = l->l_proc->p_path;
+	execname->a_v = (uintptr_t)(*stackp + vlen);
+	len = strlen(path) + 1;
+	if ((error = copyout(path, (*stackp + vlen), len)) != 0)
+		return error;
+	len = ALIGN(len);
 
 	if ((error = copyout(ai, *stackp, vlen)) != 0)
 		return error;
Index: kern/kern_exec.c
===================================================================
RCS file: /cvsroot/src/sys/kern/kern_exec.c,v
retrieving revision 1.449
diff -u -p -r1.449 kern_exec.c
--- kern/kern_exec.c	20 Oct 2017 19:06:46 -0000	1.449
+++ kern/kern_exec.c	6 Nov 2017 22:09:31 -0000
@@ -928,8 +928,7 @@ static void
 pathexec(struct exec_package *epp, struct lwp *l, const char *pathstring)
 {
 	const char		*commandname;
-	size_t			commandlen;
-	char			*path;
+	size_t			commandlen, pathlen;
 	struct proc 		*p = l->l_proc;
 
 	/* set command name & other accounting info */
@@ -939,41 +938,14 @@ pathexec(struct exec_package *epp, struc
 	} else {
 		commandname = epp->ep_resolvedname;
 	}
	commandlen = min(strlen(commandname), MAXCOMLEN);
 	(void)memcpy(p->p_comm, commandname, commandlen);
 	p->p_comm[commandlen] = '\0';
 
-
-	/*
-	 * If the path starts with /, we don't need to do any work.
-	 * This handles the majority of the cases.
-	 * In the future perhaps we could canonicalize it?
-	 */
-	path = PNBUF_GET();
-	if (pathstring[0] == '/') {
-		(void)strlcpy(path, pathstring, MAXPATHLEN);
-		epp->ep_path = path;
-	}
-#ifdef notyet
-	/*
-	 * Although this works most of the time [since the entry was just
-	 * entered in the cache] we don't use it because it will fail for
-	 * entries that are not placed in the cache because their name is
-	 * longer than NCHNAMLEN and it is not the cleanest interface,
-	 * because there could be races. When the namei cache is re-written,
-	 * this can be changed to use the appropriate function.
-	 */
-	else if (!(error = vnode_to_path(path, MAXPATHLEN, p->p_textvp, l, p)))
-		epp->ep_path = path;
-#endif
-	else {
-#ifdef notyet
-		printf("Cannot get path for pid %d [%s] (error %d)\n",
-		    (int)p->p_pid, p->p_comm, error);
-#endif
-		PNBUF_PUT(path);
- 		epp->ep_path = NULL;
-	}
+	KASSERT(pathstring[0] == '/')
+	pathlen = strlen(pathstring);
+	p->p_path = kmem_malloc(pathlen + 1, M_WAITOK);
+	memcpy(p->p_path, pathstring, pathlen + 1);
 }
 
 /* XXX elsewhere */
@@ -1463,10 +1435,6 @@ copyoutargs(struct execve_data * restric
 	error = (*epp->ep_esch->es_copyargs)(l, epp,
 	    &data->ed_arginfo, &newargs, data->ed_argp);
 
-	if (epp->ep_path) {
-		PNBUF_PUT(epp->ep_path);
-		epp->ep_path = NULL;
-	}
 	if (error) {
 		DPRINTF(("%s: copyargs failed %d\n", __func__, error));
 		return error;
Index: kern/kern_exit.c
===================================================================
RCS file: /cvsroot/src/sys/kern/kern_exit.c,v
retrieving revision 1.269
diff -u -p -r1.269 kern_exit.c
--- kern/kern_exit.c	28 Aug 2017 00:46:07 -0000	1.269
+++ kern/kern_exit.c	6 Nov 2017 22:09:31 -0000
@@ -1250,6 +1250,7 @@ proc_free(struct proc *p, struct wrusage
 	 */
 	if (p->p_textvp)
 		vrele(p->p_textvp);
+	kmem_free(p->p_path);
 
 	mutex_destroy(&p->p_auxlock);
 	mutex_obj_free(p->p_lock);
Index: kern/kern_proc.c
===================================================================
RCS file: /cvsroot/src/sys/kern/kern_proc.c,v
retrieving revision 1.207
diff -u -p -r1.207 kern_proc.c
--- kern/kern_proc.c	28 Aug 2017 00:46:07 -0000	1.207
+++ kern/kern_proc.c	6 Nov 2017 22:09:31 -0000
@@ -2433,41 +2433,29 @@ proc_find_locked(struct lwp *l, struct p
 static int
 fill_pathname(struct lwp *l, pid_t pid, void *oldp, size_t *oldlenp)
 {
-#ifndef _RUMPKERNEL
 	int error;
 	struct proc *p;
-	char *path;
 	size_t len;
 
 	if ((error = proc_find_locked(l, &p, pid)) != 0)
 		return error;
 
-	if (p->p_textvp == NULL) {
+	if (p->p_path == NULL) {
 		if (pid != -1)
 			mutex_exit(p->p_lock);
 		return ENOENT;
 	}
 
-	path = PNBUF_GET();
-	error = vnode_to_path(path, MAXPATHLEN / 2, p->p_textvp, l, p);
-	if (error)
-		goto out;
-
-	len = strlen(path) + 1;
+	len = strlen(p->p_path) + 1;
 	if (oldp != NULL) {
-		error = sysctl_copyout(l, path, oldp, *oldlenp);
+		error = sysctl_copyout(l, p->p_path, oldp, *oldlenp);
 		if (error == 0 && *oldlenp < len)
 			error = ENOSPC;
 	}
 	*oldlenp = len;
-out:
-	PNBUF_PUT(path);
 	if (pid != -1)
 		mutex_exit(p->p_lock);
 	return error;
-#else
-	return 0;
-#endif
 }
 
 int