diff --git a/briar-android/assets/tor-arm-pie.zip b/briar-android/assets/tor-arm-pie.zip
new file mode 100644
index 0000000000000000000000000000000000000000..29640aac9633d2611e900cb56ba6f53c5ad325f0
Binary files /dev/null and b/briar-android/assets/tor-arm-pie.zip differ
diff --git a/briar-android/assets/tor-arm.zip b/briar-android/assets/tor-arm.zip
new file mode 100644
index 0000000000000000000000000000000000000000..e7021a994dc3324fe87ed43110031c7a2b8a381a
Binary files /dev/null and b/briar-android/assets/tor-arm.zip differ
diff --git a/briar-android/assets/tor-pie.zip b/briar-android/assets/tor-pie.zip
deleted file mode 100644
index bee73641b80856b963141800f1f46f465fb2595b..0000000000000000000000000000000000000000
Binary files a/briar-android/assets/tor-pie.zip and /dev/null differ
diff --git a/briar-android/assets/tor-x86-pie.zip b/briar-android/assets/tor-x86-pie.zip
new file mode 100644
index 0000000000000000000000000000000000000000..31f0d948808f1ce99d1727f7d797f290808cac3a
Binary files /dev/null and b/briar-android/assets/tor-x86-pie.zip differ
diff --git a/briar-android/assets/tor-x86.zip b/briar-android/assets/tor-x86.zip
new file mode 100644
index 0000000000000000000000000000000000000000..a644759a89ba964a8e6d522d84efeeba897742b6
Binary files /dev/null and b/briar-android/assets/tor-x86.zip differ
diff --git a/briar-android/assets/tor.zip b/briar-android/assets/tor.zip
deleted file mode 100644
index 315d08366b1b7dbf097aa31e3d9032800ea8a7d4..0000000000000000000000000000000000000000
Binary files a/briar-android/assets/tor.zip and /dev/null differ
diff --git a/briar-android/src/org/briarproject/android/CrashReportActivity.java b/briar-android/src/org/briarproject/android/CrashReportActivity.java
index 769229d43b801280aaaeba687a43f451b3ec14d3..9a8bc73b6e87ac39592982b3835b75d95a68d3d8 100644
--- a/briar-android/src/org/briarproject/android/CrashReportActivity.java
+++ b/briar-android/src/org/briarproject/android/CrashReportActivity.java
@@ -27,6 +27,7 @@ import java.io.IOException;
 import java.io.PrintStream;
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
+import java.util.Collection;
 import java.util.Collections;
 import java.util.LinkedHashMap;
 import java.util.Map;
@@ -38,6 +39,7 @@ import java.util.logging.Logger;
 import java.util.regex.Pattern;
 
 import org.briarproject.R;
+import org.briarproject.android.util.AndroidUtils;
 import org.briarproject.android.util.HorizontalBorder;
 import org.briarproject.android.util.LayoutUtils;
 import org.briarproject.android.util.ListLoadingProgressBar;
