LLVM Image Activator

Nathan Whitehorn nwhitehorn at freebsd.org
Sun Jan 6 18:02:30 UTC 2013


Having LLVM/clang in the base system lets us do some interesting things
that we couldn't do with GCC. One is that LLVM ships with a JIT for LLVM
IR as well as components of a toolchain for it (this is what Google's
pNACL uses) and that you can end up producing binary files that are in
IR instead of native code. The IR isn't really cross-platform, but does
let you do CPU-specific optimizations when executed by the JIT, etc.

The attached patch causes the LLVM JIT (lli) to be built by default
(adding ~20 seconds to buildworld on my five-year-old laptop) and adds a
kernel image activator that invokes it when passed LLVM bitcode files.
It's not completely finished (see the XXX comment in the middle), but it
does work, as follows:

$ clang -emit-llvm -c -o hw.ll hw.c
$ file hw.ll
hw.ll: LLVM bitcode
$ lli hw.ll
Hello world!
$ chmod a+x hw.ll
$ ./hw.ll
Hello world!
$

Is there any interest in having features like this? It seems like this
could provides some interesting possibilities for us and nice
integration from having imported clang into base.
-Nathan
-------------- next part --------------
Index: sys/kern/imgact_llvm.c
===================================================================
--- sys/kern/imgact_llvm.c	(revision 0)
+++ sys/kern/imgact_llvm.c	(working copy)
@@ -0,0 +1,78 @@
+/*-
+ * Copyright (c) 2012 Nathan Whitehorn
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/vnode.h>
+#include <sys/proc.h>
+#include <sys/sbuf.h>
+#include <sys/systm.h>
+#include <sys/sysproto.h>
+#include <sys/exec.h>
+#include <sys/imgact.h>
+#include <sys/kernel.h>
+
+static const char llvm_magic[5] = {'B', 'C', 0xc0, 0xde, 0};
+
+static int
+exec_llvm_imgact(struct image_params *imgp)
+{
+	const char *interp = "/usr/bin/lli";
+
+	/* check for LLVM bitcode magic */
+	if (memcmp(imgp->image_header, llvm_magic, 4) != 0)
+		return (-1);
+
+	if (imgp->args->stringspace < strlen(interp) + 1)
+		return (ENOMEM);
+
+	imgp->interpreted = 1;
+
+	/* Move over arguments and set argv[0] to the interpreter */
+	memmove(imgp->args->begin_argv + strlen(interp) + 1,
+	    imgp->args->begin_argv, imgp->args->endp - imgp->args->begin_argv);
+	strcpy(imgp->args->begin_argv, interp);
+
+	/* XXX: set argv[1] to fname instead of old argv[0], call -fake-argv0 with old argv[0] */
+
+	imgp->args->begin_envv += strlen(interp) + 1;
+	imgp->args->endp += strlen(interp) + 1;
+	imgp->args->stringspace -= strlen(interp) + 1;
+	imgp->args->argc++;
+
+	imgp->interpreter_name = imgp->args->begin_argv;
+
+	return (0);
+}
+
+/*
+ * Tell kern_execve.c about it, with a little help from the linker.
+ */
+static struct execsw llvm_execsw = { exec_llvm_imgact, llvm_magic };
+EXEC_SET(llvm, llvm_execsw);
+

Property changes on: sys/kern/imgact_llvm.c
___________________________________________________________________
Added: svn:keywords
## -0,0 +1 ##
+FreeBSD=%H
\ No newline at end of property
Index: sys/conf/files
===================================================================
--- sys/conf/files	(revision 245062)
+++ sys/conf/files	(working copy)
@@ -2586,6 +2586,7 @@
 kern/device_if.m		standard
 kern/imgact_elf.c		standard
 kern/imgact_elf32.c		optional compat_freebsd32
+kern/imgact_llvm.c		standard
 kern/imgact_shell.c		standard
 kern/inflate.c			optional gzip
 kern/init_main.c		standard
Index: usr.bin/clang/Makefile
===================================================================
--- usr.bin/clang/Makefile	(revision 245062)
+++ usr.bin/clang/Makefile	(working copy)
@@ -2,12 +2,11 @@
 
 .include <bsd.own.mk>
 
-SUBDIR=	clang clang-tblgen tblgen
+SUBDIR=	clang clang-tblgen tblgen lli
 
 .if ${MK_CLANG_EXTRAS} != "no" && !defined(TOOLS_PREFIX)
 SUBDIR+=bugpoint \
 	llc \
-	lli \
 	llvm-ar \
 	llvm-as \
 	llvm-bcanalyzer \
Index: lib/clang/Makefile
===================================================================
--- lib/clang/Makefile	(revision 245062)
+++ lib/clang/Makefile	(working copy)
@@ -30,16 +30,23 @@
 	libllvmbitwriter \
 	libllvmcodegen \
 	libllvmcore \
+	libllvmdebuginfo \
+	libllvmexecutionengine \
 	libllvminstcombine \
 	libllvminstrumentation \
+	libllvminterpreter \
 	libllvmipa \
 	libllvmipo \
+	libllvmjit \
 	libllvmlinker \
 	libllvmmc \
+	libllvmmcdisassembler \
+	libllvmmcjit \
 	libllvmmcparser \
 	libllvmobject \
 	libllvmscalaropts \
 	libllvmselectiondag \
+	libllvmruntimedyld \
 	libllvmsupport \
 	libllvmtablegen \
 	libllvmtarget \
@@ -68,18 +75,8 @@
 	libllvmx86disassembler \
 	libllvmx86info \
 	libllvmx86instprinter \
-	libllvmx86utils
-
-.if ${MK_CLANG_EXTRAS} != "no"
-SUBDIR+=libllvmdebuginfo \
-	libllvmexecutionengine \
-	libllvminterpreter \
-	libllvmjit \
-	libllvmmcdisassembler \
-	libllvmmcjit \
-	libllvmruntimedyld
+	libllvmx86utils 
 .endif
-.endif
 
 SUBDIR+= include
 
Index: lib/clang/libllvmsupport/Makefile
===================================================================
--- lib/clang/libllvmsupport/Makefile	(revision 245062)
+++ lib/clang/libllvmsupport/Makefile	(working copy)
@@ -16,12 +16,16 @@
 	ConstantRange.cpp \
 	CrashRecoveryContext.cpp \
 	DAGDeltaAlgorithm.cpp \
+	DataExtractor.cpp \
+	DataStream.cpp \
 	Debug.cpp \
 	DeltaAlgorithm.cpp \
+	Disassembler.cpp \
 	Dwarf.cpp \
 	DynamicLibrary.cpp \
 	Errno.cpp \
 	ErrorHandling.cpp \
+	FileUtilities.cpp \
 	FoldingSet.cpp \
 	FormattedStream.cpp \
 	GraphWriter.cpp \
@@ -56,6 +60,7 @@
 	StringMap.cpp \
 	StringPool.cpp \
 	StringRef.cpp \
+	SystemUtils.cpp \
 	TargetRegistry.cpp \
 	ThreadLocal.cpp \
 	Threading.cpp \
@@ -76,15 +81,4 @@
 	system_error.cpp
 LLVM_REQUIRES_RTTI=
 
-.if ${MK_CLANG_EXTRAS} != "no"
-SRCS+=	BlockFrequency.cpp \
-	BranchProbability.cpp \
-	DataExtractor.cpp \
-	DataStream.cpp \
-	Disassembler.cpp \
-	FileUtilities.cpp \
-	MemoryObject.cpp \
-	SystemUtils.cpp
-.endif
-
 .include "../clang.lib.mk"


More information about the freebsd-toolchain mailing list