PERFORCE change 44212 for review

Peter Wemm peter at FreeBSD.org
Mon Dec 22 17:47:33 PST 2003


http://perforce.freebsd.org/chv.cgi?CH=44212

Change 44212 by peter at peter_daintree on 2003/12/22 17:46:41

	checkpoint of what I was doing to get rid of some
	stackgap abuse.  The only thing we actually need here is
	using a different ld-elf.so.1, and use different library
	search paths to go from there.  This allows an intercept at
	execve() time instead of translating all the file paths.
	While here, optimize elf exec a bit.  This eliminates a
	malloc()/snprintf()/free() that actually doesn't do a damn
	thing in the native code path.

Affected files ...

.. //depot/projects/hammer/sys/alpha/alpha/elf_machdep.c#8 edit
.. //depot/projects/hammer/sys/amd64/amd64/elf_machdep.c#11 edit
.. //depot/projects/hammer/sys/compat/freebsd32/freebsd32_misc.c#6 edit
.. //depot/projects/hammer/sys/compat/freebsd32/freebsd32_proto.h#5 edit
.. //depot/projects/hammer/sys/compat/freebsd32/freebsd32_syscall.h#5 edit
.. //depot/projects/hammer/sys/compat/freebsd32/freebsd32_syscalls.c#5 edit
.. //depot/projects/hammer/sys/compat/freebsd32/freebsd32_sysent.c#5 edit
.. //depot/projects/hammer/sys/compat/freebsd32/freebsd32_util.h#2 edit
.. //depot/projects/hammer/sys/compat/freebsd32/syscalls.master#8 edit
.. //depot/projects/hammer/sys/compat/ia32/ia32_sysvec.c#8 edit
.. //depot/projects/hammer/sys/i386/i386/elf_machdep.c#8 edit
.. //depot/projects/hammer/sys/ia64/ia64/elf_machdep.c#10 edit
.. //depot/projects/hammer/sys/kern/imgact_elf.c#11 edit
.. //depot/projects/hammer/sys/powerpc/powerpc/elf_machdep.c#7 edit
.. //depot/projects/hammer/sys/sparc64/sparc64/elf_machdep.c#8 edit
.. //depot/projects/hammer/sys/sys/imgact_elf.h#3 edit

Differences ...

==== //depot/projects/hammer/sys/alpha/alpha/elf_machdep.c#8 (text+ko) ====

@@ -81,15 +81,31 @@
 						ELFOSABI_FREEBSD,
 						EM_ALPHA,
 						"FreeBSD",
-						"",
+						NULL,
 						"/libexec/ld-elf.so.1",
-						&elf64_freebsd_sysvec
+						&elf64_freebsd_sysvec,
+						NULL,
 					  };
 
 SYSINIT(elf64, SI_SUB_EXEC, SI_ORDER_ANY,
 	(sysinit_cfunc_t) elf64_insert_brand_entry,
 	&freebsd_brand_info);
 
+static Elf64_Brandinfo freebsd_brand_oinfo = {
+						ELFOSABI_FREEBSD,
+						EM_ALPHA,
+						"FreeBSD",
+						NULL,
+						"/usr/libexec/ld-elf.so.1",
+						&elf64_freebsd_sysvec,
+						NULL,
+					  };
+
+SYSINIT(oelf64, SI_SUB_EXEC, SI_ORDER_ANY,
+	(sysinit_cfunc_t) elf64_insert_brand_entry,
+	&freebsd_brand_oinfo);
+
+
 /* Process one elf relocation with addend. */
 static int
 elf_reloc_internal(linker_file_t lf, const void *data, int type, int local)

==== //depot/projects/hammer/sys/amd64/amd64/elf_machdep.c#11 (text+ko) ====

@@ -78,15 +78,30 @@
 						ELFOSABI_FREEBSD,
 						EM_X86_64,
 						"FreeBSD",
-						"",
+						NULL,
 						"/libexec/ld-elf.so.1",
-						&elf64_freebsd_sysvec
+						&elf64_freebsd_sysvec,
+						NULL,
 					  };
 
 SYSINIT(elf64, SI_SUB_EXEC, SI_ORDER_ANY,
 	(sysinit_cfunc_t) elf64_insert_brand_entry,
 	&freebsd_brand_info);
 
