diff --git a/libc/Android.mk b/libc/Android.mk
index f685565d6..4f8debd84 100644
--- a/libc/Android.mk
+++ b/libc/Android.mk
@@ -80,11 +80,9 @@ libc_common_src_files := \
 	bionic/err.c \
 	bionic/ether_aton.c \
 	bionic/ether_ntoa.c \
-	bionic/fcntl.c \
 	bionic/fdprintf.c \
 	bionic/flockfile.c \
 	bionic/fork.c \
-	bionic/fstatfs.c \
 	bionic/ftime.c \
 	bionic/ftok.c \
 	bionic/fts.c \
@@ -133,9 +131,7 @@ libc_common_src_files := \
 	bionic/signal.c \
 	bionic/signame.c \
 	bionic/sigsetmask.c \
-	bionic/sigsuspend.c \
 	bionic/sleep.c \
-	bionic/statfs.c \
 	bionic/strndup.c \
 	bionic/strntoimax.c \
 	bionic/strntoumax.c \
@@ -180,6 +176,16 @@ libc_common_src_files := \
 	netbsd/nameser/ns_print.c \
 	netbsd/nameser/ns_samedomain.c \
 
+# These are shared by all the 32-bit targets, but not the 64-bit ones.
+ifeq ($(TARGET_ARCH),$(filter $(TARGET_ARCH),arm mips x86))
+libc_common_src_files += \
+    bionic/fcntl.c \
+    bionic/fstatfs.c \
+    bionic/sigsuspend.c \
+    bionic/statfs.c \
+
+endif
+
 # Fortify implementations of libc functions.
 libc_common_src_files += \
     bionic/__fgets_chk.cpp \
@@ -214,7 +220,6 @@ libc_bionic_src_files := \
     bionic/libc_init_common.cpp \
     bionic/libc_logging.cpp \
     bionic/libgen.cpp \
-    bionic/mmap.cpp \
     bionic/pthread_attr.cpp \
     bionic/pthread_detach.cpp \
     bionic/pthread_equal.cpp \
@@ -246,6 +251,13 @@ libc_bionic_src_files := \
     bionic/wait.cpp \
     bionic/wchar.cpp \
 
+# These are shared by all the 32-bit targets, but not the 64-bit ones.
+ifeq ($(TARGET_ARCH),$(filter $(TARGET_ARCH),arm mips x86))
+libc_bionic_src_files += \
+    bionic/mmap.cpp \
+
+endif
+
 libc_tzcode_src_files := \
     tzcode/asctime.c \
     tzcode/difftime.c \
@@ -360,39 +372,41 @@ libc_upstream_netbsd_src_files := \
     upstream-netbsd/libc/string/strxfrm.c \
     upstream-netbsd/libc/unistd/killpg.c \
 
+
 # Architecture specific source files go here
 # =========================================================
 ifeq ($(TARGET_ARCH),arm)
 libc_common_src_files += \
-	bionic/memmove.c.arm \
-	string/bcopy.c \
-	string/strncmp.c \
-	string/strncat.c \
-	string/strncpy.c \
-	bionic/strchr.cpp \
-	string/strrchr.c \
 	bionic/memchr.c \
+	bionic/memmove.c.arm \
 	bionic/memrchr.c \
-	string/index.c \
+	bionic/strchr.cpp \
 	bionic/strnlen.c \
+	string/bcopy.c \
+	string/index.c \
 	string/strlcat.c \
 	string/strlcpy.c \
+	string/strncat.c \
+	string/strncmp.c \
+	string/strncpy.c \
+	string/strrchr.c \
+	upstream-freebsd/lib/libc/string/wcscat.c \
 	upstream-freebsd/lib/libc/string/wcschr.c \
-	upstream-freebsd/lib/libc/string/wcsrchr.c \
 	upstream-freebsd/lib/libc/string/wcscmp.c \
 	upstream-freebsd/lib/libc/string/wcscpy.c \
