diff --git a/src/fn_call.rs b/src/fn_call.rs
index d2149ee5db..8105330b32 100644
--- a/src/fn_call.rs
+++ b/src/fn_call.rs
@@ -3,7 +3,6 @@ use rustc::ty::layout::{self, Align, LayoutOf, Size};
 use rustc::hir::def_id::{DefId, CRATE_DEF_INDEX};
 use rustc::mir;
 use rustc_data_structures::indexed_vec::Idx;
-use rustc_target::spec::abi::Abi;
 use syntax::attr;
 use syntax::codemap::Span;
 
@@ -60,7 +59,7 @@ fn write_discriminant_value<'a, 'mir, 'tcx: 'a + 'mir>(
     }
 
 pub trait EvalContextExt<'tcx> {
-    fn call_c_abi(
+    fn call_foreign_item(
         &mut self,
         def_id: DefId,
         args: &[ValTy<'tcx>],
@@ -105,9 +104,6 @@ impl<'a, 'mir, 'tcx: 'mir + 'a> EvalContextExt<'tcx> for EvalContext<'a, 'mir, '
 
         let def_id = instance.def_id();
         let item_path = self.tcx.absolute_item_path_str(def_id);
-        if item_path.starts_with("std::") {
-            //println!("{}", item_path);
-        }
         match &*item_path {
             "std::sys::unix::thread::guard::init" | "std::sys::unix::thread::guard::current" => {
                 // Return None, as it doesn't make sense to return Some, because miri detects stack overflow itself.
@@ -178,7 +174,7 @@ impl<'a, 'mir, 'tcx: 'mir + 'a> EvalContextExt<'tcx> for EvalContext<'a, 'mir, '
         Ok(false)
     }
 
-    fn call_c_abi(
+    fn call_foreign_item(
         &mut self,
         def_id: DefId,
         args: &[ValTy<'tcx>],
@@ -215,6 +211,73 @@ impl<'a, 'mir, 'tcx: 'mir + 'a> EvalContextExt<'tcx> for EvalContext<'a, 'mir, '
                 }
             }
 
+            "__rust_alloc" => {
+                let size = self.value_to_scalar(args[0])?.to_usize(self)?;
+                let align = self.value_to_scalar(args[1])?.to_usize(self)?;
+                if size == 0 {
+                    return err!(HeapAllocZeroBytes);
+                }
+                if !align.is_power_of_two() {
+                    return err!(HeapAllocNonPowerOfTwoAlignment(align));
+                }
+                let ptr = self.memory.allocate(Size::from_bytes(size),
+                                               Align::from_bytes(align, align).unwrap(),
+                                               MemoryKind::Rust.into())?;
+                self.write_scalar(dest, Scalar::Ptr(ptr), dest_ty)?;
+            }
+            "__rust_alloc_zeroed" => {
+                let size = self.value_to_scalar(args[0])?.to_usize(self)?;
+                let align = self.value_to_scalar(args[1])?.to_usize(self)?;
+                if size == 0 {
+                    return err!(HeapAllocZeroBytes);
+                }
+                if !align.is_power_of_two() {
+                    return err!(HeapAllocNonPowerOfTwoAlignment(align));
+                }
+                let ptr = self.memory.allocate(Size::from_bytes(size),
+                                               Align::from_bytes(align, align).unwrap(),
+                                               MemoryKind::Rust.into())?;
+                self.memory.write_repeat(ptr.into(), 0, Size::from_bytes(size))?;
+                self.write_scalar(dest, Scalar::Ptr(ptr), dest_ty)?;
+            }
+            "__rust_dealloc" => {
+                let ptr = self.into_ptr(args[0].value)?.to_ptr()?;
+                let old_size = self.value_to_scalar(args[1])?.to_usize(self)?;
+                let align = self.value_to_scalar(args[2])?.to_usize(self)?;
+                if old_size == 0 {
+                    return err!(HeapAllocZeroBytes);
+                }
+                if !align.is_power_of_two() {
+                    return err!(HeapAllocNonPowerOfTwoAlignment(align));
+                }
+                self.memory.deallocate(
+                    ptr,
+                    Some((Size::from_bytes(old_size), Align::from_bytes(align, align).unwrap())),
+                    MemoryKind::Rust.into(),
+                )?;
+            }
+            "__rust_realloc" => {
+                let ptr = self.into_ptr(args[0].value)?.to_ptr()?;
+                let old_size = self.value_to_scalar(args[1])?.to_usize(self)?;
+                let align = self.value_to_scalar(args[2])?.to_usize(self)?;
+                let new_size = self.value_to_scalar(args[3])?.to_usize(self)?;
+                if old_size == 0 || new_size == 0 {
+                    return err!(HeapAllocZeroBytes);
+                }
+                if !align.is_power_of_two() {
+                    return err!(HeapAllocNonPowerOfTwoAlignment(align));
+                }
+                let new_ptr = self.memory.reallocate(
+                    ptr,
+                    Size::from_bytes(old_size),
+                    Align::from_bytes(align, align).unwrap(),
+                    Size::from_bytes(new_size),
+                    Align::from_bytes(align, align).unwrap(),
+                    MemoryKind::Rust.into(),
+                )?;
+                self.write_scalar(dest, Scalar::Ptr(new_ptr), dest_ty)?;
+            }
+
             "syscall" => {
                 // TODO: read `syscall` ids like `sysconf` ids and
                 // figure out some way to actually process some of them
@@ -559,9 +622,18 @@ impl<'a, 'mir, 'tcx: 'mir + 'a> EvalContextExt<'tcx> for EvalContext<'a, 'mir, '
                 self.write_ptr(dest, addr, dest_ty)?;
             }
 
+            // Windows API subs
+            "AddVectoredExceptionHandler" |
+            "SetThreadStackGuarantee" => {
+                let usize = self.tcx.types.usize;
+                // any non zero value works for the stdlib. This is just used for stackoverflows anyway
+                self.write_scalar(dest, Scalar::from_u128(1), usize)?;
+            },
+
+            // We can't execute anything else
             _ => {
                 return err!(Unimplemented(
-                    format!("can't call C ABI function: {}", link_name),
+                    format!("can't call foreign function: {}", link_name),
                 ));
             }
         }
@@ -629,11 +701,11 @@ impl<'a, 'mir, 'tcx: 'mir + 'a> EvalContextExt<'tcx> for EvalContext<'a, 'mir, '
             || EvalErrorKind::NoMirFor(path.clone()),
         )?;
 
-        if sig.abi == Abi::C {
-            // An external C function
+        if self.tcx.is_foreign_item(instance.def_id()) {
+            // An external function
             // TODO: That functions actually has a similar preamble to what follows here.  May make sense to
             // unify these two mechanisms for "hooking into missing functions".
-            self.call_c_abi(
+            self.call_foreign_item(
                 instance.def_id(),
                 args,
                 dest,
@@ -644,74 +716,6 @@ impl<'a, 'mir, 'tcx: 'mir + 'a> EvalContextExt<'tcx> for EvalContext<'a, 'mir, '
         }
 
         match &path[..] {
-            // Allocators are magic.  They have no MIR, even when the rest of libstd does.
-            "alloc::alloc::::__rust_alloc" => {
-                let size = self.value_to_scalar(args[0])?.to_usize(self)?;
-                let align = self.value_to_scalar(args[1])?.to_usize(self)?;
-                if size == 0 {
-                    return err!(HeapAllocZeroBytes);
-                }
-                if !align.is_power_of_two() {
-                    return err!(HeapAllocNonPowerOfTwoAlignment(align));
-                }
-                let ptr = self.memory.allocate(Size::from_bytes(size),
-                                               Align::from_bytes(align, align).unwrap(),
-                                               MemoryKind::Rust.into())?;
-                self.write_scalar(dest, Scalar::Ptr(ptr), dest_ty)?;
-            }
-            "alloc::alloc::::__rust_alloc_zeroed" => {
-                let size = self.value_to_scalar(args[0])?.to_usize(self)?;
-                let align = self.value_to_scalar(args[1])?.to_usize(self)?;
-                if size == 0 {
-                    return err!(HeapAllocZeroBytes);
-                }
-                if !align.is_power_of_two() {
-                    return err!(HeapAllocNonPowerOfTwoAlignment(align));
-                }
-                let ptr = self.memory.allocate(Size::from_bytes(size),
-                                               Align::from_bytes(align, align).unwrap(),
-                                               MemoryKind::Rust.into())?;
-                self.memory.write_repeat(ptr.into(), 0, Size::from_bytes(size))?;
-                self.write_scalar(dest, Scalar::Ptr(ptr), dest_ty)?;
-            }
-            "alloc::alloc::::__rust_dealloc" => {
-                let ptr = self.into_ptr(args[0].value)?.to_ptr()?;
-                let old_size = self.value_to_scalar(args[1])?.to_usize(self)?;
-                let align = self.value_to_scalar(args[2])?.to_usize(self)?;
-                if old_size == 0 {
-                    return err!(HeapAllocZeroBytes);
-                }
-                if !align.is_power_of_two() {
-                    return err!(HeapAllocNonPowerOfTwoAlignment(align));
-                }
-                self.memory.deallocate(
-                    ptr,
-                    Some((Size::from_bytes(old_size), Align::from_bytes(align, align).unwrap())),
-                    MemoryKind::Rust.into(),
-                )?;
-            }
-            "alloc::alloc::::__rust_realloc" => {
-                let ptr = self.into_ptr(args[0].value)?.to_ptr()?;
-                let old_size = self.value_to_scalar(args[1])?.to_usize(self)?;
-                let align = self.value_to_scalar(args[2])?.to_usize(self)?;
-                let new_size = self.value_to_scalar(args[3])?.to_usize(self)?;
-                if old_size == 0 || new_size == 0 {
-                    return err!(HeapAllocZeroBytes);
-                }
-                if !align.is_power_of_two() {
-                    return err!(HeapAllocNonPowerOfTwoAlignment(align));
-                }
-                let new_ptr = self.memory.reallocate(
-                    ptr,
-                    Size::from_bytes(old_size),
-                    Align::from_bytes(align, align).unwrap(),
-                    Size::from_bytes(new_size),
-                    Align::from_bytes(align, align).unwrap(),
-                    MemoryKind::Rust.into(),
-                )?;
-                self.write_scalar(dest, Scalar::Ptr(new_ptr), dest_ty)?;
-            }
-
             // A Rust function is missing, which means we are running with MIR missing for libstd (or other dependencies).
             // Still, we can make many things mostly work by "emulating" or ignoring some functions.
             "std::io::_print" => {
@@ -733,12 +737,7 @@ impl<'a, 'mir, 'tcx: 'mir + 'a> EvalContextExt<'tcx> for EvalContext<'a, 'mir, '
                 let bool = self.tcx.types.bool;
                 self.write_scalar(dest, Scalar::from_bool(false), bool)?;
             }
-            "std::sys::imp::c::::AddVectoredExceptionHandler" |
-            "std::sys::imp::c::::SetThreadStackGuarantee" => {
-                let usize = self.tcx.types.usize;
-                // any non zero value works for the stdlib. This is just used for stackoverflows anyway
-                self.write_scalar(dest, Scalar::from_u128(1), usize)?;
-            },
+
             _ => return err!(NoMirFor(path)),
         }