+static Elf64_Brandinfo freebsd_brand_oinfo = {
+						ELFOSABI_FREEBSD,
+						EM_X86_64,
+						"FreeBSD",
+						NULL,
+						"/usr/libexec/ld-elf.so.1",
+						&elf64_freebsd_sysvec,
+						NULL,
+					  };
+
+SYSINIT(oelf64, SI_SUB_EXEC, SI_ORDER_ANY,
+	(sysinit_cfunc_t) elf64_insert_brand_entry,
+	&freebsd_brand_oinfo);
+
 /* Process one elf relocation with addend. */
 static int
 elf_reloc_internal(linker_file_t lf, const void *data, int type, int local)

==== //depot/projects/hammer/sys/compat/freebsd32/freebsd32_misc.c#6 (text+ko) ====

@@ -84,157 +84,7 @@
 CTASSERT(sizeof(struct statfs32) == 256);
 CTASSERT(sizeof(struct rusage32) == 72);
 
-/*
- * [ taken from the linux emulator ]
- * Search an alternate path before passing pathname arguments on
- * to system calls. Useful for keeping a separate 'emulation tree'.
- *
- * If cflag is set, we check if an attempt can be made to create
- * the named file, i.e. we check if the directory it should
- * be in exists.
- */
 int
-freebsd32_emul_find(td, sgp, prefix, path, pbuf, cflag)
-	struct thread	*td;
-	caddr_t		*sgp;		/* Pointer to stackgap memory */
-	const char	*prefix;
-	char		*path;
-	char		**pbuf;
-	int		cflag;
-{
-	int			error;
-	size_t			len, sz;
-	char			*buf, *cp, *ptr;
-	struct ucred		*ucred;
-	struct nameidata	nd;
-	struct nameidata	ndroot;
-	struct vattr		vat;
-	struct vattr		vatroot;
-
-	buf = (char *) malloc(MAXPATHLEN, M_TEMP, M_WAITOK);
-	*pbuf = path;
-
-	for (ptr = buf; (*ptr = *prefix) != '\0'; ptr++, prefix++)
-		continue;
-
-	sz = MAXPATHLEN - (ptr - buf);
-
-	/*
-	 * If sgp is not given then the path is already in kernel space
-	 */
-	if (sgp == NULL)
-		error = copystr(path, ptr, sz, &len);
-	else
-		error = copyinstr(path, ptr, sz, &len);
-
-	if (error) {
-		free(buf, M_TEMP);
-		return error;
-	}
-
-	if (*ptr != '/') {
-		free(buf, M_TEMP);
-		return EINVAL;
-	}
-
-	/*
-	 *  We know that there is a / somewhere in this pathname.
-	 *  Search backwards for it, to find the file's parent dir
-	 *  to see if it exists in the alternate tree. If it does,
-	 *  and we want to create a file (cflag is set). We don't
-	 *  need to worry about the root comparison in this case.
-	 */
-
-	if (cflag) {
-		for (cp = &ptr[len] - 1; *cp != '/'; cp--)
-			;
-		*cp = '\0';
-
-		NDINIT(&nd, LOOKUP, FOLLOW, UIO_SYSSPACE, buf, td);
-
-		if ((error = namei(&nd)) != 0) {
-			free(buf, M_TEMP);
-			return error;
-		}
-
-		*cp = '/';
-	} else {
-		NDINIT(&nd, LOOKUP, FOLLOW, UIO_SYSSPACE, buf, td);
-
-		if ((error = namei(&nd)) != 0) {
-			free(buf, M_TEMP);
-			return error;
-		}
-
-		/*
-		 * We now compare the vnode of the freebsd32_root to the one
-		 * vnode asked. If they resolve to be the same, then we
-		 * ignore the match so that the real root gets used.
-		 * This avoids the problem of traversing "../.." to find the
-		 * root directory and never finding it, because "/" resolves
-		 * to the emulation root directory. This is expensive :-(
-		 */
-		NDINIT(&ndroot, LOOKUP, FOLLOW, UIO_SYSSPACE,
-		    freebsd32_emul_path, td);
-
-		if ((error = namei(&ndroot)) != 0) {
-			/* Cannot happen! */
-			free(buf, M_TEMP);
-			vrele(nd.ni_vp);
-			return error;
-		}
-
-		ucred = td->td_ucred;
-		if ((error = VOP_GETATTR(nd.ni_vp, &vat, ucred, td)) != 0) {
-			goto bad;
-		}
-
-		if ((error = VOP_GETATTR(ndroot.ni_vp, &vatroot, ucred,
-		    td)) != 0) {
-			goto bad;
-		}
-
-		if (vat.va_fsid == vatroot.va_fsid &&
-		    vat.va_fileid == vatroot.va_fileid) {
-			error = ENOENT;
-			goto bad;
-		}
-
-	}
-	if (sgp == NULL)
-		*pbuf = buf;
-	else {
-		sz = &ptr[len] - buf;
-		*pbuf = stackgap_alloc(sgp, sz + 1);
-		error = copyout(buf, *pbuf, sz);
-		free(buf, M_TEMP);
-	}
-
-	vrele(nd.ni_vp);
-	if (!cflag)
-		vrele(ndroot.ni_vp);
-
-	return error;
-
-bad:
-	vrele(ndroot.ni_vp);
-	vrele(nd.ni_vp);
-	free(buf, M_TEMP);
-	return error;
-}
-
-int
-freebsd32_open(struct thread *td, struct freebsd32_open_args *uap)
-{
-	caddr_t sg;
-
-	sg = stackgap_init();
-	CHECKALTEXIST(td, &sg, uap->path);
-
-	return open(td, (struct open_args *) uap);
-}
-
-int
 freebsd32_wait4(struct thread *td, struct freebsd32_wait4_args *uap)
 {
 	int error;
@@ -333,28 +183,6 @@
 	return (error);
 }
 
