diff --git a/mk/cfg/i686-unknown-openbsd.mk b/mk/cfg/i686-unknown-openbsd.mk
new file mode 100644
index 0000000000000..b839937c9768b
--- /dev/null
+++ b/mk/cfg/i686-unknown-openbsd.mk
@@ -0,0 +1,24 @@
+# i686-unknown-openbsd configuration
+CC_i686-unknown-openbsd=$(CC)
+CXX_i686-unknown-openbsd=$(CXX)
+CPP_i686-unknown-openbsd=$(CPP)
+AR_i686-unknown-openbsd=$(AR)
+CFG_LIB_NAME_i686-unknown-openbsd=lib$(1).so
+CFG_STATIC_LIB_NAME_i686-unknown-openbsd=lib$(1).a
+CFG_LIB_GLOB_i686-unknown-openbsd=lib$(1)-*.so
+CFG_LIB_DSYM_GLOB_i686-unknown-openbsd=$(1)-*.dylib.dSYM
+CFG_JEMALLOC_CFLAGS_i686-unknown-openbsd := -m32 -I/usr/include $(CFLAGS)
+CFG_GCCISH_CFLAGS_i686-unknown-openbsd :=  -g -fPIC -m32 -I/usr/include $(CFLAGS)
+CFG_GCCISH_LINK_FLAGS_i686-unknown-openbsd := -shared -fPIC -g -pthread -m32
+CFG_GCCISH_DEF_FLAG_i686-unknown-openbsd := -Wl,--export-dynamic,--dynamic-list=
+CFG_LLC_FLAGS_i686-unknown-openbsd :=
+CFG_INSTALL_NAME_i686-unknown-openbsd =
+CFG_EXE_SUFFIX_i686-unknown-openbsd :=
+CFG_WINDOWSY_i686-unknown-openbsd :=
+CFG_UNIXY_i686-unknown-openbsd := 1
+CFG_LDPATH_i686-unknown-openbsd :=
+CFG_RUN_i686-unknown-openbsd=$(2)
+CFG_RUN_TARG_i686-unknown-openbsd=$(call CFG_RUN_i686-unknown-openbsd,,$(2))
+CFG_GNU_TRIPLE_i686-unknown-openbsd := i686-unknown-openbsd
+RUSTC_FLAGS_i686-unknown-openbsd=-C linker=$(call FIND_COMPILER,$(CC))
+CFG_DISABLE_JEMALLOC_i686-unknown-openbsd := 1
diff --git a/src/liblibc b/src/liblibc
index 6e8c1b490ccbe..0ac39c5ccf6a0 160000
--- a/src/liblibc
+++ b/src/liblibc
@@ -1 +1 @@
-Subproject commit 6e8c1b490ccbe5e84d248bab883515bc85394b5f
+Subproject commit 0ac39c5ccf6a04395b7c40dd62321cb91f63f160
diff --git a/src/librustc_back/target/i686_unknown_openbsd.rs b/src/librustc_back/target/i686_unknown_openbsd.rs
new file mode 100644
index 0000000000000..81efd37386a0f
--- /dev/null
+++ b/src/librustc_back/target/i686_unknown_openbsd.rs
@@ -0,0 +1,30 @@
+// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use target::{Target, TargetResult};
+
+pub fn target() -> TargetResult {
+    let mut base = super::openbsd_base::opts();
+    base.cpu = "pentium4".to_string();
+    base.max_atomic_width = Some(64);
+    base.pre_link_args.push("-m32".to_string());
+
+    Ok(Target {
+        llvm_target: "i686-unknown-openbsd".to_string(),
+        target_endian: "little".to_string(),
+        target_pointer_width: "32".to_string(),
+        data_layout: "e-m:e-p:32:32-f64:32:64-f80:32-n8:16:32-S128".to_string(),
+        arch: "x86".to_string(),
+        target_os: "openbsd".to_string(),
+        target_env: "".to_string(),
+        target_vendor: "unknown".to_string(),
+        options: base,
+    })
+}
diff --git a/src/librustc_back/target/mod.rs b/src/librustc_back/target/mod.rs
index f195ccb3f4292..351d469ea2809 100644
--- a/src/librustc_back/target/mod.rs
+++ b/src/librustc_back/target/mod.rs
@@ -168,7 +168,10 @@ supported_targets! {
     ("x86_64-unknown-dragonfly", x86_64_unknown_dragonfly),
 
     ("x86_64-unknown-bitrig", x86_64_unknown_bitrig),
+
+    ("i686-unknown-openbsd", i686_unknown_openbsd),
     ("x86_64-unknown-openbsd", x86_64_unknown_openbsd),
+
     ("x86_64-unknown-netbsd", x86_64_unknown_netbsd),
     ("x86_64-rumprun-netbsd", x86_64_rumprun_netbsd),
 
@@ -299,6 +302,9 @@ pub struct TargetOptions {
     pub staticlib_suffix: String,
     /// OS family to use for conditional compilation. Valid options: "unix", "windows".
     pub target_family: Option<String>,
+    /// Whether the target toolchain is like OpenBSD's.
+    /// Only useful for compiling against OpenBSD, for configuring abi when returning a struct.
+    pub is_like_openbsd: bool,
     /// Whether the target toolchain is like OSX's. Only useful for compiling against iOS/OS X, in
     /// particular running dsymutil and some other stuff like `-dead_strip`. Defaults to false.
     pub is_like_osx: bool,
@@ -403,6 +409,7 @@ impl Default for TargetOptions {
             staticlib_prefix: "lib".to_string(),
             staticlib_suffix: ".a".to_string(),
             target_family: None,
+            is_like_openbsd: false,
             is_like_osx: false,
             is_like_solaris: false,
             is_like_windows: false,
@@ -569,6 +576,7 @@ impl Target {
         key!(staticlib_prefix);
         key!(staticlib_suffix);
         key!(target_family, optional);
+        key!(is_like_openbsd, bool);
         key!(is_like_osx, bool);
         key!(is_like_solaris, bool);
         key!(is_like_windows, bool);
@@ -730,6 +738,7 @@ impl ToJson for Target {
         target_option_val!(staticlib_prefix);
         target_option_val!(staticlib_suffix);
         target_option_val!(target_family);
+        target_option_val!(is_like_openbsd);
         target_option_val!(is_like_osx);
         target_option_val!(is_like_solaris);
         target_option_val!(is_like_windows);
diff --git a/src/librustc_back/target/openbsd_base.rs b/src/librustc_back/target/openbsd_base.rs
index 90e6631841bef..1f74170e39989 100644
--- a/src/librustc_back/target/openbsd_base.rs
+++ b/src/librustc_back/target/openbsd_base.rs
@@ -17,6 +17,7 @@ pub fn opts() -> TargetOptions {
         executables: true,
         linker_is_gnu: true,
         has_rpath: true,
+        is_like_openbsd: true,
         pre_link_args: vec![
             // GNU-style linkers will use this to omit linking to libraries
             // which don't actually fulfill any relocations, but only for
diff --git a/src/librustc_trans/cabi_x86.rs b/src/librustc_trans/cabi_x86.rs
index 5377b49a2b441..ce85234f2034a 100644
--- a/src/librustc_trans/cabi_x86.rs
+++ b/src/librustc_trans/cabi_x86.rs
@@ -25,7 +25,8 @@ pub fn compute_abi_info(ccx: &CrateContext, fty: &mut FnType) {
             // http://www.angelcode.com/dev/callconv/callconv.html
             // Clang's ABI handling is in lib/CodeGen/TargetInfo.cpp
             let t = &ccx.sess().target.target;
-            if t.options.is_like_osx || t.options.is_like_windows {
+            if t.options.is_like_osx || t.options.is_like_windows
+                || t.options.is_like_openbsd {
                 match llsize_of_alloc(ccx, fty.ret.ty) {
                     1 => fty.ret.cast = Some(Type::i8(ccx)),
                     2 => fty.ret.cast = Some(Type::i16(ccx)),