libnativebridge: mount /system/etc/cpuinfo.<isa>.txt as /proc/cpuinfo
Bug: 179753190
Test: m
Change-Id: I0facaa0da9872d78ac40f6bde78bdc32ac07d597
diff --git a/libnativebridge/native_bridge.cc b/libnativebridge/native_bridge.cc
index b24d14a..e9b2a91 100644
--- a/libnativebridge/native_bridge.cc
+++ b/libnativebridge/native_bridge.cc
@@ -263,6 +263,65 @@
return strncmp(instruction_set, ABI_STRING, strlen(ABI_STRING) + 1) != 0;
}
+#ifndef __APPLE__
+static bool MountCpuinfo(const char* cpuinfo_path) {
+ // If the file does not exist, the mount command will fail,
+ // so we save the extra file existence check.
+ if (TEMP_FAILURE_RETRY(mount(cpuinfo_path, // Source.
+ "/proc/cpuinfo", // Target.
+ nullptr, // FS type.
+ MS_BIND, // Mount flags: bind mount.
+ nullptr)) == -1) { // "Data."
+ ALOGW("Failed to bind-mount %s as /proc/cpuinfo: %s", cpuinfo_path, strerror(errno));
+ return false;
+ }
+ return true;
+}
+#endif
+
+static void MountCpuinfoForInstructionSet(const char* instruction_set) {
+ if (instruction_set == nullptr) {
+ return;
+ }
+
+ size_t isa_len = strlen(instruction_set);
+ if (isa_len > 10) {
+ // 10 is a loose upper bound on the currently known instruction sets (a tight bound is 7 for
+ // x86_64 [including the trailing \0]). This is so we don't have to change here if there will
+ // be another instruction set in the future.
+ ALOGW("Instruction set %s is malformed, must be less than or equal to 10 characters.",
+ instruction_set);
+ return;
+ }
+
+#if defined(__APPLE__)
+ ALOGW("Mac OS does not support bind-mounting. Host simulation of native bridge impossible.");
+
+#elif !defined(__ANDROID__)
+ // To be able to test on the host, we hardwire a relative path.
+ MountCpuinfo("./cpuinfo");
+
+#else // __ANDROID__
+ char cpuinfo_path[1024];
+
+ // Bind-mount /system/etc/cpuinfo.<isa>.txt to /proc/cpuinfo.
+ snprintf(cpuinfo_path, sizeof(cpuinfo_path), "/system/etc/cpuinfo.%s.txt", instruction_set);
+ if (MountCpuinfo(cpuinfo_path)) {
+ return;
+ }
+
+ // Bind-mount /system/lib{,64}/<isa>/cpuinfo to /proc/cpuinfo.
+ // TODO(b/179753190): remove when all implementations migrate to system/etc!
+#ifdef __LP64__
+ snprintf(cpuinfo_path, sizeof(cpuinfo_path), "/system/lib64/%s/cpuinfo", instruction_set);
+#else
+ snprintf(cpuinfo_path, sizeof(cpuinfo_path), "/system/lib/%s/cpuinfo", instruction_set);
+#endif // __LP64__
+ MountCpuinfo(cpuinfo_path);
+
+#endif
+}
+
bool PreInitializeNativeBridge(const char* app_data_dir_in, const char* instruction_set) {
if (state != NativeBridgeState::kOpened) {
ALOGE("Invalid state: native bridge is expected to be opened.");
@@ -281,52 +340,11 @@
app_code_cache_dir = nullptr;
}
- // Bind-mount /system/lib{,64}/<isa>/cpuinfo to /proc/cpuinfo.
- // Failure is not fatal and will keep the native bridge in kPreInitialized.
+ // Mount cpuinfo that corresponds to the instruction set.
+ // Failure is not fatal.
+ MountCpuinfoForInstructionSet(instruction_set);
+
state = NativeBridgeState::kPreInitialized;
-
-#ifndef __APPLE__
- if (instruction_set == nullptr) {
- return true;
- }
- size_t isa_len = strlen(instruction_set);
- if (isa_len > 10) {
- // 10 is a loose upper bound on the currently known instruction sets (a tight bound is 7 for
- // x86_64 [including the trailing \0]). This is so we don't have to change here if there will
- // be another instruction set in the future.
- ALOGW("Instruction set %s is malformed, must be less than or equal to 10 characters.",
- instruction_set);
- return true;
- }
-
- // If the file does not exist, the mount command will fail,
- // so we save the extra file existence check.
- char cpuinfo_path[1024];
-
-#if defined(__ANDROID__)
- snprintf(cpuinfo_path, sizeof(cpuinfo_path), "/system/lib"
-#ifdef __LP64__
- "64"
-#endif // __LP64__
- "/%s/cpuinfo", instruction_set);
-#else // !__ANDROID__
- // To be able to test on the host, we hardwire a relative path.
- snprintf(cpuinfo_path, sizeof(cpuinfo_path), "./cpuinfo");
-#endif
-
- // Bind-mount.
- if (TEMP_FAILURE_RETRY(mount(cpuinfo_path, // Source.
- "/proc/cpuinfo", // Target.
- nullptr, // FS type.
- MS_BIND, // Mount flags: bind mount.
- nullptr)) == -1) { // "Data."
- ALOGW("Failed to bind-mount %s as /proc/cpuinfo: %s", cpuinfo_path, strerror(errno));
- }
-#else // __APPLE__
- UNUSED(instruction_set);
- ALOGW("Mac OS does not support bind-mounting. Host simulation of native bridge impossible.");
-#endif
-
return true;
}