-int
-freebsd32_access(struct thread *td, struct freebsd32_access_args *uap)
-{
-	caddr_t sg;
-
-	sg = stackgap_init();
-	CHECKALTEXIST(td, &sg, uap->path);
-
-	return access(td, (struct access_args *)uap);
-}
-
-int
-freebsd32_chflags(struct thread *td, struct freebsd32_chflags_args *uap)
-{
-	caddr_t sg;
-
-	sg = stackgap_init();
-	CHECKALTEXIST(td, &sg, uap->path);
-
-	return chflags(td, (struct chflags_args *)uap);
-}
-
 struct sigaltstack32 {
 	u_int32_t	ss_sp;
 	u_int32_t	ss_size;
@@ -402,7 +230,6 @@
 	int count;
 
 	sg = stackgap_init();
-	CHECKALTEXIST(td, &sg, uap->fname);
 	ap.fname = uap->fname;
 
 	if (uap->argv) {

==== //depot/projects/hammer/sys/compat/freebsd32/freebsd32_proto.h#5 (text+ko) ====

@@ -32,11 +32,6 @@
 #define	PADR_(t)	0
 #endif
 
-struct freebsd32_open_args {
-	char path_l_[PADL_(char *)]; char * path; char path_r_[PADR_(char *)];
-	char flags_l_[PADL_(int)]; int flags; char flags_r_[PADR_(int)];
-	char mode_l_[PADL_(int)]; int mode; char mode_r_[PADR_(int)];
-};
 struct freebsd32_wait4_args {
 	char pid_l_[PADL_(int)]; int pid; char pid_r_[PADR_(int)];
 	char status_l_[PADL_(int *)]; int * status; char status_r_[PADR_(int *)];
@@ -48,14 +43,6 @@
 	char bufsize_l_[PADL_(long)]; long bufsize; char bufsize_r_[PADR_(long)];
 	char flags_l_[PADL_(int)]; int flags; char flags_r_[PADR_(int)];
 };
-struct freebsd32_access_args {
-	char path_l_[PADL_(char *)]; char * path; char path_r_[PADR_(char *)];
-	char flags_l_[PADL_(int)]; int flags; char flags_r_[PADR_(int)];
-};
-struct freebsd32_chflags_args {
-	char path_l_[PADL_(char *)]; char * path; char path_r_[PADR_(char *)];
-	char flags_l_[PADL_(int)]; int flags; char flags_r_[PADR_(int)];
-};
 struct freebsd32_sigaltstack_args {
 	char ss_l_[PADL_(struct sigaltstack32 *)]; struct sigaltstack32 * ss; char ss_r_[PADR_(struct sigaltstack32 *)];
 	char oss_l_[PADL_(struct sigaltstack32 *)]; struct sigaltstack32 * oss; char oss_r_[PADR_(struct sigaltstack32 *)];
@@ -227,11 +214,8 @@
 struct freebsd32_sigreturn_args {
 	char sigcntxp_l_[PADL_(const struct freebsd32_ucontext *)]; const struct freebsd32_ucontext * sigcntxp; char sigcntxp_r_[PADR_(const struct freebsd32_ucontext *)];
 };
-int	freebsd32_open(struct thread *, struct freebsd32_open_args *);
 int	freebsd32_wait4(struct thread *, struct freebsd32_wait4_args *);
 int	freebsd32_getfsstat(struct thread *, struct freebsd32_getfsstat_args *);
-int	freebsd32_access(struct thread *, struct freebsd32_access_args *);
-int	freebsd32_chflags(struct thread *, struct freebsd32_chflags_args *);
 int	freebsd32_sigaltstack(struct thread *, struct freebsd32_sigaltstack_args *);
 int	freebsd32_execve(struct thread *, struct freebsd32_execve_args *);
 int	freebsd32_setitimer(struct thread *, struct freebsd32_setitimer_args *);

==== //depot/projects/hammer/sys/compat/freebsd32/freebsd32_syscall.h#5 (text+ko) ====

@@ -11,7 +11,7 @@
 #define	FREEBSD32_SYS_fork	2
 #define	FREEBSD32_SYS_read	3
 #define	FREEBSD32_SYS_write	4
-#define	FREEBSD32_SYS_freebsd32_open	5
+#define	FREEBSD32_SYS_open	5
 #define	FREEBSD32_SYS_close	6
 #define	FREEBSD32_SYS_freebsd32_wait4	7
 				/* 8 is obsolete old creat */
@@ -38,8 +38,8 @@
 #define	FREEBSD32_SYS_accept	30
 #define	FREEBSD32_SYS_getpeername	31
 #define	FREEBSD32_SYS_getsockname	32
-#define	FREEBSD32_SYS_freebsd32_access	33
-#define	FREEBSD32_SYS_freebsd32_chflags	34
+#define	FREEBSD32_SYS_access	33
+#define	FREEBSD32_SYS_chflags	34
 #define	FREEBSD32_SYS_fchflags	35
 #define	FREEBSD32_SYS_sync	36
 #define	FREEBSD32_SYS_kill	37

==== //depot/projects/hammer/sys/compat/freebsd32/freebsd32_syscalls.c#5 (text+ko) ====

@@ -12,7 +12,7 @@
 	"fork",			/* 2 = fork */
 	"read",			/* 3 = read */
 	"write",			/* 4 = write */
-	"freebsd32_open",			/* 5 = freebsd32_open */
+	"open",			/* 5 = open */
 	"close",			/* 6 = close */
 	"freebsd32_wait4",			/* 7 = freebsd32_wait4 */
 	"obs_old",			/* 8 = obsolete old creat */
@@ -40,8 +40,8 @@
 	"accept",			/* 30 = accept */
 	"getpeername",			/* 31 = getpeername */
 	"getsockname",			/* 32 = getsockname */
-	"freebsd32_access",			/* 33 = freebsd32_access */
-	"freebsd32_chflags",			/* 34 = freebsd32_chflags */
+	"access",			/* 33 = access */
+	"chflags",			/* 34 = chflags */
 	"fchflags",			/* 35 = fchflags */
 	"sync",			/* 36 = sync */
 	"kill",			/* 37 = kill */

==== //depot/projects/hammer/sys/compat/freebsd32/freebsd32_sysent.c#5 (text+ko) ====

@@ -30,7 +30,7 @@
 	{ SYF_MPSAFE | 0, (sy_call_t *)fork },		/* 2 = fork */
 	{ SYF_MPSAFE | AS(read_args), (sy_call_t *)read },	/* 3 = read */
 	{ SYF_MPSAFE | AS(write_args), (sy_call_t *)write },	/* 4 = write */
-	{ AS(freebsd32_open_args), (sy_call_t *)freebsd32_open },	/* 5 = freebsd32_open */
+	{ AS(open_args), (sy_call_t *)open },		/* 5 = open */
 	{ SYF_MPSAFE | AS(close_args), (sy_call_t *)close },	/* 6 = close */
 	{ SYF_MPSAFE | AS(freebsd32_wait4_args), (sy_call_t *)freebsd32_wait4 },	/* 7 = freebsd32_wait4 */
 	{ 0, (sy_call_t *)nosys },			/* 8 = obsolete old creat */
@@ -58,8 +58,8 @@
 	{ SYF_MPSAFE | AS(accept_args), (sy_call_t *)accept },	/* 30 = accept */
 	{ SYF_MPSAFE | AS(getpeername_args), (sy_call_t *)getpeername },	/* 31 = getpeername */
 	{ SYF_MPSAFE | AS(getsockname_args), (sy_call_t *)getsockname },	/* 32 = getsockname */
-	{ AS(freebsd32_access_args), (sy_call_t *)freebsd32_access },	/* 33 = freebsd32_access */
-	{ AS(freebsd32_chflags_args), (sy_call_t *)freebsd32_chflags },	/* 34 = freebsd32_chflags */
+	{ AS(access_args), (sy_call_t *)access },	/* 33 = access */
+	{ AS(chflags_args), (sy_call_t *)chflags },	/* 34 = chflags */
 	{ AS(fchflags_args), (sy_call_t *)fchflags },	/* 35 = fchflags */
 	{ 0, (sy_call_t *)sync },			/* 36 = sync */
 	{ SYF_MPSAFE | AS(kill_args), (sy_call_t *)kill },	/* 37 = kill */

==== //depot/projects/hammer/sys/compat/freebsd32/freebsd32_util.h#2 (text+ko) ====

@@ -74,22 +74,3 @@
 	*sgp += ALIGN(sz);
 	return p;
 }
-
-
-extern const char freebsd32_emul_path[];
-int freebsd32_emul_find(struct thread *, caddr_t *, const char *, char *,
-			char **, int);
-
-#define CHECKALT(p, sgp, path, i)					\
-	do {								\
-		int _error;						\
-									\
-		_error = freebsd32_emul_find(p, sgp,			\
-					freebsd32_emul_path, path,	\
-					&path, i);			\
-		if (_error == EFAULT)					\
-			return (_error);				\
-	} while (0)
-
-#define	CHECKALTEXIST(p, sgp, path) CHECKALT((p), (sgp), (path), 0)
-#define	CHECKALTCREAT(p, sgp, path) CHECKALT((p), (sgp), (path), 1)

==== //depot/projects/hammer/sys/compat/freebsd32/syscalls.master#8 (text+ko) ====

@@ -20,7 +20,7 @@
 2	MNOPROTO POSIX	{ int fork(void); }
 3	MNOPROTO POSIX	{ ssize_t read(int fd, void *buf, size_t nbyte); }
 4	MNOPROTO POSIX	{ ssize_t write(int fd, const void *buf, size_t nbyte); }
-5	STD	POSIX	{ int freebsd32_open(char *path, int flags, int mode); }
+5	NOPROTO	POSIX	{ int open(char *path, int flags, int mode); }
 6	MNOPROTO POSIX	{ int close(int fd); }
 7	MSTD BSD	{ int freebsd32_wait4(int pid, int *status, int options, \
 			    struct rusage32 *rusage); }
@@ -55,8 +55,8 @@
 30	MNOPROTO BSD	{ int accept(int s, caddr_t name, int *anamelen); }
 31	MNOPROTO BSD	{ int getpeername(int fdes, caddr_t asa, int *alen); }
 32	MNOPROTO BSD	{ int getsockname(int fdes, caddr_t asa, int *alen); }
-33	STD	POSIX	{ int freebsd32_access(char *path, int flags); }
-34	STD	BSD	{ int freebsd32_chflags(char *path, int flags); }
+33	NOPROTO	POSIX	{ int access(char *path, int flags); }
+34	NOPROTO	BSD	{ int chflags(char *path, int flags); }
 35	NOPROTO	BSD	{ int fchflags(int fd, int flags); }
 36	NOPROTO	BSD	{ int sync(void); }
 37	MNOPROTO POSIX	{ int kill(int pid, int signum); }

==== //depot/projects/hammer/sys/compat/ia32/ia32_sysvec.c#8 (text+ko) ====

@@ -129,21 +129,34 @@
 };
 
 
-const char freebsd32_emul_path[] = "/compat/ia32";
-
 static Elf32_Brandinfo ia32_brand_info = {
 						ELFOSABI_FREEBSD,
 						EM_386,
 						"FreeBSD",
-						"/compat/ia32",
-						"/usr/libexec/ld-elf.so.1",
-						&ia32_freebsd_sysvec
+						NULL,
+						"/libexec/ld-elf.so.1",
+						&ia32_freebsd_sysvec,
+						"/libexec/ld-elf-32.so.1",
 					  };
 
 SYSINIT(ia32, SI_SUB_EXEC, SI_ORDER_ANY,
 	(sysinit_cfunc_t) elf32_insert_brand_entry,
 	&ia32_brand_info);
 
+static Elf32_Brandinfo ia32_brand_oinfo = {
+						ELFOSABI_FREEBSD,
+						EM_386,
+						"FreeBSD",
+						NULL,
+						"/usr/libexec/ld-elf.so.1",
+						&ia32_freebsd_sysvec,
+						"/usr/libexec/ld-elf-32.so.1",
+					  };
+
+SYSINIT(oia32, SI_SUB_EXEC, SI_ORDER_ANY,
+	(sysinit_cfunc_t) elf32_insert_brand_entry,
+	&ia32_brand_oinfo);
+
 /* XXX may be freebsd32 MI */
 static register_t *
 ia32_copyout_strings(struct image_params *imgp)

==== //depot/projects/hammer/sys/i386/i386/elf_machdep.c#8 (text+ko) ====

@@ -78,15 +78,30 @@
 						ELFOSABI_FREEBSD,
 						EM_386,
 						"FreeBSD",
-						"",
+						NULL,
 						"/libexec/ld-elf.so.1",
-						&elf32_freebsd_sysvec
+						&elf32_freebsd_sysvec,
+						NULL,
 					  };
 
 SYSINIT(elf32, SI_SUB_EXEC, SI_ORDER_ANY,
 	(sysinit_cfunc_t) elf32_insert_brand_entry,
 	&freebsd_brand_info);
 
