diff --git a/src/Makefile b/src/Makefile
index 221ec9ffcca26..76f768dfdff7a 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -32,6 +32,26 @@ CFG_RUSTC_FLAGS := -nowarn
 # embedded into the executable, so use a no-op command.
 DSYMUTIL := true
 
+ifeq ($(CFG_OSTYPE), FreeBSD)
+  CFG_RUNTIME := librustrt.so
+  CFG_STDLIB := libstd.so
+  CFG_GCC_CFLAGS += -fPIC -march=i686 -I/usr/local/include
+  CFG_GCC_LINK_FLAGS += -shared -fPIC -lpthread -lrt
+  ifeq ($(CFG_CPUTYPE), x86_64)
+    CFG_GCC_CFLAGS += -m32
+    CFG_GCC_LINK_FLAGS += -m32
+  endif
+  CFG_NATIVE := 1
+  CFG_UNIXY := 1
+  CFG_VALGRIND := $(shell which valgrind)
+  ifdef CFG_VALGRIND
+    CFG_VALGRIND += --leak-check=full \
+                    --error-exitcode=1 \
+                    --quiet --vex-iropt-level=0 \
+                    --suppressions=etc/x86.supp
+  endif
+endif
+
 ifeq ($(CFG_OSTYPE), Linux)
   CFG_RUNTIME := librustrt.so
   CFG_STDLIB := libstd.so
diff --git a/src/boot/be/elf.ml b/src/boot/be/elf.ml
index 406508e4b5e82..2192eaa96f695 100644
--- a/src/boot/be/elf.ml
+++ b/src/boot/be/elf.ml
@@ -59,7 +59,7 @@ let elf_identification ei_class ei_data =
              | ELFDATA2LSB -> 1
              | ELFDATA2MSB -> 2);
           1;                    (* EI_VERSION = EV_CURRENT *)