@@ -181,7 +183,6 @@ public class CrashReportActivity extends Activity implements OnClickListener {
 
 	// FIXME: Load strings from resources if we're keeping this activity
 	@SuppressLint("NewApi")
-	@SuppressWarnings("deprecation")
 	private Map<String, String> getStatusMap() {
 		Map<String, String> statusMap = new LinkedHashMap<String, String>();
 
@@ -202,19 +203,9 @@ public class CrashReportActivity extends Activity implements OnClickListener {
 		statusMap.put("Android version:", release + " (" + sdk + ")");
 
 		// CPU architectures
-		String arch = null;
-		if(Build.VERSION.SDK_INT >= 21) {
-			for(String abi : Build.SUPPORTED_ABIS) {
-				if(arch == null) arch = abi;
-				else arch = arch + ", " + abi;
-			}
-		} else if(Build.VERSION.SDK_INT >= 8) {
-			if(Build.CPU_ABI2 == null) arch = Build.CPU_ABI;
-			else arch = Build.CPU_ABI + ", " + Build.CPU_ABI2;
-		} else {
-			arch = Build.CPU_ABI;
-		}
-		statusMap.put("Architecture:", arch);
+		Collection<String> abis = AndroidUtils.getSupportedArchitectures();
+		String joined = StringUtils.join(abis, ", ");
+		statusMap.put("Architecture:", joined);
 
 		// System memory
 		Object o = getSystemService(ACTIVITY_SERVICE);
diff --git a/briar-android/src/org/briarproject/android/TestingActivity.java b/briar-android/src/org/briarproject/android/TestingActivity.java
index 1a0acb6bd9bb190c9bba73b37dc9001ec6507751..72ef2ab63bf6949299c892807fd6ad4b47901391 100644
--- a/briar-android/src/org/briarproject/android/TestingActivity.java
+++ b/briar-android/src/org/briarproject/android/TestingActivity.java
@@ -26,6 +26,7 @@ import java.io.IOException;
 import java.io.PrintStream;
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
+import java.util.Collection;
 import java.util.Collections;
 import java.util.LinkedHashMap;
 import java.util.Map;
@@ -39,6 +40,7 @@ import java.util.regex.Pattern;
 import javax.inject.Inject;
 
 import org.briarproject.R;
+import org.briarproject.android.util.AndroidUtils;
 import org.briarproject.android.util.ElasticHorizontalSpace;
 import org.briarproject.android.util.HorizontalBorder;
 import org.briarproject.android.util.LayoutUtils;
@@ -192,7 +194,6 @@ public class TestingActivity extends BriarActivity implements OnClickListener {
 
 	// FIXME: Load strings from resources if we're keeping this activity
 	@SuppressLint("NewApi")
-	@SuppressWarnings("deprecation")
 	private Map<String, String> getStatusMap() {
 		Map<String, String> statusMap = new LinkedHashMap<String, String>();
 
@@ -212,18 +213,10 @@ public class TestingActivity extends BriarActivity implements OnClickListener {
 		int sdk = Build.VERSION.SDK_INT;
 		statusMap.put("Android version:", release + " (" + sdk + ")");
 
-		// CPU architecture
-		String arch = null;
-		if(Build.VERSION.SDK_INT >= 21) {
-			for(String abi : Build.SUPPORTED_ABIS) {
-				if(arch == null) arch = abi;
-				else arch = arch + ", " + abi;
-			}
-		} else {
-			if(Build.CPU_ABI2 == null) arch = Build.CPU_ABI;
-			else arch = Build.CPU_ABI + ", " + Build.CPU_ABI2;
-		}
-		statusMap.put("Architecture:", arch);
+		// CPU architectures
+		Collection<String> abis = AndroidUtils.getSupportedArchitectures();
+		String joined = StringUtils.join(abis, ", ");
+		statusMap.put("Architecture:", joined);
 
 		// System memory
 		Object o = getSystemService(ACTIVITY_SERVICE);
diff --git a/briar-android/src/org/briarproject/android/util/AndroidUtils.java b/briar-android/src/org/briarproject/android/util/AndroidUtils.java
new file mode 100644
index 0000000000000000000000000000000000000000..64e39aee221af447004d279436025c99487f650a
--- /dev/null
+++ b/briar-android/src/org/briarproject/android/util/AndroidUtils.java
@@ -0,0 +1,27 @@
+package org.briarproject.android.util;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+
+import android.annotation.SuppressLint;
+import android.os.Build;
+
+public class AndroidUtils {
+
+	@SuppressLint("NewApi")
+	@SuppressWarnings("deprecation")
+	public static Collection<String> getSupportedArchitectures() {
+		List<String> abis = new ArrayList<String>();
+		if(Build.VERSION.SDK_INT >= 21) {
+			for(String abi : Build.SUPPORTED_ABIS) abis.add(abi);
+		} else if(Build.VERSION.SDK_INT >= 8) {
+			abis.add(Build.CPU_ABI);
+			if(Build.CPU_ABI2 != null) abis.add(Build.CPU_ABI2);
+		} else {
+			abis.add(Build.CPU_ABI);
+		}
+		return Collections.unmodifiableList(abis);
+	}
+}
diff --git a/briar-android/src/org/briarproject/plugins/tor/TorPlugin.java b/briar-android/src/org/briarproject/plugins/tor/TorPlugin.java
index 4aa1b43e689674e60af6d41e600d7ca943825935..264f2ee99232e22aa1f80cb84b7bb0f748a6f94d 100644
--- a/briar-android/src/org/briarproject/plugins/tor/TorPlugin.java
+++ b/briar-android/src/org/briarproject/plugins/tor/TorPlugin.java
@@ -75,6 +75,7 @@ class TorPlugin implements DuplexPlugin, EventHandler {
 	private final Context appContext;
 	private final LocationUtils locationUtils;
 	private final DuplexPluginCallback callback;
+	private final String architecture;
 	private final int maxLatency, maxIdleTime, pollingInterval, socketTimeout;
 	private final File torDirectory, torFile, geoIpFile, configFile, doneFile;
 	private final File cookieFile, hostnameFile;
@@ -89,11 +90,13 @@ class TorPlugin implements DuplexPlugin, EventHandler {
 
 	TorPlugin(Executor ioExecutor, Context appContext,
 			LocationUtils locationUtils, DuplexPluginCallback callback,
-			int maxLatency, int maxIdleTime, int pollingInterval) {
+			String architecture, int maxLatency, int maxIdleTime,
+			int pollingInterval) {
 		this.ioExecutor = ioExecutor;
 		this.appContext = appContext;
 		this.locationUtils = locationUtils;
 		this.callback = callback;
+		this.architecture = architecture;
 		this.maxLatency = maxLatency;
 		this.maxIdleTime = maxIdleTime;
 		this.pollingInterval = pollingInterval;
@@ -266,14 +269,9 @@ class TorPlugin implements DuplexPlugin, EventHandler {
 	}
 
 	private InputStream getTorInputStream() throws IOException {
-		String filename;
-		if(Build.VERSION.SDK_INT >= 16) {
-			LOG.info("Installing PIE Tor binary");
-			filename = "tor-pie.zip";
-		} else {
-			LOG.info("Installing non-PIE Tor binary");
-			filename = "tor.zip";
-		}
+		if(LOG.isLoggable(INFO))
+			LOG.info("Installing Tor binary for " + architecture);
+		String filename = "tor-" + architecture + ".zip";
 		InputStream in = appContext.getResources().getAssets().open(filename);
 		ZipInputStream zin = new ZipInputStream(in);
 		if(zin.getNextEntry() == null) throw new IOException();
diff --git a/briar-android/src/org/briarproject/plugins/tor/TorPluginFactory.java b/briar-android/src/org/briarproject/plugins/tor/TorPluginFactory.java
index 9c49b389cab941b7d607b4a0ff3cad447df35c55..32f351012acc4a7b5fb098d9d16cbab90a987443 100644
--- a/briar-android/src/org/briarproject/plugins/tor/TorPluginFactory.java
+++ b/briar-android/src/org/briarproject/plugins/tor/TorPluginFactory.java
@@ -1,17 +1,15 @@
 package org.briarproject.plugins.tor;
 
-import java.util.ArrayList;
-import java.util.List;
 import java.util.concurrent.Executor;
 import java.util.logging.Logger;
 
+import org.briarproject.android.util.AndroidUtils;
 import org.briarproject.api.TransportId;
 import org.briarproject.api.plugins.duplex.DuplexPlugin;
 import org.briarproject.api.plugins.duplex.DuplexPluginCallback;
 import org.briarproject.api.plugins.duplex.DuplexPluginFactory;
 import org.briarproject.api.system.LocationUtils;
 
-import android.annotation.SuppressLint;
 import android.content.Context;
 import android.os.Build;
 
@@ -39,26 +37,25 @@ public class TorPluginFactory implements DuplexPluginFactory {
 		return TorPlugin.ID;
 	}
 
-	@SuppressLint("NewApi")
-	@SuppressWarnings("deprecation")
 	public DuplexPlugin createPlugin(DuplexPluginCallback callback) {
 		// Check that we have a Tor binary for this architecture
-		List<String> abis = new ArrayList<String>();
-		if(Build.VERSION.SDK_INT >= 21) {
-			for(String abi : Build.SUPPORTED_ABIS) abis.add(abi);
-		} else if(Build.VERSION.SDK_INT >= 8) {
-			abis.add(Build.CPU_ABI);
-			if(Build.CPU_ABI2 != null) abis.add(Build.CPU_ABI2);
-		} else {
-			abis.add(Build.CPU_ABI);
+		String architecture = null;
+		for(String abi : AndroidUtils.getSupportedArchitectures()) {
+			if(abi.startsWith("x86")) {
+				architecture = "x86";
+				break;
+			} else if(abi.startsWith("armeabi")) {
+				architecture = "arm";
+				break;
+			}
 		}
-		boolean supported = false;
-		for(String abi : abis) if(abi.startsWith("armeabi")) supported = true;
-		if(!supported) {
+		if(architecture == null) {
 			LOG.info("Tor is not supported on this architecture");
 			return null;
 		}
+		// Use position-independent executable for SDK >= 16
+		if(Build.VERSION.SDK_INT >= 16) architecture += "-pie";
 		return new TorPlugin(ioExecutor,appContext, locationUtils, callback,
-				MAX_LATENCY, MAX_IDLE_TIME, POLLING_INTERVAL);
+				architecture, MAX_LATENCY, MAX_IDLE_TIME, POLLING_INTERVAL);
 	}
 }
diff --git a/briar-core/src/org/briarproject/util/StringUtils.java b/briar-core/src/org/briarproject/util/StringUtils.java
index 2da9fa7f895e7e47356b9564f5bde030cd6ddd35..c8dd0e1513f60555440df404d369a723c7a24002 100644
--- a/briar-core/src/org/briarproject/util/StringUtils.java
+++ b/briar-core/src/org/briarproject/util/StringUtils.java
@@ -1,6 +1,7 @@
 package org.briarproject.util;
 
 import java.io.UnsupportedEncodingException;
+import java.util.Collection;
 
 public class StringUtils {
 
@@ -13,6 +14,15 @@ public class StringUtils {
 		return s == null || s.length() == 0;
 	}
 
+	public static String join(Collection<String> strings, String separator) {
+		StringBuilder joined = new StringBuilder();
+		for(String s : strings) {
+			if(joined.length() > 0) joined.append(separator);
+			joined.append(s);
+		}
+		return joined.toString();
+	}
+
 	public static byte[] toUtf8(String s) {
 		try {
 			return s.getBytes("UTF-8");