+static Elf32_Brandinfo freebsd_brand_oinfo = {
+						ELFOSABI_FREEBSD,
+						EM_386,
+						"FreeBSD",
+						NULL,
+						"/usr/libexec/ld-elf.so.1",
+						&elf32_freebsd_sysvec,
+						NULL,
+					  };
+
+SYSINIT(oelf32, SI_SUB_EXEC, SI_ORDER_ANY,
+	(sysinit_cfunc_t) elf32_insert_brand_entry,
+	&freebsd_brand_oinfo);
+
 /* Process one elf relocation with addend. */
 static int
 elf_reloc_internal(linker_file_t lf, const void *data, int type, int local)

==== //depot/projects/hammer/sys/ia64/ia64/elf_machdep.c#10 (text+ko) ====

@@ -84,15 +84,30 @@
 						ELFOSABI_FREEBSD,
 						EM_IA_64,
 						"FreeBSD",
-						"",
+						NULL,
 						"/libexec/ld-elf.so.1",
-						&elf64_freebsd_sysvec
+						&elf64_freebsd_sysvec,
+						NULL,
 					  };
 
 SYSINIT(elf64, SI_SUB_EXEC, SI_ORDER_ANY,
 	(sysinit_cfunc_t) elf64_insert_brand_entry,
 	&freebsd_brand_info);
 