-          0;                    (* EI_PAD #7 *)
+          9;                    (* EI_PAD #7 *)
           0;                    (* EI_PAD #8 *)
           0;                    (* EI_PAD #9 *)
           0;                    (* EI_PAD #A *)
@@ -1290,7 +1290,7 @@ let elf32_linux_x86_file
   in
 
   let interp_section =
-    DEF (interp_section_fixup, ZSTRING "/lib/ld-linux.so.2")
+    DEF (interp_section_fixup, ZSTRING "/libexec/ld-elf.so.1")
   in
 
   let text_section =
@@ -1584,7 +1584,7 @@ let emit_file
 
   let needed_libs =
     [|
-      "libc.so.6";
+      "libc.so.7";
       "librustrt.so"
     |]
   in
diff --git a/src/boot/driver/lib.ml b/src/boot/driver/lib.ml
index a4769e83ed1e4..00b1b8341f517 100644
--- a/src/boot/driver/lib.ml
+++ b/src/boot/driver/lib.ml
@@ -249,6 +249,7 @@ let get_ar
               Win32_x86_pe -> Pe.sniff
             | MacOS_x86_macho -> Macho.sniff
             | Linux_x86_elf -> Elf.sniff
+            | FreeBSD_x86_elf -> Elf.sniff
         in
           sniff sess filename
     end
@@ -270,6 +271,7 @@ let get_sects
                     Win32_x86_pe -> Pe.get_sections
                   | MacOS_x86_macho -> Macho.get_sections
                   | Linux_x86_elf -> Elf.get_sections
+                  | FreeBSD_x86_elf -> Elf.get_sections
               in
                 Some (ar, (get_sections sess ar))
     end
@@ -350,6 +352,7 @@ let get_mod
         Win32_x86_pe -> ".dll"
       | MacOS_x86_macho -> ".dylib"
       | Linux_x86_elf -> ".so"
+      | FreeBSD_x86_elf -> ".so"
   in
   let rec meta_matches i f_meta =
     if i >= (Array.length meta)
@@ -447,6 +450,7 @@ let infer_lib_name
       Win32_x86_pe -> ident ^ ".dll"
     | MacOS_x86_macho -> "lib" ^ ident ^ ".dylib"
     | Linux_x86_elf -> "lib" ^ ident ^ ".so"
+    | FreeBSD_x86_elf -> "lib" ^ ident ^ ".so"
 ;;
 
 
diff --git a/src/boot/driver/main.ml b/src/boot/driver/main.ml
index 2bbc832bf04ff..332073478faa1 100644
--- a/src/boot/driver/main.ml
+++ b/src/boot/driver/main.ml
@@ -10,6 +10,8 @@ let (targ:Common.target) =
   match Sys.os_type with
       "Unix" when Unix.system "test `uname -s` = 'Darwin'" = Unix.WEXITED 0 ->
         MacOS_x86_macho
+    | "Unix" when Unix.system "test `uname -s` = 'FreeBSD'" = Unix.WEXITED 0 ->
+        FreeBSD_x86_elf
     | "Unix" -> Linux_x86_elf
     | "Win32" -> Win32_x86_pe
     | "Cygwin" -> Win32_x86_pe
@@ -96,6 +98,7 @@ let default_output_filename (sess:Session.sess) : filename option =
           else
             base ^ (match sess.Session.sess_targ with
                         Linux_x86_elf -> ""
+                      | FreeBSD_x86_elf -> ""
                       | MacOS_x86_macho -> ""
                       | Win32_x86_pe -> ".exe")
         in
@@ -144,16 +147,18 @@ let flag f opt desc =
 
 let argspecs =
   [
-    ("-t", Arg.Symbol (["linux-x86-elf"; "win32-x86-pe"; "macos-x86-macho"],
+    ("-t", Arg.Symbol (["linux-x86-elf"; "win32-x86-pe"; "macos-x86-macho"; "freebsd-x86-elf"],
                        fun s -> (sess.Session.sess_targ <-
                                    (match s with
                                         "win32-x86-pe" -> Win32_x86_pe
                                       | "macos-x86-macho" -> MacOS_x86_macho
+                                      | "freebsd-x86-macho" -> FreeBSD_x86_elf
                                       | _ -> Linux_x86_elf))),
      (" target (default: " ^ (match sess.Session.sess_targ with
                                   Win32_x86_pe -> "win32-x86-pe"
                                 | Linux_x86_elf -> "linux-x86-elf"
                                 | MacOS_x86_macho -> "macos-x86-macho"
+                                | FreeBSD_x86_elf -> "freebsd-x86-elf"
                              ) ^ ")"));
     ("-o", Arg.String (fun s -> sess.Session.sess_out <- Some s),
      "file to output (default: "
@@ -320,6 +325,7 @@ let parse_input_crate
             let depfile =
               match sess.Session.sess_targ with
                   Linux_x86_elf
+                | FreeBSD_x86_elf
                 | MacOS_x86_macho -> outfile ^ ".d"
                 | Win32_x86_pe -> (Filename.chop_extension outfile) ^ ".d"
             in
@@ -473,6 +479,7 @@ let main_pipeline _ =
               Win32_x86_pe -> Pe.emit_file
             | MacOS_x86_macho -> Macho.emit_file
             | Linux_x86_elf -> Elf.emit_file
+            | FreeBSD_x86_elf -> Elf.emit_file
         in
           Session.time_inner "emit" sess
             (fun _ -> emitter sess crate code data sem_cx dwarf);
diff --git a/src/boot/fe/cexp.ml b/src/boot/fe/cexp.ml
index 56f3e878ca4b7..0f216fc299370 100644
--- a/src/boot/fe/cexp.ml
+++ b/src/boot/fe/cexp.ml
@@ -628,6 +628,7 @@ let parse_crate_file
     let (os, arch, libc) =
       match sess.Session.sess_targ with
           Linux_x86_elf -> ("linux", "x86", "libc.so.6")
+        | FreeBSD_x86_elf -> ("freebsd", "x86", "libc.so.7")
         | Win32_x86_pe -> ("win32", "x86", "msvcrt.dll")
         | MacOS_x86_macho -> ("macos", "x86", "libc.dylib")
     in
diff --git a/src/boot/util/common.ml b/src/boot/util/common.ml
index f9b18246c79ca..c76da0de552b0 100644
--- a/src/boot/util/common.ml
+++ b/src/boot/util/common.ml
@@ -56,6 +56,7 @@ type target =
     Linux_x86_elf
   | Win32_x86_pe
   | MacOS_x86_macho
+  | FreeBSD_x86_elf
 ;;
 
 type ty_mach =