Skip to content

Commit

Permalink
Implement Marshmallow sysdpes getSupportedAbis to avoid read /proc/se…
Browse files Browse the repository at this point in the history
…lf/exe error on Android M+

Summary:
We can't guarantee we have permission to access `/proc/self/exe`.  `Os.readlink("/proc/self/exe").contains("64")` is not a perfect way to check is64bit.

On Android M, there's a public API to check 64bit. [Process#is64Bit()](https://developer.android.com/reference/android/os/Process#is64Bit())

Differential Revision: D20130485

fbshipit-source-id: f287285056214831d3777255010932d9c7259595
  • Loading branch information
simpleton authored and facebook-github-bot committed Feb 28, 2020
1 parent 3311e1a commit c796ed6
Showing 1 changed file with 36 additions and 3 deletions.
39 changes: 36 additions & 3 deletions java/com/facebook/soloader/SysUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -73,10 +73,12 @@ public static void deleteOrThrow(File file) throws IOException {
* @return Ordered array of supported ABIs
*/
public static String[] getSupportedAbis() {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
return new String[] {Build.CPU_ABI, Build.CPU_ABI2};
} else {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
return MarshmallowSysdeps.getSupportedAbis();
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
return LollipopSysdeps.getSupportedAbis();
} else {
return new String[] {Build.CPU_ABI, Build.CPU_ABI2};
}
}

Expand Down Expand Up @@ -187,6 +189,37 @@ public static boolean is64Bit() throws ErrnoException {
@TargetApi(Build.VERSION_CODES.M)
@DoNotOptimize
private static final class MarshmallowSysdeps {
@DoNotOptimize
public static String[] getSupportedAbis() {
String[] supportedAbis = Build.SUPPORTED_ABIS;
TreeSet<String> allowedAbis = new TreeSet<>();
// 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 (is64Bit()) {
allowedAbis.add(MinElf.ISA.AARCH64.toString());
allowedAbis.add(MinElf.ISA.X86_64.toString());
} else {
allowedAbis.add(MinElf.ISA.ARM.toString());
allowedAbis.add(MinElf.ISA.X86.toString());
}
// 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
public static boolean is64Bit() {
return android.os.Process.is64Bit();
Expand Down

0 comments on commit c796ed6

Please sign in to comment.