+static Elf64_Brandinfo freebsd_brand_oinfo = {
+						ELFOSABI_FREEBSD,
+						EM_IA_64,
+						"FreeBSD",
+						NULL,
+						"/usr/libexec/ld-elf.so.1",
+						&elf64_freebsd_sysvec,
+						NULL,
+					  };
+
+SYSINIT(oelf64, SI_SUB_EXEC, SI_ORDER_ANY,
+	(sysinit_cfunc_t) elf64_insert_brand_entry,
+	&freebsd_brand_oinfo);
+
 Elf_Addr link_elf_get_gp(linker_file_t);
 
 extern Elf_Addr fptr_storage[];

==== //depot/projects/hammer/sys/kern/imgact_elf.c#11 (text+ko) ====

@@ -708,6 +708,8 @@
 		goto fail;
 	}
 	sv = brand_info->sysvec;
+	if (brand_info->interp_newpath != NULL)
+		interp = brand_info->interp_newpath;
 
 	if ((error = exec_extract_strings(imgp)) != 0)
 		goto fail;
@@ -818,21 +820,24 @@
 	imgp->entry_addr = entry;
 
 	imgp->proc->p_sysent = sv;
-	if (interp != NULL) {
+	if (interp != NULL && brand_info->emul_path != NULL &&
+	    brand_info->emul_path[0] != '\0') {
 		path = malloc(MAXPATHLEN, M_TEMP, M_WAITOK);
 		snprintf(path, MAXPATHLEN, "%s%s", brand_info->emul_path,
 		    interp);
-		if ((error = __elfN(load_file)(imgp->proc, path, &addr,
-		    &imgp->entry_addr, sv->sv_pagesize)) != 0) {
-			if ((error = __elfN(load_file)(imgp->proc, interp,
-			    &addr, &imgp->entry_addr, sv->sv_pagesize)) != 0) {
-				uprintf("ELF interpreter %s not found\n",
-				    path);
-				free(path, M_TEMP);
-				goto fail;
-			}
+		error = __elfN(load_file)(imgp->proc, path, &addr,
+		    &imgp->entry_addr, sv->sv_pagesize);
+		free(path, M_TEMP);
+		if (error == 0)
+			interp = NULL;
+	}
+	if (interp != NULL) {
+		error = __elfN(load_file)(imgp->proc, interp, &addr,
+		    &imgp->entry_addr, sv->sv_pagesize);
+		if (error != 0) {
+			uprintf("ELF interpreter %s not found\n", interp);
+			goto fail;
 		}
-		free(path, M_TEMP);
 	}
 
 	/*

==== //depot/projects/hammer/sys/powerpc/powerpc/elf_machdep.c#7 (text+ko) ====

@@ -80,15 +80,30 @@
 						ELFOSABI_FREEBSD,
 						EM_PPC,
 						"FreeBSD",
-						"",
+						NULL,
 						"/libexec/ld-elf.so.1",
-						&elf32_freebsd_sysvec
+						&elf32_freebsd_sysvec,
+						NULL,
 					  };
 
 SYSINIT(elf32, SI_SUB_EXEC, SI_ORDER_ANY,
 	(sysinit_cfunc_t) elf32_insert_brand_entry,
 	&freebsd_brand_info);
 
+static Elf32_Brandinfo freebsd_brand_oinfo = {
+						ELFOSABI_FREEBSD,
+						EM_PPC,
+						"FreeBSD",
+						NULL,
+						"/usr/libexec/ld-elf.so.1",
+						&elf32_freebsd_sysvec,
+						NULL,
+					  };
+
+SYSINIT(oelf32, SI_SUB_EXEC, SI_ORDER_ANY,
+	(sysinit_cfunc_t) elf32_insert_brand_entry,
+	&freebsd_brand_oinfo);
+
 /* Process one elf relocation with addend. */
 static int
 elf_reloc_internal(linker_file_t lf, const void *data, int type, int local)

==== //depot/projects/hammer/sys/sparc64/sparc64/elf_machdep.c#8 (text+ko) ====

@@ -91,15 +91,30 @@
 						ELFOSABI_FREEBSD,
 						EM_SPARCV9,
 						"FreeBSD",
-						"",
+						NULL,
 						"/libexec/ld-elf.so.1",
-						&elf64_freebsd_sysvec
+						&elf64_freebsd_sysvec,
+						NULL,
 					  };
 
 SYSINIT(elf64, SI_SUB_EXEC, SI_ORDER_ANY,
 	(sysinit_cfunc_t) elf64_insert_brand_entry,
 	&freebsd_brand_info);
 
+static Elf64_Brandinfo freebsd_brand_oinfo = {
+						ELFOSABI_FREEBSD,
+						EM_SPARCV9,
+						"FreeBSD",
+						NULL,
+						"/usr/libexec/ld-elf.so.1",
+						&elf64_freebsd_sysvec,
+						NULL,
+					  };
+
+SYSINIT(oelf64, SI_SUB_EXEC, SI_ORDER_ANY,
+	(sysinit_cfunc_t) elf64_insert_brand_entry,
+	&freebsd_brand_oinfo);
+
 /*
  * The following table holds for each relocation type:
  *	- the width in bits of the memory location the relocation

==== //depot/projects/hammer/sys/sys/imgact_elf.h#3 (text+ko) ====

@@ -61,13 +61,14 @@
 	const char *compat_3_brand;	/* pre Binutils 2.10 method (FBSD 3) */
 	const char *emul_path;
 	const char *interp_path;
-        struct sysentvec *sysvec;
+	struct sysentvec *sysvec;
+	const char *interp_newpath;
 } __ElfN(Brandinfo);
 
 __ElfType(Auxargs);
 __ElfType(Brandinfo);
 
-#define MAX_BRANDS      8
+#define MAX_BRANDS	8
 
 int	__elfN(brand_inuse)(Elf_Brandinfo *entry);
 int	__elfN(insert_brand_entry)(Elf_Brandinfo *entry);


More information about the p4-projects mailing list