Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 2 Mar 2013 17:06:40 +0000 (UTC)
From:      Dmitry Chagin <dchagin@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-user@freebsd.org
Subject:   svn commit: r247642 - in user/dchagin/lemul/sys: amd64/linux32 i386/linux kern sys
Message-ID:  <201303021706.r22H6eRl067742@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: dchagin
Date: Sat Mar  2 17:06:39 2013
New Revision: 247642
URL: http://svnweb.freebsd.org/changeset/base/247642

Log:
  To allow to run the interpreter itself add a new ELF branding type.
  Allow Linux ABI to run ELF interpreter.

Modified:
  user/dchagin/lemul/sys/amd64/linux32/linux32_sysvec.c
  user/dchagin/lemul/sys/i386/linux/linux_sysvec.c
  user/dchagin/lemul/sys/kern/imgact_elf.c
  user/dchagin/lemul/sys/sys/imgact_elf.h

Modified: user/dchagin/lemul/sys/amd64/linux32/linux32_sysvec.c
==============================================================================
--- user/dchagin/lemul/sys/amd64/linux32/linux32_sysvec.c	Sat Mar  2 16:45:58 2013	(r247641)
+++ user/dchagin/lemul/sys/amd64/linux32/linux32_sysvec.c	Sat Mar  2 17:06:39 2013	(r247642)
@@ -1105,7 +1105,7 @@ static Elf32_Brandinfo linux_brand = {
 	.sysvec		= &elf_linux_sysvec,
 	.interp_newpath	= NULL,
 	.brand_note	= &linux32_brandnote,
-	.flags		= BI_CAN_EXEC_DYN | BI_BRAND_NOTE
+	.flags		= BI_CAN_EXEC_DYN | BI_BRAND_NOTE | BI_CAN_EXEC_INTERP
 };
 
 static Elf32_Brandinfo linux_glibc2brand = {
@@ -1117,7 +1117,7 @@ static Elf32_Brandinfo linux_glibc2brand
 	.sysvec		= &elf_linux_sysvec,
 	.interp_newpath	= NULL,
 	.brand_note	= &linux32_brandnote,
-	.flags		= BI_CAN_EXEC_DYN | BI_BRAND_NOTE
+	.flags		= BI_CAN_EXEC_DYN | BI_BRAND_NOTE | BI_CAN_EXEC_INTERP
 };
 
 Elf32_Brandinfo *linux_brandlist[] = {

Modified: user/dchagin/lemul/sys/i386/linux/linux_sysvec.c
==============================================================================
--- user/dchagin/lemul/sys/i386/linux/linux_sysvec.c	Sat Mar  2 16:45:58 2013	(r247641)
+++ user/dchagin/lemul/sys/i386/linux/linux_sysvec.c	Sat Mar  2 17:06:39 2013	(r247642)
@@ -1078,7 +1078,7 @@ static Elf32_Brandinfo linux_brand = {
 	.sysvec		= &elf_linux_sysvec,
 	.interp_newpath	= NULL,
 	.brand_note	= &linux_brandnote,
-	.flags		= BI_CAN_EXEC_DYN | BI_BRAND_NOTE
+	.flags		= BI_CAN_EXEC_DYN | BI_BRAND_NOTE | BI_CAN_EXEC_INTERP 
 };
 
 static Elf32_Brandinfo linux_glibc2brand = {
@@ -1090,7 +1090,7 @@ static Elf32_Brandinfo linux_glibc2brand
 	.sysvec		= &elf_linux_sysvec,
 	.interp_newpath	= NULL,
 	.brand_note	= &linux_brandnote,
-	.flags		= BI_CAN_EXEC_DYN | BI_BRAND_NOTE
+	.flags		= BI_CAN_EXEC_DYN | BI_BRAND_NOTE | BI_CAN_EXEC_INTERP 
 };
 
 Elf32_Brandinfo *linux_brandlist[] = {

Modified: user/dchagin/lemul/sys/kern/imgact_elf.c
==============================================================================
--- user/dchagin/lemul/sys/kern/imgact_elf.c	Sat Mar  2 16:45:58 2013	(r247641)
+++ user/dchagin/lemul/sys/kern/imgact_elf.c	Sat Mar  2 17:06:39 2013	(r247642)
@@ -258,6 +258,8 @@ __elfN(get_brandinfo)(struct image_param
 {
 	const Elf_Ehdr *hdr = (const Elf_Ehdr *)imgp->image_header;
 	Elf_Brandinfo *bi;
+	const char *fname_name, *interp_brand_name;
+	int fname_len, interp_len;
 	boolean_t ret;
 	int i;
 
@@ -308,6 +310,33 @@ __elfN(get_brandinfo)(struct image_param
 		}
 	}
 
+	/* Some ABI allows to run the interpreter itself. */
+	for (i = 0; i < MAX_BRANDS; i++) {
+		bi = elf_brand_list[i];
+		if (bi == NULL || bi->flags & BI_BRAND_NOTE_MANDATORY)
+			continue;
+		if (hdr->e_machine != bi->machine ||
+		    (bi->flags & BI_CAN_EXEC_INTERP) == 0)
+			continue;
+		/*
+		 * Compare the interpreter name not the path to allow run it
+		 * from everywhere.
+		 */
+		interp_brand_name = strrchr(bi->interp_path, '/');
+		if (interp_brand_name == NULL)
+			interp_brand_name = bi->interp_path;
+		interp_len = strlen(interp_brand_name);
+		fname_name = strrchr(imgp->args->fname, '/');
+		if (fname_name == NULL)
+			fname_name = imgp->args->fname;
+		fname_len = strlen(fname_name);
+		if (fname_len < interp_len)
+			continue;
+		ret = strncmp(fname_name, interp_brand_name, interp_len);
+		if (ret == 0)
+			return (bi);
+	}
+
 	/* Lacking a recognized interpreter, try the default brand */
 	for (i = 0; i < MAX_BRANDS; i++) {
 		bi = elf_brand_list[i];

Modified: user/dchagin/lemul/sys/sys/imgact_elf.h
==============================================================================
--- user/dchagin/lemul/sys/sys/imgact_elf.h	Sat Mar  2 16:45:58 2013	(r247641)
+++ user/dchagin/lemul/sys/sys/imgact_elf.h	Sat Mar  2 17:06:39 2013	(r247642)
@@ -77,6 +77,7 @@ typedef struct {
 #define	BI_CAN_EXEC_DYN		0x0001
 #define	BI_BRAND_NOTE		0x0002	/* May have note.ABI-tag section. */
 #define	BI_BRAND_NOTE_MANDATORY	0x0004	/* Must have note.ABI-tag section. */
+#define	BI_CAN_EXEC_INTERP	0x0008	/* Allow to run interpreter itself. */
 } __ElfN(Brandinfo);
 
 __ElfType(Auxargs);



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201303021706.r22H6eRl067742>