-	upstream-freebsd/lib/libc/string/wmemcmp.c \
 	upstream-freebsd/lib/libc/string/wcslen.c \
-	upstream-freebsd/lib/libc/string/wcscat.c
+	upstream-freebsd/lib/libc/string/wcsrchr.c \
+	upstream-freebsd/lib/libc/string/wmemcmp.c \
 
 # These files need to be arm so that gdbserver
 # can set breakpoints in them without messing
 # up any thumb code.
+# TODO: is this actually necessary?
 libc_common_src_files += \
-	bionic/pthread-atfork.c.arm \
-	bionic/pthread-rwlocks.c.arm \
-	bionic/pthread-timers.c.arm \
-	bionic/ptrace.c.arm
+    bionic/pthread-atfork.c.arm \
+    bionic/pthread-rwlocks.c.arm \
+    bionic/pthread-timers.c.arm \
+    bionic/ptrace.c.arm \
 
 libc_static_common_src_files += \
     bionic/pthread.c.arm \
@@ -415,31 +429,72 @@ libc_static_common_src_files += \
 
 endif # x86
 
+ifeq ($(TARGET_ARCH),$(filter $(TARGET_ARCH),x86_64))
+libc_common_src_files += \
+    bionic/memchr.c \
+    bionic/memcmp.c \
+    bionic/memcpy.c \
+    bionic/memmove.c \
+    bionic/memrchr.c \
+    bionic/memset.c \
+    bionic/pthread-atfork.c \
+    bionic/pthread-rwlocks.c \
+    bionic/pthread-timers.c \
+    bionic/ptrace.c \
+    bionic/strchr.cpp \
+    bionic/strnlen.c \
+    string/bcopy.c \
+    string/index.c \
+    string/strcat.c \
+    string/strcmp.c \
+    string/strcpy.c \
+    string/strlcat.c \
+    string/strlcpy.c \
+    string/strlen.c \
+    string/strncat.c \
+    string/strncmp.c \
+    string/strncpy.c \
+    string/strrchr.c \
+    upstream-freebsd/lib/libc/string/wcscat.c \
+    upstream-freebsd/lib/libc/string/wcschr.c \
+    upstream-freebsd/lib/libc/string/wcscmp.c \
+    upstream-freebsd/lib/libc/string/wcscpy.c \
+    upstream-freebsd/lib/libc/string/wcslen.c \
+    upstream-freebsd/lib/libc/string/wcsrchr.c \
+    upstream-freebsd/lib/libc/string/wmemcmp.c \
+
+libc_static_common_src_files += \
+    bionic/pthread.c \
+    bionic/pthread_create.cpp \
+    bionic/pthread_key.cpp \
+
+endif # x86_64
+
 ifeq ($(TARGET_ARCH),mips)
 libc_common_src_files += \
+	bionic/memchr.c \
 	bionic/memcmp.c \
+	bionic/memrchr.c \
+	bionic/strchr.cpp \
+	bionic/strnlen.c \
 	string/bcopy.c \
+	string/index.c \
+	string/strcat.c \
 	string/strcmp.c \
 	string/strcpy.c \
-	string/strncmp.c \
-	string/strcat.c \
-	string/strncat.c \
-	string/strncpy.c \
-	bionic/strchr.cpp \
-	string/strrchr.c \
-	bionic/memchr.c \
-	bionic/memrchr.c \
-	string/index.c \
-	bionic/strnlen.c \
 	string/strlcat.c \
 	string/strlcpy.c \
+	string/strncat.c \
+	string/strncmp.c \
+	string/strncpy.c \
+	string/strrchr.c \
+	upstream-freebsd/lib/libc/string/wcscat.c
 	upstream-freebsd/lib/libc/string/wcschr.c \
-	upstream-freebsd/lib/libc/string/wcsrchr.c \
 	upstream-freebsd/lib/libc/string/wcscmp.c \
 	upstream-freebsd/lib/libc/string/wcscpy.c \
-	upstream-freebsd/lib/libc/string/wmemcmp.c \
 	upstream-freebsd/lib/libc/string/wcslen.c \
