Skip to content

Commit

Permalink
Filter out incompatible ABIs but do not reorder the list
Browse files Browse the repository at this point in the history
Summary:
This logic is supposed to filter out absolutely incompatible ABIs from the list
given by `Build.SUPPORTED_ABIS`. This is particularly a problem on Oppo phones
where 64-bit-capable devices (as reported in SUPPORTED_ABIS) launch 32-bit
processes.

However, this logic also ended up reordering the list. In particular, if both
`armeabi-v7a` and `x86` were in the list, it would always reorder `armeabi-v7a`
first. This is incorrect on devices with houdini-like capabilities, like the
Android Pie Google APIs emulator image.

This diff preserves the filtering logic but removes the reordering.

This addresses one incarnation of Issue #55.

Reviewed By: oprisnik

Differential Revision: D19506390

fbshipit-source-id: 224155605fde7853227a57ea5b21a4e23ecdd972
  • Loading branch information
Delyan Kratunov authored and facebook-github-bot committed Jan 22, 2020
1 parent b6854af commit 20198bf
Showing 1 changed file with 26 additions and 27 deletions.
53 changes: 26 additions & 27 deletions java/com/facebook/soloader/SysUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
import java.io.RandomAccessFile;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.TreeSet;

public final class SysUtil {

Expand Down Expand Up @@ -127,42 +127,41 @@ private static final class LollipopSysdeps {
@DoNotOptimize
public static String[] getSupportedAbis() {
String[] supportedAbis = Build.SUPPORTED_ABIS;
ArrayList<String> priorAbis = new ArrayList<>();
TreeSet<String> allowedAbis = new TreeSet<>();
try {
// SoLoader will give first rank to arm64-v8a & x86_64, if current process is app_process64.
// Otherwise(means current process is app_process32), give first rank to armeabi-v7a & x86.
// Some devices report both 64-bit and 32-bit ABIs but *actually* run
// the process in 32-bit mode.
//
// Determine the current process bitness and use that to filter
// out incompatible ABIs from SUPPORTED_ABIS.
if (Os.readlink("/proc/self/exe").contains("64")) {
priorAbis.add(MinElf.ISA.AARCH64.toString());
priorAbis.add(MinElf.ISA.X86_64.toString());
allowedAbis.add(MinElf.ISA.AARCH64.toString());
allowedAbis.add(MinElf.ISA.X86_64.toString());
} else {
priorAbis.add(MinElf.ISA.ARM.toString());
priorAbis.add(MinElf.ISA.X86.toString());
allowedAbis.add(MinElf.ISA.ARM.toString());
allowedAbis.add(MinElf.ISA.X86.toString());
}
} catch (ErrnoException e) {
Log.e(
TAG,
String.format(
"Could not read /proc/self/exe. Falling back to default ABI list. errno: %d Err msg: %s",
e.errno, e.getMessage()));
"Could not read /proc/self/exe. Falling back to default ABI list: %s. errno: %d Err msg: %s",
Arrays.toString(supportedAbis), e.errno, e.getMessage()));
return Build.SUPPORTED_ABIS;
}
final ArrayList<String> finalPriorAbis = priorAbis;
// Reorder supported ABIs based on preferred ABIs for the current process.
Arrays.sort(
supportedAbis,
new Comparator<String>() {
@Override
public int compare(String o1, String o2) {
if (finalPriorAbis.contains(o1)) {
return -1;
} else if (finalPriorAbis.contains(o2)) {
return 1;
} else {
return 0;
}
}
});
return supportedAbis;
// Filter out the incompatible ABIs from the list of supported ABIs,
// retaining the original order.
ArrayList<String> compatibleSupportedAbis = new ArrayList<>();
for (String abi : supportedAbis) {
if (allowedAbis.contains(abi)) {
compatibleSupportedAbis.add(abi);
}
}

String[] finalAbis = new String[compatibleSupportedAbis.size()];
finalAbis = compatibleSupportedAbis.toArray(finalAbis);

return finalAbis;
}

@DoNotOptimize
Expand Down

0 comments on commit 20198bf

Please sign in to comment.