-	upstream-freebsd/lib/libc/string/wcscat.c
+	upstream-freebsd/lib/libc/string/wcsrchr.c \
+	upstream-freebsd/lib/libc/string/wmemcmp.c \
 
 libc_common_src_files += \
 	bionic/pthread-atfork.c \
@@ -516,16 +571,23 @@ ifeq ($(TARGET_ARCH),arm)
 endif # !arm
 
 ifeq ($(TARGET_ARCH),x86)
-  libc_common_cflags += -DSOFTFLOAT
   libc_crt_target_cflags := -m32
   libc_crt_target_ldflags := -melf_i386
+endif
+ifeq ($(TARGET_ARCH),x86_64)
+  libc_crt_target_cflags := -m64
+  libc_crt_target_ldflags := -melf_x86_64
+endif
+
+ifeq ($(TARGET_ARCH),$(filter $(TARGET_ARCH),x86 x86_64))
+  libc_common_cflags += -DSOFTFLOAT
   ifeq ($(ARCH_X86_HAVE_SSE2),true)
       libc_crt_target_cflags += -DUSE_SSE2=1
   endif
   ifeq ($(ARCH_X86_HAVE_SSSE3),true)
       libc_crt_target_cflags += -DUSE_SSSE3=1
   endif
-endif # x86
+endif
 
 ifeq ($(TARGET_ARCH),mips)
   ifneq ($(ARCH_MIPS_HAS_FPU),true)
@@ -581,7 +643,7 @@ endif
 ifeq ($(TARGET_ARCH),mips)
     libc_crt_target_so_cflags := -fPIC
 endif
-ifeq ($(TARGET_ARCH),x86)
+ifeq ($(TARGET_ARCH),$(filter $(TARGET_ARCH),x86 x86_64))
     libc_crt_target_so_cflags := -fPIC
 endif
 libc_crt_target_so_cflags += $(libc_crt_target_cflags)
diff --git a/libc/arch-x86_64/x86_64.mk b/libc/arch-x86_64/x86_64.mk
new file mode 100644
index 000000000..6a2bb9c4f
--- /dev/null
+++ b/libc/arch-x86_64/x86_64.mk
@@ -0,0 +1,19 @@
+_LIBC_ARCH_COMMON_SRC_FILES := \
+    arch-x86_64/bionic/__get_sp.S \
+    arch-x86_64/bionic/__get_tls.c \
+    arch-x86_64/bionic/__set_tls.c \
+    arch-x86_64/bionic/clone.S \
+    arch-x86_64/bionic/_exit_with_stack_teardown.S \
+    arch-x86_64/bionic/futex_x86_64.S \
+    arch-x86_64/bionic/setjmp.S \
+    arch-x86_64/bionic/_setjmp.S \
+    arch-x86_64/bionic/sigsetjmp.S \
+    arch-x86_64/bionic/syscall.S \
+    arch-x86_64/bionic/sigprocmask.c \
+    arch-x86_64/bionic/sigaction.c \
+    arch-x86_64/bionic/sigsuspend.c \
+
+_LIBC_ARCH_STATIC_SRC_FILES := \
+    bionic/dl_iterate_phdr_static.c \
+
+_LIBC_ARCH_DYNAMIC_SRC_FILES :=
diff --git a/libdl/Android.mk b/libdl/Android.mk
index e6c6bf4b4..9d1e1e0af 100644
--- a/libdl/Android.mk
+++ b/libdl/Android.mk
@@ -18,7 +18,7 @@ include $(CLEAR_VARS)
 LOCAL_LDFLAGS := -Wl,--exclude-libs=libgcc.a
 
 # for x86, exclude libgcc_eh.a for the same reasons as above
-ifeq ($(TARGET_ARCH),x86)
+ifeq ($(TARGET_ARCH),$(filter $(TARGET_ARCH),x86 x86_64))
 LOCAL_LDFLAGS += -Wl,--exclude-libs=libgcc_eh.a
 endif