summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--adb/Android.bp1
-rw-r--r--adb/adb.cpp15
-rw-r--r--adb/adb.h23
-rw-r--r--adb/client/auth.cpp1
-rw-r--r--adb/client/commandline.cpp5
-rw-r--r--adb/client/main.cpp1
-rw-r--r--adb/daemon/jdwp_service.cpp2
-rw-r--r--adb/daemon/remount_service.cpp99
-rw-r--r--adb/daemon/usb.cpp47
-rw-r--r--adb/sockets.cpp2
-rw-r--r--adb/test_adb.py281
-rw-r--r--adb/transport.cpp227
-rw-r--r--adb/transport.h24
-rw-r--r--adb/transport_local.cpp58
-rw-r--r--base/Android.bp1
-rwxr-xr-xbootstat/boot_reason_test.sh19
-rw-r--r--debuggerd/debuggerd_test.cpp7
-rw-r--r--debuggerd/handler/debuggerd_fallback.cpp11
-rw-r--r--fastboot/Android.mk11
-rw-r--r--fastboot/fastboot.cpp6
-rw-r--r--fs_mgr/Android.bp1
-rw-r--r--fs_mgr/fs_mgr.cpp39
-rw-r--r--fs_mgr/fs_mgr_avb.cpp16
-rw-r--r--fs_mgr/fs_mgr_dm_ioctl.cpp28
-rw-r--r--fs_mgr/fs_mgr_dm_linear.cpp141
-rw-r--r--fs_mgr/fs_mgr_fstab.cpp74
-rw-r--r--fs_mgr/fs_mgr_priv.h3
-rw-r--r--fs_mgr/fs_mgr_priv_dm_ioctl.h12
-rw-r--r--fs_mgr/fs_mgr_slotselect.cpp23
-rw-r--r--fs_mgr/fs_mgr_verity.cpp10
-rw-r--r--fs_mgr/include/fs_mgr.h1
-rw-r--r--fs_mgr/include/fs_mgr_dm_linear.h99
-rw-r--r--fs_mgr/include_fstab/fstab/fstab.h4
-rw-r--r--init/Android.bp1
-rw-r--r--init/README.md4
-rw-r--r--init/builtins.cpp26
-rw-r--r--init/devices.cpp24
-rw-r--r--init/devices.h6
-rw-r--r--init/devices_test.cpp2
-rw-r--r--init/epoll.cpp84
-rw-r--r--init/epoll.h49
-rw-r--r--init/host_init_stubs.cpp4
-rw-r--r--init/host_init_stubs.h6
-rw-r--r--init/init.cpp112
-rw-r--r--init/init.h3
-rw-r--r--init/init_first_stage.cpp98
-rw-r--r--init/keychords.cpp305
-rw-r--r--init/keychords.h5
-rw-r--r--init/property_service.cpp16
-rw-r--r--init/property_service.h4
-rw-r--r--init/selinux.cpp27
-rw-r--r--init/selinux.h1
-rw-r--r--init/service.cpp92
-rw-r--r--init/service.h16
-rw-r--r--init/subcontext.cpp5
-rw-r--r--init/ueventd.cpp4
-rw-r--r--libbacktrace/Android.bp6
-rw-r--r--libbacktrace/BacktraceMap.cpp40
-rw-r--r--libbacktrace/include/backtrace/BacktraceMap.h2
-rw-r--r--libcutils/Android.bp11
-rw-r--r--libcutils/ashmem-host.cpp1
-rw-r--r--libcutils/canned_fs_config.cpp1
-rw-r--r--libcutils/hashmap.cpp1
-rw-r--r--libcutils/trace-dev.inc1
-rw-r--r--liblog/Android.bp3
-rw-r--r--liblog/logprint.c6
-rw-r--r--libmemunreachable/Android.bp2
-rw-r--r--libmemunreachable/LineBuffer.cpp66
-rw-r--r--libmemunreachable/LineBuffer.h40
-rw-r--r--libmemunreachable/MemUnreachable.cpp15
-rw-r--r--libmemunreachable/ProcessMappings.cpp51
-rw-r--r--libmemunreachable/ProcessMappings.h9
-rw-r--r--libmemunreachable/README.md21
-rw-r--r--libmemunreachable/include/memunreachable/memunreachable.h7
-rw-r--r--libmemunreachable/tests/MemUnreachable_test.cpp66
-rw-r--r--libmetricslogger/Android.bp7
-rw-r--r--libmetricslogger/include/metricslogger/metrics_logger.h41
-rw-r--r--libmetricslogger/metrics_logger.cpp29
-rw-r--r--libpackagelistparser/Android.bp1
-rw-r--r--libprocinfo/Android.bp32
-rw-r--r--libprocinfo/include/procinfo/process_map.h151
-rw-r--r--libprocinfo/process_map_benchmark.cpp85
-rw-r--r--libprocinfo/process_map_test.cpp60
-rw-r--r--libprocinfo/testdata/maps2043
-rw-r--r--libstats/Android.bp37
-rw-r--r--libstats/OWNERS4
-rw-r--r--libstats/include/stats_event_list.h250
-rw-r--r--libstats/stats_event_list.c181
-rw-r--r--libstats/statsd_writer.c260
-rw-r--r--libstats/statsd_writer.h43
-rw-r--r--libsystem/Android.bp1
-rw-r--r--libunwindstack/Android.bp5
-rw-r--r--libunwindstack/Elf.cpp6
-rw-r--r--libunwindstack/ElfInterface.cpp6
-rw-r--r--libunwindstack/Maps.cpp183
-rw-r--r--libunwindstack/Unwinder.cpp3
-rw-r--r--libunwindstack/include/unwindstack/Elf.h4
-rw-r--r--libunwindstack/include/unwindstack/MapInfo.h7
-rw-r--r--libunwindstack/tests/ElfTest.cpp8
-rw-r--r--libunwindstack/tests/UnwindOfflineTest.cpp127
-rw-r--r--libunwindstack/tests/files/offline/offset_arm/libc.sobin0 -> 839184 bytes
-rw-r--r--libunwindstack/tests/files/offline/offset_arm/libunwindstack_testbin0 -> 3784164 bytes
-rw-r--r--libunwindstack/tests/files/offline/offset_arm/maps.txt2
-rw-r--r--libunwindstack/tests/files/offline/offset_arm/regs.txt16
-rw-r--r--libunwindstack/tests/files/offline/offset_arm/stack0.databin0 -> 828 bytes
-rw-r--r--libunwindstack/tests/files/offline/offset_arm/stack1.databin0 -> 4392 bytes
-rw-r--r--libunwindstack/tools/unwind_for_offline.cpp107
-rw-r--r--libutils/Android.bp1
-rw-r--r--lmkd/lmkd.c88
-rw-r--r--logcat/event.logtags3
-rw-r--r--logd/main.cpp1
-rw-r--r--property_service/libpropertyinfoparser/Android.bp1
-rw-r--r--rootdir/Android.mk70
-rw-r--r--rootdir/init.rc1
114 files changed, 5493 insertions, 906 deletions
diff --git a/adb/Android.bp b/adb/Android.bp
index b9a15966e..99de54e1c 100644
--- a/adb/Android.bp
+++ b/adb/Android.bp
@@ -222,7 +222,6 @@ cc_benchmark {
222 222
223cc_binary_host { 223cc_binary_host {
224 name: "adb", 224 name: "adb",
225 tags: ["debug"],
226 225
227 defaults: ["adb_defaults"], 226 defaults: ["adb_defaults"],
228 227
diff --git a/adb/adb.cpp b/adb/adb.cpp
index 7fc4cc2cd..f8a54c6bf 100644
--- a/adb/adb.cpp
+++ b/adb/adb.cpp
@@ -365,8 +365,8 @@ void handle_packet(apacket *p, atransport *t)
365 switch (p->msg.arg0) { 365 switch (p->msg.arg0) {
366#if ADB_HOST 366#if ADB_HOST
367 case ADB_AUTH_TOKEN: 367 case ADB_AUTH_TOKEN:
368 if (t->GetConnectionState() == kCsOffline) { 368 if (t->GetConnectionState() != kCsAuthorizing) {
369 t->SetConnectionState(kCsUnauthorized); 369 t->SetConnectionState(kCsAuthorizing);
370 } 370 }
371 send_auth_response(p->payload.data(), p->msg.data_length, t); 371 send_auth_response(p->payload.data(), p->msg.data_length, t);
372 break; 372 break;
@@ -1101,14 +1101,11 @@ int handle_host_request(const char* service, TransportType type, const char* ser
1101 if (!strcmp(service, "reconnect-offline")) { 1101 if (!strcmp(service, "reconnect-offline")) {
1102 std::string response; 1102 std::string response;
1103 close_usb_devices([&response](const atransport* transport) { 1103 close_usb_devices([&response](const atransport* transport) {
1104 switch (transport->GetConnectionState()) { 1104 if (!ConnectionStateIsOnline(transport->GetConnectionState())) {
1105 case kCsOffline: 1105 response += "reconnecting " + transport->serial_name() + "\n";
1106 case kCsUnauthorized: 1106 return true;
1107 response += "reconnecting " + transport->serial_name() + "\n";
1108 return true;
1109 default:
1110 return false;
1111 } 1107 }
1108 return false;
1112 }); 1109 });
1113 if (!response.empty()) { 1110 if (!response.empty()) {
1114 response.resize(response.size() - 1); 1111 response.resize(response.size() - 1);
diff --git a/adb/adb.h b/adb/adb.h
index 1e58ee1f0..ede55da34 100644
--- a/adb/adb.h
+++ b/adb/adb.h
@@ -95,16 +95,33 @@ enum TransportType {
95 95
96enum ConnectionState { 96enum ConnectionState {
97 kCsAny = -1, 97 kCsAny = -1,
98 kCsOffline = 0, 98
99 kCsConnecting = 0, // Haven't received a response from the device yet.
100 kCsAuthorizing, // Authorizing with keys from ADB_VENDOR_KEYS.
101 kCsUnauthorized, // ADB_VENDOR_KEYS exhausted, fell back to user prompt.
102 kCsNoPerm, // Insufficient permissions to communicate with the device.
103 kCsOffline,
104
99 kCsBootloader, 105 kCsBootloader,
100 kCsDevice, 106 kCsDevice,
101 kCsHost, 107 kCsHost,
102 kCsRecovery, 108 kCsRecovery,
103 kCsNoPerm, // Insufficient permissions to communicate with the device.
104 kCsSideload, 109 kCsSideload,
105 kCsUnauthorized,
106}; 110};
107 111
112inline bool ConnectionStateIsOnline(ConnectionState state) {
113 switch (state) {
114 case kCsBootloader:
115 case kCsDevice:
116 case kCsHost:
117 case kCsRecovery:
118 case kCsSideload:
119 return true;
120 default:
121 return false;
122 }
123}
124
108void print_packet(const char* label, apacket* p); 125void print_packet(const char* label, apacket* p);
109 126
110// These use the system (v)fprintf, not the adb prefixed ones defined in sysdeps.h, so they 127// These use the system (v)fprintf, not the adb prefixed ones defined in sysdeps.h, so they
diff --git a/adb/client/auth.cpp b/adb/client/auth.cpp
index ade2623b8..0f4dd3397 100644
--- a/adb/client/auth.cpp
+++ b/adb/client/auth.cpp
@@ -464,6 +464,7 @@ void send_auth_response(const char* token, size_t token_size, atransport* t) {
464 std::shared_ptr<RSA> key = t->NextKey(); 464 std::shared_ptr<RSA> key = t->NextKey();
465 if (key == nullptr) { 465 if (key == nullptr) {
466 // No more private keys to try, send the public key. 466 // No more private keys to try, send the public key.
467 t->SetConnectionState(kCsUnauthorized);
467 send_auth_publickey(t); 468 send_auth_publickey(t);
468 return; 469 return;
469 } 470 }
diff --git a/adb/client/commandline.cpp b/adb/client/commandline.cpp
index e476e07cf..39983ab4c 100644
--- a/adb/client/commandline.cpp
+++ b/adb/client/commandline.cpp
@@ -149,8 +149,8 @@ static void help() {
149 " emu COMMAND run emulator console command\n" 149 " emu COMMAND run emulator console command\n"
150 "\n" 150 "\n"
151 "app installation:\n" 151 "app installation:\n"
152 " install [-lrtsdg] PACKAGE\n" 152 " install [-lrtsdg] [--instant] PACKAGE\n"
153 " install-multiple [-lrtsdpg] PACKAGE...\n" 153 " install-multiple [-lrtsdpg] [--instant] PACKAGE...\n"
154 " push package(s) to the device and install them\n" 154 " push package(s) to the device and install them\n"
155 " -l: forward lock application\n" 155 " -l: forward lock application\n"
156 " -r: replace existing application\n" 156 " -r: replace existing application\n"
@@ -159,6 +159,7 @@ static void help() {
159 " -d: allow version code downgrade (debuggable packages only)\n" 159 " -d: allow version code downgrade (debuggable packages only)\n"
160 " -p: partial application install (install-multiple only)\n" 160 " -p: partial application install (install-multiple only)\n"
161 " -g: grant all runtime permissions\n" 161 " -g: grant all runtime permissions\n"
162 " --instant: cause the app to be installed as an ephemeral install app\n"
162 " uninstall [-k] PACKAGE\n" 163 " uninstall [-k] PACKAGE\n"
163 " remove this app package from the device\n" 164 " remove this app package from the device\n"
164 " '-k': keep the data and cache directories\n" 165 " '-k': keep the data and cache directories\n"
diff --git a/adb/client/main.cpp b/adb/client/main.cpp
index 31cb8536a..44ed3a253 100644
--- a/adb/client/main.cpp
+++ b/adb/client/main.cpp
@@ -117,6 +117,7 @@ int adb_server_main(int is_daemon, const std::string& socket_spec, int ack_reply
117 atexit(adb_server_cleanup); 117 atexit(adb_server_cleanup);
118 118
119 init_transport_registration(); 119 init_transport_registration();
120 init_reconnect_handler();
120 init_mdns_transport_discovery(); 121 init_mdns_transport_discovery();
121 122
122 usb_init(); 123 usb_init();
diff --git a/adb/daemon/jdwp_service.cpp b/adb/daemon/jdwp_service.cpp
index 211d8f345..367695dc6 100644
--- a/adb/daemon/jdwp_service.cpp
+++ b/adb/daemon/jdwp_service.cpp
@@ -289,8 +289,6 @@ static void jdwp_process_event(int socket, unsigned events, void* _proc) {
289 goto CloseProcess; 289 goto CloseProcess;
290 } 290 }
291 291
292 adb_close(fd);
293
294 D("sent file descriptor %d to JDWP process %d", fd, proc->pid); 292 D("sent file descriptor %d to JDWP process %d", fd, proc->pid);
295 293
296 proc->out_fds.pop_back(); 294 proc->out_fds.pop_back();
diff --git a/adb/daemon/remount_service.cpp b/adb/daemon/remount_service.cpp
index d679a6dff..eb4690377 100644
--- a/adb/daemon/remount_service.cpp
+++ b/adb/daemon/remount_service.cpp
@@ -21,18 +21,23 @@
21#include <errno.h> 21#include <errno.h>
22#include <fcntl.h> 22#include <fcntl.h>
23#include <mntent.h> 23#include <mntent.h>
24#include <spawn.h>
24#include <stdio.h> 25#include <stdio.h>
25#include <stdlib.h> 26#include <stdlib.h>
26#include <string.h> 27#include <string.h>
27#include <sys/mount.h> 28#include <sys/mount.h>
29#include <sys/vfs.h>
28#include <unistd.h> 30#include <unistd.h>
29 31
30#include <string> 32#include <string>
33#include <vector>
31 34
32#include <android-base/properties.h> 35#include <android-base/properties.h>
36#include <ext4_utils/ext4_utils.h>
33 37
34#include "adb.h" 38#include "adb.h"
35#include "adb_io.h" 39#include "adb_io.h"
40#include "adb_unique_fd.h"
36#include "adb_utils.h" 41#include "adb_utils.h"
37#include "fs_mgr.h" 42#include "fs_mgr.h"
38 43
@@ -82,7 +87,62 @@ bool make_block_device_writable(const std::string& dev) {
82 return result; 87 return result;
83} 88}
84 89
85static bool remount_partition(int fd, const char* dir) { 90static bool fs_has_shared_blocks(const char* dev) {
91 struct statfs fs;
92 if (statfs(dev, &fs) == -1 || fs.f_type == EXT4_SUPER_MAGIC) {
93 return false;
94 }
95 unique_fd fd(unix_open(dev, O_RDONLY));
96 if (fd < 0) {
97 return false;
98 }
99 struct ext4_super_block sb;
100 if (lseek64(fd, 1024, SEEK_SET) < 0 || unix_read(fd, &sb, sizeof(sb)) < 0) {
101 return false;
102 }
103 struct fs_info info;
104 if (ext4_parse_sb(&sb, &info) < 0) {
105 return false;
106 }
107 return (info.feat_ro_compat & EXT4_FEATURE_RO_COMPAT_SHARED_BLOCKS) != 0;
108}
109
110static bool can_unshare_blocks(int fd, const char* dev) {
111 const char* E2FSCK_BIN = "/system/bin/e2fsck";
112 if (access(E2FSCK_BIN, X_OK)) {
113 WriteFdFmt(fd, "e2fsck is not available, cannot undo deduplication on %s\n", dev);
114 return false;
115 }
116
117 pid_t child;
118 char* env[] = {nullptr};
119 const char* argv[] = {E2FSCK_BIN, "-n", "-E", "unshare_blocks", dev, nullptr};
120 if (posix_spawn(&child, E2FSCK_BIN, nullptr, nullptr, const_cast<char**>(argv), env)) {
121 WriteFdFmt(fd, "failed to e2fsck to check deduplication: %s\n", strerror(errno));
122 return false;
123 }
124 int status = 0;
125 int ret = TEMP_FAILURE_RETRY(waitpid(child, &status, 0));
126 if (ret < 0) {
127 WriteFdFmt(fd, "failed to get e2fsck status: %s\n", strerror(errno));
128 return false;
129 }
130 if (!WIFEXITED(status)) {
131 WriteFdFmt(fd, "e2fsck exited abnormally with status %d\n", status);
132 return false;
133 }
134 int rc = WEXITSTATUS(status);
135 if (rc != 0) {
136 WriteFdFmt(fd,
137 "%s is deduplicated, and an e2fsck check failed. It might not "
138 "have enough free-space to be remounted as writable.\n",
139 dev);
140 return false;
141 }
142 return true;
143}
144
145static bool remount_partition(int fd, const char* dir, std::vector<std::string>& dedup) {
86 if (!directory_exists(dir)) { 146 if (!directory_exists(dir)) {
87 return true; 147 return true;
88 } 148 }
@@ -108,6 +168,15 @@ static bool remount_partition(int fd, const char* dir) {
108 return false; 168 return false;
109 } 169 }
110 if (mount(dev.c_str(), dir, "none", MS_REMOUNT, nullptr) == -1) { 170 if (mount(dev.c_str(), dir, "none", MS_REMOUNT, nullptr) == -1) {
171 if (errno == EROFS && fs_has_shared_blocks(dev.c_str())) {
172 if (!can_unshare_blocks(fd, dev.c_str())) {
173 return false;
174 }
175 // We return true so remount_service() can detect that the only
176 // failure was deduplicated filesystems.
177 dedup.push_back(dev);
178 return true;
179 }
111 WriteFdFmt(fd, "remount of the %s superblock failed: %s\n", dir, strerror(errno)); 180 WriteFdFmt(fd, "remount of the %s superblock failed: %s\n", dir, strerror(errno));
112 return false; 181 return false;
113 } 182 }
@@ -140,17 +209,29 @@ void remount_service(int fd, void* cookie) {
140 } 209 }
141 210
142 bool success = true; 211 bool success = true;
212 std::vector<std::string> dedup;
143 if (android::base::GetBoolProperty("ro.build.system_root_image", false)) { 213 if (android::base::GetBoolProperty("ro.build.system_root_image", false)) {
144 success &= remount_partition(fd, "/"); 214 success &= remount_partition(fd, "/", dedup);
145 } else { 215 } else {
146 success &= remount_partition(fd, "/system"); 216 success &= remount_partition(fd, "/system", dedup);
217 }
218 success &= remount_partition(fd, "/odm", dedup);
219 success &= remount_partition(fd, "/oem", dedup);
220 success &= remount_partition(fd, "/product", dedup);
221 success &= remount_partition(fd, "/vendor", dedup);
222
223 if (!success) {
224 WriteFdExactly(fd, "remount failed\n");
225 } else if (dedup.empty()) {
226 WriteFdExactly(fd, "remount succeeded\n");
227 } else {
228 WriteFdExactly(fd,
229 "The following partitions are deduplicated and could "
230 "not be remounted:\n");
231 for (const std::string& name : dedup) {
232 WriteFdFmt(fd, " %s\n", name.c_str());
233 }
147 } 234 }
148 success &= remount_partition(fd, "/odm");
149 success &= remount_partition(fd, "/oem");
150 success &= remount_partition(fd, "/product");
151 success &= remount_partition(fd, "/vendor");
152
153 WriteFdExactly(fd, success ? "remount succeeded\n" : "remount failed\n");
154 235
155 adb_close(fd); 236 adb_close(fd);
156} 237}
diff --git a/adb/daemon/usb.cpp b/adb/daemon/usb.cpp
index ab11bdd1b..c724b1102 100644
--- a/adb/daemon/usb.cpp
+++ b/adb/daemon/usb.cpp
@@ -234,6 +234,10 @@ static void aio_block_init(aio_block* aiob) {
234 for (unsigned i = 0; i < USB_FFS_NUM_BUFS; i++) { 234 for (unsigned i = 0; i < USB_FFS_NUM_BUFS; i++) {
235 aiob->iocbs[i] = &aiob->iocb[i]; 235 aiob->iocbs[i] = &aiob->iocb[i];
236 } 236 }
237 memset(&aiob->ctx, 0, sizeof(aiob->ctx));
238 if (io_setup(USB_FFS_NUM_BUFS, &aiob->ctx)) {
239 D("[ aio: got error on io_setup (%d) ]", errno);
240 }
237} 241}
238 242
239static int getMaxPacketSize(int ffs_fd) { 243static int getMaxPacketSize(int ffs_fd) {
@@ -312,13 +316,6 @@ bool init_functionfs(struct usb_handle* h) {
312 goto err; 316 goto err;
313 } 317 }
314 318
315 memset(&h->read_aiob.ctx, 0, sizeof(h->read_aiob.ctx));
316 memset(&h->write_aiob.ctx, 0, sizeof(h->write_aiob.ctx));
317 if (io_setup(USB_FFS_NUM_BUFS, &h->read_aiob.ctx) ||
318 io_setup(USB_FFS_NUM_BUFS, &h->write_aiob.ctx)) {
319 D("[ aio: got error on io_setup (%d) ]", errno);
320 }
321
322 h->read_aiob.fd = h->bulk_out; 319 h->read_aiob.fd = h->bulk_out;
323 h->write_aiob.fd = h->bulk_in; 320 h->write_aiob.fd = h->bulk_in;
324 return true; 321 return true;
@@ -439,23 +436,29 @@ static int usb_ffs_do_aio(usb_handle* h, const void* data, int len, bool read) {
439 num_bufs += 1; 436 num_bufs += 1;
440 } 437 }
441 438
442 if (io_submit(aiob->ctx, num_bufs, aiob->iocbs.data()) < num_bufs) { 439 while (true) {
443 D("[ aio: got error submitting %s (%d) ]", read ? "read" : "write", errno); 440 if (TEMP_FAILURE_RETRY(io_submit(aiob->ctx, num_bufs, aiob->iocbs.data())) < num_bufs) {
444 return -1; 441 PLOG(ERROR) << "aio: got error submitting " << (read ? "read" : "write");
445 } 442 return -1;
446 if (TEMP_FAILURE_RETRY( 443 }
447 io_getevents(aiob->ctx, num_bufs, num_bufs, aiob->events.data(), nullptr)) < num_bufs) { 444 if (TEMP_FAILURE_RETRY(io_getevents(aiob->ctx, num_bufs, num_bufs, aiob->events.data(),
448 D("[ aio: got error waiting %s (%d) ]", read ? "read" : "write", errno); 445 nullptr)) < num_bufs) {
449 return -1; 446 PLOG(ERROR) << "aio: got error waiting " << (read ? "read" : "write");
450 }
451 for (int i = 0; i < num_bufs; i++) {
452 if (aiob->events[i].res < 0) {
453 errno = aiob->events[i].res;
454 D("[ aio: got error event on %s (%d) ]", read ? "read" : "write", errno);
455 return -1; 447 return -1;
456 } 448 }
449 if (num_bufs == 1 && aiob->events[0].res == -EINTR) {
450 continue;
451 }
452 for (int i = 0; i < num_bufs; i++) {
453 if (aiob->events[i].res < 0) {
454 errno = -aiob->events[i].res;
455 PLOG(ERROR) << "aio: got error event on " << (read ? "read" : "write")
456 << " total bufs " << num_bufs;
457 return -1;
458 }
459 }
460 return 0;
457 } 461 }
458 return 0;
459} 462}
460 463
461static int usb_ffs_aio_read(usb_handle* h, void* data, int len) { 464static int usb_ffs_aio_read(usb_handle* h, void* data, int len) {
@@ -494,8 +497,6 @@ static void usb_ffs_close(usb_handle* h) {
494 h->kicked = false; 497 h->kicked = false;
495 adb_close(h->bulk_out); 498 adb_close(h->bulk_out);
496 adb_close(h->bulk_in); 499 adb_close(h->bulk_in);
497 io_destroy(h->read_aiob.ctx);
498 io_destroy(h->write_aiob.ctx);
499 500
500 // Notify usb_adb_open_thread to open a new connection. 501 // Notify usb_adb_open_thread to open a new connection.
501 h->lock.lock(); 502 h->lock.lock();
diff --git a/adb/sockets.cpp b/adb/sockets.cpp
index 4f4fbfbaa..9a6dcbec5 100644
--- a/adb/sockets.cpp
+++ b/adb/sockets.cpp
@@ -750,7 +750,7 @@ static int smart_socket_enqueue(asocket* s, apacket::payload_type data) {
750 if (!s->transport) { 750 if (!s->transport) {
751 SendFail(s->peer->fd, "device offline (no transport)"); 751 SendFail(s->peer->fd, "device offline (no transport)");
752 goto fail; 752 goto fail;
753 } else if (s->transport->GetConnectionState() == kCsOffline) { 753 } else if (!ConnectionStateIsOnline(s->transport->GetConnectionState())) {
754 /* if there's no remote we fail the connection 754 /* if there's no remote we fail the connection
755 ** right here and terminate it 755 ** right here and terminate it
756 */ 756 */
diff --git a/adb/test_adb.py b/adb/test_adb.py
index 32bf0297c..ddd3ff041 100644
--- a/adb/test_adb.py
+++ b/adb/test_adb.py
@@ -36,10 +36,11 @@ import adb
36 36
37 37
38@contextlib.contextmanager 38@contextlib.contextmanager
39def fake_adb_server(protocol=socket.AF_INET, port=0): 39def fake_adbd(protocol=socket.AF_INET, port=0):
40 """Creates a fake ADB server that just replies with a CNXN packet.""" 40 """Creates a fake ADB daemon that just replies with a CNXN packet."""
41 41
42 serversock = socket.socket(protocol, socket.SOCK_STREAM) 42 serversock = socket.socket(protocol, socket.SOCK_STREAM)
43 serversock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
43 if protocol == socket.AF_INET: 44 if protocol == socket.AF_INET:
44 serversock.bind(('127.0.0.1', port)) 45 serversock.bind(('127.0.0.1', port))
45 else: 46 else:
@@ -60,31 +61,33 @@ def fake_adb_server(protocol=socket.AF_INET, port=0):
60 rlist = [readpipe, serversock] 61 rlist = [readpipe, serversock]
61 cnxn_sent = {} 62 cnxn_sent = {}
62 while True: 63 while True:
63 ready, _, _ = select.select(rlist, [], []) 64 read_ready, _, _ = select.select(rlist, [], [])
64 for r in ready: 65 for ready in read_ready:
65 if r == readpipe: 66 if ready == readpipe:
66 # Closure pipe 67 # Closure pipe
67 os.close(r) 68 os.close(ready)
68 serversock.shutdown(socket.SHUT_RDWR) 69 serversock.shutdown(socket.SHUT_RDWR)
69 serversock.close() 70 serversock.close()
70 return 71 return
71 elif r == serversock: 72 elif ready == serversock:
72 # Server socket 73 # Server socket
73 conn, _ = r.accept() 74 conn, _ = ready.accept()
74 rlist.append(conn) 75 rlist.append(conn)
75 else: 76 else:
76 # Client socket 77 # Client socket
77 data = r.recv(1024) 78 data = ready.recv(1024)
78 if not data: 79 if not data or data.startswith('OPEN'):
79 if r in cnxn_sent: 80 if ready in cnxn_sent:
80 del cnxn_sent[r] 81 del cnxn_sent[ready]
81 rlist.remove(r) 82 ready.shutdown(socket.SHUT_RDWR)
83 ready.close()
84 rlist.remove(ready)
82 continue 85 continue
83 if r in cnxn_sent: 86 if ready in cnxn_sent:
84 continue 87 continue
85 cnxn_sent[r] = True 88 cnxn_sent[ready] = True
86 r.sendall(_adb_packet('CNXN', 0x01000001, 1024 * 1024, 89 ready.sendall(_adb_packet('CNXN', 0x01000001, 1024 * 1024,
87 'device::ro.product.name=fakeadb')) 90 'device::ro.product.name=fakeadb'))
88 91
89 port = serversock.getsockname()[1] 92 port = serversock.getsockname()[1]
90 server_thread = threading.Thread(target=_handle) 93 server_thread = threading.Thread(target=_handle)
@@ -97,8 +100,52 @@ def fake_adb_server(protocol=socket.AF_INET, port=0):
97 server_thread.join() 100 server_thread.join()
98 101
99 102
100class NonApiTest(unittest.TestCase): 103@contextlib.contextmanager
101 """Tests for ADB that aren't a part of the AndroidDevice API.""" 104def adb_connect(unittest, serial):
105 """Context manager for an ADB connection.
106
107 This automatically disconnects when done with the connection.
108 """
109
110 output = subprocess.check_output(['adb', 'connect', serial])
111 unittest.assertEqual(output.strip(), 'connected to {}'.format(serial))
112
113 try:
114 yield
115 finally:
116 # Perform best-effort disconnection. Discard the output.
117 subprocess.Popen(['adb', 'disconnect', serial],
118 stdout=subprocess.PIPE,
119 stderr=subprocess.PIPE).communicate()
120
121
122@contextlib.contextmanager
123def adb_server():
124 """Context manager for an ADB server.
125
126 This creates an ADB server and returns the port it's listening on.
127 """
128
129 port = 5038
130 # Kill any existing server on this non-default port.
131 subprocess.check_output(['adb', '-P', str(port), 'kill-server'],
132 stderr=subprocess.STDOUT)
133 read_pipe, write_pipe = os.pipe()
134 proc = subprocess.Popen(['adb', '-L', 'tcp:localhost:{}'.format(port),
135 'fork-server', 'server',
136 '--reply-fd', str(write_pipe)])
137 try:
138 os.close(write_pipe)
139 greeting = os.read(read_pipe, 1024)
140 assert greeting == 'OK\n', repr(greeting)
141 yield port
142 finally:
143 proc.terminate()
144 proc.wait()
145
146
147class CommandlineTest(unittest.TestCase):
148 """Tests for the ADB commandline."""
102 149
103 def test_help(self): 150 def test_help(self):
104 """Make sure we get _something_ out of help.""" 151 """Make sure we get _something_ out of help."""
@@ -120,28 +167,37 @@ class NonApiTest(unittest.TestCase):
120 revision_line, r'^Revision [0-9a-f]{12}-android$') 167 revision_line, r'^Revision [0-9a-f]{12}-android$')
121 168
122 def test_tcpip_error_messages(self): 169 def test_tcpip_error_messages(self):
123 p = subprocess.Popen(['adb', 'tcpip'], stdout=subprocess.PIPE, 170 """Make sure 'adb tcpip' parsing is sane."""
124 stderr=subprocess.STDOUT) 171 proc = subprocess.Popen(['adb', 'tcpip'], stdout=subprocess.PIPE,
125 out, _ = p.communicate() 172 stderr=subprocess.STDOUT)
126 self.assertEqual(1, p.returncode) 173 out, _ = proc.communicate()
174 self.assertEqual(1, proc.returncode)
127 self.assertIn('requires an argument', out) 175 self.assertIn('requires an argument', out)
128 176
129 p = subprocess.Popen(['adb', 'tcpip', 'foo'], stdout=subprocess.PIPE, 177 proc = subprocess.Popen(['adb', 'tcpip', 'foo'], stdout=subprocess.PIPE,
130 stderr=subprocess.STDOUT) 178 stderr=subprocess.STDOUT)
131 out, _ = p.communicate() 179 out, _ = proc.communicate()
132 self.assertEqual(1, p.returncode) 180 self.assertEqual(1, proc.returncode)
133 self.assertIn('invalid port', out) 181 self.assertIn('invalid port', out)
134 182
135 # Helper method that reads a pipe until it is closed, then sets the event. 183
136 def _read_pipe_and_set_event(self, pipe, event): 184class ServerTest(unittest.TestCase):
137 x = pipe.read() 185 """Tests for the ADB server."""
186
187 @staticmethod
188 def _read_pipe_and_set_event(pipe, event):
189 """Reads a pipe until it is closed, then sets the event."""
190 pipe.read()
138 event.set() 191 event.set()
139 192
140 # Test that launch_server() does not let the adb server inherit
141 # stdin/stdout/stderr handles which can cause callers of adb.exe to hang.
142 # This test also runs fine on unix even though the impetus is an issue
143 # unique to Windows.
144 def test_handle_inheritance(self): 193 def test_handle_inheritance(self):
194 """Test that launch_server() does not inherit handles.
195
196 launch_server() should not let the adb server inherit
197 stdin/stdout/stderr handles, which can cause callers of adb.exe to hang.
198 This test also runs fine on unix even though the impetus is an issue
199 unique to Windows.
200 """
145 # This test takes 5 seconds to run on Windows: if there is no adb server 201 # This test takes 5 seconds to run on Windows: if there is no adb server
146 # running on the the port used below, adb kill-server tries to make a 202 # running on the the port used below, adb kill-server tries to make a
147 # TCP connection to a closed port and that takes 1 second on Windows; 203 # TCP connection to a closed port and that takes 1 second on Windows;
@@ -163,29 +219,30 @@ class NonApiTest(unittest.TestCase):
163 219
164 try: 220 try:
165 # Run the adb client and have it start the adb server. 221 # Run the adb client and have it start the adb server.
166 p = subprocess.Popen(['adb', '-P', str(port), 'start-server'], 222 proc = subprocess.Popen(['adb', '-P', str(port), 'start-server'],
167 stdin=subprocess.PIPE, stdout=subprocess.PIPE, 223 stdin=subprocess.PIPE,
168 stderr=subprocess.PIPE) 224 stdout=subprocess.PIPE,
225 stderr=subprocess.PIPE)
169 226
170 # Start threads that set events when stdout/stderr are closed. 227 # Start threads that set events when stdout/stderr are closed.
171 stdout_event = threading.Event() 228 stdout_event = threading.Event()
172 stdout_thread = threading.Thread( 229 stdout_thread = threading.Thread(
173 target=self._read_pipe_and_set_event, 230 target=ServerTest._read_pipe_and_set_event,
174 args=(p.stdout, stdout_event)) 231 args=(proc.stdout, stdout_event))
175 stdout_thread.daemon = True 232 stdout_thread.daemon = True
176 stdout_thread.start() 233 stdout_thread.start()
177 234
178 stderr_event = threading.Event() 235 stderr_event = threading.Event()
179 stderr_thread = threading.Thread( 236 stderr_thread = threading.Thread(
180 target=self._read_pipe_and_set_event, 237 target=ServerTest._read_pipe_and_set_event,
181 args=(p.stderr, stderr_event)) 238 args=(proc.stderr, stderr_event))
182 stderr_thread.daemon = True 239 stderr_thread.daemon = True
183 stderr_thread.start() 240 stderr_thread.start()
184 241
185 # Wait for the adb client to finish. Once that has occurred, if 242 # Wait for the adb client to finish. Once that has occurred, if
186 # stdin/stderr/stdout are still open, it must be open in the adb 243 # stdin/stderr/stdout are still open, it must be open in the adb
187 # server. 244 # server.
188 p.wait() 245 proc.wait()
189 246
190 # Try to write to stdin which we expect is closed. If it isn't 247 # Try to write to stdin which we expect is closed. If it isn't
191 # closed, we should get an IOError. If we don't get an IOError, 248 # closed, we should get an IOError. If we don't get an IOError,
@@ -193,7 +250,7 @@ class NonApiTest(unittest.TestCase):
193 # probably letting the adb server inherit stdin which would be 250 # probably letting the adb server inherit stdin which would be
194 # wrong. 251 # wrong.
195 with self.assertRaises(IOError): 252 with self.assertRaises(IOError):
196 p.stdin.write('x') 253 proc.stdin.write('x')
197 254
198 # Wait a few seconds for stdout/stderr to be closed (in the success 255 # Wait a few seconds for stdout/stderr to be closed (in the success
199 # case, this won't wait at all). If there is a timeout, that means 256 # case, this won't wait at all). If there is a timeout, that means
@@ -207,8 +264,12 @@ class NonApiTest(unittest.TestCase):
207 subprocess.check_output(['adb', '-P', str(port), 'kill-server'], 264 subprocess.check_output(['adb', '-P', str(port), 'kill-server'],
208 stderr=subprocess.STDOUT) 265 stderr=subprocess.STDOUT)
209 266
210 # Use SO_LINGER to cause TCP RST segment to be sent on socket close. 267
268class EmulatorTest(unittest.TestCase):
269 """Tests for the emulator connection."""
270
211 def _reset_socket_on_close(self, sock): 271 def _reset_socket_on_close(self, sock):
272 """Use SO_LINGER to cause TCP RST segment to be sent on socket close."""
212 # The linger structure is two shorts on Windows, but two ints on Unix. 273 # The linger structure is two shorts on Windows, but two ints on Unix.
213 linger_format = 'hh' if os.name == 'nt' else 'ii' 274 linger_format = 'hh' if os.name == 'nt' else 'ii'
214 l_onoff = 1 275 l_onoff = 1
@@ -227,7 +288,7 @@ class NonApiTest(unittest.TestCase):
227 Bug: https://code.google.com/p/android/issues/detail?id=21021 288 Bug: https://code.google.com/p/android/issues/detail?id=21021
228 """ 289 """
229 with contextlib.closing( 290 with contextlib.closing(
230 socket.socket(socket.AF_INET, socket.SOCK_STREAM)) as listener: 291 socket.socket(socket.AF_INET, socket.SOCK_STREAM)) as listener:
231 # Use SO_REUSEADDR so subsequent runs of the test can grab the port 292 # Use SO_REUSEADDR so subsequent runs of the test can grab the port
232 # even if it is in TIME_WAIT. 293 # even if it is in TIME_WAIT.
233 listener.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) 294 listener.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
@@ -237,7 +298,7 @@ class NonApiTest(unittest.TestCase):
237 298
238 # Now that listening has started, start adb emu kill, telling it to 299 # Now that listening has started, start adb emu kill, telling it to
239 # connect to our mock emulator. 300 # connect to our mock emulator.
240 p = subprocess.Popen( 301 proc = subprocess.Popen(
241 ['adb', '-s', 'emulator-' + str(port), 'emu', 'kill'], 302 ['adb', '-s', 'emulator-' + str(port), 'emu', 'kill'],
242 stderr=subprocess.STDOUT) 303 stderr=subprocess.STDOUT)
243 304
@@ -246,12 +307,16 @@ class NonApiTest(unittest.TestCase):
246 # If WSAECONNABORTED (10053) is raised by any socket calls, 307 # If WSAECONNABORTED (10053) is raised by any socket calls,
247 # then adb probably isn't reading the data that we sent it. 308 # then adb probably isn't reading the data that we sent it.
248 conn.sendall('Android Console: type \'help\' for a list ' + 309 conn.sendall('Android Console: type \'help\' for a list ' +
249 'of commands\r\n') 310 'of commands\r\n')
250 conn.sendall('OK\r\n') 311 conn.sendall('OK\r\n')
251 312
252 with contextlib.closing(conn.makefile()) as f: 313 with contextlib.closing(conn.makefile()) as connf:
253 self.assertEqual('kill\n', f.readline()) 314 line = connf.readline()
254 self.assertEqual('quit\n', f.readline()) 315 if line.startswith('auth'):
316 # Ignore the first auth line.
317 line = connf.readline()
318 self.assertEqual('kill\n', line)
319 self.assertEqual('quit\n', connf.readline())
255 320
256 conn.sendall('OK: killing emulator, bye bye\r\n') 321 conn.sendall('OK: killing emulator, bye bye\r\n')
257 322
@@ -264,11 +329,48 @@ class NonApiTest(unittest.TestCase):
264 self._reset_socket_on_close(conn) 329 self._reset_socket_on_close(conn)
265 330
266 # Wait for adb to finish, so we can check return code. 331 # Wait for adb to finish, so we can check return code.
267 p.communicate() 332 proc.communicate()
268 333
269 # If this fails, adb probably isn't ignoring WSAECONNRESET when 334 # If this fails, adb probably isn't ignoring WSAECONNRESET when
270 # reading the response from the adb emu kill command (on Windows). 335 # reading the response from the adb emu kill command (on Windows).
271 self.assertEqual(0, p.returncode) 336 self.assertEqual(0, proc.returncode)
337
338 def test_emulator_connect(self):
339 """Ensure that the emulator can connect.
340
341 Bug: http://b/78991667
342 """
343 with adb_server() as server_port:
344 with fake_adbd() as port:
345 serial = 'emulator-{}'.format(port - 1)
346 # Ensure that the emulator is not there.
347 try:
348 subprocess.check_output(['adb', '-P', str(server_port),
349 '-s', serial, 'get-state'],
350 stderr=subprocess.STDOUT)
351 self.fail('Device should not be available')
352 except subprocess.CalledProcessError as err:
353 self.assertEqual(
354 err.output.strip(),
355 'error: device \'{}\' not found'.format(serial))
356
357 # Let the ADB server know that the emulator has started.
358 with contextlib.closing(
359 socket.socket(socket.AF_INET, socket.SOCK_STREAM)) as sock:
360 sock.connect(('localhost', server_port))
361 command = 'host:emulator:{}'.format(port)
362 sock.sendall('%04x%s' % (len(command), command))
363
364 # Ensure the emulator is there.
365 subprocess.check_call(['adb', '-P', str(server_port),
366 '-s', serial, 'wait-for-device'])
367 output = subprocess.check_output(['adb', '-P', str(server_port),
368 '-s', serial, 'get-state'])
369 self.assertEqual(output.strip(), 'device')
370
371
372class ConnectionTest(unittest.TestCase):
373 """Tests for adb connect."""
272 374
273 def test_connect_ipv4_ipv6(self): 375 def test_connect_ipv4_ipv6(self):
274 """Ensure that `adb connect localhost:1234` will try both IPv4 and IPv6. 376 """Ensure that `adb connect localhost:1234` will try both IPv4 and IPv6.
@@ -277,38 +379,67 @@ class NonApiTest(unittest.TestCase):
277 """ 379 """
278 for protocol in (socket.AF_INET, socket.AF_INET6): 380 for protocol in (socket.AF_INET, socket.AF_INET6):
279 try: 381 try:
280 with fake_adb_server(protocol=protocol) as port: 382 with fake_adbd(protocol=protocol) as port:
281 output = subprocess.check_output( 383 serial = 'localhost:{}'.format(port)
282 ['adb', 'connect', 'localhost:{}'.format(port)]) 384 with adb_connect(self, serial):
283 385 pass
284 self.assertEqual(
285 output.strip(), 'connected to localhost:{}'.format(port))
286 except socket.error: 386 except socket.error:
287 print("IPv6 not available, skipping") 387 print("IPv6 not available, skipping")
288 continue 388 continue
289 389
290 def test_already_connected(self): 390 def test_already_connected(self):
291 with fake_adb_server() as port: 391 """Ensure that an already-connected device stays connected."""
292 output = subprocess.check_output( 392
293 ['adb', 'connect', 'localhost:{}'.format(port)]) 393 with fake_adbd() as port:
294 394 serial = 'localhost:{}'.format(port)
295 self.assertEqual( 395 with adb_connect(self, serial):
296 output.strip(), 'connected to localhost:{}'.format(port)) 396 # b/31250450: this always returns 0 but probably shouldn't.
297 397 output = subprocess.check_output(['adb', 'connect', serial])
298 # b/31250450: this always returns 0 but probably shouldn't. 398 self.assertEqual(
299 output = subprocess.check_output( 399 output.strip(), 'already connected to {}'.format(serial))
300 ['adb', 'connect', 'localhost:{}'.format(port)]) 400
401 def test_reconnect(self):
402 """Ensure that a disconnected device reconnects."""
403
404 with fake_adbd() as port:
405 serial = 'localhost:{}'.format(port)
406 with adb_connect(self, serial):
407 output = subprocess.check_output(['adb', '-s', serial,
408 'get-state'])
409 self.assertEqual(output.strip(), 'device')
410
411 # This will fail.
412 proc = subprocess.Popen(['adb', '-s', serial, 'shell', 'true'],
413 stdout=subprocess.PIPE,
414 stderr=subprocess.STDOUT)
415 output, _ = proc.communicate()
416 self.assertEqual(output.strip(), 'error: closed')
417
418 subprocess.check_call(['adb', '-s', serial, 'wait-for-device'])
419
420 output = subprocess.check_output(['adb', '-s', serial,
421 'get-state'])
422 self.assertEqual(output.strip(), 'device')
423
424 # Once we explicitly kick a device, it won't attempt to
425 # reconnect.
426 output = subprocess.check_output(['adb', 'disconnect', serial])
427 self.assertEqual(
428 output.strip(), 'disconnected {}'.format(serial))
429 try:
430 subprocess.check_output(['adb', '-s', serial, 'get-state'],
431 stderr=subprocess.STDOUT)
432 self.fail('Device should not be available')
433 except subprocess.CalledProcessError as err:
434 self.assertEqual(
435 err.output.strip(),
436 'error: device \'{}\' not found'.format(serial))
301 437
302 self.assertEqual(
303 output.strip(), 'already connected to localhost:{}'.format(port))
304 438
305def main(): 439def main():
440 """Main entrypoint."""
306 random.seed(0) 441 random.seed(0)
307 if len(adb.get_devices()) > 0: 442 unittest.main(verbosity=3)
308 suite = unittest.TestLoader().loadTestsFromName(__name__)
309 unittest.TextTestRunner(verbosity=3).run(suite)
310 else:
311 print('Test suite must be run with attached devices')
312 443
313 444
314if __name__ == '__main__': 445if __name__ == '__main__':
diff --git a/adb/transport.cpp b/adb/transport.cpp
index 4c9c90c8d..7db9bf218 100644
--- a/adb/transport.cpp
+++ b/adb/transport.cpp
@@ -33,6 +33,7 @@
33#include <deque> 33#include <deque>
34#include <list> 34#include <list>
35#include <mutex> 35#include <mutex>
36#include <queue>
36#include <thread> 37#include <thread>
37 38
38#include <android-base/logging.h> 39#include <android-base/logging.h>
@@ -50,7 +51,9 @@
50#include "adb_utils.h" 51#include "adb_utils.h"
51#include "fdevent.h" 52#include "fdevent.h"
52 53
53static void transport_unref(atransport *t); 54static void register_transport(atransport* transport);
55static void remove_transport(atransport* transport);
56static void transport_unref(atransport* transport);
54 57
55// TODO: unordered_map<TransportId, atransport*> 58// TODO: unordered_map<TransportId, atransport*>
56static auto& transport_list = *new std::list<atransport*>(); 59static auto& transport_list = *new std::list<atransport*>();
@@ -77,6 +80,130 @@ class SCOPED_CAPABILITY ScopedAssumeLocked {
77 ~ScopedAssumeLocked() RELEASE() {} 80 ~ScopedAssumeLocked() RELEASE() {}
78}; 81};
79 82
83// Tracks and handles atransport*s that are attempting reconnection.
84class ReconnectHandler {
85 public:
86 ReconnectHandler() = default;
87 ~ReconnectHandler() = default;
88
89 // Starts the ReconnectHandler thread.
90 void Start();
91
92 // Requests the ReconnectHandler thread to stop.
93 void Stop();
94
95 // Adds the atransport* to the queue of reconnect attempts.
96 void TrackTransport(atransport* transport);
97
98 private:
99 // The main thread loop.
100 void Run();
101
102 // Tracks a reconnection attempt.
103 struct ReconnectAttempt {
104 atransport* transport;
105 std::chrono::system_clock::time_point deadline;
106 size_t attempts_left;
107 };
108
109 // Only retry for up to one minute.
110 static constexpr const std::chrono::seconds kDefaultTimeout = std::chrono::seconds(10);
111 static constexpr const size_t kMaxAttempts = 6;
112
113 // Protects all members.
114 std::mutex reconnect_mutex_;
115 bool running_ GUARDED_BY(reconnect_mutex_) = true;
116 std::thread handler_thread_;
117 std::condition_variable reconnect_cv_;
118 std::queue<ReconnectAttempt> reconnect_queue_ GUARDED_BY(reconnect_mutex_);
119
120 DISALLOW_COPY_AND_ASSIGN(ReconnectHandler);
121};
122
123void ReconnectHandler::Start() {
124 check_main_thread();
125 handler_thread_ = std::thread(&ReconnectHandler::Run, this);
126}
127
128void ReconnectHandler::Stop() {
129 check_main_thread();
130 {
131 std::lock_guard<std::mutex> lock(reconnect_mutex_);
132 running_ = false;
133 }
134 reconnect_cv_.notify_one();
135 handler_thread_.join();
136
137 // Drain the queue to free all resources.
138 std::lock_guard<std::mutex> lock(reconnect_mutex_);
139 while (!reconnect_queue_.empty()) {
140 ReconnectAttempt attempt = reconnect_queue_.front();
141 reconnect_queue_.pop();
142 remove_transport(attempt.transport);
143 }
144}
145
146void ReconnectHandler::TrackTransport(atransport* transport) {
147 check_main_thread();
148 {
149 std::lock_guard<std::mutex> lock(reconnect_mutex_);
150 if (!running_) return;
151 reconnect_queue_.emplace(ReconnectAttempt{
152 transport, std::chrono::system_clock::now() + ReconnectHandler::kDefaultTimeout,
153 ReconnectHandler::kMaxAttempts});
154 }
155 reconnect_cv_.notify_one();
156}
157
158void ReconnectHandler::Run() {
159 while (true) {
160 ReconnectAttempt attempt;
161 {
162 std::unique_lock<std::mutex> lock(reconnect_mutex_);
163 ScopedAssumeLocked assume_lock(reconnect_mutex_);
164
165 auto deadline = std::chrono::time_point<std::chrono::system_clock>::max();
166 if (!reconnect_queue_.empty()) deadline = reconnect_queue_.front().deadline;
167 reconnect_cv_.wait_until(lock, deadline, [&]() REQUIRES(reconnect_mutex_) {
168 return !running_ ||
169 (!reconnect_queue_.empty() && reconnect_queue_.front().deadline < deadline);
170 });
171
172 if (!running_) return;
173 attempt = reconnect_queue_.front();
174 reconnect_queue_.pop();
175 if (attempt.transport->kicked()) {
176 D("transport %s was kicked. giving up on it.", attempt.transport->serial);
177 remove_transport(attempt.transport);
178 continue;
179 }
180 }
181 D("attempting to reconnect %s", attempt.transport->serial);
182
183 if (!attempt.transport->Reconnect()) {
184 D("attempting to reconnect %s failed.", attempt.transport->serial);
185 if (attempt.attempts_left == 0) {
186 D("transport %s exceeded the number of retry attempts. giving up on it.",
187 attempt.transport->serial);
188 remove_transport(attempt.transport);
189 continue;
190 }
191
192 std::lock_guard<std::mutex> lock(reconnect_mutex_);
193 reconnect_queue_.emplace(ReconnectAttempt{
194 attempt.transport,
195 std::chrono::system_clock::now() + ReconnectHandler::kDefaultTimeout,
196 attempt.attempts_left - 1});
197 continue;
198 }
199
200 D("reconnection to %s succeeded.", attempt.transport->serial);
201 register_transport(attempt.transport);
202 }
203}
204
205static auto& reconnect_handler = *new ReconnectHandler();
206
80} // namespace 207} // namespace
81 208
82TransportId NextTransportId() { 209TransportId NextTransportId() {
@@ -477,8 +604,6 @@ static int transport_write_action(int fd, struct tmsg* m) {
477 return 0; 604 return 0;
478} 605}
479 606
480static void remove_transport(atransport*);
481
482static void transport_registration_func(int _fd, unsigned ev, void*) { 607static void transport_registration_func(int _fd, unsigned ev, void*) {
483 tmsg m; 608 tmsg m;
484 atransport* t; 609 atransport* t;
@@ -515,8 +640,9 @@ static void transport_registration_func(int _fd, unsigned ev, void*) {
515 640
516 /* don't create transport threads for inaccessible devices */ 641 /* don't create transport threads for inaccessible devices */
517 if (t->GetConnectionState() != kCsNoPerm) { 642 if (t->GetConnectionState() != kCsNoPerm) {
518 /* initial references are the two threads */ 643 // The connection gets a reference to the atransport. It will release it
519 t->ref_count = 1; 644 // upon a read/write error.
645 t->ref_count++;
520 t->connection()->SetTransportName(t->serial_name()); 646 t->connection()->SetTransportName(t->serial_name());
521 t->connection()->SetReadCallback([t](Connection*, std::unique_ptr<apacket> p) { 647 t->connection()->SetReadCallback([t](Connection*, std::unique_ptr<apacket> p) {
522 if (!check_header(p.get(), t)) { 648 if (!check_header(p.get(), t)) {
@@ -547,13 +673,20 @@ static void transport_registration_func(int _fd, unsigned ev, void*) {
547 673
548 { 674 {
549 std::lock_guard<std::recursive_mutex> lock(transport_lock); 675 std::lock_guard<std::recursive_mutex> lock(transport_lock);
550 pending_list.remove(t); 676 auto it = std::find(pending_list.begin(), pending_list.end(), t);
551 transport_list.push_front(t); 677 if (it != pending_list.end()) {
678 pending_list.remove(t);
679 transport_list.push_front(t);
680 }
552 } 681 }
553 682
554 update_transports(); 683 update_transports();
555} 684}
556 685
686void init_reconnect_handler(void) {
687 reconnect_handler.Start();
688}
689
557void init_transport_registration(void) { 690void init_transport_registration(void) {
558 int s[2]; 691 int s[2];
559 692
@@ -571,6 +704,7 @@ void init_transport_registration(void) {
571} 704}
572 705
573void kick_all_transports() { 706void kick_all_transports() {
707 reconnect_handler.Stop();
574 // To avoid only writing part of a packet to a transport after exit, kick all transports. 708 // To avoid only writing part of a packet to a transport after exit, kick all transports.
575 std::lock_guard<std::recursive_mutex> lock(transport_lock); 709 std::lock_guard<std::recursive_mutex> lock(transport_lock);
576 for (auto t : transport_list) { 710 for (auto t : transport_list) {
@@ -600,15 +734,21 @@ static void remove_transport(atransport* transport) {
600} 734}
601 735
602static void transport_unref(atransport* t) { 736static void transport_unref(atransport* t) {
737 check_main_thread();
603 CHECK(t != nullptr); 738 CHECK(t != nullptr);
604 739
605 std::lock_guard<std::recursive_mutex> lock(transport_lock); 740 std::lock_guard<std::recursive_mutex> lock(transport_lock);
606 CHECK_GT(t->ref_count, 0u); 741 CHECK_GT(t->ref_count, 0u);
607 t->ref_count--; 742 t->ref_count--;
608 if (t->ref_count == 0) { 743 if (t->ref_count == 0) {
609 D("transport: %s unref (kicking and closing)", t->serial);
610 t->connection()->Stop(); 744 t->connection()->Stop();
611 remove_transport(t); 745 if (t->IsTcpDevice() && !t->kicked()) {
746 D("transport: %s unref (attempting reconnection) %d", t->serial, t->kicked());
747 reconnect_handler.TrackTransport(t);
748 } else {
749 D("transport: %s unref (kicking and closing)", t->serial);
750 remove_transport(t);
751 }
612 } else { 752 } else {
613 D("transport: %s unref (count=%zu)", t->serial, t->ref_count); 753 D("transport: %s unref (count=%zu)", t->serial, t->ref_count);
614 } 754 }
@@ -707,22 +847,41 @@ atransport* acquire_one_transport(TransportType type, const char* serial, Transp
707 } 847 }
708 lock.unlock(); 848 lock.unlock();
709 849
710 // Don't return unauthorized devices; the caller can't do anything with them. 850 if (result && !accept_any_state) {
711 if (result && result->GetConnectionState() == kCsUnauthorized && !accept_any_state) { 851 // The caller requires an active transport.
712 *error_out = "device unauthorized.\n"; 852 // Make sure that we're actually connected.
713 char* ADB_VENDOR_KEYS = getenv("ADB_VENDOR_KEYS"); 853 ConnectionState state = result->GetConnectionState();
714 *error_out += "This adb server's $ADB_VENDOR_KEYS is "; 854 switch (state) {
715 *error_out += ADB_VENDOR_KEYS ? ADB_VENDOR_KEYS : "not set"; 855 case kCsConnecting:
716 *error_out += "\n"; 856 *error_out = "device still connecting";
717 *error_out += "Try 'adb kill-server' if that seems wrong.\n"; 857 result = nullptr;
718 *error_out += "Otherwise check for a confirmation dialog on your device."; 858 break;
719 result = nullptr;
720 }
721 859
722 // Don't return offline devices; the caller can't do anything with them. 860 case kCsAuthorizing:
723 if (result && result->GetConnectionState() == kCsOffline && !accept_any_state) { 861 *error_out = "device still authorizing";
724 *error_out = "device offline"; 862 result = nullptr;
725 result = nullptr; 863 break;
864
865 case kCsUnauthorized: {
866 *error_out = "device unauthorized.\n";
867 char* ADB_VENDOR_KEYS = getenv("ADB_VENDOR_KEYS");
868 *error_out += "This adb server's $ADB_VENDOR_KEYS is ";
869 *error_out += ADB_VENDOR_KEYS ? ADB_VENDOR_KEYS : "not set";
870 *error_out += "\n";
871 *error_out += "Try 'adb kill-server' if that seems wrong.\n";
872 *error_out += "Otherwise check for a confirmation dialog on your device.";
873 result = nullptr;
874 break;
875 }
876
877 case kCsOffline:
878 *error_out = "device offline";
879 result = nullptr;
880 break;
881
882 default:
883 break;
884 }
726 } 885 }
727 886
728 if (result) { 887 if (result) {
@@ -761,9 +920,8 @@ int atransport::Write(apacket* p) {
761} 920}
762 921
763void atransport::Kick() { 922void atransport::Kick() {
764 if (!kicked_) { 923 if (!kicked_.exchange(true)) {
765 D("kicking transport %s", this->serial); 924 D("kicking transport %p %s", this, this->serial);
766 kicked_ = true;
767 this->connection()->Stop(); 925 this->connection()->Stop();
768 } 926 }
769} 927}
@@ -801,6 +959,10 @@ std::string atransport::connection_state_name() const {
801 return "sideload"; 959 return "sideload";
802 case kCsUnauthorized: 960 case kCsUnauthorized:
803 return "unauthorized"; 961 return "unauthorized";
962 case kCsAuthorizing:
963 return "authorizing";
964 case kCsConnecting:
965 return "connecting";
804 default: 966 default:
805 return "unknown"; 967 return "unknown";
806 } 968 }
@@ -917,6 +1079,10 @@ void atransport::SetConnectionEstablished(bool success) {
917 connection_waitable_->SetConnectionEstablished(success); 1079 connection_waitable_->SetConnectionEstablished(success);
918} 1080}
919 1081
1082bool atransport::Reconnect() {
1083 return reconnect_(this);
1084}
1085
920#if ADB_HOST 1086#if ADB_HOST
921 1087
922// We use newline as our delimiter, make sure to never output it. 1088// We use newline as our delimiter, make sure to never output it.
@@ -997,8 +1163,9 @@ void close_usb_devices() {
997} 1163}
998#endif // ADB_HOST 1164#endif // ADB_HOST
999 1165
1000int register_socket_transport(int s, const char* serial, int port, int local) { 1166int register_socket_transport(int s, const char* serial, int port, int local,
1001 atransport* t = new atransport(); 1167 atransport::ReconnectCallback reconnect) {
1168 atransport* t = new atransport(std::move(reconnect), kCsOffline);
1002 1169
1003 if (!serial) { 1170 if (!serial) {
1004 char buf[32]; 1171 char buf[32];
@@ -1079,7 +1246,7 @@ void kick_all_tcp_devices() {
1079 1246
1080void register_usb_transport(usb_handle* usb, const char* serial, const char* devpath, 1247void register_usb_transport(usb_handle* usb, const char* serial, const char* devpath,
1081 unsigned writeable) { 1248 unsigned writeable) {
1082 atransport* t = new atransport((writeable ? kCsOffline : kCsNoPerm)); 1249 atransport* t = new atransport(writeable ? kCsOffline : kCsNoPerm);
1083 1250
1084 D("transport: %p init'ing for usb_handle %p (sn='%s')", t, usb, serial ? serial : ""); 1251 D("transport: %p init'ing for usb_handle %p (sn='%s')", t, usb, serial ? serial : "");
1085 init_usb_transport(t, usb); 1252 init_usb_transport(t, usb);
diff --git a/adb/transport.h b/adb/transport.h
index ebc186bf9..ae9cc023c 100644
--- a/adb/transport.h
+++ b/adb/transport.h
@@ -198,20 +198,27 @@ class atransport {
198 // class in one go is a very large change. Given how bad our testing is, 198 // class in one go is a very large change. Given how bad our testing is,
199 // it's better to do this piece by piece. 199 // it's better to do this piece by piece.
200 200
201 atransport(ConnectionState state = kCsOffline) 201 using ReconnectCallback = std::function<bool(atransport*)>;
202
203 atransport(ReconnectCallback reconnect, ConnectionState state)
202 : id(NextTransportId()), 204 : id(NextTransportId()),
205 kicked_(false),
203 connection_state_(state), 206 connection_state_(state),
204 connection_waitable_(std::make_shared<ConnectionWaitable>()), 207 connection_waitable_(std::make_shared<ConnectionWaitable>()),
205 connection_(nullptr) { 208 connection_(nullptr),
209 reconnect_(std::move(reconnect)) {
206 // Initialize protocol to min version for compatibility with older versions. 210 // Initialize protocol to min version for compatibility with older versions.
207 // Version will be updated post-connect. 211 // Version will be updated post-connect.
208 protocol_version = A_VERSION_MIN; 212 protocol_version = A_VERSION_MIN;
209 max_payload = MAX_PAYLOAD; 213 max_payload = MAX_PAYLOAD;
210 } 214 }
215 atransport(ConnectionState state = kCsOffline)
216 : atransport([](atransport*) { return false; }, state) {}
211 virtual ~atransport(); 217 virtual ~atransport();
212 218
213 int Write(apacket* p); 219 int Write(apacket* p);
214 void Kick(); 220 void Kick();
221 bool kicked() const { return kicked_; }
215 222
216 // ConnectionState can be read by all threads, but can only be written in the main thread. 223 // ConnectionState can be read by all threads, but can only be written in the main thread.
217 ConnectionState GetConnectionState() const; 224 ConnectionState GetConnectionState() const;
@@ -286,8 +293,12 @@ class atransport {
286 // Gets a shared reference to the ConnectionWaitable. 293 // Gets a shared reference to the ConnectionWaitable.
287 std::shared_ptr<ConnectionWaitable> connection_waitable() { return connection_waitable_; } 294 std::shared_ptr<ConnectionWaitable> connection_waitable() { return connection_waitable_; }
288 295
296 // Attempts to reconnect with the underlying Connection. Returns true if the
297 // reconnection attempt succeeded.
298 bool Reconnect();
299
289 private: 300 private:
290 bool kicked_ = false; 301 std::atomic<bool> kicked_;
291 302
292 // A set of features transmitted in the banner with the initial connection. 303 // A set of features transmitted in the banner with the initial connection.
293 // This is stored in the banner as 'features=feature0,feature1,etc'. 304 // This is stored in the banner as 'features=feature0,feature1,etc'.
@@ -310,6 +321,9 @@ class atransport {
310 // The underlying connection object. 321 // The underlying connection object.
311 std::shared_ptr<Connection> connection_ GUARDED_BY(mutex_); 322 std::shared_ptr<Connection> connection_ GUARDED_BY(mutex_);
312 323
324 // A callback that will be invoked when the atransport needs to reconnect.
325 ReconnectCallback reconnect_;
326
313 std::mutex mutex_; 327 std::mutex mutex_;
314 328
315 DISALLOW_COPY_AND_ASSIGN(atransport); 329 DISALLOW_COPY_AND_ASSIGN(atransport);
@@ -333,6 +347,7 @@ void update_transports(void);
333// Stops iteration and returns false if fn returns false, otherwise returns true. 347// Stops iteration and returns false if fn returns false, otherwise returns true.
334bool iterate_transports(std::function<bool(const atransport*)> fn); 348bool iterate_transports(std::function<bool(const atransport*)> fn);
335 349
350void init_reconnect_handler(void);
336void init_transport_registration(void); 351void init_transport_registration(void);
337void init_mdns_transport_discovery(void); 352void init_mdns_transport_discovery(void);
338std::string list_transports(bool long_listing); 353std::string list_transports(bool long_listing);
@@ -347,7 +362,8 @@ void register_usb_transport(usb_handle* h, const char* serial,
347void connect_device(const std::string& address, std::string* response); 362void connect_device(const std::string& address, std::string* response);
348 363
349/* cause new transports to be init'd and added to the list */ 364/* cause new transports to be init'd and added to the list */
350int register_socket_transport(int s, const char* serial, int port, int local); 365int register_socket_transport(int s, const char* serial, int port, int local,
366 atransport::ReconnectCallback reconnect);
351 367
352// This should only be used for transports with connection_state == kCsNoPerm. 368// This should only be used for transports with connection_state == kCsNoPerm.
353void unregister_usb_transport(usb_handle* usb); 369void unregister_usb_transport(usb_handle* usb);
diff --git a/adb/transport_local.cpp b/adb/transport_local.cpp
index e81f27c95..181d6665d 100644
--- a/adb/transport_local.cpp
+++ b/adb/transport_local.cpp
@@ -68,28 +68,24 @@ bool local_connect(int port) {
68 return local_connect_arbitrary_ports(port - 1, port, &dummy) == 0; 68 return local_connect_arbitrary_ports(port - 1, port, &dummy) == 0;
69} 69}
70 70
71void connect_device(const std::string& address, std::string* response) { 71std::tuple<unique_fd, int, std::string> tcp_connect(const std::string& address,
72 if (address.empty()) { 72 std::string* response) {
73 *response = "empty address";
74 return;
75 }
76
77 std::string serial; 73 std::string serial;
78 std::string host; 74 std::string host;
79 int port = DEFAULT_ADB_LOCAL_TRANSPORT_PORT; 75 int port = DEFAULT_ADB_LOCAL_TRANSPORT_PORT;
80 if (!android::base::ParseNetAddress(address, &host, &port, &serial, response)) { 76 if (!android::base::ParseNetAddress(address, &host, &port, &serial, response)) {
81 return; 77 return std::make_tuple(unique_fd(), port, serial);
82 } 78 }
83 79
84 std::string error; 80 std::string error;
85 int fd = network_connect(host.c_str(), port, SOCK_STREAM, 10, &error); 81 unique_fd fd(network_connect(host.c_str(), port, SOCK_STREAM, 10, &error));
86 if (fd == -1) { 82 if (fd == -1) {
87 *response = android::base::StringPrintf("unable to connect to %s: %s", 83 *response = android::base::StringPrintf("unable to connect to %s: %s",
88 serial.c_str(), error.c_str()); 84 serial.c_str(), error.c_str());
89 return; 85 return std::make_tuple(std::move(fd), port, serial);
90 } 86 }
91 87
92 D("client: connected %s remote on fd %d", serial.c_str(), fd); 88 D("client: connected %s remote on fd %d", serial.c_str(), fd.get());
93 close_on_exec(fd); 89 close_on_exec(fd);
94 disable_tcp_nagle(fd); 90 disable_tcp_nagle(fd);
95 91
@@ -98,7 +94,38 @@ void connect_device(const std::string& address, std::string* response) {
98 D("warning: failed to configure TCP keepalives (%s)", strerror(errno)); 94 D("warning: failed to configure TCP keepalives (%s)", strerror(errno));
99 } 95 }
100 96
101 int ret = register_socket_transport(fd, serial.c_str(), port, 0); 97 return std::make_tuple(std::move(fd), port, serial);
98}
99
100void connect_device(const std::string& address, std::string* response) {
101 if (address.empty()) {
102 *response = "empty address";
103 return;
104 }
105
106 unique_fd fd;
107 int port;
108 std::string serial;
109 std::tie(fd, port, serial) = tcp_connect(address, response);
110 auto reconnect = [address](atransport* t) {
111 std::string response;
112 unique_fd fd;
113 int port;
114 std::string serial;
115 std::tie(fd, port, serial) = tcp_connect(address, &response);
116 if (fd == -1) {
117 D("reconnect failed: %s", response.c_str());
118 return false;
119 }
120
121 // This invokes the part of register_socket_transport() that needs to be
122 // invoked if the atransport* has already been setup. This eventually
123 // calls atransport->SetConnection() with a newly created Connection*
124 // that will in turn send the CNXN packet.
125 return init_socket_transport(t, fd.release(), port, 0) >= 0;
126 };
127
128 int ret = register_socket_transport(fd.release(), serial.c_str(), port, 0, std::move(reconnect));
102 if (ret < 0) { 129 if (ret < 0) {
103 adb_close(fd); 130 adb_close(fd);
104 if (ret == -EALREADY) { 131 if (ret == -EALREADY) {
@@ -135,7 +162,8 @@ int local_connect_arbitrary_ports(int console_port, int adb_port, std::string* e
135 close_on_exec(fd); 162 close_on_exec(fd);
136 disable_tcp_nagle(fd); 163 disable_tcp_nagle(fd);
137 std::string serial = getEmulatorSerialString(console_port); 164 std::string serial = getEmulatorSerialString(console_port);
138 if (register_socket_transport(fd, serial.c_str(), adb_port, 1) == 0) { 165 if (register_socket_transport(fd, serial.c_str(), adb_port, 1,
166 [](atransport*) { return false; }) == 0) {
139 return 0; 167 return 0;
140 } 168 }
141 adb_close(fd); 169 adb_close(fd);
@@ -239,7 +267,8 @@ static void server_socket_thread(int port) {
239 close_on_exec(fd); 267 close_on_exec(fd);
240 disable_tcp_nagle(fd); 268 disable_tcp_nagle(fd);
241 std::string serial = android::base::StringPrintf("host-%d", fd); 269 std::string serial = android::base::StringPrintf("host-%d", fd);
242 if (register_socket_transport(fd, serial.c_str(), port, 1) != 0) { 270 if (register_socket_transport(fd, serial.c_str(), port, 1,
271 [](atransport*) { return false; }) != 0) {
243 adb_close(fd); 272 adb_close(fd);
244 } 273 }
245 } 274 }
@@ -338,7 +367,8 @@ static void qemu_socket_thread(int port) {
338 /* Host is connected. Register the transport, and start the 367 /* Host is connected. Register the transport, and start the
339 * exchange. */ 368 * exchange. */
340 std::string serial = android::base::StringPrintf("host-%d", fd); 369 std::string serial = android::base::StringPrintf("host-%d", fd);
341 if (register_socket_transport(fd, serial.c_str(), port, 1) != 0 || 370 if (register_socket_transport(fd, serial.c_str(), port, 1,
371 [](atransport*) { return false; }) != 0 ||
342 !WriteFdExactly(fd, _start_req, strlen(_start_req))) { 372 !WriteFdExactly(fd, _start_req, strlen(_start_req))) {
343 adb_close(fd); 373 adb_close(fd);
344 } 374 }
diff --git a/base/Android.bp b/base/Android.bp
index ec81f6122..47b29c6a6 100644
--- a/base/Android.bp
+++ b/base/Android.bp
@@ -26,6 +26,7 @@ cc_defaults {
26cc_library_headers { 26cc_library_headers {
27 name: "libbase_headers", 27 name: "libbase_headers",
28 vendor_available: true, 28 vendor_available: true,
29 recovery_available: true,
29 host_supported: true, 30 host_supported: true,
30 export_include_dirs: ["include"], 31 export_include_dirs: ["include"],
31 32
diff --git a/bootstat/boot_reason_test.sh b/bootstat/boot_reason_test.sh
index b194bbe7b..01b894842 100755
--- a/bootstat/boot_reason_test.sh
+++ b/bootstat/boot_reason_test.sh
@@ -312,6 +312,7 @@ init : processing action (boot) from (/system/etc/init/bootstat.rc
312init : processing action (ro.boot.bootreason=*) from (/system/etc/init/bootstat.rc 312init : processing action (ro.boot.bootreason=*) from (/system/etc/init/bootstat.rc
313init : processing action (sys.boot_completed=1 && sys.logbootcomplete=1) from (/system/etc/init/bootstat.rc 313init : processing action (sys.boot_completed=1 && sys.logbootcomplete=1) from (/system/etc/init/bootstat.rc
314 (/system/bin/bootstat --record_boot_complete --record_boot_reason --record_time_since_factory_reset -l)' 314 (/system/bin/bootstat --record_boot_complete --record_boot_reason --record_time_since_factory_reset -l)'
315 (/system/bin/bootstat --set_system_boot_reason --record_boot_complete --record_boot_reason --record_time_since_factory_reset -l)'
315 (/system/bin/bootstat -r post_decrypt_time_elapsed)' 316 (/system/bin/bootstat -r post_decrypt_time_elapsed)'
316init : Command 'exec - system log -- /system/bin/bootstat --record_boot_complete' action=sys.boot_completed=1 && sys.logbootcomplete=1 (/system/etc/init/bootstat.rc: 317init : Command 'exec - system log -- /system/bin/bootstat --record_boot_complete' action=sys.boot_completed=1 && sys.logbootcomplete=1 (/system/etc/init/bootstat.rc:
317init : Command 'exec - system log -- /system/bin/bootstat --record_boot_reason' action=sys.boot_completed=1 && sys.logbootcomplete=1 (/system/etc/init/bootstat.rc: 318init : Command 'exec - system log -- /system/bin/bootstat --record_boot_reason' action=sys.boot_completed=1 && sys.logbootcomplete=1 (/system/etc/init/bootstat.rc:
@@ -582,9 +583,9 @@ blind_reboot_test() {
582 duration_test 583 duration_test
583 case ${TEST} in 584 case ${TEST} in
584 bootloader | recovery | cold | hard | warm ) reason=${TEST} ;; 585 bootloader | recovery | cold | hard | warm ) reason=${TEST} ;;
585 *) reason=reboot,${TEST} ;; 586 *) reason=reboot,${TEST#optional_} ;;
586 esac 587 esac
587 adb reboot ${TEST} 588 adb reboot ${TEST#optional_}
588 wait_for_screen 589 wait_for_screen
589 bootloader_reason=`validate_property ro.boot.bootreason` 590 bootloader_reason=`validate_property ro.boot.bootreason`
590 EXPECT_PROPERTY ro.boot.bootreason ${bootloader_reason} 591 EXPECT_PROPERTY ro.boot.bootreason ${bootloader_reason}
@@ -948,6 +949,20 @@ test_adb_reboot() {
948 report_bootstat_logs reboot,adb 949 report_bootstat_logs reboot,adb
949} 950}
950 951
952[ "USAGE: test_rescueparty
953
954rescueparty test
955- adb reboot rescueparty
956- (wait until screen is up, boot has completed)
957- adb shell getprop sys.boot.reason
958- adb shell getprop ro.boot.bootreason
959- NB: should report reboot,rescueparty" ]
960test_optional_rescueparty() {
961 blind_reboot_test
962 echo "WARNING: legacy devices are allowed to fail following ro.boot.bootreason result" >&2
963 EXPECT_PROPERTY ro.boot.bootreason reboot,rescueparty
964}
965
951[ "USAGE: test_Its_Just_So_Hard_reboot 966[ "USAGE: test_Its_Just_So_Hard_reboot
952 967
953Its Just So Hard reboot test: 968Its Just So Hard reboot test:
diff --git a/debuggerd/debuggerd_test.cpp b/debuggerd/debuggerd_test.cpp
index 9b64be70f..dfb7a6a7c 100644
--- a/debuggerd/debuggerd_test.cpp
+++ b/debuggerd/debuggerd_test.cpp
@@ -80,8 +80,13 @@ constexpr char kWaitForGdbKey[] = "debug.debuggerd.wait_for_gdb";
80 return value; \ 80 return value; \
81 }() 81 }()
82 82
83// Backtrace frame dump could contain:
84// #01 pc 0001cded /data/tmp/debuggerd_test32 (raise_debugger_signal+80)
85// or
86// #01 pc 00022a09 /data/tmp/debuggerd_test32 (offset 0x12000) (raise_debugger_signal+80)
83#define ASSERT_BACKTRACE_FRAME(result, frame_name) \ 87#define ASSERT_BACKTRACE_FRAME(result, frame_name) \
84 ASSERT_MATCH(result, R"(#\d\d pc [0-9a-f]+\s+ \S+ \()" frame_name R"(\+)"); 88 ASSERT_MATCH(result, \
89 R"(#\d\d pc [0-9a-f]+\s+ \S+ (\(offset 0x[0-9a-f]+\) )?\()" frame_name R"(\+)");
85 90
86static void tombstoned_intercept(pid_t target_pid, unique_fd* intercept_fd, unique_fd* output_fd, 91static void tombstoned_intercept(pid_t target_pid, unique_fd* intercept_fd, unique_fd* output_fd,
87 InterceptStatus* status, DebuggerdDumpType intercept_type) { 92 InterceptStatus* status, DebuggerdDumpType intercept_type) {
diff --git a/debuggerd/handler/debuggerd_fallback.cpp b/debuggerd/handler/debuggerd_fallback.cpp
index dea2e17eb..079a574d3 100644
--- a/debuggerd/handler/debuggerd_fallback.cpp
+++ b/debuggerd/handler/debuggerd_fallback.cpp
@@ -304,7 +304,16 @@ static void crash_handler(siginfo_t* info, ucontext_t* ucontext, void* abort_mes
304 304
305 crash_mutex.lock(); 305 crash_mutex.lock();
306 if (lock_count++ > 0) { 306 if (lock_count++ > 0) {
307 async_safe_format_log(ANDROID_LOG_ERROR, "libc", "recursed signal handler call, exiting"); 307 async_safe_format_log(ANDROID_LOG_ERROR, "libc", "recursed signal handler call, aborting");
308 signal(SIGABRT, SIG_DFL);
309 raise(SIGABRT);
310 sigset_t sigset;
311 sigemptyset(&sigset);
312 sigaddset(&sigset, SIGABRT);
313 sigprocmask(SIG_UNBLOCK, &sigset, nullptr);
314
315 // Just in case...
316 async_safe_format_log(ANDROID_LOG_ERROR, "libc", "abort didn't exit, exiting");
308 _exit(1); 317 _exit(1);
309 } 318 }
310 319
diff --git a/fastboot/Android.mk b/fastboot/Android.mk
index 9bd0628b5..983e195dc 100644
--- a/fastboot/Android.mk
+++ b/fastboot/Android.mk
@@ -101,14 +101,13 @@ include $(BUILD_HOST_EXECUTABLE)
101# 101#
102 102
103my_dist_files := $(HOST_OUT_EXECUTABLES)/fastboot 103my_dist_files := $(HOST_OUT_EXECUTABLES)/fastboot
104my_dist_files += $(HOST_OUT_EXECUTABLES)/mke2fs$(HOST_EXECUTABLE_SUFFIX) 104my_dist_files += $(HOST_OUT_EXECUTABLES)/mke2fs
105my_dist_files += $(HOST_OUT_EXECUTABLES)/e2fsdroid$(HOST_EXECUTABLE_SUFFIX) 105my_dist_files += $(HOST_OUT_EXECUTABLES)/e2fsdroid
106my_dist_files += $(HOST_OUT_EXECUTABLES)/make_f2fs$(HOST_EXECUTABLE_SUFFIX) 106my_dist_files += $(HOST_OUT_EXECUTABLES)/make_f2fs
107my_dist_files += $(HOST_OUT_EXECUTABLES)/sload_f2fs$(HOST_EXECUTABLE_SUFFIX) 107my_dist_files += $(HOST_OUT_EXECUTABLES)/sload_f2fs
108$(call dist-for-goals,dist_files sdk win_sdk,$(my_dist_files)) 108$(call dist-for-goals,dist_files sdk win_sdk,$(my_dist_files))
109ifdef HOST_CROSS_OS 109ifdef HOST_CROSS_OS
110# Archive fastboot.exe for win_sdk build. 110$(call dist-for-goals,dist_files sdk win_sdk,$(ALL_MODULES.host_cross_fastboot.BUILT))
111$(call dist-for-goals,win_sdk,$(ALL_MODULES.host_cross_fastboot.BUILT))
112endif 111endif
113my_dist_files := 112my_dist_files :=
114 113
diff --git a/fastboot/fastboot.cpp b/fastboot/fastboot.cpp
index 9463cc917..649326280 100644
--- a/fastboot/fastboot.cpp
+++ b/fastboot/fastboot.cpp
@@ -507,7 +507,8 @@ static std::string make_temporary_template() {
507static std::string make_temporary_directory() { 507static std::string make_temporary_directory() {
508 std::string result(make_temporary_template()); 508 std::string result(make_temporary_template());
509 if (mkdtemp(&result[0]) == nullptr) { 509 if (mkdtemp(&result[0]) == nullptr) {
510 die("unable to create temporary directory: %s", strerror(errno)); 510 die("unable to create temporary directory with template %s: %s",
511 result.c_str(), strerror(errno));
511 } 512 }
512 return result; 513 return result;
513} 514}
@@ -516,7 +517,8 @@ static int make_temporary_fd(const char* what) {
516 std::string path_template(make_temporary_template()); 517 std::string path_template(make_temporary_template());
517 int fd = mkstemp(&path_template[0]); 518 int fd = mkstemp(&path_template[0]);
518 if (fd == -1) { 519 if (fd == -1) {
519 die("failed to create temporary file for %s: %s\n", what, strerror(errno)); 520 die("failed to create temporary file for %s with template %s: %s\n",
521 path_template.c_str(), what, strerror(errno));
520 } 522 }
521 unlink(path_template.c_str()); 523 unlink(path_template.c_str());
522 return fd; 524 return fd;
diff --git a/fs_mgr/Android.bp b/fs_mgr/Android.bp
index f23150d1c..05dba1524 100644
--- a/fs_mgr/Android.bp
+++ b/fs_mgr/Android.bp
@@ -42,6 +42,7 @@ cc_library_static {
42 "fs_mgr_verity.cpp", 42 "fs_mgr_verity.cpp",
43 "fs_mgr_avb.cpp", 43 "fs_mgr_avb.cpp",
44 "fs_mgr_avb_ops.cpp", 44 "fs_mgr_avb_ops.cpp",
45 "fs_mgr_dm_linear.cpp",
45 ], 46 ],
46 static_libs: [ 47 static_libs: [
47 "libfec", 48 "libfec",
diff --git a/fs_mgr/fs_mgr.cpp b/fs_mgr/fs_mgr.cpp
index 6769fda67..6e9ffba59 100644
--- a/fs_mgr/fs_mgr.cpp
+++ b/fs_mgr/fs_mgr.cpp
@@ -794,6 +794,29 @@ static bool call_vdc(const std::vector<std::string>& args) {
794 return true; 794 return true;
795} 795}
796 796
797bool fs_mgr_update_logical_partition(struct fstab_rec* rec) {
798 // Logical partitions are specified with a named partition rather than a
799 // block device, so if the block device is a path, then it has already
800 // been updated.
801 if (rec->blk_device[0] == '/') {
802 return true;
803 }
804
805 android::base::unique_fd dm_fd(open("/dev/device-mapper", O_RDONLY));
806 if (dm_fd < 0) {
807 PLOG(ERROR) << "open /dev/device-mapper failed";
808 return false;
809 }
810 struct dm_ioctl io;
811 std::string device_name;
812 if (!fs_mgr_dm_get_device_name(&io, rec->blk_device, dm_fd, &device_name)) {
813 return false;
814 }
815 free(rec->blk_device);
816 rec->blk_device = strdup(device_name.c_str());
817 return true;
818}
819
797/* When multiple fstab records share the same mount_point, it will 820/* When multiple fstab records share the same mount_point, it will
798 * try to mount each one in turn, and ignore any duplicates after a 821 * try to mount each one in turn, and ignore any duplicates after a
799 * first successful mount. 822 * first successful mount.
@@ -845,6 +868,13 @@ int fs_mgr_mount_all(struct fstab *fstab, int mount_mode)
845 } 868 }
846 } 869 }
847 870
871 if ((fstab->recs[i].fs_mgr_flags & MF_LOGICAL)) {
872 if (!fs_mgr_update_logical_partition(&fstab->recs[i])) {
873 LERROR << "Could not set up logical partition, skipping!";
874 continue;
875 }
876 }
877
848 if (fstab->recs[i].fs_mgr_flags & MF_WAIT && 878 if (fstab->recs[i].fs_mgr_flags & MF_WAIT &&
849 !fs_mgr_wait_for_file(fstab->recs[i].blk_device, 20s)) { 879 !fs_mgr_wait_for_file(fstab->recs[i].blk_device, 20s)) {
850 LERROR << "Skipping '" << fstab->recs[i].blk_device << "' during mount_all"; 880 LERROR << "Skipping '" << fstab->recs[i].blk_device << "' during mount_all";
@@ -1065,6 +1095,13 @@ int fs_mgr_do_mount(struct fstab *fstab, const char *n_name, char *n_blk_device,
1065 return FS_MGR_DOMNT_FAILED; 1095 return FS_MGR_DOMNT_FAILED;
1066 } 1096 }
1067 1097
1098 if ((fstab->recs[i].fs_mgr_flags & MF_LOGICAL)) {
1099 if (!fs_mgr_update_logical_partition(&fstab->recs[i])) {
1100 LERROR << "Could not set up logical partition, skipping!";
1101 continue;
1102 }
1103 }
1104
1068 /* First check the filesystem if requested */ 1105 /* First check the filesystem if requested */
1069 if (fstab->recs[i].fs_mgr_flags & MF_WAIT && !fs_mgr_wait_for_file(n_blk_device, 20s)) { 1106 if (fstab->recs[i].fs_mgr_flags & MF_WAIT && !fs_mgr_wait_for_file(n_blk_device, 20s)) {
1070 LERROR << "Skipping mounting '" << n_blk_device << "'"; 1107 LERROR << "Skipping mounting '" << n_blk_device << "'";
@@ -1383,7 +1420,7 @@ bool fs_mgr_update_verity_state(fs_mgr_verity_state_callback callback) {
1383 mount_point = basename(fstab->recs[i].mount_point); 1420 mount_point = basename(fstab->recs[i].mount_point);
1384 } 1421 }
1385 1422
1386 fs_mgr_verity_ioctl_init(io, mount_point); 1423 fs_mgr_dm_ioctl_init(io, DM_BUF_SIZE, mount_point);
1387 1424
1388 const char* status; 1425 const char* status;
1389 if (ioctl(fd, DM_TABLE_STATUS, io)) { 1426 if (ioctl(fd, DM_TABLE_STATUS, io)) {
diff --git a/fs_mgr/fs_mgr_avb.cpp b/fs_mgr/fs_mgr_avb.cpp
index 6ea38335e..5a9cb654f 100644
--- a/fs_mgr/fs_mgr_avb.cpp
+++ b/fs_mgr/fs_mgr_avb.cpp
@@ -303,7 +303,7 @@ static std::string construct_verity_table(const AvbHashtreeDescriptor& hashtree_
303 303
304static bool load_verity_table(struct dm_ioctl* io, const std::string& dm_device_name, int fd, 304static bool load_verity_table(struct dm_ioctl* io, const std::string& dm_device_name, int fd,
305 uint64_t image_size, const std::string& verity_table) { 305 uint64_t image_size, const std::string& verity_table) {
306 fs_mgr_verity_ioctl_init(io, dm_device_name); 306 fs_mgr_dm_ioctl_init(io, DM_BUF_SIZE, dm_device_name);
307 307
308 // The buffer consists of [dm_ioctl][dm_target_spec][verity_params]. 308 // The buffer consists of [dm_ioctl][dm_target_spec][verity_params].
309 char* buffer = (char*)io; 309 char* buffer = (char*)io;
@@ -360,14 +360,14 @@ static bool hashtree_dm_verity_setup(struct fstab_rec* fstab_entry,
360 alignas(dm_ioctl) char buffer[DM_BUF_SIZE]; 360 alignas(dm_ioctl) char buffer[DM_BUF_SIZE];
361 struct dm_ioctl* io = (struct dm_ioctl*)buffer; 361 struct dm_ioctl* io = (struct dm_ioctl*)buffer;
362 const std::string mount_point(basename(fstab_entry->mount_point)); 362 const std::string mount_point(basename(fstab_entry->mount_point));
363 if (!fs_mgr_create_verity_device(io, mount_point, fd)) { 363 if (!fs_mgr_dm_create_device(io, mount_point, fd)) {
364 LERROR << "Couldn't create verity device!"; 364 LERROR << "Couldn't create verity device!";
365 return false; 365 return false;
366 } 366 }
367 367
368 // Gets the name of the device file. 368 // Gets the name of the device file.
369 std::string verity_blk_name; 369 std::string verity_blk_name;
370 if (!fs_mgr_get_verity_device_name(io, mount_point, fd, &verity_blk_name)) { 370 if (!fs_mgr_dm_get_device_name(io, mount_point, fd, &verity_blk_name)) {
371 LERROR << "Couldn't get verity device number!"; 371 LERROR << "Couldn't get verity device number!";
372 return false; 372 return false;
373 } 373 }
@@ -386,7 +386,7 @@ static bool hashtree_dm_verity_setup(struct fstab_rec* fstab_entry,
386 } 386 }
387 387
388 // Activates the device. 388 // Activates the device.
389 if (!fs_mgr_resume_verity_table(io, mount_point, fd)) { 389 if (!fs_mgr_dm_resume_table(io, mount_point, fd)) {
390 return false; 390 return false;
391 } 391 }
392 392
@@ -585,7 +585,13 @@ SetUpAvbHashtreeResult FsManagerAvbHandle::SetUpAvbHashtree(struct fstab_rec* fs
585 585
586 // Derives partition_name from blk_device to query the corresponding AVB HASHTREE descriptor 586 // Derives partition_name from blk_device to query the corresponding AVB HASHTREE descriptor
587 // to setup dm-verity. The partition_names in AVB descriptors are without A/B suffix. 587 // to setup dm-verity. The partition_names in AVB descriptors are without A/B suffix.
588 std::string partition_name(basename(fstab_entry->blk_device)); 588 std::string partition_name;
589 if (fstab_entry->fs_mgr_flags & MF_LOGICAL) {
590 partition_name = fstab_entry->logical_partition_name;
591 } else {
592 partition_name = basename(fstab_entry->blk_device);
593 }
594
589 if (fstab_entry->fs_mgr_flags & MF_SLOTSELECT) { 595 if (fstab_entry->fs_mgr_flags & MF_SLOTSELECT) {
590 auto ab_suffix = partition_name.rfind(fs_mgr_get_slot_suffix()); 596 auto ab_suffix = partition_name.rfind(fs_mgr_get_slot_suffix());
591 if (ab_suffix != std::string::npos) { 597 if (ab_suffix != std::string::npos) {
diff --git a/fs_mgr/fs_mgr_dm_ioctl.cpp b/fs_mgr/fs_mgr_dm_ioctl.cpp
index 5f9b11868..3a7fae42e 100644
--- a/fs_mgr/fs_mgr_dm_ioctl.cpp
+++ b/fs_mgr/fs_mgr_dm_ioctl.cpp
@@ -23,9 +23,9 @@
23#include "fs_mgr_priv.h" 23#include "fs_mgr_priv.h"
24#include "fs_mgr_priv_dm_ioctl.h" 24#include "fs_mgr_priv_dm_ioctl.h"
25 25
26void fs_mgr_verity_ioctl_init(struct dm_ioctl* io, const std::string& name) { 26void fs_mgr_dm_ioctl_init(struct dm_ioctl* io, size_t size, const std::string& name) {
27 memset(io, 0, DM_BUF_SIZE); 27 memset(io, 0, size);
28 io->data_size = DM_BUF_SIZE; 28 io->data_size = size;
29 io->data_start = sizeof(struct dm_ioctl); 29 io->data_start = sizeof(struct dm_ioctl);
30 io->version[0] = 4; 30 io->version[0] = 4;
31 io->version[1] = 0; 31 io->version[1] = 0;
@@ -35,8 +35,8 @@ void fs_mgr_verity_ioctl_init(struct dm_ioctl* io, const std::string& name) {
35 } 35 }
36} 36}
37 37
38bool fs_mgr_create_verity_device(struct dm_ioctl* io, const std::string& name, int fd) { 38bool fs_mgr_dm_create_device(struct dm_ioctl* io, const std::string& name, int fd) {
39 fs_mgr_verity_ioctl_init(io, name); 39 fs_mgr_dm_ioctl_init(io, sizeof(*io), name);
40 if (ioctl(fd, DM_DEV_CREATE, io)) { 40 if (ioctl(fd, DM_DEV_CREATE, io)) {
41 PERROR << "Error creating device mapping"; 41 PERROR << "Error creating device mapping";
42 return false; 42 return false;
@@ -44,8 +44,8 @@ bool fs_mgr_create_verity_device(struct dm_ioctl* io, const std::string& name, i
44 return true; 44 return true;
45} 45}
46 46
47bool fs_mgr_destroy_verity_device(struct dm_ioctl* io, const std::string& name, int fd) { 47bool fs_mgr_dm_destroy_device(struct dm_ioctl* io, const std::string& name, int fd) {
48 fs_mgr_verity_ioctl_init(io, name); 48 fs_mgr_dm_ioctl_init(io, sizeof(*io), name);
49 if (ioctl(fd, DM_DEV_REMOVE, io)) { 49 if (ioctl(fd, DM_DEV_REMOVE, io)) {
50 PERROR << "Error removing device mapping"; 50 PERROR << "Error removing device mapping";
51 return false; 51 return false;
@@ -53,13 +53,13 @@ bool fs_mgr_destroy_verity_device(struct dm_ioctl* io, const std::string& name,
53 return true; 53 return true;
54} 54}
55 55
56bool fs_mgr_get_verity_device_name(struct dm_ioctl* io, const std::string& name, int fd, 56bool fs_mgr_dm_get_device_name(struct dm_ioctl* io, const std::string& name, int fd,
57 std::string* out_dev_name) { 57 std::string* out_dev_name) {
58 FS_MGR_CHECK(out_dev_name != nullptr); 58 FS_MGR_CHECK(out_dev_name != nullptr);
59 59
60 fs_mgr_verity_ioctl_init(io, name); 60 fs_mgr_dm_ioctl_init(io, sizeof(*io), name);
61 if (ioctl(fd, DM_DEV_STATUS, io)) { 61 if (ioctl(fd, DM_DEV_STATUS, io)) {
62 PERROR << "Error fetching verity device number"; 62 PERROR << "Error fetching device-mapper device number";
63 return false; 63 return false;
64 } 64 }
65 65
@@ -69,10 +69,10 @@ bool fs_mgr_get_verity_device_name(struct dm_ioctl* io, const std::string& name,
69 return true; 69 return true;
70} 70}
71 71
72bool fs_mgr_resume_verity_table(struct dm_ioctl* io, const std::string& name, int fd) { 72bool fs_mgr_dm_resume_table(struct dm_ioctl* io, const std::string& name, int fd) {
73 fs_mgr_verity_ioctl_init(io, name); 73 fs_mgr_dm_ioctl_init(io, sizeof(*io), name);
74 if (ioctl(fd, DM_DEV_SUSPEND, io)) { 74 if (ioctl(fd, DM_DEV_SUSPEND, io)) {
75 PERROR << "Error activating verity device"; 75 PERROR << "Error activating device table";
76 return false; 76 return false;
77 } 77 }
78 return true; 78 return true;
diff --git a/fs_mgr/fs_mgr_dm_linear.cpp b/fs_mgr/fs_mgr_dm_linear.cpp
new file mode 100644
index 000000000..b2f3a6887
--- /dev/null
+++ b/fs_mgr/fs_mgr_dm_linear.cpp
@@ -0,0 +1,141 @@
1/*
2 * Copyright (C) 2018 The Android Open Source Project
3 *
4 * Permission is hereby granted, free of charge, to any person
5 * obtaining a copy of this software and associated documentation
6 * files (the "Software"), to deal in the Software without
7 * restriction, including without limitation the rights to use, copy,
8 * modify, merge, publish, distribute, sublicense, and/or sell copies
9 * of the Software, and to permit persons to whom the Software is
10 * furnished to do so, subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice shall be
13 * included in all copies or substantial portions of the Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
19 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
20 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 * SOFTWARE.
23 */
24
25#include "fs_mgr_dm_linear.h"
26
27#include <inttypes.h>
28#include <linux/dm-ioctl.h>
29#include <string.h>
30#include <sys/ioctl.h>
31#include <sys/stat.h>
32#include <unistd.h>
33
34#include <sstream>
35
36#include <android-base/logging.h>
37#include <android-base/stringprintf.h>
38#include <android-base/strings.h>
39#include <android-base/unique_fd.h>
40
41#include "fs_mgr_priv.h"
42#include "fs_mgr_priv_dm_ioctl.h"
43
44namespace android {
45namespace fs_mgr {
46
47std::string LogicalPartitionExtent::Serialize() const {
48 // Note: we need to include an explicit null-terminator.
49 std::string argv =
50 android::base::StringPrintf("%s %" PRIu64, block_device_.c_str(), first_sector_);
51 argv.push_back(0);
52
53 // The kernel expects each target to be aligned.
54 size_t spec_bytes = sizeof(struct dm_target_spec) + argv.size();
55 size_t padding = ((spec_bytes + 7) & ~7) - spec_bytes;
56 for (size_t i = 0; i < padding; i++) {
57 argv.push_back(0);
58 }
59
60 struct dm_target_spec spec;
61 spec.sector_start = logical_sector_;
62 spec.length = num_sectors_;
63 spec.status = 0;
64 strcpy(spec.target_type, "linear");
65 spec.next = sizeof(struct dm_target_spec) + argv.size();
66
67 return std::string((char*)&spec, sizeof(spec)) + argv;
68}
69
70static bool LoadDmTable(int dm_fd, const LogicalPartition& partition) {
71 // Combine all dm_target_spec buffers together.
72 std::string target_string;
73 for (const auto& extent : partition.extents) {
74 target_string += extent.Serialize();
75 }
76
77 // Allocate the ioctl buffer.
78 size_t buffer_size = sizeof(struct dm_ioctl) + target_string.size();
79 std::unique_ptr<uint8_t[]> buffer = std::make_unique<uint8_t[]>(buffer_size);
80
81 // Initialize the ioctl buffer header, then copy our target specs in.
82 struct dm_ioctl* io = reinterpret_cast<struct dm_ioctl*>(buffer.get());
83 fs_mgr_dm_ioctl_init(io, buffer_size, partition.name);
84 io->target_count = partition.extents.size();
85 if (partition.attributes & kPartitionReadonly) {
86 io->flags |= DM_READONLY_FLAG;
87 }
88 memcpy(io + 1, target_string.c_str(), target_string.size());
89
90 if (ioctl(dm_fd, DM_TABLE_LOAD, io)) {
91 PERROR << "Failed ioctl() on DM_TABLE_LOAD, partition " << partition.name;
92 return false;
93 }
94 return true;
95}
96
97static bool LoadTablesAndActivate(int dm_fd, const LogicalPartition& partition) {
98 if (!LoadDmTable(dm_fd, partition)) {
99 return false;
100 }
101
102 struct dm_ioctl io;
103 return fs_mgr_dm_resume_table(&io, partition.name, dm_fd);
104}
105
106static bool CreateDmDeviceForPartition(int dm_fd, const LogicalPartition& partition) {
107 struct dm_ioctl io;
108 if (!fs_mgr_dm_create_device(&io, partition.name, dm_fd)) {
109 return false;
110 }
111 if (!LoadTablesAndActivate(dm_fd, partition)) {
112 // Remove the device rather than leave it in an inactive state.
113 fs_mgr_dm_destroy_device(&io, partition.name, dm_fd);
114 return false;
115 }
116
117 LINFO << "Created device-mapper device: " << partition.name;
118 return true;
119}
120
121bool CreateLogicalPartitions(const LogicalPartitionTable& table) {
122 android::base::unique_fd dm_fd(open("/dev/device-mapper", O_RDWR));
123 if (dm_fd < 0) {
124 PLOG(ERROR) << "failed to open /dev/device-mapper";
125 return false;
126 }
127 for (const auto& partition : table.partitions) {
128 if (!CreateDmDeviceForPartition(dm_fd, partition)) {
129 LOG(ERROR) << "could not create dm-linear device for partition: " << partition.name;
130 return false;
131 }
132 }
133 return true;
134}
135
136std::unique_ptr<LogicalPartitionTable> LoadPartitionsFromDeviceTree() {
137 return nullptr;
138}
139
140} // namespace fs_mgr
141} // namespace android
diff --git a/fs_mgr/fs_mgr_fstab.cpp b/fs_mgr/fs_mgr_fstab.cpp
index 3fbef9fc2..af4d6c1e1 100644
--- a/fs_mgr/fs_mgr_fstab.cpp
+++ b/fs_mgr/fs_mgr_fstab.cpp
@@ -109,6 +109,7 @@ static struct flag_list fs_mgr_flags[] = {
109 {"logicalblk=", MF_LOGICALBLKSIZE}, 109 {"logicalblk=", MF_LOGICALBLKSIZE},
110 {"sysfs_path=", MF_SYSFS}, 110 {"sysfs_path=", MF_SYSFS},
111 {"defaults", 0}, 111 {"defaults", 0},
112 {"logical", MF_LOGICAL},
112 {0, 0}, 113 {0, 0},
113}; 114};
114 115
@@ -445,10 +446,6 @@ static std::string read_fstab_from_dt() {
445 LERROR << "dt_fstab: Failed to find device for partition " << dp->d_name; 446 LERROR << "dt_fstab: Failed to find device for partition " << dp->d_name;
446 return {}; 447 return {};
447 } 448 }
448 if (!StartsWith(value, "/dev")) {
449 LERROR << "dt_fstab: Invalid device node for partition " << dp->d_name;
450 return {};
451 }
452 fstab_entry.push_back(value); 449 fstab_entry.push_back(value);
453 450
454 std::string mount_point; 451 std::string mount_point;
@@ -631,6 +628,10 @@ static struct fstab *fs_mgr_read_fstab_file(FILE *fstab_file)
631 fstab->recs[cnt].erase_blk_size = flag_vals.erase_blk_size; 628 fstab->recs[cnt].erase_blk_size = flag_vals.erase_blk_size;
632 fstab->recs[cnt].logical_blk_size = flag_vals.logical_blk_size; 629 fstab->recs[cnt].logical_blk_size = flag_vals.logical_blk_size;
633 fstab->recs[cnt].sysfs_path = flag_vals.sysfs_path; 630 fstab->recs[cnt].sysfs_path = flag_vals.sysfs_path;
631 if (fstab->recs[cnt].fs_mgr_flags & MF_LOGICAL) {
632 fstab->recs[cnt].logical_partition_name = strdup(fstab->recs[cnt].blk_device);
633 }
634
634 cnt++; 635 cnt++;
635 } 636 }
636 /* If an A/B partition, modify block device to be the real block device */ 637 /* If an A/B partition, modify block device to be the real block device */
@@ -685,6 +686,49 @@ static struct fstab *in_place_merge(struct fstab *a, struct fstab *b)
685 return a; 686 return a;
686} 687}
687 688
689/* Extracts <device>s from the by-name symlinks specified in a fstab:
690 * /dev/block/<type>/<device>/by-name/<partition>
691 *
692 * <type> can be: platform, pci or vbd.
693 *
694 * For example, given the following entries in the input fstab:
695 * /dev/block/platform/soc/1da4000.ufshc/by-name/system
696 * /dev/block/pci/soc.0/f9824900.sdhci/by-name/vendor
697 * it returns a set { "soc/1da4000.ufshc", "soc.0/f9824900.sdhci" }.
698 */
699static std::set<std::string> extract_boot_devices(const fstab& fstab) {
700 std::set<std::string> boot_devices;
701
702 for (int i = 0; i < fstab.num_entries; i++) {
703 std::string blk_device(fstab.recs[i].blk_device);
704 // Skips blk_device that doesn't conform to the format.
705 if (!android::base::StartsWith(blk_device, "/dev/block") ||
706 android::base::StartsWith(blk_device, "/dev/block/by-name") ||
707 android::base::StartsWith(blk_device, "/dev/block/bootdevice/by-name")) {
708 continue;
709 }
710 // Skips non-by_name blk_device.
711 // /dev/block/<type>/<device>/by-name/<partition>
712 // ^ slash_by_name
713 auto slash_by_name = blk_device.find("/by-name");
714 if (slash_by_name == std::string::npos) continue;
715 blk_device.erase(slash_by_name); // erases /by-name/<partition>
716
717 // Erases /dev/block/, now we have <type>/<device>
718 blk_device.erase(0, std::string("/dev/block/").size());
719
720 // <type>/<device>
721 // ^ first_slash
722 auto first_slash = blk_device.find('/');
723 if (first_slash == std::string::npos) continue;
724
725 auto boot_device = blk_device.substr(first_slash + 1);
726 if (!boot_device.empty()) boot_devices.insert(std::move(boot_device));
727 }
728
729 return boot_devices;
730}
731
688struct fstab *fs_mgr_read_fstab(const char *fstab_path) 732struct fstab *fs_mgr_read_fstab(const char *fstab_path)
689{ 733{
690 FILE *fstab_file; 734 FILE *fstab_file;
@@ -797,6 +841,7 @@ void fs_mgr_free_fstab(struct fstab *fstab)
797 for (i = 0; i < fstab->num_entries; i++) { 841 for (i = 0; i < fstab->num_entries; i++) {
798 /* Free the pointers return by strdup(3) */ 842 /* Free the pointers return by strdup(3) */
799 free(fstab->recs[i].blk_device); 843 free(fstab->recs[i].blk_device);
844 free(fstab->recs[i].logical_partition_name);
800 free(fstab->recs[i].mount_point); 845 free(fstab->recs[i].mount_point);
801 free(fstab->recs[i].fs_type); 846 free(fstab->recs[i].fs_type);
802 free(fstab->recs[i].fs_options); 847 free(fstab->recs[i].fs_options);
@@ -861,6 +906,23 @@ struct fstab_rec* fs_mgr_get_entry_for_mount_point(struct fstab* fstab, const st
861 return nullptr; 906 return nullptr;
862} 907}
863 908
909std::set<std::string> fs_mgr_get_boot_devices() {
910 // boot_devices can be specified in device tree.
911 std::string dt_value;
912 std::string file_name = get_android_dt_dir() + "/boot_devices";
913 if (read_dt_file(file_name, &dt_value)) {
914 auto boot_devices = android::base::Split(dt_value, ",");
915 return std::set<std::string>(boot_devices.begin(), boot_devices.end());
916 }
917
918 // Fallback to extract boot devices from fstab.
919 std::unique_ptr<fstab, decltype(&fs_mgr_free_fstab)> fstab(fs_mgr_read_fstab_default(),
920 fs_mgr_free_fstab);
921 if (fstab) return extract_boot_devices(*fstab);
922
923 return {};
924}
925
864int fs_mgr_is_voldmanaged(const struct fstab_rec *fstab) 926int fs_mgr_is_voldmanaged(const struct fstab_rec *fstab)
865{ 927{
866 return fstab->fs_mgr_flags & MF_VOLDMANAGED; 928 return fstab->fs_mgr_flags & MF_VOLDMANAGED;
@@ -944,3 +1006,7 @@ int fs_mgr_has_sysfs_path(const struct fstab_rec *fstab)
944{ 1006{
945 return fstab->fs_mgr_flags & MF_SYSFS; 1007 return fstab->fs_mgr_flags & MF_SYSFS;
946} 1008}
1009
1010int fs_mgr_is_logical(const struct fstab_rec* fstab) {
1011 return fstab->fs_mgr_flags & MF_LOGICAL;
1012}
diff --git a/fs_mgr/fs_mgr_priv.h b/fs_mgr/fs_mgr_priv.h
index ade0cc4cd..afd722790 100644
--- a/fs_mgr/fs_mgr_priv.h
+++ b/fs_mgr/fs_mgr_priv.h
@@ -82,6 +82,7 @@
82 * 82 *
83 */ 83 */
84 84
85// clang-format off
85#define MF_WAIT 0x1 86#define MF_WAIT 0x1
86#define MF_CHECK 0x2 87#define MF_CHECK 0x2
87#define MF_CRYPT 0x4 88#define MF_CRYPT 0x4
@@ -111,6 +112,8 @@
111#define MF_AVB 0X2000000 112#define MF_AVB 0X2000000
112#define MF_KEYDIRECTORY 0X4000000 113#define MF_KEYDIRECTORY 0X4000000
113#define MF_SYSFS 0X8000000 114#define MF_SYSFS 0X8000000
115#define MF_LOGICAL 0x10000000
116// clang-format on
114 117
115#define DM_BUF_SIZE 4096 118#define DM_BUF_SIZE 4096
116 119
diff --git a/fs_mgr/fs_mgr_priv_dm_ioctl.h b/fs_mgr/fs_mgr_priv_dm_ioctl.h
index 792683eca..792475df7 100644
--- a/fs_mgr/fs_mgr_priv_dm_ioctl.h
+++ b/fs_mgr/fs_mgr_priv_dm_ioctl.h
@@ -20,15 +20,15 @@
20#include <linux/dm-ioctl.h> 20#include <linux/dm-ioctl.h>
21#include <string> 21#include <string>
22 22
23void fs_mgr_verity_ioctl_init(struct dm_ioctl* io, const std::string& name); 23void fs_mgr_dm_ioctl_init(struct dm_ioctl* io, size_t size, const std::string& name);
24 24
25bool fs_mgr_create_verity_device(struct dm_ioctl* io, const std::string& name, int fd); 25bool fs_mgr_dm_create_device(struct dm_ioctl* io, const std::string& name, int fd);
26 26
27bool fs_mgr_destroy_verity_device(struct dm_ioctl* io, const std::string& name, int fd); 27bool fs_mgr_dm_destroy_device(struct dm_ioctl* io, const std::string& name, int fd);
28 28
29bool fs_mgr_get_verity_device_name(struct dm_ioctl* io, const std::string& name, int fd, 29bool fs_mgr_dm_get_device_name(struct dm_ioctl* io, const std::string& name, int fd,
30 std::string* out_dev_name); 30 std::string* out_dev_name);
31 31
32bool fs_mgr_resume_verity_table(struct dm_ioctl* io, const std::string& name, int fd); 32bool fs_mgr_dm_resume_table(struct dm_ioctl* io, const std::string& name, int fd);
33 33
34#endif /* __CORE_FS_MGR_PRIV_DM_IOCTL_H */ 34#endif /* __CORE_FS_MGR_PRIV_DM_IOCTL_H */
diff --git a/fs_mgr/fs_mgr_slotselect.cpp b/fs_mgr/fs_mgr_slotselect.cpp
index 0a113b47e..3b01d0e80 100644
--- a/fs_mgr/fs_mgr_slotselect.cpp
+++ b/fs_mgr/fs_mgr_slotselect.cpp
@@ -36,19 +36,30 @@ bool fs_mgr_update_for_slotselect(struct fstab *fstab) {
36 std::string ab_suffix; 36 std::string ab_suffix;
37 37
38 for (n = 0; n < fstab->num_entries; n++) { 38 for (n = 0; n < fstab->num_entries; n++) {
39 if (fstab->recs[n].fs_mgr_flags & MF_SLOTSELECT) { 39 fstab_rec& record = fstab->recs[n];
40 char *tmp; 40 if (record.fs_mgr_flags & MF_SLOTSELECT) {
41 if (ab_suffix.empty()) { 41 if (ab_suffix.empty()) {
42 ab_suffix = fs_mgr_get_slot_suffix(); 42 ab_suffix = fs_mgr_get_slot_suffix();
43 // Return false if failed to get ab_suffix when MF_SLOTSELECT is specified. 43 // Return false if failed to get ab_suffix when MF_SLOTSELECT is specified.
44 if (ab_suffix.empty()) return false; 44 if (ab_suffix.empty()) return false;
45 } 45 }
46 if (asprintf(&tmp, "%s%s", fstab->recs[n].blk_device, ab_suffix.c_str()) > 0) { 46
47 free(fstab->recs[n].blk_device); 47 char* new_blk_device;
48 fstab->recs[n].blk_device = tmp; 48 if (asprintf(&new_blk_device, "%s%s", record.blk_device, ab_suffix.c_str()) <= 0) {
49 } else {
50 return false; 49 return false;
51 } 50 }
51 free(record.blk_device);
52 record.blk_device = new_blk_device;
53
54 char* new_partition_name;
55 if (record.logical_partition_name) {
56 if (asprintf(&new_partition_name, "%s%s", record.logical_partition_name,
57 ab_suffix.c_str()) <= 0) {
58 return false;
59 }
60 free(record.logical_partition_name);
61 record.logical_partition_name = new_partition_name;
62 }
52 } 63 }
53 } 64 }
54 return true; 65 return true;
diff --git a/fs_mgr/fs_mgr_verity.cpp b/fs_mgr/fs_mgr_verity.cpp
index d0bb05826..fe41f8ac2 100644
--- a/fs_mgr/fs_mgr_verity.cpp
+++ b/fs_mgr/fs_mgr_verity.cpp
@@ -258,7 +258,7 @@ static int load_verity_table(struct dm_ioctl *io, const std::string &name,
258 char *buffer = (char*) io; 258 char *buffer = (char*) io;
259 size_t bufsize; 259 size_t bufsize;
260 260
261 fs_mgr_verity_ioctl_init(io, name); 261 fs_mgr_dm_ioctl_init(io, DM_BUF_SIZE, name);
262 262
263 struct dm_target_spec *tgt = (struct dm_target_spec *) &buffer[sizeof(struct dm_ioctl)]; 263 struct dm_target_spec *tgt = (struct dm_target_spec *) &buffer[sizeof(struct dm_ioctl)];
264 264
@@ -805,13 +805,13 @@ int fs_mgr_setup_verity(struct fstab_rec *fstab, bool wait_for_verity_dev)
805 } 805 }
806 806
807 // create the device 807 // create the device
808 if (!fs_mgr_create_verity_device(io, mount_point, fd)) { 808 if (!fs_mgr_dm_create_device(io, mount_point, fd)) {
809 LERROR << "Couldn't create verity device!"; 809 LERROR << "Couldn't create verity device!";
810 goto out; 810 goto out;
811 } 811 }
812 812
813 // get the name of the device file 813 // get the name of the device file
814 if (!fs_mgr_get_verity_device_name(io, mount_point, fd, &verity_blk_name)) { 814 if (!fs_mgr_dm_get_device_name(io, mount_point, fd, &verity_blk_name)) {
815 LERROR << "Couldn't get verity device number!"; 815 LERROR << "Couldn't get verity device number!";
816 goto out; 816 goto out;
817 } 817 }
@@ -900,7 +900,7 @@ int fs_mgr_setup_verity(struct fstab_rec *fstab, bool wait_for_verity_dev)
900loaded: 900loaded:
901 901
902 // activate the device 902 // activate the device
903 if (!fs_mgr_resume_verity_table(io, mount_point, fd)) { 903 if (!fs_mgr_dm_resume_table(io, mount_point, fd)) {
904 goto out; 904 goto out;
905 } 905 }
906 906
@@ -923,7 +923,7 @@ loaded:
923 if (!verified_at_boot) { 923 if (!verified_at_boot) {
924 free(fstab->blk_device); 924 free(fstab->blk_device);
925 fstab->blk_device = strdup(verity_blk_name.c_str()); 925 fstab->blk_device = strdup(verity_blk_name.c_str());
926 } else if (!fs_mgr_destroy_verity_device(io, mount_point, fd)) { 926 } else if (!fs_mgr_dm_destroy_device(io, mount_point, fd)) {
927 LERROR << "Failed to remove verity device " << mount_point.c_str(); 927 LERROR << "Failed to remove verity device " << mount_point.c_str();
928 goto out; 928 goto out;
929 } 929 }
diff --git a/fs_mgr/include/fs_mgr.h b/fs_mgr/include/fs_mgr.h
index 653d8fa01..72f019e21 100644
--- a/fs_mgr/include/fs_mgr.h
+++ b/fs_mgr/include/fs_mgr.h
@@ -76,6 +76,7 @@ void fs_mgr_get_crypt_info(struct fstab* fstab, char* key_loc, char* real_blk_de
76bool fs_mgr_load_verity_state(int* mode); 76bool fs_mgr_load_verity_state(int* mode);
77bool fs_mgr_update_verity_state(fs_mgr_verity_state_callback callback); 77bool fs_mgr_update_verity_state(fs_mgr_verity_state_callback callback);
78int fs_mgr_swapon_all(struct fstab *fstab); 78int fs_mgr_swapon_all(struct fstab *fstab);
79bool fs_mgr_update_logical_partition(struct fstab_rec* rec);
79 80
80int fs_mgr_do_format(struct fstab_rec *fstab, bool reserve_footer); 81int fs_mgr_do_format(struct fstab_rec *fstab, bool reserve_footer);
81 82
diff --git a/fs_mgr/include/fs_mgr_dm_linear.h b/fs_mgr/include/fs_mgr_dm_linear.h
new file mode 100644
index 000000000..7f928e508
--- /dev/null
+++ b/fs_mgr/include/fs_mgr_dm_linear.h
@@ -0,0 +1,99 @@
1/*
2 * Copyright (C) 2018 The Android Open Source Project
3 *
4 * Permission is hereby granted, free of charge, to any person
5 * obtaining a copy of this software and associated documentation
6 * files (the "Software"), to deal in the Software without
7 * restriction, including without limitation the rights to use, copy,
8 * modify, merge, publish, distribute, sublicense, and/or sell copies
9 * of the Software, and to permit persons to whom the Software is
10 * furnished to do so, subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice shall be
13 * included in all copies or substantial portions of the Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
19 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
20 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 * SOFTWARE.
23 */
24
25#ifndef __CORE_FS_MGR_DM_LINEAR_H
26#define __CORE_FS_MGR_DM_LINEAR_H
27
28#include <stdint.h>
29#include <memory>
30#include <string>
31#include <vector>
32
33namespace android {
34namespace fs_mgr {
35
36static const uint32_t kPartitionReadonly = 0x1;
37
38class LogicalPartitionExtent {
39 public:
40 LogicalPartitionExtent() : logical_sector_(0), first_sector_(0), num_sectors_(0) {}
41 LogicalPartitionExtent(uint64_t logical_sector, uint64_t first_sector, uint64_t num_sectors,
42 const std::string& block_device)
43 : logical_sector_(logical_sector),
44 first_sector_(first_sector),
45 num_sectors_(num_sectors),
46 block_device_(block_device) {}
47
48 // Return a string containing the dm_target_spec buffer needed to use this
49 // extent in a device-mapper table.
50 std::string Serialize() const;
51
52 const std::string& block_device() const { return block_device_; }
53
54 private:
55 // Logical sector this extent represents in the presented block device.
56 // This is equal to the previous extent's logical sector plus the number
57 // of sectors in that extent. The first extent always starts at 0.
58 uint64_t logical_sector_;
59 // First 512-byte sector of this extent, on the source block device.
60 uint64_t first_sector_;
61 // Number of 512-byte sectors.
62 uint64_t num_sectors_;
63 // Target block device.
64 std::string block_device_;
65};
66
67struct LogicalPartition {
68 LogicalPartition() : attributes(0), num_sectors(0) {}
69
70 std::string name;
71 uint32_t attributes;
72 // Number of 512-byte sectors total.
73 uint64_t num_sectors;
74 // List of extents.
75 std::vector<LogicalPartitionExtent> extents;
76};
77
78struct LogicalPartitionTable {
79 // List of partitions in the partition table.
80 std::vector<LogicalPartition> partitions;
81};
82
83// Load a dm-linear table from the device tree if one is available; otherwise,
84// return null.
85std::unique_ptr<LogicalPartitionTable> LoadPartitionsFromDeviceTree();
86
87// Create device-mapper devices for the given partition table.
88//
89// On success, two devices nodes will be created for each partition, both
90// pointing to the same device:
91// /dev/block/dm-<N> where N is a sequential ID assigned by device-mapper.
92// /dev/block/dm-<name> where |name| is the partition name.
93//
94bool CreateLogicalPartitions(const LogicalPartitionTable& table);
95
96} // namespace fs_mgr
97} // namespace android
98
99#endif // __CORE_FS_MGR_DM_LINEAR_H
diff --git a/fs_mgr/include_fstab/fstab/fstab.h b/fs_mgr/include_fstab/fstab/fstab.h
index 8c585dd2f..d232cca86 100644
--- a/fs_mgr/include_fstab/fstab/fstab.h
+++ b/fs_mgr/include_fstab/fstab/fstab.h
@@ -22,6 +22,7 @@
22#include <stdint.h> 22#include <stdint.h>
23#include <stdio.h> 23#include <stdio.h>
24 24
25#include <set>
25#include <string> 26#include <string>
26 27
27/* 28/*
@@ -37,6 +38,7 @@ struct fstab {
37 38
38struct fstab_rec { 39struct fstab_rec {
39 char* blk_device; 40 char* blk_device;
41 char* logical_partition_name;
40 char* mount_point; 42 char* mount_point;
41 char* fs_type; 43 char* fs_type;
42 unsigned long flags; 44 unsigned long flags;
@@ -84,8 +86,10 @@ int fs_mgr_is_slotselect(const struct fstab_rec* fstab);
84int fs_mgr_is_nofail(const struct fstab_rec* fstab); 86int fs_mgr_is_nofail(const struct fstab_rec* fstab);
85int fs_mgr_is_latemount(const struct fstab_rec* fstab); 87int fs_mgr_is_latemount(const struct fstab_rec* fstab);
86int fs_mgr_is_quota(const struct fstab_rec* fstab); 88int fs_mgr_is_quota(const struct fstab_rec* fstab);
89int fs_mgr_is_logical(const struct fstab_rec* fstab);
87int fs_mgr_has_sysfs_path(const struct fstab_rec* fstab); 90int fs_mgr_has_sysfs_path(const struct fstab_rec* fstab);
88 91
89std::string fs_mgr_get_slot_suffix(); 92std::string fs_mgr_get_slot_suffix();
93std::set<std::string> fs_mgr_get_boot_devices();
90 94
91#endif /* __CORE_FS_TAB_H */ 95#endif /* __CORE_FS_TAB_H */
diff --git a/init/Android.bp b/init/Android.bp
index a31c5a587..63f3fca50 100644
--- a/init/Android.bp
+++ b/init/Android.bp
@@ -100,6 +100,7 @@ cc_library_static {
100 "capabilities.cpp", 100 "capabilities.cpp",
101 "descriptors.cpp", 101 "descriptors.cpp",
102 "devices.cpp", 102 "devices.cpp",
103 "epoll.cpp",
103 "firmware_handler.cpp", 104 "firmware_handler.cpp",
104 "import_parser.cpp", 105 "import_parser.cpp",
105 "init.cpp", 106 "init.cpp",
diff --git a/init/README.md b/init/README.md
index c08b07ad2..550ef0582 100644
--- a/init/README.md
+++ b/init/README.md
@@ -195,6 +195,10 @@ runs the service.
195> This service will not automatically start with its class. 195> This service will not automatically start with its class.
196 It must be explicitly started by name or by interface name. 196 It must be explicitly started by name or by interface name.
197 197
198`enter_namespace <type> <path>`
199> Enters the namespace of type _type_ located at _path_. Only network namespaces are supported with
200 _type_ set to "net". Note that only one namespace of a given _type_ may be entered.
201
198`file <path> <type>` 202`file <path> <type>`
199> Open a file path and pass its fd to the launched process. _type_ must be 203> Open a file path and pass its fd to the launched process. _type_ must be
200 "r", "w" or "rw". For native executables see libcutils 204 "r", "w" or "rw". For native executables see libcutils
diff --git a/init/builtins.cpp b/init/builtins.cpp
index 8bd92ccdd..17d34e134 100644
--- a/init/builtins.cpp
+++ b/init/builtins.cpp
@@ -240,6 +240,29 @@ static Result<Success> do_insmod(const BuiltinArguments& args) {
240 return Success(); 240 return Success();
241} 241}
242 242
243static Result<Success> do_interface_restart(const BuiltinArguments& args) {
244 Service* svc = ServiceList::GetInstance().FindInterface(args[1]);
245 if (!svc) return Error() << "interface " << args[1] << " not found";
246 svc->Restart();
247 return Success();
248}
249
250static Result<Success> do_interface_start(const BuiltinArguments& args) {
251 Service* svc = ServiceList::GetInstance().FindInterface(args[1]);
252 if (!svc) return Error() << "interface " << args[1] << " not found";
253 if (auto result = svc->Start(); !result) {
254 return Error() << "Could not start interface: " << result.error();
255 }
256 return Success();
257}
258
259static Result<Success> do_interface_stop(const BuiltinArguments& args) {
260 Service* svc = ServiceList::GetInstance().FindInterface(args[1]);
261 if (!svc) return Error() << "interface " << args[1] << " not found";
262 svc->Stop();
263 return Success();
264}
265
243// mkdir <path> [mode] [owner] [group] 266// mkdir <path> [mode] [owner] [group]
244static Result<Success> do_mkdir(const BuiltinArguments& args) { 267static Result<Success> do_mkdir(const BuiltinArguments& args) {
245 mode_t mode = 0755; 268 mode_t mode = 0755;
@@ -1050,6 +1073,9 @@ const BuiltinFunctionMap::Map& BuiltinFunctionMap::map() const {
1050 {"init_user0", {0, 0, {false, do_init_user0}}}, 1073 {"init_user0", {0, 0, {false, do_init_user0}}},
1051 {"insmod", {1, kMax, {true, do_insmod}}}, 1074 {"insmod", {1, kMax, {true, do_insmod}}},
1052 {"installkey", {1, 1, {false, do_installkey}}}, 1075 {"installkey", {1, 1, {false, do_installkey}}},
1076 {"interface_restart", {1, 1, {false, do_interface_restart}}},
1077 {"interface_start", {1, 1, {false, do_interface_start}}},
1078 {"interface_stop", {1, 1, {false, do_interface_stop}}},
1053 {"load_persist_props", {0, 0, {false, do_load_persist_props}}}, 1079 {"load_persist_props", {0, 0, {false, do_load_persist_props}}},
1054 {"load_system_props", {0, 0, {false, do_load_system_props}}}, 1080 {"load_system_props", {0, 0, {false, do_load_system_props}}},
1055 {"loglevel", {1, 1, {false, do_loglevel}}}, 1081 {"loglevel", {1, 1, {false, do_loglevel}}},
diff --git a/init/devices.cpp b/init/devices.cpp
index 8d27f4f09..ada1e2870 100644
--- a/init/devices.cpp
+++ b/init/devices.cpp
@@ -329,10 +329,10 @@ std::vector<std::string> DeviceHandler::GetBlockDeviceSymlinks(const Uevent& uev
329 << partition_name_sanitized << "'"; 329 << partition_name_sanitized << "'";
330 } 330 }
331 links.emplace_back(link_path + "/by-name/" + partition_name_sanitized); 331 links.emplace_back(link_path + "/by-name/" + partition_name_sanitized);
332 } 332 // Adds symlink: /dev/block/by-name/<partition_name>.
333 333 if (boot_devices_.find(device) != boot_devices_.end()) {
334 if (uevent.partition_num >= 0) { 334 links.emplace_back("/dev/block/by-name/" + partition_name_sanitized);
335 links.emplace_back(link_path + "/by-num/p" + std::to_string(uevent.partition_num)); 335 }
336 } 336 }
337 337
338 auto last_slash = uevent.path.rfind('/'); 338 auto last_slash = uevent.path.rfind('/');
@@ -350,8 +350,14 @@ void DeviceHandler::HandleDevice(const std::string& action, const std::string& d
350 PLOG(ERROR) << "Failed to create directory " << Dirname(link); 350 PLOG(ERROR) << "Failed to create directory " << Dirname(link);
351 } 351 }
352 352
353 if (symlink(devpath.c_str(), link.c_str()) && errno != EEXIST) { 353 if (symlink(devpath.c_str(), link.c_str())) {
354 PLOG(ERROR) << "Failed to symlink " << devpath << " to " << link; 354 if (errno != EEXIST) {
355 PLOG(ERROR) << "Failed to symlink " << devpath << " to " << link;
356 } else if (std::string link_path;
357 Readlink(link, &link_path) && link_path != devpath) {
358 PLOG(ERROR) << "Failed to symlink " << devpath << " to " << link
359 << ", which already links to: " << link_path;
360 }
355 } 361 }
356 } 362 }
357 } 363 }
@@ -415,16 +421,18 @@ void DeviceHandler::HandleDeviceEvent(const Uevent& uevent) {
415 421
416DeviceHandler::DeviceHandler(std::vector<Permissions> dev_permissions, 422DeviceHandler::DeviceHandler(std::vector<Permissions> dev_permissions,
417 std::vector<SysfsPermissions> sysfs_permissions, 423 std::vector<SysfsPermissions> sysfs_permissions,
418 std::vector<Subsystem> subsystems, bool skip_restorecon) 424 std::vector<Subsystem> subsystems, std::set<std::string> boot_devices,
425 bool skip_restorecon)
419 : dev_permissions_(std::move(dev_permissions)), 426 : dev_permissions_(std::move(dev_permissions)),
420 sysfs_permissions_(std::move(sysfs_permissions)), 427 sysfs_permissions_(std::move(sysfs_permissions)),
421 subsystems_(std::move(subsystems)), 428 subsystems_(std::move(subsystems)),
429 boot_devices_(std::move(boot_devices)),
422 skip_restorecon_(skip_restorecon), 430 skip_restorecon_(skip_restorecon),
423 sysfs_mount_point_("/sys") {} 431 sysfs_mount_point_("/sys") {}
424 432
425DeviceHandler::DeviceHandler() 433DeviceHandler::DeviceHandler()
426 : DeviceHandler(std::vector<Permissions>{}, std::vector<SysfsPermissions>{}, 434 : DeviceHandler(std::vector<Permissions>{}, std::vector<SysfsPermissions>{},
427 std::vector<Subsystem>{}, false) {} 435 std::vector<Subsystem>{}, std::set<std::string>{}, false) {}
428 436
429} // namespace init 437} // namespace init
430} // namespace android 438} // namespace android
diff --git a/init/devices.h b/init/devices.h
index 1f8f1e8a9..f9035da3d 100644
--- a/init/devices.h
+++ b/init/devices.h
@@ -21,6 +21,7 @@
21#include <sys/types.h> 21#include <sys/types.h>
22 22
23#include <algorithm> 23#include <algorithm>
24#include <set>
24#include <string> 25#include <string>
25#include <vector> 26#include <vector>
26 27
@@ -103,8 +104,8 @@ class DeviceHandler {
103 104
104 DeviceHandler(); 105 DeviceHandler();
105 DeviceHandler(std::vector<Permissions> dev_permissions, 106 DeviceHandler(std::vector<Permissions> dev_permissions,
106 std::vector<SysfsPermissions> sysfs_permissions, 107 std::vector<SysfsPermissions> sysfs_permissions, std::vector<Subsystem> subsystems,
107 std::vector<Subsystem> subsystems, bool skip_restorecon); 108 std::set<std::string> boot_devices, bool skip_restorecon);
108 ~DeviceHandler(){}; 109 ~DeviceHandler(){};
109 110
110 void HandleDeviceEvent(const Uevent& uevent); 111 void HandleDeviceEvent(const Uevent& uevent);
@@ -125,6 +126,7 @@ class DeviceHandler {
125 std::vector<Permissions> dev_permissions_; 126 std::vector<Permissions> dev_permissions_;
126 std::vector<SysfsPermissions> sysfs_permissions_; 127 std::vector<SysfsPermissions> sysfs_permissions_;
127 std::vector<Subsystem> subsystems_; 128 std::vector<Subsystem> subsystems_;
129 std::set<std::string> boot_devices_;
128 bool skip_restorecon_; 130 bool skip_restorecon_;
129 std::string sysfs_mount_point_; 131 std::string sysfs_mount_point_;
130}; 132};
diff --git a/init/devices_test.cpp b/init/devices_test.cpp
index eba00cb78..d658f4d9a 100644
--- a/init/devices_test.cpp
+++ b/init/devices_test.cpp
@@ -84,7 +84,6 @@ TEST(device_handler, get_block_device_symlinks_success_platform_with_partition)
84 }; 84 };
85 std::vector<std::string> expected_result{ 85 std::vector<std::string> expected_result{
86 "/dev/block/platform/soc.0/f9824900.sdhci/by-name/modem", 86 "/dev/block/platform/soc.0/f9824900.sdhci/by-name/modem",
87 "/dev/block/platform/soc.0/f9824900.sdhci/by-num/p1",
88 "/dev/block/platform/soc.0/f9824900.sdhci/mmcblk0p1", 87 "/dev/block/platform/soc.0/f9824900.sdhci/mmcblk0p1",
89 }; 88 };
90 89
@@ -100,7 +99,6 @@ TEST(device_handler, get_block_device_symlinks_success_platform_with_partition_o
100 .partition_num = 1, 99 .partition_num = 1,
101 }; 100 };
102 std::vector<std::string> expected_result{ 101 std::vector<std::string> expected_result{
103 "/dev/block/platform/soc.0/f9824900.sdhci/by-num/p1",
104 "/dev/block/platform/soc.0/f9824900.sdhci/mmcblk0p1", 102 "/dev/block/platform/soc.0/f9824900.sdhci/mmcblk0p1",
105 }; 103 };
106 104
diff --git a/init/epoll.cpp b/init/epoll.cpp
new file mode 100644
index 000000000..4bca09e6d
--- /dev/null
+++ b/init/epoll.cpp
@@ -0,0 +1,84 @@
1/*
2 * Copyright (C) 2018 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include "epoll.h"
18
19#include <sys/epoll.h>
20
21#include <chrono>
22#include <functional>
23#include <map>
24
25namespace android {
26namespace init {
27
28Epoll::Epoll() {}
29
30Result<Success> Epoll::Open() {
31 if (epoll_fd_ >= 0) return Success();
32 epoll_fd_.reset(epoll_create1(EPOLL_CLOEXEC));
33
34 if (epoll_fd_ == -1) {
35 return ErrnoError() << "epoll_create1 failed";
36 }
37 return Success();
38}
39
40Result<Success> Epoll::RegisterHandler(int fd, std::function<void()> handler) {
41 auto [it, inserted] = epoll_handlers_.emplace(fd, std::move(handler));
42 if (!inserted) {
43 return Error() << "Cannot specify two epoll handlers for a given FD";
44 }
45 epoll_event ev;
46 ev.events = EPOLLIN;
47 // std::map's iterators do not get invalidated until erased, so we use the
48 // pointer to the std::function in the map directly for epoll_ctl.
49 ev.data.ptr = reinterpret_cast<void*>(&it->second);
50 if (epoll_ctl(epoll_fd_, EPOLL_CTL_ADD, fd, &ev) == -1) {
51 Result<Success> result = ErrnoError() << "epoll_ctl failed to add fd";
52 epoll_handlers_.erase(fd);
53 return result;
54 }
55 return Success();
56}
57
58Result<Success> Epoll::UnregisterHandler(int fd) {
59 if (epoll_ctl(epoll_fd_, EPOLL_CTL_DEL, fd, nullptr) == -1) {
60 return ErrnoError() << "epoll_ctl failed to remove fd";
61 }
62 if (epoll_handlers_.erase(fd) != 1) {
63 return Error() << "Attempting to remove epoll handler for FD without an existing handler";
64 }
65 return Success();
66}
67
68Result<Success> Epoll::Wait(std::optional<std::chrono::milliseconds> timeout) {
69 int timeout_ms = -1;
70 if (timeout && timeout->count() < INT_MAX) {
71 timeout_ms = timeout->count();
72 }
73 epoll_event ev;
74 auto nr = TEMP_FAILURE_RETRY(epoll_wait(epoll_fd_, &ev, 1, timeout_ms));
75 if (nr == -1) {
76 return ErrnoError() << "epoll_wait failed";
77 } else if (nr == 1) {
78 std::invoke(*reinterpret_cast<std::function<void()>*>(ev.data.ptr));
79 }
80 return Success();
81}
82
83} // namespace init
84} // namespace android
diff --git a/init/epoll.h b/init/epoll.h
new file mode 100644
index 000000000..85a791c60
--- /dev/null
+++ b/init/epoll.h
@@ -0,0 +1,49 @@
1/*
2 * Copyright (C) 2018 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#ifndef _INIT_EPOLL_H
18#define _INIT_EPOLL_H
19
20#include <chrono>
21#include <functional>
22#include <map>
23#include <optional>
24
25#include <android-base/unique_fd.h>
26
27#include "result.h"
28
29namespace android {
30namespace init {
31
32class Epoll {
33 public:
34 Epoll();
35
36 Result<Success> Open();
37 Result<Success> RegisterHandler(int fd, std::function<void()> handler);
38 Result<Success> UnregisterHandler(int fd);
39 Result<Success> Wait(std::optional<std::chrono::milliseconds> timeout);
40
41 private:
42 android::base::unique_fd epoll_fd_;
43 std::map<int, std::function<void()>> epoll_handlers_;
44};
45
46} // namespace init
47} // namespace android
48
49#endif
diff --git a/init/host_init_stubs.cpp b/init/host_init_stubs.cpp
index e6cc08a9a..4451ac8b9 100644
--- a/init/host_init_stubs.cpp
+++ b/init/host_init_stubs.cpp
@@ -49,6 +49,10 @@ uint32_t HandlePropertySet(const std::string&, const std::string&, const std::st
49} 49}
50 50
51// selinux.h 51// selinux.h
52bool SelinuxHasVendorInit() {
53 return true;
54}
55
52void SelabelInitialize() {} 56void SelabelInitialize() {}
53 57
54bool SelabelLookupFileContext(const std::string& key, int type, std::string* result) { 58bool SelabelLookupFileContext(const std::string& key, int type, std::string* result) {
diff --git a/init/host_init_stubs.h b/init/host_init_stubs.h
index ddfb7ae7d..bb241af9b 100644
--- a/init/host_init_stubs.h
+++ b/init/host_init_stubs.h
@@ -35,11 +35,6 @@ namespace base {
35 35
36std::string GetProperty(const std::string& key, const std::string& default_value); 36std::string GetProperty(const std::string& key, const std::string& default_value);
37bool GetBoolProperty(const std::string& key, bool default_value); 37bool GetBoolProperty(const std::string& key, bool default_value);
38template <typename T>
39T GetIntProperty(const std::string&, T default_value, T = std::numeric_limits<T>::min(),
40 T = std::numeric_limits<T>::max()) {
41 return default_value;
42}
43 38
44} // namespace base 39} // namespace base
45} // namespace android 40} // namespace android
@@ -56,6 +51,7 @@ uint32_t HandlePropertySet(const std::string& name, const std::string& value,
56 const std::string& source_context, const ucred& cr, std::string* error); 51 const std::string& source_context, const ucred& cr, std::string* error);
57 52
58// selinux.h 53// selinux.h
54bool SelinuxHasVendorInit();
59void SelabelInitialize(); 55void SelabelInitialize();
60bool SelabelLookupFileContext(const std::string& key, int type, std::string* result); 56bool SelabelLookupFileContext(const std::string& key, int type, std::string* result);
61 57
diff --git a/init/init.cpp b/init/init.cpp
index 0d5690b07..fd9a90cd7 100644
--- a/init/init.cpp
+++ b/init/init.cpp
@@ -24,13 +24,16 @@
24#include <signal.h> 24#include <signal.h>
25#include <stdlib.h> 25#include <stdlib.h>
26#include <string.h> 26#include <string.h>
27#include <sys/epoll.h>
28#include <sys/mount.h> 27#include <sys/mount.h>
29#include <sys/signalfd.h> 28#include <sys/signalfd.h>
30#include <sys/sysmacros.h> 29#include <sys/sysmacros.h>
31#include <sys/types.h> 30#include <sys/types.h>
32#include <unistd.h> 31#include <unistd.h>
33 32
33#include <map>
34#include <memory>
35#include <optional>
36
34#include <android-base/chrono_utils.h> 37#include <android-base/chrono_utils.h>
35#include <android-base/file.h> 38#include <android-base/file.h>
36#include <android-base/logging.h> 39#include <android-base/logging.h>
@@ -43,10 +46,8 @@
43#include <private/android_filesystem_config.h> 46#include <private/android_filesystem_config.h>
44#include <selinux/android.h> 47#include <selinux/android.h>
45 48
46#include <memory>
47#include <optional>
48
49#include "action_parser.h" 49#include "action_parser.h"
50#include "epoll.h"
50#include "import_parser.h" 51#include "import_parser.h"
51#include "init_first_stage.h" 52#include "init_first_stage.h"
52#include "keychords.h" 53#include "keychords.h"
@@ -60,6 +61,7 @@
60#include "util.h" 61#include "util.h"
61#include "watchdogd.h" 62#include "watchdogd.h"
62 63
64using namespace std::chrono_literals;
63using namespace std::string_literals; 65using namespace std::string_literals;
64 66
65using android::base::boot_clock; 67using android::base::boot_clock;
@@ -78,7 +80,6 @@ static char qemu[32];
78 80
79std::string default_console = "/dev/console"; 81std::string default_console = "/dev/console";
80 82
81static int epoll_fd = -1;
82static int signal_fd = -1; 83static int signal_fd = -1;
83 84
84static std::unique_ptr<Timer> waiting_for_prop(nullptr); 85static std::unique_ptr<Timer> waiting_for_prop(nullptr);
@@ -130,15 +131,6 @@ static void LoadBootScripts(ActionManager& action_manager, ServiceList& service_
130 } 131 }
131} 132}
132 133
133void register_epoll_handler(int fd, void (*fn)()) {
134 epoll_event ev;
135 ev.events = EPOLLIN;
136 ev.data.ptr = reinterpret_cast<void*>(fn);
137 if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, fd, &ev) == -1) {
138 PLOG(ERROR) << "epoll_ctl failed";
139 }
140}
141
142bool start_waiting_for_property(const char *name, const char *value) 134bool start_waiting_for_property(const char *name, const char *value)
143{ 135{
144 if (waiting_for_prop) { 136 if (waiting_for_prop) {
@@ -277,40 +269,29 @@ void HandleControlMessage(const std::string& msg, const std::string& name, pid_t
277 269
278 const ControlMessageFunction& function = it->second; 270 const ControlMessageFunction& function = it->second;
279 271
280 if (function.target == ControlTarget::SERVICE) { 272 Service* svc = nullptr;
281 Service* svc = ServiceList::GetInstance().FindService(name);
282 if (svc == nullptr) {
283 LOG(ERROR) << "No such service '" << name << "' for ctl." << msg;
284 return;
285 }
286 if (auto result = function.action(svc); !result) {
287 LOG(ERROR) << "Could not ctl." << msg << " for service " << name << ": "
288 << result.error();
289 }
290
291 return;
292 }
293
294 if (function.target == ControlTarget::INTERFACE) {
295 for (const auto& svc : ServiceList::GetInstance()) {
296 if (svc->interfaces().count(name) == 0) {
297 continue;
298 }
299
300 if (auto result = function.action(svc.get()); !result) {
301 LOG(ERROR) << "Could not handle ctl." << msg << " for service " << svc->name()
302 << " with interface " << name << ": " << result.error();
303 }
304 273
274 switch (function.target) {
275 case ControlTarget::SERVICE:
276 svc = ServiceList::GetInstance().FindService(name);
277 break;
278 case ControlTarget::INTERFACE:
279 svc = ServiceList::GetInstance().FindInterface(name);
280 break;
281 default:
282 LOG(ERROR) << "Invalid function target from static map key '" << msg << "': "
283 << static_cast<std::underlying_type<ControlTarget>::type>(function.target);
305 return; 284 return;
306 } 285 }
307 286
308 LOG(ERROR) << "Could not find service hosting interface " << name; 287 if (svc == nullptr) {
288 LOG(ERROR) << "Could not find '" << name << "' for ctl." << msg;
309 return; 289 return;
310 } 290 }
311 291
312 LOG(ERROR) << "Invalid function target from static map key '" << msg 292 if (auto result = function.action(svc); !result) {
313 << "': " << static_cast<std::underlying_type<ControlTarget>::type>(function.target); 293 LOG(ERROR) << "Could not ctl." << msg << " for '" << name << "': " << result.error();
294 }
314} 295}
315 296
316static Result<Success> wait_for_coldboot_done_action(const BuiltinArguments& args) { 297static Result<Success> wait_for_coldboot_done_action(const BuiltinArguments& args) {
@@ -334,11 +315,6 @@ static Result<Success> wait_for_coldboot_done_action(const BuiltinArguments& arg
334 return Success(); 315 return Success();
335} 316}
336 317
337static Result<Success> keychord_init_action(const BuiltinArguments& args) {
338 keychord_init();
339 return Success();
340}
341
342static Result<Success> console_init_action(const BuiltinArguments& args) { 318static Result<Success> console_init_action(const BuiltinArguments& args) {
343 std::string console = GetProperty("ro.boot.console", ""); 319 std::string console = GetProperty("ro.boot.console", "");
344 if (!console.empty()) { 320 if (!console.empty()) {
@@ -541,7 +517,7 @@ static void UnblockSignals() {
541 } 517 }
542} 518}
543 519
544static void InstallSignalFdHandler() { 520static void InstallSignalFdHandler(Epoll* epoll) {
545 // Applying SA_NOCLDSTOP to a defaulted SIGCHLD handler prevents the signalfd from receiving 521 // Applying SA_NOCLDSTOP to a defaulted SIGCHLD handler prevents the signalfd from receiving
546 // SIGCHLD when a child process stops or continues (b/77867680#comment9). 522 // SIGCHLD when a child process stops or continues (b/77867680#comment9).
547 const struct sigaction act { .sa_handler = SIG_DFL, .sa_flags = SA_NOCLDSTOP }; 523 const struct sigaction act { .sa_handler = SIG_DFL, .sa_flags = SA_NOCLDSTOP };
@@ -572,7 +548,9 @@ static void InstallSignalFdHandler() {
572 PLOG(FATAL) << "failed to create signalfd"; 548 PLOG(FATAL) << "failed to create signalfd";
573 } 549 }
574 550
575 register_epoll_handler(signal_fd, HandleSignalFd); 551 if (auto result = epoll->RegisterHandler(signal_fd, HandleSignalFd); !result) {
552 LOG(FATAL) << result.error();
553 }
576} 554}
577 555
578int main(int argc, char** argv) { 556int main(int argc, char** argv) {
@@ -718,16 +696,16 @@ int main(int argc, char** argv) {
718 SelabelInitialize(); 696 SelabelInitialize();
719 SelinuxRestoreContext(); 697 SelinuxRestoreContext();
720 698
721 epoll_fd = epoll_create1(EPOLL_CLOEXEC); 699 Epoll epoll;
722 if (epoll_fd == -1) { 700 if (auto result = epoll.Open(); !result) {
723 PLOG(FATAL) << "epoll_create1 failed"; 701 PLOG(FATAL) << result.error();
724 } 702 }
725 703
726 InstallSignalFdHandler(); 704 InstallSignalFdHandler(&epoll);
727 705
728 property_load_boot_defaults(); 706 property_load_boot_defaults();
729 export_oem_lock_status(); 707 export_oem_lock_status();
730 start_property_service(); 708 StartPropertyService(&epoll);
731 set_usb_controller(); 709 set_usb_controller();
732 710
733 const BuiltinFunctionMap function_map; 711 const BuiltinFunctionMap function_map;
@@ -752,7 +730,12 @@ int main(int argc, char** argv) {
752 am.QueueBuiltinAction(MixHwrngIntoLinuxRngAction, "MixHwrngIntoLinuxRng"); 730 am.QueueBuiltinAction(MixHwrngIntoLinuxRngAction, "MixHwrngIntoLinuxRng");
753 am.QueueBuiltinAction(SetMmapRndBitsAction, "SetMmapRndBits"); 731 am.QueueBuiltinAction(SetMmapRndBitsAction, "SetMmapRndBits");
754 am.QueueBuiltinAction(SetKptrRestrictAction, "SetKptrRestrict"); 732 am.QueueBuiltinAction(SetKptrRestrictAction, "SetKptrRestrict");
755 am.QueueBuiltinAction(keychord_init_action, "keychord_init"); 733 am.QueueBuiltinAction(
734 [&epoll](const BuiltinArguments& args) -> Result<Success> {
735 KeychordInit(&epoll);
736 return Success();
737 },
738 "KeychordInit");
756 am.QueueBuiltinAction(console_init_action, "console_init"); 739 am.QueueBuiltinAction(console_init_action, "console_init");
757 740
758 // Trigger all the boot actions to get us started. 741 // Trigger all the boot actions to get us started.
@@ -775,7 +758,7 @@ int main(int argc, char** argv) {
775 758
776 while (true) { 759 while (true) {
777 // By default, sleep until something happens. 760 // By default, sleep until something happens.
778 int epoll_timeout_ms = -1; 761 auto epoll_timeout = std::optional<std::chrono::milliseconds>{};
779 762
780 if (do_shutdown && !shutting_down) { 763 if (do_shutdown && !shutting_down) {
781 do_shutdown = false; 764 do_shutdown = false;
@@ -793,23 +776,18 @@ int main(int argc, char** argv) {
793 776
794 // If there's a process that needs restarting, wake up in time for that. 777 // If there's a process that needs restarting, wake up in time for that.
795 if (next_process_restart_time) { 778 if (next_process_restart_time) {
796 epoll_timeout_ms = std::chrono::ceil<std::chrono::milliseconds>( 779 epoll_timeout = std::chrono::ceil<std::chrono::milliseconds>(
797 *next_process_restart_time - boot_clock::now()) 780 *next_process_restart_time - boot_clock::now());
798 .count(); 781 if (*epoll_timeout < 0ms) epoll_timeout = 0ms;
799 if (epoll_timeout_ms < 0) epoll_timeout_ms = 0;
800 } 782 }
801 } 783 }
802 784
803 // If there's more work to do, wake up again immediately. 785 // If there's more work to do, wake up again immediately.
804 if (am.HasMoreCommands()) epoll_timeout_ms = 0; 786 if (am.HasMoreCommands()) epoll_timeout = 0ms;
805 } 787 }
806 788
807 epoll_event ev; 789 if (auto result = epoll.Wait(epoll_timeout); !result) {
808 int nr = TEMP_FAILURE_RETRY(epoll_wait(epoll_fd, &ev, 1, epoll_timeout_ms)); 790 LOG(ERROR) << result.error();
809 if (nr == -1) {
810 PLOG(ERROR) << "epoll_wait failed";
811 } else if (nr == 1) {
812 ((void (*)()) ev.data.ptr)();
813 } 791 }
814 } 792 }
815 793
diff --git a/init/init.h b/init/init.h
index d4a0e963b..6c82fa12c 100644
--- a/init/init.h
+++ b/init/init.h
@@ -19,6 +19,7 @@
19 19
20#include <sys/types.h> 20#include <sys/types.h>
21 21
22#include <functional>
22#include <string> 23#include <string>
23#include <vector> 24#include <vector>
24 25
@@ -42,8 +43,6 @@ void HandleControlMessage(const std::string& msg, const std::string& arg, pid_t
42 43
43void property_changed(const std::string& name, const std::string& value); 44void property_changed(const std::string& name, const std::string& value);
44 45
45void register_epoll_handler(int fd, void (*fn)());
46
47bool start_waiting_for_property(const char *name, const char *value); 46bool start_waiting_for_property(const char *name, const char *value);
48 47
49void DumpState(); 48void DumpState();
diff --git a/init/init_first_stage.cpp b/init/init_first_stage.cpp
index 1b6e97ec7..34de640f3 100644
--- a/init/init_first_stage.cpp
+++ b/init/init_first_stage.cpp
@@ -33,11 +33,13 @@
33#include "devices.h" 33#include "devices.h"
34#include "fs_mgr.h" 34#include "fs_mgr.h"
35#include "fs_mgr_avb.h" 35#include "fs_mgr_avb.h"
36#include "fs_mgr_dm_linear.h"
36#include "uevent.h" 37#include "uevent.h"
37#include "uevent_listener.h" 38#include "uevent_listener.h"
38#include "util.h" 39#include "util.h"
39 40
40using android::base::Timer; 41using android::base::Timer;
42using android::fs_mgr::LogicalPartitionTable;
41 43
42namespace android { 44namespace android {
43namespace init { 45namespace init {
@@ -58,21 +60,24 @@ class FirstStageMount {
58 protected: 60 protected:
59 ListenerAction HandleBlockDevice(const std::string& name, const Uevent&); 61 ListenerAction HandleBlockDevice(const std::string& name, const Uevent&);
60 bool InitRequiredDevices(); 62 bool InitRequiredDevices();
61 bool InitVerityDevice(const std::string& verity_device); 63 bool InitMappedDevice(const std::string& verity_device);
64 bool CreateLogicalPartitions();
62 bool MountPartitions(); 65 bool MountPartitions();
66 bool GetBackingDmLinearDevices();
63 67
64 virtual ListenerAction UeventCallback(const Uevent& uevent); 68 virtual ListenerAction UeventCallback(const Uevent& uevent);
65 69
66 // Pure virtual functions. 70 // Pure virtual functions.
67 virtual bool GetRequiredDevices() = 0; 71 virtual bool GetDmVerityDevices() = 0;
68 virtual bool SetUpDmVerity(fstab_rec* fstab_rec) = 0; 72 virtual bool SetUpDmVerity(fstab_rec* fstab_rec) = 0;
69 73
70 bool need_dm_verity_; 74 bool need_dm_verity_;
71 75
72 std::unique_ptr<fstab, decltype(&fs_mgr_free_fstab)> device_tree_fstab_; 76 std::unique_ptr<fstab, decltype(&fs_mgr_free_fstab)> device_tree_fstab_;
77 std::unique_ptr<LogicalPartitionTable> dm_linear_table_;
73 std::vector<fstab_rec*> mount_fstab_recs_; 78 std::vector<fstab_rec*> mount_fstab_recs_;
74 std::set<std::string> required_devices_partition_names_; 79 std::set<std::string> required_devices_partition_names_;
75 DeviceHandler device_handler_; 80 std::unique_ptr<DeviceHandler> device_handler_;
76 UeventListener uevent_listener_; 81 UeventListener uevent_listener_;
77}; 82};
78 83
@@ -82,7 +87,7 @@ class FirstStageMountVBootV1 : public FirstStageMount {
82 ~FirstStageMountVBootV1() override = default; 87 ~FirstStageMountVBootV1() override = default;
83 88
84 protected: 89 protected:
85 bool GetRequiredDevices() override; 90 bool GetDmVerityDevices() override;
86 bool SetUpDmVerity(fstab_rec* fstab_rec) override; 91 bool SetUpDmVerity(fstab_rec* fstab_rec) override;
87}; 92};
88 93
@@ -95,7 +100,7 @@ class FirstStageMountVBootV2 : public FirstStageMount {
95 100
96 protected: 101 protected:
97 ListenerAction UeventCallback(const Uevent& uevent) override; 102 ListenerAction UeventCallback(const Uevent& uevent) override;
98 bool GetRequiredDevices() override; 103 bool GetDmVerityDevices() override;
99 bool SetUpDmVerity(fstab_rec* fstab_rec) override; 104 bool SetUpDmVerity(fstab_rec* fstab_rec) override;
100 bool InitAvbHandle(); 105 bool InitAvbHandle();
101 106
@@ -114,6 +119,17 @@ static bool inline IsRecoveryMode() {
114 return access("/sbin/recovery", F_OK) == 0; 119 return access("/sbin/recovery", F_OK) == 0;
115} 120}
116 121
122static inline bool IsDmLinearEnabled() {
123 bool enabled = false;
124 import_kernel_cmdline(
125 false, [&enabled](const std::string& key, const std::string& value, bool in_qemu) {
126 if (key == "androidboot.lrap" && value == "1") {
127 enabled = true;
128 }
129 });
130 return enabled;
131}
132
117// Class Definitions 133// Class Definitions
118// ----------------- 134// -----------------
119FirstStageMount::FirstStageMount() 135FirstStageMount::FirstStageMount()
@@ -127,6 +143,15 @@ FirstStageMount::FirstStageMount()
127 } else { 143 } else {
128 LOG(INFO) << "Failed to read fstab from device tree"; 144 LOG(INFO) << "Failed to read fstab from device tree";
129 } 145 }
146
147 if (IsDmLinearEnabled()) {
148 dm_linear_table_ = android::fs_mgr::LoadPartitionsFromDeviceTree();
149 }
150
151 auto boot_devices = fs_mgr_get_boot_devices();
152 device_handler_ =
153 std::make_unique<DeviceHandler>(std::vector<Permissions>{}, std::vector<SysfsPermissions>{},
154 std::vector<Subsystem>{}, std::move(boot_devices), false);
130} 155}
131 156
132std::unique_ptr<FirstStageMount> FirstStageMount::Create() { 157std::unique_ptr<FirstStageMount> FirstStageMount::Create() {
@@ -138,7 +163,7 @@ std::unique_ptr<FirstStageMount> FirstStageMount::Create() {
138} 163}
139 164
140bool FirstStageMount::DoFirstStageMount() { 165bool FirstStageMount::DoFirstStageMount() {
141 if (mount_fstab_recs_.empty()) { 166 if (!dm_linear_table_ && mount_fstab_recs_.empty()) {
142 // Nothing to mount. 167 // Nothing to mount.
143 LOG(INFO) << "First stage mount skipped (missing/incompatible/empty fstab in device tree)"; 168 LOG(INFO) << "First stage mount skipped (missing/incompatible/empty fstab in device tree)";
144 return true; 169 return true;
@@ -146,13 +171,30 @@ bool FirstStageMount::DoFirstStageMount() {
146 171
147 if (!InitDevices()) return false; 172 if (!InitDevices()) return false;
148 173
174 if (!CreateLogicalPartitions()) return false;
175
149 if (!MountPartitions()) return false; 176 if (!MountPartitions()) return false;
150 177
151 return true; 178 return true;
152} 179}
153 180
154bool FirstStageMount::InitDevices() { 181bool FirstStageMount::InitDevices() {
155 return GetRequiredDevices() && InitRequiredDevices(); 182 return GetBackingDmLinearDevices() && GetDmVerityDevices() && InitRequiredDevices();
183}
184
185bool FirstStageMount::GetBackingDmLinearDevices() {
186 // Add any additional devices required for dm-linear mappings.
187 if (!dm_linear_table_) {
188 return true;
189 }
190
191 for (const auto& partition : dm_linear_table_->partitions) {
192 for (const auto& extent : partition.extents) {
193 const std::string& partition_name = android::base::Basename(extent.block_device());
194 required_devices_partition_names_.emplace(partition_name);
195 }
196 }
197 return true;
156} 198}
157 199
158// Creates devices with uevent->partition_name matching one in the member variable 200// Creates devices with uevent->partition_name matching one in the member variable
@@ -163,12 +205,12 @@ bool FirstStageMount::InitRequiredDevices() {
163 return true; 205 return true;
164 } 206 }
165 207
166 if (need_dm_verity_) { 208 if (dm_linear_table_ || need_dm_verity_) {
167 const std::string dm_path = "/devices/virtual/misc/device-mapper"; 209 const std::string dm_path = "/devices/virtual/misc/device-mapper";
168 bool found = false; 210 bool found = false;
169 auto dm_callback = [this, &dm_path, &found](const Uevent& uevent) { 211 auto dm_callback = [this, &dm_path, &found](const Uevent& uevent) {
170 if (uevent.path == dm_path) { 212 if (uevent.path == dm_path) {
171 device_handler_.HandleDeviceEvent(uevent); 213 device_handler_->HandleDeviceEvent(uevent);
172 found = true; 214 found = true;
173 return ListenerAction::kStop; 215 return ListenerAction::kStop;
174 } 216 }
@@ -210,6 +252,13 @@ bool FirstStageMount::InitRequiredDevices() {
210 return true; 252 return true;
211} 253}
212 254
255bool FirstStageMount::CreateLogicalPartitions() {
256 if (!dm_linear_table_) {
257 return true;
258 }
259 return android::fs_mgr::CreateLogicalPartitions(*dm_linear_table_.get());
260}
261
213ListenerAction FirstStageMount::HandleBlockDevice(const std::string& name, const Uevent& uevent) { 262ListenerAction FirstStageMount::HandleBlockDevice(const std::string& name, const Uevent& uevent) {
214 // Matches partition name to create device nodes. 263 // Matches partition name to create device nodes.
215 // Both required_devices_partition_names_ and uevent->partition_name have A/B 264 // Both required_devices_partition_names_ and uevent->partition_name have A/B
@@ -218,7 +267,7 @@ ListenerAction FirstStageMount::HandleBlockDevice(const std::string& name, const
218 if (iter != required_devices_partition_names_.end()) { 267 if (iter != required_devices_partition_names_.end()) {
219 LOG(VERBOSE) << __PRETTY_FUNCTION__ << ": found partition: " << *iter; 268 LOG(VERBOSE) << __PRETTY_FUNCTION__ << ": found partition: " << *iter;
220 required_devices_partition_names_.erase(iter); 269 required_devices_partition_names_.erase(iter);
221 device_handler_.HandleDeviceEvent(uevent); 270 device_handler_->HandleDeviceEvent(uevent);
222 if (required_devices_partition_names_.empty()) { 271 if (required_devices_partition_names_.empty()) {
223 return ListenerAction::kStop; 272 return ListenerAction::kStop;
224 } else { 273 } else {
@@ -247,15 +296,15 @@ ListenerAction FirstStageMount::UeventCallback(const Uevent& uevent) {
247} 296}
248 297
249// Creates "/dev/block/dm-XX" for dm-verity by running coldboot on /sys/block/dm-XX. 298// Creates "/dev/block/dm-XX" for dm-verity by running coldboot on /sys/block/dm-XX.
250bool FirstStageMount::InitVerityDevice(const std::string& verity_device) { 299bool FirstStageMount::InitMappedDevice(const std::string& dm_device) {
251 const std::string device_name(basename(verity_device.c_str())); 300 const std::string device_name(basename(dm_device.c_str()));
252 const std::string syspath = "/sys/block/" + device_name; 301 const std::string syspath = "/sys/block/" + device_name;
253 bool found = false; 302 bool found = false;
254 303
255 auto verity_callback = [&device_name, &verity_device, this, &found](const Uevent& uevent) { 304 auto verity_callback = [&device_name, &dm_device, this, &found](const Uevent& uevent) {
256 if (uevent.device_name == device_name) { 305 if (uevent.device_name == device_name) {
257 LOG(VERBOSE) << "Creating dm-verity device : " << verity_device; 306 LOG(VERBOSE) << "Creating device-mapper device : " << dm_device;
258 device_handler_.HandleDeviceEvent(uevent); 307 device_handler_->HandleDeviceEvent(uevent);
259 found = true; 308 found = true;
260 return ListenerAction::kStop; 309 return ListenerAction::kStop;
261 } 310 }
@@ -279,6 +328,14 @@ bool FirstStageMount::InitVerityDevice(const std::string& verity_device) {
279 328
280bool FirstStageMount::MountPartitions() { 329bool FirstStageMount::MountPartitions() {
281 for (auto fstab_rec : mount_fstab_recs_) { 330 for (auto fstab_rec : mount_fstab_recs_) {
331 if (fs_mgr_is_logical(fstab_rec)) {
332 if (!fs_mgr_update_logical_partition(fstab_rec)) {
333 return false;
334 }
335 if (!InitMappedDevice(fstab_rec->blk_device)) {
336 return false;
337 }
338 }
282 if (!SetUpDmVerity(fstab_rec)) { 339 if (!SetUpDmVerity(fstab_rec)) {
283 PLOG(ERROR) << "Failed to setup verity for '" << fstab_rec->mount_point << "'"; 340 PLOG(ERROR) << "Failed to setup verity for '" << fstab_rec->mount_point << "'";
284 return false; 341 return false;
@@ -291,7 +348,7 @@ bool FirstStageMount::MountPartitions() {
291 return true; 348 return true;
292} 349}
293 350
294bool FirstStageMountVBootV1::GetRequiredDevices() { 351bool FirstStageMountVBootV1::GetDmVerityDevices() {
295 std::string verity_loc_device; 352 std::string verity_loc_device;
296 need_dm_verity_ = false; 353 need_dm_verity_ = false;
297 354
@@ -344,7 +401,7 @@ bool FirstStageMountVBootV1::SetUpDmVerity(fstab_rec* fstab_rec) {
344 // The exact block device name (fstab_rec->blk_device) is changed to 401 // The exact block device name (fstab_rec->blk_device) is changed to
345 // "/dev/block/dm-XX". Needs to create it because ueventd isn't started in init 402 // "/dev/block/dm-XX". Needs to create it because ueventd isn't started in init
346 // first stage. 403 // first stage.
347 return InitVerityDevice(fstab_rec->blk_device); 404 return InitMappedDevice(fstab_rec->blk_device);
348 default: 405 default:
349 return false; 406 return false;
350 } 407 }
@@ -371,7 +428,7 @@ FirstStageMountVBootV2::FirstStageMountVBootV2() : avb_handle_(nullptr) {
371 } 428 }
372} 429}
373 430
374bool FirstStageMountVBootV2::GetRequiredDevices() { 431bool FirstStageMountVBootV2::GetDmVerityDevices() {
375 need_dm_verity_ = false; 432 need_dm_verity_ = false;
376 433
377 // fstab_rec->blk_device has A/B suffix. 434 // fstab_rec->blk_device has A/B suffix.
@@ -416,9 +473,8 @@ ListenerAction FirstStageMountVBootV2::UeventCallback(const Uevent& uevent) {
416 // the content of uevent. by-name symlink will be at [0] if uevent->partition_name 473 // the content of uevent. by-name symlink will be at [0] if uevent->partition_name
417 // is not empty. e.g., 474 // is not empty. e.g.,
418 // - /dev/block/platform/soc.0/f9824900.sdhci/by-name/modem 475 // - /dev/block/platform/soc.0/f9824900.sdhci/by-name/modem
419 // - /dev/block/platform/soc.0/f9824900.sdhci/by-num/p1
420 // - /dev/block/platform/soc.0/f9824900.sdhci/mmcblk0p1 476 // - /dev/block/platform/soc.0/f9824900.sdhci/mmcblk0p1
421 std::vector<std::string> links = device_handler_.GetBlockDeviceSymlinks(uevent); 477 std::vector<std::string> links = device_handler_->GetBlockDeviceSymlinks(uevent);
422 if (!links.empty()) { 478 if (!links.empty()) {
423 auto[it, inserted] = by_name_symlink_map_.emplace(uevent.partition_name, links[0]); 479 auto[it, inserted] = by_name_symlink_map_.emplace(uevent.partition_name, links[0]);
424 if (!inserted) { 480 if (!inserted) {
@@ -444,7 +500,7 @@ bool FirstStageMountVBootV2::SetUpDmVerity(fstab_rec* fstab_rec) {
444 // The exact block device name (fstab_rec->blk_device) is changed to 500 // The exact block device name (fstab_rec->blk_device) is changed to
445 // "/dev/block/dm-XX". Needs to create it because ueventd isn't started in init 501 // "/dev/block/dm-XX". Needs to create it because ueventd isn't started in init
446 // first stage. 502 // first stage.
447 return InitVerityDevice(fstab_rec->blk_device); 503 return InitMappedDevice(fstab_rec->blk_device);
448 default: 504 default:
449 return false; 505 return false;
450 } 506 }
diff --git a/init/keychords.cpp b/init/keychords.cpp
index e686ce1e4..418cdeb22 100644
--- a/init/keychords.cpp
+++ b/init/keychords.cpp
@@ -16,66 +16,115 @@
16 16
17#include "keychords.h" 17#include "keychords.h"
18 18
19#include <dirent.h>
19#include <fcntl.h> 20#include <fcntl.h>
20#include <stdlib.h> 21#include <linux/input.h>
21#include <sys/stat.h> 22#include <sys/cdefs.h>
23#include <sys/inotify.h>
24#include <sys/ioctl.h>
22#include <sys/types.h> 25#include <sys/types.h>
23#include <linux/keychord.h>
24#include <unistd.h> 26#include <unistd.h>
25 27
28#include <algorithm>
29#include <functional>
30#include <map>
31#include <memory>
32#include <string>
33#include <vector>
34
26#include <android-base/logging.h> 35#include <android-base/logging.h>
27#include <android-base/properties.h> 36#include <android-base/properties.h>
28 37
29#include "init.h" 38#include "init.h"
39#include "service.h"
30 40
31namespace android { 41namespace android {
32namespace init { 42namespace init {
33 43
34static struct input_keychord *keychords = 0; 44namespace {
35static int keychords_count = 0; 45
36static int keychords_length = 0; 46int keychords_count;
37static int keychord_fd = -1; 47Epoll* epoll;
38 48
39void add_service_keycodes(Service* svc) 49struct KeychordEntry {
40{ 50 const std::vector<int> keycodes;
41 struct input_keychord *keychord; 51 bool notified;
42 size_t i, size; 52 int id;
43 53
44 if (!svc->keycodes().empty()) { 54 KeychordEntry(const std::vector<int>& keycodes, int id)
45 /* add a new keychord to the list */ 55 : keycodes(keycodes), notified(false), id(id) {}
46 size = sizeof(*keychord) + svc->keycodes().size() * sizeof(keychord->keycodes[0]); 56};
47 keychords = (input_keychord*) realloc(keychords, keychords_length + size); 57
48 if (!keychords) { 58std::vector<KeychordEntry> keychord_entries;
49 PLOG(ERROR) << "could not allocate keychords"; 59
50 keychords_length = 0; 60// Bit management
51 keychords_count = 0; 61class KeychordMask {
52 return; 62 private:
63 typedef unsigned int mask_t;
64 std::vector<mask_t> bits;
65 static constexpr size_t bits_per_byte = 8;
66
67 public:
68 explicit KeychordMask(size_t bit = 0) : bits((bit + sizeof(mask_t) - 1) / sizeof(mask_t), 0) {}
69
70 void SetBit(size_t bit, bool value = true) {
71 auto idx = bit / (bits_per_byte * sizeof(mask_t));
72 if (idx >= bits.size()) return;
73 if (value) {
74 bits[idx] |= mask_t(1) << (bit % (bits_per_byte * sizeof(mask_t)));
75 } else {
76 bits[idx] &= ~(mask_t(1) << (bit % (bits_per_byte * sizeof(mask_t))));
53 } 77 }
78 }
54 79
55 keychord = (struct input_keychord *)((char *)keychords + keychords_length); 80 bool GetBit(size_t bit) const {
56 keychord->version = KEYCHORD_VERSION; 81 auto idx = bit / (bits_per_byte * sizeof(mask_t));
57 keychord->id = keychords_count + 1; 82 return bits[idx] & (mask_t(1) << (bit % (bits_per_byte * sizeof(mask_t))));
58 keychord->count = svc->keycodes().size(); 83 }
59 svc->set_keychord_id(keychord->id);
60 84
61 for (i = 0; i < svc->keycodes().size(); i++) { 85 size_t bytesize() const { return bits.size() * sizeof(mask_t); }
62 keychord->keycodes[i] = svc->keycodes()[i]; 86 void* data() { return bits.data(); }
87 size_t size() const { return bits.size() * sizeof(mask_t) * bits_per_byte; }
88 void resize(size_t bit) {
89 auto idx = bit / (bits_per_byte * sizeof(mask_t));
90 if (idx >= bits.size()) {
91 bits.resize(idx + 1, 0);
63 } 92 }
64 keychords_count++;
65 keychords_length += size;
66 } 93 }
67}
68 94
69static void handle_keychord() { 95 operator bool() const {
70 int ret; 96 for (size_t i = 0; i < bits.size(); ++i) {
71 __u16 id; 97 if (bits[i]) return true;
98 }
99 return false;
100 }
72 101
73 ret = read(keychord_fd, &id, sizeof(id)); 102 KeychordMask operator&(const KeychordMask& rval) const {
74 if (ret != sizeof(id)) { 103 auto len = std::min(bits.size(), rval.bits.size());
75 PLOG(ERROR) << "could not read keychord id"; 104 KeychordMask ret;
76 return; 105 ret.bits.resize(len);
106 for (size_t i = 0; i < len; ++i) {
107 ret.bits[i] = bits[i] & rval.bits[i];
108 }
109 return ret;
77 } 110 }
78 111
112 void operator|=(const KeychordMask& rval) {
113 size_t len = rval.bits.size();
114 bits.resize(len);
115 for (size_t i = 0; i < len; ++i) {
116 bits[i] |= rval.bits[i];
117 }
118 }
119};
120
121KeychordMask keychord_current;
122
123constexpr char kDevicePath[] = "/dev/input";
124
125std::map<std::string, int> keychord_registration;
126
127void HandleKeychord(int id) {
79 // Only handle keychords if adb is enabled. 128 // Only handle keychords if adb is enabled.
80 std::string adb_enabled = android::base::GetProperty("init.svc.adbd", ""); 129 std::string adb_enabled = android::base::GetProperty("init.svc.adbd", "");
81 if (adb_enabled == "running") { 130 if (adb_enabled == "running") {
@@ -94,32 +143,180 @@ static void handle_keychord() {
94 } 143 }
95} 144}
96 145
97void keychord_init() { 146void KeychordLambdaCheck() {
98 for (const auto& service : ServiceList::GetInstance()) { 147 for (auto& e : keychord_entries) {
99 add_service_keycodes(service.get()); 148 bool found = true;
149 for (auto& code : e.keycodes) {
150 if (!keychord_current.GetBit(code)) {
151 e.notified = false;
152 found = false;
153 break;
154 }
155 }
156 if (!found) continue;
157 if (e.notified) continue;
158 e.notified = true;
159 HandleKeychord(e.id);
160 }
161}
162
163void KeychordLambdaHandler(int fd) {
164 input_event event;
165 auto res = TEMP_FAILURE_RETRY(::read(fd, &event, sizeof(event)));
166 if ((res != sizeof(event)) || (event.type != EV_KEY)) return;
167 keychord_current.SetBit(event.code, event.value);
168 KeychordLambdaCheck();
169}
170
171bool KeychordGeteventEnable(int fd) {
172 static bool EviocsmaskSupported = true;
173
174 // Make sure it is an event channel, should pass this ioctl call
175 int version;
176 if (::ioctl(fd, EVIOCGVERSION, &version)) return false;
177
178 if (EviocsmaskSupported) {
179 KeychordMask mask(EV_KEY);
180 mask.SetBit(EV_KEY);
181 input_mask msg = {};
182 msg.type = EV_SYN;
183 msg.codes_size = mask.bytesize();
184 msg.codes_ptr = reinterpret_cast<uintptr_t>(mask.data());
185 if (::ioctl(fd, EVIOCSMASK, &msg) == -1) {
186 PLOG(WARNING) << "EVIOCSMASK not supported";
187 EviocsmaskSupported = false;
188 }
189 }
190
191 KeychordMask mask;
192 for (auto& e : keychord_entries) {
193 for (auto& code : e.keycodes) {
194 mask.resize(code);
195 mask.SetBit(code);
196 }
197 }
198
199 keychord_current.resize(mask.size());
200 KeychordMask available(mask.size());
201 auto res = ::ioctl(fd, EVIOCGBIT(EV_KEY, available.bytesize()), available.data());
202 if (res == -1) return false;
203 if (!(available & mask)) return false;
204
205 if (EviocsmaskSupported) {
206 input_mask msg = {};
207 msg.type = EV_KEY;
208 msg.codes_size = mask.bytesize();
209 msg.codes_ptr = reinterpret_cast<uintptr_t>(mask.data());
210 ::ioctl(fd, EVIOCSMASK, &msg);
211 }
212
213 KeychordMask set(mask.size());
214 res = ::ioctl(fd, EVIOCGKEY(res), set.data());
215 if (res > 0) {
216 keychord_current |= mask & available & set;
217 KeychordLambdaCheck();
100 } 218 }
219 epoll->RegisterHandler(fd, [fd]() { KeychordLambdaHandler(fd); });
220 return true;
221}
101 222
102 // Nothing to do if no services require keychords. 223void GeteventOpenDevice(const std::string& device) {
103 if (!keychords) { 224 if (keychord_registration.count(device)) return;
225 auto fd = TEMP_FAILURE_RETRY(::open(device.c_str(), O_RDWR | O_CLOEXEC));
226 if (fd == -1) {
227 PLOG(ERROR) << "Can not open " << device;
104 return; 228 return;
105 } 229 }
230 if (!KeychordGeteventEnable(fd)) {
231 ::close(fd);
232 } else {
233 keychord_registration.emplace(device, fd);
234 }
235}
236
237void GeteventCloseDevice(const std::string& device) {
238 auto it = keychord_registration.find(device);
239 if (it == keychord_registration.end()) return;
240 auto fd = (*it).second;
241 epoll->UnregisterHandler(fd);
242 keychord_registration.erase(it);
243 ::close(fd);
244}
245
246int inotify_fd = -1;
106 247
107 keychord_fd = TEMP_FAILURE_RETRY(open("/dev/keychord", O_RDWR | O_CLOEXEC)); 248void InotifyHandler() {
108 if (keychord_fd == -1) { 249 unsigned char buf[512];
109 PLOG(ERROR) << "could not open /dev/keychord"; 250
251 auto res = TEMP_FAILURE_RETRY(::read(inotify_fd, buf, sizeof(buf)));
252 if (res < 0) {
253 PLOG(WARNING) << "could not get event";
110 return; 254 return;
111 } 255 }
112 256
113 int ret = write(keychord_fd, keychords, keychords_length); 257 auto event_buf = buf;
114 if (ret != keychords_length) { 258 while (static_cast<size_t>(res) >= sizeof(inotify_event)) {
115 PLOG(ERROR) << "could not configure /dev/keychord " << ret; 259 auto event = reinterpret_cast<inotify_event*>(event_buf);
116 close(keychord_fd); 260 auto event_size = sizeof(inotify_event) + event->len;
261 if (static_cast<size_t>(res) < event_size) break;
262 if (event->len) {
263 std::string devname(kDevicePath);
264 devname += '/';
265 devname += event->name;
266 if (event->mask & IN_CREATE) {
267 GeteventOpenDevice(devname);
268 } else {
269 GeteventCloseDevice(devname);
270 }
271 }
272 res -= event_size;
273 event_buf += event_size;
274 }
275}
276
277void GeteventOpenDevice() {
278 inotify_fd = ::inotify_init1(IN_NONBLOCK | IN_CLOEXEC);
279 if (inotify_fd < 0) {
280 PLOG(WARNING) << "Could not instantiate inotify for " << kDevicePath;
281 } else if (::inotify_add_watch(inotify_fd, kDevicePath, IN_DELETE | IN_CREATE | IN_ONLYDIR) < 0) {
282 PLOG(WARNING) << "Could not add watch for " << kDevicePath;
283 ::close(inotify_fd);
284 inotify_fd = -1;
285 }
286
287 std::unique_ptr<DIR, decltype(&closedir)> device(opendir(kDevicePath), closedir);
288 if (device) {
289 dirent* entry;
290 while ((entry = readdir(device.get()))) {
291 if (entry->d_name[0] == '.') continue;
292 std::string devname(kDevicePath);
293 devname += '/';
294 devname += entry->d_name;
295 GeteventOpenDevice(devname);
296 }
297 }
298
299 if (inotify_fd >= 0) epoll->RegisterHandler(inotify_fd, InotifyHandler);
300}
301
302void AddServiceKeycodes(Service* svc) {
303 if (svc->keycodes().empty()) return;
304 for (auto& code : svc->keycodes()) {
305 if ((code < 0) || (code >= KEY_MAX)) return;
117 } 306 }
307 ++keychords_count;
308 keychord_entries.emplace_back(KeychordEntry(svc->keycodes(), keychords_count));
309 svc->set_keychord_id(keychords_count);
310}
118 311
119 free(keychords); 312} // namespace
120 keychords = nullptr;
121 313
122 register_epoll_handler(keychord_fd, handle_keychord); 314void KeychordInit(Epoll* init_epoll) {
315 epoll = init_epoll;
316 for (const auto& service : ServiceList::GetInstance()) {
317 AddServiceKeycodes(service.get());
318 }
319 if (keychords_count) GeteventOpenDevice();
123} 320}
124 321
125} // namespace init 322} // namespace init
diff --git a/init/keychords.h b/init/keychords.h
index 1c3409865..f3aecbb56 100644
--- a/init/keychords.h
+++ b/init/keychords.h
@@ -17,13 +17,12 @@
17#ifndef _INIT_KEYCHORDS_H_ 17#ifndef _INIT_KEYCHORDS_H_
18#define _INIT_KEYCHORDS_H_ 18#define _INIT_KEYCHORDS_H_
19 19
20#include "service.h" 20#include "epoll.h"
21 21
22namespace android { 22namespace android {
23namespace init { 23namespace init {
24 24
25void add_service_keycodes(Service* svc); 25void KeychordInit(Epoll* init_epoll);
26void keychord_init();
27 26
28} // namespace init 27} // namespace init
29} // namespace android 28} // namespace android
diff --git a/init/property_service.cpp b/init/property_service.cpp
index 99d3c83b1..741fde0b9 100644
--- a/init/property_service.cpp
+++ b/init/property_service.cpp
@@ -56,15 +56,16 @@
56#include <selinux/label.h> 56#include <selinux/label.h>
57#include <selinux/selinux.h> 57#include <selinux/selinux.h>
58 58
59#include "epoll.h"
59#include "init.h" 60#include "init.h"
60#include "persistent_properties.h" 61#include "persistent_properties.h"
61#include "property_type.h" 62#include "property_type.h"
63#include "selinux.h"
62#include "subcontext.h" 64#include "subcontext.h"
63#include "util.h" 65#include "util.h"
64 66
65using namespace std::literals; 67using namespace std::literals;
66 68
67using android::base::GetIntProperty;
68using android::base::ReadFileToString; 69using android::base::ReadFileToString;
69using android::base::Split; 70using android::base::Split;
70using android::base::StartsWith; 71using android::base::StartsWith;
@@ -371,6 +372,7 @@ class SocketConnection {
371 372
372 int result = TEMP_FAILURE_RETRY(recv(socket_, data, bytes_left, MSG_DONTWAIT)); 373 int result = TEMP_FAILURE_RETRY(recv(socket_, data, bytes_left, MSG_DONTWAIT));
373 if (result <= 0) { 374 if (result <= 0) {
375 PLOG(ERROR) << "sys_prop: recv error";
374 return false; 376 return false;
375 } 377 }
376 378
@@ -378,6 +380,10 @@ class SocketConnection {
378 data += result; 380 data += result;
379 } 381 }
380 382
383 if (bytes_left != 0) {
384 LOG(ERROR) << "sys_prop: recv data is not properly obtained.";
385 }
386
381 return bytes_left == 0; 387 return bytes_left == 0;
382 } 388 }
383 389
@@ -542,7 +548,7 @@ static void LoadProperties(char* data, const char* filter, const char* filename)
542 size_t flen = 0; 548 size_t flen = 0;
543 549
544 const char* context = kInitContext.c_str(); 550 const char* context = kInitContext.c_str();
545 if (GetIntProperty("ro.vndk.version", 28) >= 28) { 551 if (SelinuxHasVendorInit()) {
546 for (const auto& [path_prefix, secontext] : paths_and_secontexts) { 552 for (const auto& [path_prefix, secontext] : paths_and_secontexts) {
547 if (StartsWith(filename, path_prefix)) { 553 if (StartsWith(filename, path_prefix)) {
548 context = secontext; 554 context = secontext;
@@ -808,7 +814,7 @@ void CreateSerializedPropertyInfo() {
808 selinux_android_restorecon(kPropertyInfosPath, 0); 814 selinux_android_restorecon(kPropertyInfosPath, 0);
809} 815}
810 816
811void start_property_service() { 817void StartPropertyService(Epoll* epoll) {
812 selinux_callback cb; 818 selinux_callback cb;
813 cb.func_audit = SelinuxAuditCallback; 819 cb.func_audit = SelinuxAuditCallback;
814 selinux_set_callback(SELINUX_CB_AUDIT, cb); 820 selinux_set_callback(SELINUX_CB_AUDIT, cb);
@@ -823,7 +829,9 @@ void start_property_service() {
823 829
824 listen(property_set_fd, 8); 830 listen(property_set_fd, 8);
825 831
826 register_epoll_handler(property_set_fd, handle_property_set_fd); 832 if (auto result = epoll->RegisterHandler(property_set_fd, handle_property_set_fd); !result) {
833 PLOG(FATAL) << result.error();
834 }
827} 835}
828 836
829} // namespace init 837} // namespace init
diff --git a/init/property_service.h b/init/property_service.h
index 29eaaa901..4a354c27f 100644
--- a/init/property_service.h
+++ b/init/property_service.h
@@ -21,6 +21,8 @@
21 21
22#include <string> 22#include <string>
23 23
24#include "epoll.h"
25
24namespace android { 26namespace android {
25namespace init { 27namespace init {
26 28
@@ -40,7 +42,7 @@ void property_init(void);
40void property_load_boot_defaults(void); 42void property_load_boot_defaults(void);
41void load_persist_props(void); 43void load_persist_props(void);
42void load_system_props(void); 44void load_system_props(void);
43void start_property_service(void); 45void StartPropertyService(Epoll* epoll);
44 46
45} // namespace init 47} // namespace init
46} // namespace android 48} // namespace android
diff --git a/init/selinux.cpp b/init/selinux.cpp
index 6aba9c1ef..0ba5c4ae3 100644
--- a/init/selinux.cpp
+++ b/init/selinux.cpp
@@ -55,12 +55,14 @@
55#include <android-base/chrono_utils.h> 55#include <android-base/chrono_utils.h>
56#include <android-base/file.h> 56#include <android-base/file.h>
57#include <android-base/logging.h> 57#include <android-base/logging.h>
58#include <android-base/parseint.h>
58#include <android-base/unique_fd.h> 59#include <android-base/unique_fd.h>
59#include <selinux/android.h> 60#include <selinux/android.h>
60 61
61#include "log.h" 62#include "log.h"
62#include "util.h" 63#include "util.h"
63 64
65using android::base::ParseInt;
64using android::base::Timer; 66using android::base::Timer;
65using android::base::unique_fd; 67using android::base::unique_fd;
66 68
@@ -453,6 +455,31 @@ void SelinuxSetupKernelLogging() {
453 selinux_set_callback(SELINUX_CB_LOG, cb); 455 selinux_set_callback(SELINUX_CB_LOG, cb);
454} 456}
455 457
458// This function checks whether the sepolicy supports vendor init.
459bool SelinuxHasVendorInit() {
460 if (!IsSplitPolicyDevice()) {
461 // If this device does not split sepolicy files, vendor_init will be available in the latest
462 // monolithic sepolicy file.
463 return true;
464 }
465
466 std::string version;
467 if (!GetVendorMappingVersion(&version)) {
468 // Return true as the default if we failed to load the vendor sepolicy version.
469 return true;
470 }
471
472 int major_version;
473 std::string major_version_str(version, 0, version.find('.'));
474 if (!ParseInt(major_version_str, &major_version)) {
475 PLOG(ERROR) << "Failed to parse the vendor sepolicy major version " << major_version_str;
476 // Return true as the default if we failed to parse the major version.
477 return true;
478 }
479
480 return major_version >= 28;
481}
482
456// selinux_android_file_context_handle() takes on the order of 10+ms to run, so we want to cache 483// selinux_android_file_context_handle() takes on the order of 10+ms to run, so we want to cache
457// its value. selinux_android_restorecon() also needs an sehandle for file context look up. It 484// its value. selinux_android_restorecon() also needs an sehandle for file context look up. It
458// will create and store its own copy, but selinux_android_set_sehandle() can be used to provide 485// will create and store its own copy, but selinux_android_set_sehandle() can be used to provide
diff --git a/init/selinux.h b/init/selinux.h
index 7b880eccc..30069b53d 100644
--- a/init/selinux.h
+++ b/init/selinux.h
@@ -27,6 +27,7 @@ void SelinuxInitialize();
27void SelinuxRestoreContext(); 27void SelinuxRestoreContext();
28 28
29void SelinuxSetupKernelLogging(); 29void SelinuxSetupKernelLogging();
30bool SelinuxHasVendorInit();
30 31
31void SelabelInitialize(); 32void SelabelInitialize();
32bool SelabelLookupFileContext(const std::string& key, int type, std::string* result); 33bool SelabelLookupFileContext(const std::string& key, int type, std::string* result);
diff --git a/init/service.cpp b/init/service.cpp
index 03c2ceec8..0e08d9bba 100644
--- a/init/service.cpp
+++ b/init/service.cpp
@@ -34,6 +34,7 @@
34#include <android-base/parseint.h> 34#include <android-base/parseint.h>
35#include <android-base/stringprintf.h> 35#include <android-base/stringprintf.h>
36#include <android-base/strings.h> 36#include <android-base/strings.h>
37#include <android-base/unique_fd.h>
37#include <hidl-util/FQName.h> 38#include <hidl-util/FQName.h>
38#include <processgroup/processgroup.h> 39#include <processgroup/processgroup.h>
39#include <selinux/selinux.h> 40#include <selinux/selinux.h>
@@ -59,13 +60,13 @@ using android::base::Join;
59using android::base::ParseInt; 60using android::base::ParseInt;
60using android::base::StartsWith; 61using android::base::StartsWith;
61using android::base::StringPrintf; 62using android::base::StringPrintf;
63using android::base::unique_fd;
62using android::base::WriteStringToFile; 64using android::base::WriteStringToFile;
63 65
64namespace android { 66namespace android {
65namespace init { 67namespace init {
66 68
67static Result<std::string> ComputeContextFromExecutable(std::string& service_name, 69static Result<std::string> ComputeContextFromExecutable(const std::string& service_path) {
68 const std::string& service_path) {
69 std::string computed_context; 70 std::string computed_context;
70 71
71 char* raw_con = nullptr; 72 char* raw_con = nullptr;
@@ -101,36 +102,49 @@ static Result<std::string> ComputeContextFromExecutable(std::string& service_nam
101 return computed_context; 102 return computed_context;
102} 103}
103 104
104static void SetUpPidNamespace(const std::string& service_name) { 105Result<Success> Service::SetUpMountNamespace() const {
105 constexpr unsigned int kSafeFlags = MS_NODEV | MS_NOEXEC | MS_NOSUID; 106 constexpr unsigned int kSafeFlags = MS_NODEV | MS_NOEXEC | MS_NOSUID;
106 107
107 // It's OK to LOG(FATAL) in this function since it's running in the first
108 // child process.
109
110 // Recursively remount / as slave like zygote does so unmounting and mounting /proc 108 // Recursively remount / as slave like zygote does so unmounting and mounting /proc
111 // doesn't interfere with the parent namespace's /proc mount. This will also 109 // doesn't interfere with the parent namespace's /proc mount. This will also
112 // prevent any other mounts/unmounts initiated by the service from interfering 110 // prevent any other mounts/unmounts initiated by the service from interfering
113 // with the parent namespace but will still allow mount events from the parent 111 // with the parent namespace but will still allow mount events from the parent
114 // namespace to propagate to the child. 112 // namespace to propagate to the child.
115 if (mount("rootfs", "/", nullptr, (MS_SLAVE | MS_REC), nullptr) == -1) { 113 if (mount("rootfs", "/", nullptr, (MS_SLAVE | MS_REC), nullptr) == -1) {
116 PLOG(FATAL) << "couldn't remount(/) recursively as slave for " << service_name; 114 return ErrnoError() << "Could not remount(/) recursively as slave";
117 } 115 }
118 // umount() then mount() /proc. 116
117 // umount() then mount() /proc and/or /sys
119 // Note that it is not sufficient to mount with MS_REMOUNT. 118 // Note that it is not sufficient to mount with MS_REMOUNT.
120 if (umount("/proc") == -1) { 119 if (namespace_flags_ & CLONE_NEWPID) {
121 PLOG(FATAL) << "couldn't umount(/proc) for " << service_name; 120 if (umount("/proc") == -1) {
121 return ErrnoError() << "Could not umount(/proc)";
122 }
123 if (mount("", "/proc", "proc", kSafeFlags, "") == -1) {
124 return ErrnoError() << "Could not mount(/proc)";
125 }
122 } 126 }
123 if (mount("", "/proc", "proc", kSafeFlags, "") == -1) { 127 bool remount_sys = std::any_of(namespaces_to_enter_.begin(), namespaces_to_enter_.end(),
124 PLOG(FATAL) << "couldn't mount(/proc) for " << service_name; 128 [](const auto& entry) { return entry.first == CLONE_NEWNET; });
129 if (remount_sys) {
130 if (umount2("/sys", MNT_DETACH) == -1) {
131 return ErrnoError() << "Could not umount(/sys)";
132 }
133 if (mount("", "/sys", "sys", kSafeFlags, "") == -1) {
134 return ErrnoError() << "Could not mount(/sys)";
135 }
125 } 136 }
137 return Success();
138}
126 139
127 if (prctl(PR_SET_NAME, service_name.c_str()) == -1) { 140Result<Success> Service::SetUpPidNamespace() const {
128 PLOG(FATAL) << "couldn't set name for " << service_name; 141 if (prctl(PR_SET_NAME, name_.c_str()) == -1) {
142 return ErrnoError() << "Could not set name";
129 } 143 }
130 144
131 pid_t child_pid = fork(); 145 pid_t child_pid = fork();
132 if (child_pid == -1) { 146 if (child_pid == -1) {
133 PLOG(FATAL) << "couldn't fork init inside the PID namespace for " << service_name; 147 return ErrnoError() << "Could not fork init inside the PID namespace";
134 } 148 }
135 149
136 if (child_pid > 0) { 150 if (child_pid > 0) {
@@ -153,6 +167,20 @@ static void SetUpPidNamespace(const std::string& service_name) {
153 } 167 }
154 _exit(WEXITSTATUS(init_exitstatus)); 168 _exit(WEXITSTATUS(init_exitstatus));
155 } 169 }
170 return Success();
171}
172
173Result<Success> Service::EnterNamespaces() const {
174 for (const auto& [nstype, path] : namespaces_to_enter_) {
175 auto fd = unique_fd{open(path.c_str(), O_RDONLY | O_CLOEXEC)};
176 if (!fd) {
177 return ErrnoError() << "Could not open namespace at " << path;
178 }
179 if (setns(fd, nstype) == -1) {
180 return ErrnoError() << "Could not setns() namespace at " << path;
181 }
182 }
183 return Success();
156} 184}
157 185
158static bool ExpandArgsAndExecv(const std::vector<std::string>& args, bool sigstop) { 186static bool ExpandArgsAndExecv(const std::vector<std::string>& args, bool sigstop) {
@@ -422,6 +450,20 @@ Result<Success> Service::ParseDisabled(const std::vector<std::string>& args) {
422 return Success(); 450 return Success();
423} 451}
424 452
453Result<Success> Service::ParseEnterNamespace(const std::vector<std::string>& args) {
454 if (args[1] != "net") {
455 return Error() << "Init only supports entering network namespaces";
456 }
457 if (!namespaces_to_enter_.empty()) {
458 return Error() << "Only one network namespace may be entered";
459 }
460 // Network namespaces require that /sys is remounted, otherwise the old adapters will still be
461 // present. Therefore, they also require mount namespaces.
462 namespace_flags_ |= CLONE_NEWNS;
463 namespaces_to_enter_.emplace_back(CLONE_NEWNET, args[2]);
464 return Success();
465}
466
425Result<Success> Service::ParseGroup(const std::vector<std::string>& args) { 467Result<Success> Service::ParseGroup(const std::vector<std::string>& args) {
426 auto gid = DecodeUid(args[1]); 468 auto gid = DecodeUid(args[1]);
427 if (!gid) { 469 if (!gid) {
@@ -691,6 +733,8 @@ const Service::OptionParserMap::Map& Service::OptionParserMap::map() const {
691 {"console", {0, 1, &Service::ParseConsole}}, 733 {"console", {0, 1, &Service::ParseConsole}},
692 {"critical", {0, 0, &Service::ParseCritical}}, 734 {"critical", {0, 0, &Service::ParseCritical}},
693 {"disabled", {0, 0, &Service::ParseDisabled}}, 735 {"disabled", {0, 0, &Service::ParseDisabled}},
736 {"enter_namespace",
737 {2, 2, &Service::ParseEnterNamespace}},
694 {"file", {2, 2, &Service::ParseFile}}, 738 {"file", {2, 2, &Service::ParseFile}},
695 {"group", {1, NR_SVC_SUPP_GIDS + 1, &Service::ParseGroup}}, 739 {"group", {1, NR_SVC_SUPP_GIDS + 1, &Service::ParseGroup}},
696 {"interface", {2, 2, &Service::ParseInterface}}, 740 {"interface", {2, 2, &Service::ParseInterface}},
@@ -793,7 +837,7 @@ Result<Success> Service::Start() {
793 if (!seclabel_.empty()) { 837 if (!seclabel_.empty()) {
794 scon = seclabel_; 838 scon = seclabel_;
795 } else { 839 } else {
796 auto result = ComputeContextFromExecutable(name_, args_[0]); 840 auto result = ComputeContextFromExecutable(args_[0]);
797 if (!result) { 841 if (!result) {
798 return result.error(); 842 return result.error();
799 } 843 }
@@ -812,10 +856,24 @@ Result<Success> Service::Start() {
812 if (pid == 0) { 856 if (pid == 0) {
813 umask(077); 857 umask(077);
814 858
859 if (auto result = EnterNamespaces(); !result) {
860 LOG(FATAL) << "Service '" << name_ << "' could not enter namespaces: " << result.error();
861 }
862
863 if (namespace_flags_ & CLONE_NEWNS) {
864 if (auto result = SetUpMountNamespace(); !result) {
865 LOG(FATAL) << "Service '" << name_
866 << "' could not set up mount namespace: " << result.error();
867 }
868 }
869
815 if (namespace_flags_ & CLONE_NEWPID) { 870 if (namespace_flags_ & CLONE_NEWPID) {
816 // This will fork again to run an init process inside the PID 871 // This will fork again to run an init process inside the PID
817 // namespace. 872 // namespace.
818 SetUpPidNamespace(name_); 873 if (auto result = SetUpPidNamespace(); !result) {
874 LOG(FATAL) << "Service '" << name_
875 << "' could not set up PID namespace: " << result.error();
876 }
819 } 877 }
820 878
821 for (const auto& [key, value] : environment_vars_) { 879 for (const auto& [key, value] : environment_vars_) {
diff --git a/init/service.h b/init/service.h
index cf38f69a1..cbfd52f29 100644
--- a/init/service.h
+++ b/init/service.h
@@ -125,6 +125,9 @@ class Service {
125 using OptionParser = Result<Success> (Service::*)(const std::vector<std::string>& args); 125 using OptionParser = Result<Success> (Service::*)(const std::vector<std::string>& args);
126 class OptionParserMap; 126 class OptionParserMap;
127 127
128 Result<Success> SetUpMountNamespace() const;
129 Result<Success> SetUpPidNamespace() const;
130 Result<Success> EnterNamespaces() const;
128 void NotifyStateChange(const std::string& new_state) const; 131 void NotifyStateChange(const std::string& new_state) const;
129 void StopOrReset(int how); 132 void StopOrReset(int how);
130 void ZapStdio() const; 133 void ZapStdio() const;
@@ -137,6 +140,7 @@ class Service {
137 Result<Success> ParseConsole(const std::vector<std::string>& args); 140 Result<Success> ParseConsole(const std::vector<std::string>& args);
138 Result<Success> ParseCritical(const std::vector<std::string>& args); 141 Result<Success> ParseCritical(const std::vector<std::string>& args);
139 Result<Success> ParseDisabled(const std::vector<std::string>& args); 142 Result<Success> ParseDisabled(const std::vector<std::string>& args);
143 Result<Success> ParseEnterNamespace(const std::vector<std::string>& args);
140 Result<Success> ParseGroup(const std::vector<std::string>& args); 144 Result<Success> ParseGroup(const std::vector<std::string>& args);
141 Result<Success> ParsePriority(const std::vector<std::string>& args); 145 Result<Success> ParsePriority(const std::vector<std::string>& args);
142 Result<Success> ParseInterface(const std::vector<std::string>& args); 146 Result<Success> ParseInterface(const std::vector<std::string>& args);
@@ -181,6 +185,8 @@ class Service {
181 std::vector<gid_t> supp_gids_; 185 std::vector<gid_t> supp_gids_;
182 CapSet capabilities_; 186 CapSet capabilities_;
183 unsigned namespace_flags_; 187 unsigned namespace_flags_;
188 // Pair of namespace type, path to namespace.
189 std::vector<std::pair<int, std::string>> namespaces_to_enter_;
184 190
185 std::string seclabel_; 191 std::string seclabel_;
186 192
@@ -244,6 +250,16 @@ class ServiceList {
244 return nullptr; 250 return nullptr;
245 } 251 }
246 252
253 Service* FindInterface(const std::string& interface_name) {
254 for (const auto& svc : services_) {
255 if (svc->interfaces().count(interface_name) > 0) {
256 return svc.get();
257 }
258 }
259
260 return nullptr;
261 }
262
247 void DumpState() const; 263 void DumpState() const;
248 264
249 auto begin() const { return services_.begin(); } 265 auto begin() const { return services_.begin(); }
diff --git a/init/subcontext.cpp b/init/subcontext.cpp
index 9c0c0bb4f..267d530f0 100644
--- a/init/subcontext.cpp
+++ b/init/subcontext.cpp
@@ -30,8 +30,6 @@
30#include "util.h" 30#include "util.h"
31 31
32#if defined(__ANDROID__) 32#if defined(__ANDROID__)
33#include <android-base/properties.h>
34
35#include "property_service.h" 33#include "property_service.h"
36#include "selinux.h" 34#include "selinux.h"
37#else 35#else
@@ -39,7 +37,6 @@
39#endif 37#endif
40 38
41using android::base::GetExecutablePath; 39using android::base::GetExecutablePath;
42using android::base::GetIntProperty;
43using android::base::Join; 40using android::base::Join;
44using android::base::Socketpair; 41using android::base::Socketpair;
45using android::base::Split; 42using android::base::Split;
@@ -357,7 +354,7 @@ Result<std::vector<std::string>> Subcontext::ExpandArgs(const std::vector<std::s
357static std::vector<Subcontext> subcontexts; 354static std::vector<Subcontext> subcontexts;
358 355
359std::vector<Subcontext>* InitializeSubcontexts() { 356std::vector<Subcontext>* InitializeSubcontexts() {
360 if (GetIntProperty("ro.vndk.version", 28) >= 28) { 357 if (SelinuxHasVendorInit()) {
361 for (const auto& [path_prefix, secontext] : paths_and_secontexts) { 358 for (const auto& [path_prefix, secontext] : paths_and_secontexts) {
362 subcontexts.emplace_back(path_prefix, secontext); 359 subcontexts.emplace_back(path_prefix, secontext);
363 } 360 }
diff --git a/init/ueventd.cpp b/init/ueventd.cpp
index 1435d82ef..a284203ba 100644
--- a/init/ueventd.cpp
+++ b/init/ueventd.cpp
@@ -30,6 +30,7 @@
30#include <android-base/chrono_utils.h> 30#include <android-base/chrono_utils.h>
31#include <android-base/logging.h> 31#include <android-base/logging.h>
32#include <android-base/properties.h> 32#include <android-base/properties.h>
33#include <fstab/fstab.h>
33#include <selinux/android.h> 34#include <selinux/android.h>
34#include <selinux/selinux.h> 35#include <selinux/selinux.h>
35 36
@@ -242,8 +243,9 @@ DeviceHandler CreateDeviceHandler() {
242 std::string hardware = android::base::GetProperty("ro.hardware", ""); 243 std::string hardware = android::base::GetProperty("ro.hardware", "");
243 parser.ParseConfig("/ueventd." + hardware + ".rc"); 244 parser.ParseConfig("/ueventd." + hardware + ".rc");
244 245
246 auto boot_devices = fs_mgr_get_boot_devices();
245 return DeviceHandler(std::move(dev_permissions), std::move(sysfs_permissions), 247 return DeviceHandler(std::move(dev_permissions), std::move(sysfs_permissions),
246 std::move(subsystems), true); 248 std::move(subsystems), std::move(boot_devices), true);
247} 249}
248 250
249int ueventd_main(int argc, char** argv) { 251int ueventd_main(int argc, char** argv) {
diff --git a/libbacktrace/Android.bp b/libbacktrace/Android.bp
index 11b8144be..0f93dd071 100644
--- a/libbacktrace/Android.bp
+++ b/libbacktrace/Android.bp
@@ -51,6 +51,7 @@ libbacktrace_sources = [
51cc_library_headers { 51cc_library_headers {
52 name: "libbacktrace_headers", 52 name: "libbacktrace_headers",
53 vendor_available: true, 53 vendor_available: true,
54 recovery_available: true,
54 export_include_dirs: ["include"], 55 export_include_dirs: ["include"],
55} 56}
56 57
@@ -91,7 +92,10 @@ cc_library {
91 "libdexfile", 92 "libdexfile",
92 ], 93 ],
93 94
94 static_libs: ["libcutils"], 95 static_libs: [
96 "libcutils",
97 "libprocinfo",
98 ],
95 99
96 // libdexfile will eventually properly export headers, for now 100 // libdexfile will eventually properly export headers, for now
97 // include these directly. 101 // include these directly.
diff --git a/libbacktrace/BacktraceMap.cpp b/libbacktrace/BacktraceMap.cpp
index bdae14062..399721dc1 100644
--- a/libbacktrace/BacktraceMap.cpp
+++ b/libbacktrace/BacktraceMap.cpp
@@ -28,6 +28,9 @@
28#include <backtrace/Backtrace.h> 28#include <backtrace/Backtrace.h>
29#include <backtrace/BacktraceMap.h> 29#include <backtrace/BacktraceMap.h>
30#include <backtrace/backtrace_constants.h> 30#include <backtrace/backtrace_constants.h>
31#if defined(__linux__)
32#include <procinfo/process_map.h>
33#endif
31 34
32#include "thread_utils.h" 35#include "thread_utils.h"
33 36
@@ -60,27 +63,19 @@ void BacktraceMap::FillIn(uint64_t addr, backtrace_map_t* map) {
60 *map = {}; 63 *map = {};
61} 64}
62 65
63bool BacktraceMap::ParseLine(const char* line, backtrace_map_t* map) { 66#if defined(__APPLE__)
67static bool ParseLine(const char* line, backtrace_map_t* map) {
64 uint64_t start; 68 uint64_t start;
65 uint64_t end; 69 uint64_t end;
66 char permissions[5]; 70 char permissions[5];
67 int name_pos; 71 int name_pos;
68 72
69#if defined(__APPLE__)
70// Mac OS vmmap(1) output: 73// Mac OS vmmap(1) output:
71// __TEXT 0009f000-000a1000 [ 8K 8K] r-x/rwx SM=COW /Volumes/android/dalvik-dev/out/host/darwin-x86/bin/libcorkscrew_test\n 74// __TEXT 0009f000-000a1000 [ 8K 8K] r-x/rwx SM=COW /Volumes/android/dalvik-dev/out/host/darwin-x86/bin/libcorkscrew_test\n
72// 012345678901234567890123456789012345678901234567890123456789 75// 012345678901234567890123456789012345678901234567890123456789
73// 0 1 2 3 4 5 76// 0 1 2 3 4 5
74 if (sscanf(line, "%*21c %" SCNx64 "-%" SCNx64 " [%*13c] %3c/%*3c SM=%*3c %n", 77 if (sscanf(line, "%*21c %" SCNx64 "-%" SCNx64 " [%*13c] %3c/%*3c SM=%*3c %n",
75 &start, &end, permissions, &name_pos) != 3) { 78 &start, &end, permissions, &name_pos) != 3) {
76#else
77// Linux /proc/<pid>/maps lines:
78// 6f000000-6f01e000 rwxp 00000000 00:0c 16389419 /system/lib/libcomposer.so\n
79// 012345678901234567890123456789012345678901234567890123456789
80// 0 1 2 3 4 5
81 if (sscanf(line, "%" SCNx64 "-%" SCNx64 " %4s %*x %*x:%*x %*d %n",
82 &start, &end, permissions, &name_pos) != 3) {
83#endif
84 return false; 79 return false;
85 } 80 }
86 81
@@ -107,24 +102,15 @@ bool BacktraceMap::ParseLine(const char* line, backtrace_map_t* map) {
107 map->flags, map->name.c_str()); 102 map->flags, map->name.c_str());
108 return true; 103 return true;
109} 104}
105#endif // defined(__APPLE__)
110 106
111bool BacktraceMap::Build() { 107bool BacktraceMap::Build() {
112#if defined(__APPLE__) 108#if defined(__APPLE__)
113 char cmd[sizeof(pid_t)*3 + sizeof("vmmap -w -resident -submap -allSplitLibs -interleaved ") + 1]; 109 char cmd[sizeof(pid_t)*3 + sizeof("vmmap -w -resident -submap -allSplitLibs -interleaved ") + 1];
114#else
115 char path[sizeof(pid_t)*3 + sizeof("/proc//maps") + 1];
116#endif
117 char line[1024]; 110 char line[1024];
118
119#if defined(__APPLE__)
120 // cmd is guaranteed to always be big enough to hold this string. 111 // cmd is guaranteed to always be big enough to hold this string.
121 snprintf(cmd, sizeof(cmd), "vmmap -w -resident -submap -allSplitLibs -interleaved %d", pid_); 112 snprintf(cmd, sizeof(cmd), "vmmap -w -resident -submap -allSplitLibs -interleaved %d", pid_);
122 FILE* fp = popen(cmd, "r"); 113 FILE* fp = popen(cmd, "r");
123#else
124 // path is guaranteed to always be big enough to hold this string.
125 snprintf(path, sizeof(path), "/proc/%d/maps", pid_);
126 FILE* fp = fopen(path, "r");
127#endif
128 if (fp == nullptr) { 114 if (fp == nullptr) {
129 return false; 115 return false;
130 } 116 }
@@ -135,13 +121,19 @@ bool BacktraceMap::Build() {
135 maps_.push_back(map); 121 maps_.push_back(map);
136 } 122 }
137 } 123 }
138#if defined(__APPLE__)
139 pclose(fp); 124 pclose(fp);
125 return true;
140#else 126#else
141 fclose(fp); 127 return android::procinfo::ReadProcessMaps(
128 pid_, [&](uint64_t start, uint64_t end, uint16_t flags, uint64_t, const char* name) {
129 maps_.resize(maps_.size() + 1);
130 backtrace_map_t& map = maps_.back();
131 map.start = start;
132 map.end = end;
133 map.flags = flags;
134 map.name = name;
135 });
142#endif 136#endif
143
144 return true;
145} 137}
146 138
147#if defined(__APPLE__) 139#if defined(__APPLE__)
diff --git a/libbacktrace/include/backtrace/BacktraceMap.h b/libbacktrace/include/backtrace/BacktraceMap.h
index c94cad188..a9cfce4cb 100644
--- a/libbacktrace/include/backtrace/BacktraceMap.h
+++ b/libbacktrace/include/backtrace/BacktraceMap.h
@@ -169,8 +169,6 @@ public:
169 169
170 virtual uint64_t GetLoadBias(size_t /* index */) { return 0; } 170 virtual uint64_t GetLoadBias(size_t /* index */) { return 0; }
171 171
172 virtual bool ParseLine(const char* line, backtrace_map_t* map);
173
174 pid_t pid_; 172 pid_t pid_;
175 std::deque<backtrace_map_t> maps_; 173 std::deque<backtrace_map_t> maps_;
176 std::vector<std::string> suffixes_to_ignore_; 174 std::vector<std::string> suffixes_to_ignore_;
diff --git a/libcutils/Android.bp b/libcutils/Android.bp
index dd46750fc..cdbb65f45 100644
--- a/libcutils/Android.bp
+++ b/libcutils/Android.bp
@@ -32,6 +32,7 @@ libcutils_nonwindows_sources = [
32cc_library_headers { 32cc_library_headers {
33 name: "libcutils_headers", 33 name: "libcutils_headers",
34 vendor_available: true, 34 vendor_available: true,
35 recovery_available: true,
35 host_supported: true, 36 host_supported: true,
36 export_include_dirs: ["include"], 37 export_include_dirs: ["include"],
37 target: { 38 target: {
@@ -54,6 +55,7 @@ cc_library {
54 enabled: true, 55 enabled: true,
55 support_system_process: true, 56 support_system_process: true,
56 }, 57 },
58 recovery_available: true,
57 host_supported: true, 59 host_supported: true,
58 srcs: [ 60 srcs: [
59 "config_utils.cpp", 61 "config_utils.cpp",
@@ -160,6 +162,15 @@ cc_library {
160 misc_undefined: ["integer"], 162 misc_undefined: ["integer"],
161 }, 163 },
162 }, 164 },
165
166 vendor: {
167 exclude_srcs: [
168 // qtaguid.cpp loads libnetd_client.so with dlopen(). Since
169 // the interface of libnetd_client.so may vary between AOSP
170 // releases, exclude qtaguid.cpp from the VNDK-SP variant.
171 "qtaguid.cpp",
172 ],
173 }
163 }, 174 },
164 175
165 shared_libs: ["liblog"], 176 shared_libs: ["liblog"],
diff --git a/libcutils/ashmem-host.cpp b/libcutils/ashmem-host.cpp
index b2bec9966..bb990d562 100644
--- a/libcutils/ashmem-host.cpp
+++ b/libcutils/ashmem-host.cpp
@@ -24,7 +24,6 @@
24#include <errno.h> 24#include <errno.h>
25#include <fcntl.h> 25#include <fcntl.h>
26#include <limits.h> 26#include <limits.h>
27#include <stdbool.h>
28#include <stdio.h> 27#include <stdio.h>
29#include <stdlib.h> 28#include <stdlib.h>
30#include <string.h> 29#include <string.h>
diff --git a/libcutils/canned_fs_config.cpp b/libcutils/canned_fs_config.cpp
index 6b5763b16..2772ef0e9 100644
--- a/libcutils/canned_fs_config.cpp
+++ b/libcutils/canned_fs_config.cpp
@@ -21,7 +21,6 @@
21#include <errno.h> 21#include <errno.h>
22#include <inttypes.h> 22#include <inttypes.h>
23#include <limits.h> 23#include <limits.h>
24#include <stdbool.h>
25#include <stdio.h> 24#include <stdio.h>
26#include <stdlib.h> 25#include <stdlib.h>
27#include <string.h> 26#include <string.h>
diff --git a/libcutils/hashmap.cpp b/libcutils/hashmap.cpp
index 65b6ab185..10e3b2505 100644
--- a/libcutils/hashmap.cpp
+++ b/libcutils/hashmap.cpp
@@ -21,7 +21,6 @@
21#include <cutils/threads.h> 21#include <cutils/threads.h>
22#include <stdlib.h> 22#include <stdlib.h>
23#include <string.h> 23#include <string.h>
24#include <stdbool.h>
25#include <sys/types.h> 24#include <sys/types.h>
26 25
27typedef struct Entry Entry; 26typedef struct Entry Entry;
diff --git a/libcutils/trace-dev.inc b/libcutils/trace-dev.inc
index f95c6c559..c9580af04 100644
--- a/libcutils/trace-dev.inc
+++ b/libcutils/trace-dev.inc
@@ -24,7 +24,6 @@
24#include <limits.h> 24#include <limits.h>
25#include <pthread.h> 25#include <pthread.h>
26#include <stdatomic.h> 26#include <stdatomic.h>
27#include <stdbool.h>
28#include <stdlib.h> 27#include <stdlib.h>
29#include <string.h> 28#include <string.h>
30#include <sys/types.h> 29#include <sys/types.h>
diff --git a/liblog/Android.bp b/liblog/Android.bp
index 7d9e30602..2d5a5dbb2 100644
--- a/liblog/Android.bp
+++ b/liblog/Android.bp
@@ -46,6 +46,7 @@ cc_library_headers {
46 name: "liblog_headers", 46 name: "liblog_headers",
47 host_supported: true, 47 host_supported: true,
48 vendor_available: true, 48 vendor_available: true,
49 recovery_available: true,
49 export_include_dirs: ["include"], 50 export_include_dirs: ["include"],
50 target: { 51 target: {
51 windows: { 52 windows: {
@@ -65,7 +66,7 @@ cc_library_headers {
65cc_library { 66cc_library {
66 name: "liblog", 67 name: "liblog",
67 host_supported: true, 68 host_supported: true,
68 69 recovery_available: true,
69 srcs: liblog_sources, 70 srcs: liblog_sources,
70 71
71 target: { 72 target: {
diff --git a/liblog/logprint.c b/liblog/logprint.c
index a2839bfb6..7937cb1c5 100644
--- a/liblog/logprint.c
+++ b/liblog/logprint.c
@@ -1632,8 +1632,10 @@ LIBLOG_ABI_PUBLIC char* android_log_formatLogLine(AndroidLogFormat* p_format,
1632 prefixLen = snprintf(prefixBuf, sizeof(prefixBuf), "\x1B[38;5;%dm", 1632 prefixLen = snprintf(prefixBuf, sizeof(prefixBuf), "\x1B[38;5;%dm",
1633 colorFromPri(entry->priority)); 1633 colorFromPri(entry->priority));
1634 prefixLen = MIN(prefixLen, sizeof(prefixBuf)); 1634 prefixLen = MIN(prefixLen, sizeof(prefixBuf));
1635 suffixLen = snprintf(suffixBuf, sizeof(suffixBuf), "\x1B[0m"); 1635
1636 suffixLen = MIN(suffixLen, sizeof(suffixBuf)); 1636 const char suffixContents[] = "\x1B[0m";
1637 strcpy(suffixBuf, suffixContents);
1638 suffixLen = strlen(suffixContents);
1637 } 1639 }
1638 1640
1639 char uid[16]; 1641 char uid[16];
diff --git a/libmemunreachable/Android.bp b/libmemunreachable/Android.bp
index f164a19e0..248a9d25c 100644
--- a/libmemunreachable/Android.bp
+++ b/libmemunreachable/Android.bp
@@ -29,7 +29,6 @@ cc_library {
29 "HeapWalker.cpp", 29 "HeapWalker.cpp",
30 "LeakFolding.cpp", 30 "LeakFolding.cpp",
31 "LeakPipe.cpp", 31 "LeakPipe.cpp",
32 "LineBuffer.cpp",
33 "MemUnreachable.cpp", 32 "MemUnreachable.cpp",
34 "ProcessMappings.cpp", 33 "ProcessMappings.cpp",
35 "PtracerThread.cpp", 34 "PtracerThread.cpp",
@@ -38,6 +37,7 @@ cc_library {
38 37
39 static_libs: [ 38 static_libs: [
40 "libc_malloc_debug_backtrace", 39 "libc_malloc_debug_backtrace",
40 "libprocinfo",
41 ], 41 ],
42 // Only need this for arm since libc++ uses its own unwind code that 42 // Only need this for arm since libc++ uses its own unwind code that
43 // doesn't mix with the other default unwind code. 43 // doesn't mix with the other default unwind code.
diff --git a/libmemunreachable/LineBuffer.cpp b/libmemunreachable/LineBuffer.cpp
deleted file mode 100644
index 4ea0542c7..000000000
--- a/libmemunreachable/LineBuffer.cpp
+++ /dev/null
@@ -1,66 +0,0 @@
1/*
2 * Copyright (C) 2015 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17// Copied from system/extras/memory_replay/LineBuffer.cpp
18// TODO(ccross): find a way to share between libmemunreachable and memory_replay?
19
20#include <errno.h>
21#include <string.h>
22#include <unistd.h>
23
24#include "LineBuffer.h"
25
26namespace android {
27
28LineBuffer::LineBuffer(int fd, char* buffer, size_t buffer_len)
29 : fd_(fd), buffer_(buffer), buffer_len_(buffer_len) {}
30
31bool LineBuffer::GetLine(char** line, size_t* line_len) {
32 while (true) {
33 if (bytes_ > 0) {
34 char* newline = reinterpret_cast<char*>(memchr(buffer_ + start_, '\n', bytes_));
35 if (newline != nullptr) {
36 *newline = '\0';
37 *line = buffer_ + start_;
38 start_ = newline - buffer_ + 1;
39 bytes_ -= newline - *line + 1;
40 *line_len = newline - *line;
41 return true;
42 }
43 }
44 if (start_ > 0) {
45 // Didn't find anything, copy the current to the front of the buffer.
46 memmove(buffer_, buffer_ + start_, bytes_);
47 start_ = 0;
48 }
49 ssize_t bytes = TEMP_FAILURE_RETRY(read(fd_, buffer_ + bytes_, buffer_len_ - bytes_ - 1));
50 if (bytes <= 0) {
51 if (bytes_ > 0) {
52 // The read data might not contain a nul terminator, so add one.
53 buffer_[bytes_] = '\0';
54 *line = buffer_ + start_;
55 *line_len = bytes_;
56 bytes_ = 0;
57 start_ = 0;
58 return true;
59 }
60 return false;
61 }
62 bytes_ += bytes;
63 }
64}
65
66} // namespace android
diff --git a/libmemunreachable/LineBuffer.h b/libmemunreachable/LineBuffer.h
deleted file mode 100644
index cc6cd0c6a..000000000
--- a/libmemunreachable/LineBuffer.h
+++ /dev/null
@@ -1,40 +0,0 @@
1/*
2 * Copyright (C) 2015 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#ifndef _LIBMEMUNREACHABLE_LINE_BUFFER_H
18#define _LIBMEMUNREACHABLE_LINE_BUFFER_H
19
20#include <stdint.h>
21
22namespace android {
23
24class LineBuffer {
25 public:
26 LineBuffer(int fd, char* buffer, size_t buffer_len);
27
28 bool GetLine(char** line, size_t* line_len);
29
30 private:
31 int fd_;
32 char* buffer_ = nullptr;
33 size_t buffer_len_ = 0;
34 size_t start_ = 0;
35 size_t bytes_ = 0;
36};
37
38} // namespace android
39
40#endif // _LIBMEMUNREACHABLE_LINE_BUFFER_H
diff --git a/libmemunreachable/MemUnreachable.cpp b/libmemunreachable/MemUnreachable.cpp
index 24fdc7f37..529a0437e 100644
--- a/libmemunreachable/MemUnreachable.cpp
+++ b/libmemunreachable/MemUnreachable.cpp
@@ -495,6 +495,21 @@ std::string UnreachableMemoryInfo::ToString(bool log_contents) const {
495 return oss.str(); 495 return oss.str();
496} 496}
497 497
498UnreachableMemoryInfo::~UnreachableMemoryInfo() {
499 // Clear the memory that holds the leaks, otherwise the next attempt to
500 // detect leaks may find the old data (for example in the jemalloc tcache)
501 // and consider all the leaks to be referenced.
502 memset(leaks.data(), 0, leaks.capacity() * sizeof(Leak));
503
504 std::vector<Leak> tmp;
505 leaks.swap(tmp);
506
507 // Disable and re-enable malloc to flush the jemalloc tcache to make sure
508 // there are no copies of the leaked pointer addresses there.
509 malloc_disable();
510 malloc_enable();
511}
512
498std::string GetUnreachableMemoryString(bool log_contents, size_t limit) { 513std::string GetUnreachableMemoryString(bool log_contents, size_t limit) {
499 UnreachableMemoryInfo info; 514 UnreachableMemoryInfo info;
500 if (!GetUnreachableMemory(info, limit)) { 515 if (!GetUnreachableMemory(info, limit)) {
diff --git a/libmemunreachable/ProcessMappings.cpp b/libmemunreachable/ProcessMappings.cpp
index 9a0687052..701ce1670 100644
--- a/libmemunreachable/ProcessMappings.cpp
+++ b/libmemunreachable/ProcessMappings.cpp
@@ -14,21 +14,30 @@
14 * limitations under the License. 14 * limitations under the License.
15 */ 15 */
16 16
17#include <errno.h>
17#include <fcntl.h> 18#include <fcntl.h>
18#include <inttypes.h> 19#include <inttypes.h>
19#include <string.h> 20#include <string.h>
20#include <unistd.h> 21#include <unistd.h>
21 22
22#include <android-base/unique_fd.h> 23#include <android-base/unique_fd.h>
24#include <procinfo/process_map.h>
23 25
24#include "LineBuffer.h"
25#include "ProcessMappings.h" 26#include "ProcessMappings.h"
26#include "log.h"
27 27
28namespace android { 28namespace android {
29 29
30// This function is not re-entrant since it uses a static buffer for 30struct ReadMapCallback {
31// the line data. 31 ReadMapCallback(allocator::vector<Mapping>& mappings) : mappings_(mappings) {}
32
33 void operator()(uint64_t start, uint64_t end, uint16_t flags, uint64_t, const char* name) const {
34 mappings_.emplace_back(start, end, flags & PROT_READ, flags & PROT_WRITE, flags & PROT_EXEC,
35 name);
36 }
37
38 allocator::vector<Mapping>& mappings_;
39};
40
32bool ProcessMappings(pid_t pid, allocator::vector<Mapping>& mappings) { 41bool ProcessMappings(pid_t pid, allocator::vector<Mapping>& mappings) {
33 char map_buffer[1024]; 42 char map_buffer[1024];
34 snprintf(map_buffer, sizeof(map_buffer), "/proc/%d/maps", pid); 43 snprintf(map_buffer, sizeof(map_buffer), "/proc/%d/maps", pid);
@@ -36,35 +45,13 @@ bool ProcessMappings(pid_t pid, allocator::vector<Mapping>& mappings) {
36 if (fd == -1) { 45 if (fd == -1) {
37 return false; 46 return false;
38 } 47 }
39 48 allocator::string content(mappings.get_allocator());
40 LineBuffer line_buf(fd, map_buffer, sizeof(map_buffer)); 49 ssize_t n;
41 char* line; 50 while ((n = TEMP_FAILURE_RETRY(read(fd, map_buffer, sizeof(map_buffer)))) > 0) {
42 size_t line_len; 51 content.append(map_buffer, n);
43 while (line_buf.GetLine(&line, &line_len)) {
44 int name_pos;
45 char perms[5];
46 Mapping mapping{};
47 if (sscanf(line, "%" SCNxPTR "-%" SCNxPTR " %4s %*x %*x:%*x %*d %n", &mapping.begin,
48 &mapping.end, perms, &name_pos) == 3) {
49 if (perms[0] == 'r') {
50 mapping.read = true;
51 }
52 if (perms[1] == 'w') {
53 mapping.write = true;
54 }
55 if (perms[2] == 'x') {
56 mapping.execute = true;
57 }
58 if (perms[3] == 'p') {
59 mapping.priv = true;
60 }
61 if ((size_t)name_pos < line_len) {
62 strlcpy(mapping.name, line + name_pos, sizeof(mapping.name));
63 }
64 mappings.emplace_back(mapping);
65 }
66 } 52 }
67 return true; 53 ReadMapCallback callback(mappings);
54 return android::procinfo::ReadMapFileContent(&content[0], callback);
68} 55}
69 56
70} // namespace android 57} // namespace android
diff --git a/libmemunreachable/ProcessMappings.h b/libmemunreachable/ProcessMappings.h
index a0e97e9fc..94da69b11 100644
--- a/libmemunreachable/ProcessMappings.h
+++ b/libmemunreachable/ProcessMappings.h
@@ -17,6 +17,8 @@
17#ifndef LIBMEMUNREACHABLE_PROCESS_MAPPING_H_ 17#ifndef LIBMEMUNREACHABLE_PROCESS_MAPPING_H_
18#define LIBMEMUNREACHABLE_PROCESS_MAPPING_H_ 18#define LIBMEMUNREACHABLE_PROCESS_MAPPING_H_
19 19
20#include <string.h>
21
20#include "Allocator.h" 22#include "Allocator.h"
21 23
22namespace android { 24namespace android {
@@ -27,8 +29,13 @@ struct Mapping {
27 bool read; 29 bool read;
28 bool write; 30 bool write;
29 bool execute; 31 bool execute;
30 bool priv;
31 char name[96]; 32 char name[96];
33
34 Mapping() {}
35 Mapping(uintptr_t begin, uintptr_t end, bool read, bool write, bool execute, const char* name)
36 : begin(begin), end(end), read(read), write(write), execute(execute) {
37 strlcpy(this->name, name, sizeof(this->name));
38 }
32}; 39};
33 40
34// This function is not re-entrant since it uses a static buffer for 41// This function is not re-entrant since it uses a static buffer for
diff --git a/libmemunreachable/README.md b/libmemunreachable/README.md
index ae8fa94b3..6d9141a5f 100644
--- a/libmemunreachable/README.md
+++ b/libmemunreachable/README.md
@@ -12,6 +12,27 @@ In the default (zero-overhead) mode, the returned data on leaks is limited to th
12Usage 12Usage
13------- 13-------
14 14
15### In Android apps ###
16
17libmemunreachble is loaded by zygote and can be triggered with `dumpsys -t 600 meminfo --unreachable [process]`.
18
19To enable malloc\_debug backtraces on allocations for a single app process on a userdebug device, use:
20```
21adb root
22adb shell setprop libc.debug.malloc.program app_process
23adb shell setprop wrap.[process] "\$\@"
24adb shell setprop libc.debug.malloc.options backtrace=4
25```
26
27Kill and restart the app, trigger the leak, and then run `dumpsys -t 600 meminfo --unreachable [process]`.
28
29To disable malloc\_debug:
30```
31adb shell setprop libc.debug.malloc.options "''"
32adb shell setprop libc.debug.malloc.program "''"
33adb shell setprop wrap.[process] "''"
34```
35
15### C interface ### 36### C interface ###
16 37
17#### `bool LogUnreachableMemory(bool log_contents, size_t limit)` #### 38#### `bool LogUnreachableMemory(bool log_contents, size_t limit)` ####
diff --git a/libmemunreachable/include/memunreachable/memunreachable.h b/libmemunreachable/include/memunreachable/memunreachable.h
index 438fcafe1..c028eabf2 100644
--- a/libmemunreachable/include/memunreachable/memunreachable.h
+++ b/libmemunreachable/include/memunreachable/memunreachable.h
@@ -62,12 +62,7 @@ struct UnreachableMemoryInfo {
62 size_t allocation_bytes; 62 size_t allocation_bytes;
63 63
64 UnreachableMemoryInfo() {} 64 UnreachableMemoryInfo() {}
65 ~UnreachableMemoryInfo() { 65 ~UnreachableMemoryInfo();
66 // Clear the memory that holds the leaks, otherwise the next attempt to
67 // detect leaks may find the old data (for example in the jemalloc tcache)
68 // and consider all the leaks to be referenced.
69 memset(leaks.data(), 0, leaks.capacity() * sizeof(Leak));
70 }
71 66
72 std::string ToString(bool log_contents) const; 67 std::string ToString(bool log_contents) const;
73}; 68};
diff --git a/libmemunreachable/tests/MemUnreachable_test.cpp b/libmemunreachable/tests/MemUnreachable_test.cpp
index 87417f132..bba0c6d11 100644
--- a/libmemunreachable/tests/MemUnreachable_test.cpp
+++ b/libmemunreachable/tests/MemUnreachable_test.cpp
@@ -23,6 +23,8 @@
23 23
24#include <memunreachable/memunreachable.h> 24#include <memunreachable/memunreachable.h>
25 25
26#include "bionic.h"
27
26namespace android { 28namespace android {
27 29
28class HiddenPointer { 30class HiddenPointer {
@@ -48,7 +50,35 @@ static void Ref(void** ptr) {
48 write(0, ptr, 0); 50 write(0, ptr, 0);
49} 51}
50 52
51TEST(MemunreachableTest, clean) { 53class MemunreachableTest : public ::testing::Test {
54 protected:
55 virtual void SetUp() {
56 CleanStack(8192);
57 CleanTcache();
58 }
59
60 virtual void TearDown() {
61 CleanStack(8192);
62 CleanTcache();
63 }
64
65 // Allocate a buffer on the stack and zero it to make sure there are no
66 // stray pointers from old test runs.
67 void __attribute__((noinline)) CleanStack(size_t size) {
68 void* buf = alloca(size);
69 memset(buf, 0, size);
70 Ref(&buf);
71 }
72
73 // Disable and re-enable malloc to flush the jemalloc tcache to make sure
74 // there are stray pointers from old test runs there.
75 void CleanTcache() {
76 malloc_disable();
77 malloc_enable();
78 }
79};
80
81TEST_F(MemunreachableTest, clean) {
52 UnreachableMemoryInfo info; 82 UnreachableMemoryInfo info;
53 83
54 ASSERT_TRUE(LogUnreachableMemory(true, 100)); 84 ASSERT_TRUE(LogUnreachableMemory(true, 100));
@@ -57,7 +87,7 @@ TEST(MemunreachableTest, clean) {
57 ASSERT_EQ(0U, info.leaks.size()); 87 ASSERT_EQ(0U, info.leaks.size());
58} 88}
59 89
60TEST(MemunreachableTest, stack) { 90TEST_F(MemunreachableTest, stack) {
61 HiddenPointer hidden_ptr; 91 HiddenPointer hidden_ptr;
62 92
63 { 93 {
@@ -91,7 +121,7 @@ TEST(MemunreachableTest, stack) {
91 121
92void* g_ptr; 122void* g_ptr;
93 123
94TEST(MemunreachableTest, global) { 124TEST_F(MemunreachableTest, global) {
95 HiddenPointer hidden_ptr; 125 HiddenPointer hidden_ptr;
96 126
97 g_ptr = hidden_ptr.Get(); 127 g_ptr = hidden_ptr.Get();
@@ -122,7 +152,7 @@ TEST(MemunreachableTest, global) {
122 } 152 }
123} 153}
124 154
125TEST(MemunreachableTest, tls) { 155TEST_F(MemunreachableTest, tls) {
126 HiddenPointer hidden_ptr; 156 HiddenPointer hidden_ptr;
127 pthread_key_t key; 157 pthread_key_t key;
128 pthread_key_create(&key, nullptr); 158 pthread_key_create(&key, nullptr);
@@ -157,10 +187,22 @@ TEST(MemunreachableTest, tls) {
157 pthread_key_delete(key); 187 pthread_key_delete(key);
158} 188}
159 189
160TEST(MemunreachableTest, twice) { 190TEST_F(MemunreachableTest, twice) {
161 HiddenPointer hidden_ptr; 191 HiddenPointer hidden_ptr;
162 192
163 { 193 {
194 void* ptr = hidden_ptr.Get();
195 Ref(&ptr);
196
197 UnreachableMemoryInfo info;
198
199 ASSERT_TRUE(GetUnreachableMemory(info));
200 ASSERT_EQ(0U, info.leaks.size());
201
202 ptr = nullptr;
203 }
204
205 {
164 UnreachableMemoryInfo info; 206 UnreachableMemoryInfo info;
165 207
166 ASSERT_TRUE(GetUnreachableMemory(info)); 208 ASSERT_TRUE(GetUnreachableMemory(info));
@@ -184,7 +226,7 @@ TEST(MemunreachableTest, twice) {
184 } 226 }
185} 227}
186 228
187TEST(MemunreachableTest, log) { 229TEST_F(MemunreachableTest, log) {
188 HiddenPointer hidden_ptr; 230 HiddenPointer hidden_ptr;
189 231
190 ASSERT_TRUE(LogUnreachableMemory(true, 100)); 232 ASSERT_TRUE(LogUnreachableMemory(true, 100));
@@ -199,17 +241,23 @@ TEST(MemunreachableTest, log) {
199 } 241 }
200} 242}
201 243
202TEST(MemunreachableTest, notdumpable) { 244TEST_F(MemunreachableTest, notdumpable) {
245 if (getuid() == 0) {
246 // TODO(ccross): make this a skipped test when gtest supports them
247 printf("[ SKIP ] Not testable when running as root\n");
248 return;
249 }
250
203 ASSERT_EQ(0, prctl(PR_SET_DUMPABLE, 0)); 251 ASSERT_EQ(0, prctl(PR_SET_DUMPABLE, 0));
204 252
205 HiddenPointer hidden_ptr; 253 HiddenPointer hidden_ptr;
206 254
207 ASSERT_TRUE(LogUnreachableMemory(true, 100)); 255 EXPECT_FALSE(LogUnreachableMemory(true, 100));
208 256
209 ASSERT_EQ(0, prctl(PR_SET_DUMPABLE, 1)); 257 ASSERT_EQ(0, prctl(PR_SET_DUMPABLE, 1));
210} 258}
211 259
212TEST(MemunreachableTest, leak_lots) { 260TEST_F(MemunreachableTest, leak_lots) {
213 std::vector<HiddenPointer> hidden_ptrs; 261 std::vector<HiddenPointer> hidden_ptrs;
214 hidden_ptrs.resize(1024); 262 hidden_ptrs.resize(1024);
215 263
diff --git a/libmetricslogger/Android.bp b/libmetricslogger/Android.bp
index 6549b8d56..e6e17ce87 100644
--- a/libmetricslogger/Android.bp
+++ b/libmetricslogger/Android.bp
@@ -29,6 +29,13 @@ cc_library_shared {
29 defaults: ["metricslogger_defaults"], 29 defaults: ["metricslogger_defaults"],
30} 30}
31 31
32// static version of libmetricslogger, needed by a few art static binaries
33cc_library_static {
34 name: "libmetricslogger_static",
35 srcs: metricslogger_lib_src_files,
36 defaults: ["metricslogger_defaults"],
37}
38
32// metricslogger shared library, debug 39// metricslogger shared library, debug
33// ----------------------------------------------------------------------------- 40// -----------------------------------------------------------------------------
34cc_library_shared { 41cc_library_shared {
diff --git a/libmetricslogger/include/metricslogger/metrics_logger.h b/libmetricslogger/include/metricslogger/metrics_logger.h
index 189bc4b63..2c768695d 100644
--- a/libmetricslogger/include/metricslogger/metrics_logger.h
+++ b/libmetricslogger/include/metricslogger/metrics_logger.h
@@ -14,6 +14,7 @@
14 * limitations under the License. 14 * limitations under the License.
15 */ 15 */
16 16
17#include <log/log_event_list.h>
17#include <cstdint> 18#include <cstdint>
18#include <string> 19#include <string>
19 20
@@ -32,6 +33,34 @@ void LogCounter(const std::string& name, int32_t val);
32// |value| in the field |field|. 33// |value| in the field |field|.
33void LogMultiAction(int32_t category, int32_t field, const std::string& value); 34void LogMultiAction(int32_t category, int32_t field, const std::string& value);
34 35
36// Logs a Tron complex event.
37//
38// A complex event can include data in a structure not suppored by the other
39// log event types above.
40//
41// Note that instances of this class are single use. You must call Record()
42// to write the event to the event log.
43class ComplexEventLogger {
44 private:
45 android_log_event_list logger;
46
47 public:
48 // Create a complex event with category|category|.
49 explicit ComplexEventLogger(int category);
50 // Add tagged data to the event, with the given tag and integer value.
51 void AddTaggedData(int tag, int32_t value);
52 // Add tagged data to the event, with the given tag and string value.
53 void AddTaggedData(int tag, const std::string& value);
54 // Add tagged data to the event, with the given tag and integer value.
55 void AddTaggedData(int tag, int64_t value);
56 // Add tagged data to the event, with the given tag and float value.
57 void AddTaggedData(int tag, float value);
58 // Record this event. This method can only be used once per instance
59 // of ComplexEventLogger. Do not made any subsequent calls to AddTaggedData
60 // after recording an event.
61 void Record();
62};
63
35// TODO: replace these with the metric_logger.proto definitions 64// TODO: replace these with the metric_logger.proto definitions
36enum { 65enum {
37 LOGBUILDER_CATEGORY = 757, 66 LOGBUILDER_CATEGORY = 757,
@@ -44,11 +73,23 @@ enum {
44 73
45 ACTION_BOOT = 1098, 74 ACTION_BOOT = 1098,
46 FIELD_PLATFORM_REASON = 1099, 75 FIELD_PLATFORM_REASON = 1099,
76
77 ACTION_HIDDEN_API_ACCESSED = 1391,
78 FIELD_HIDDEN_API_ACCESS_METHOD = 1392,
79 FIELD_HIDDEN_API_ACCESS_DENIED = 1393,
80 FIELD_HIDDEN_API_SIGNATURE = 1394,
47}; 81};
48 82
49enum { 83enum {
50 TYPE_ACTION = 4, 84 TYPE_ACTION = 4,
51}; 85};
52 86
87enum {
88 ACCESS_METHOD_NONE = 0,
89 ACCESS_METHOD_REFLECTION = 1,
90 ACCESS_METHOD_JNI = 2,
91 ACCESS_METHOD_LINKING = 3,
92};
93
53} // namespace metricslogger 94} // namespace metricslogger
54} // namespace android 95} // namespace android
diff --git a/libmetricslogger/metrics_logger.cpp b/libmetricslogger/metrics_logger.cpp
index fdc44071b..912fa1281 100644
--- a/libmetricslogger/metrics_logger.cpp
+++ b/libmetricslogger/metrics_logger.cpp
@@ -23,9 +23,14 @@
23 23
24namespace { 24namespace {
25 25
26#ifdef __ANDROID__
26EventTagMap* kEventTagMap = android_openEventTagMap(nullptr); 27EventTagMap* kEventTagMap = android_openEventTagMap(nullptr);
27const int kSysuiMultiActionTag = android_lookupEventTagNum( 28const int kSysuiMultiActionTag = android_lookupEventTagNum(
28 kEventTagMap, "sysui_multi_action", "(content|4)", ANDROID_LOG_UNKNOWN); 29 kEventTagMap, "sysui_multi_action", "(content|4)", ANDROID_LOG_UNKNOWN);
30#else
31// android_openEventTagMap does not work on host builds.
32const int kSysuiMultiActionTag = 0;
33#endif
29 34
30} // namespace 35} // namespace
31 36
@@ -53,5 +58,29 @@ void LogMultiAction(int32_t category, int32_t field, const std::string& value) {
53 << field << value << LOG_ID_EVENTS; 58 << field << value << LOG_ID_EVENTS;
54} 59}
55 60
61ComplexEventLogger::ComplexEventLogger(int category) : logger(kSysuiMultiActionTag) {
62 logger << LOGBUILDER_CATEGORY << category;
63}
64
65void ComplexEventLogger::AddTaggedData(int tag, int32_t value) {
66 logger << tag << value;
67}
68
69void ComplexEventLogger::AddTaggedData(int tag, const std::string& value) {
70 logger << tag << value;
71}
72
73void ComplexEventLogger::AddTaggedData(int tag, int64_t value) {
74 logger << tag << value;
75}
76
77void ComplexEventLogger::AddTaggedData(int tag, float value) {
78 logger << tag << value;
79}
80
81void ComplexEventLogger::Record() {
82 logger << LOG_ID_EVENTS;
83}
84
56} // namespace metricslogger 85} // namespace metricslogger
57} // namespace android 86} // namespace android
diff --git a/libpackagelistparser/Android.bp b/libpackagelistparser/Android.bp
index 27693b3f8..c38594a97 100644
--- a/libpackagelistparser/Android.bp
+++ b/libpackagelistparser/Android.bp
@@ -1,6 +1,7 @@
1cc_library { 1cc_library {
2 2
3 name: "libpackagelistparser", 3 name: "libpackagelistparser",
4 recovery_available: true,
4 srcs: ["packagelistparser.c"], 5 srcs: ["packagelistparser.c"],
5 cflags: [ 6 cflags: [
6 "-Wall", 7 "-Wall",
diff --git a/libprocinfo/Android.bp b/libprocinfo/Android.bp
index b35882c57..d776b3d8e 100644
--- a/libprocinfo/Android.bp
+++ b/libprocinfo/Android.bp
@@ -59,6 +59,7 @@ cc_test {
59 host_supported: true, 59 host_supported: true,
60 srcs: [ 60 srcs: [
61 "process_test.cpp", 61 "process_test.cpp",
62 "process_map_test.cpp",
62 ], 63 ],
63 target: { 64 target: {
64 darwin: { 65 darwin: {
@@ -84,5 +85,36 @@ cc_test {
84 }, 85 },
85 }, 86 },
86 87
88 data: [
89 "testdata/*",
90 ],
91
87 test_suites: ["device-tests"], 92 test_suites: ["device-tests"],
88} 93}
94
95cc_benchmark {
96 name: "libprocinfo_benchmark",
97 defaults: ["libprocinfo_defaults"],
98 srcs: [
99 "process_map_benchmark.cpp",
100 ],
101 shared_libs: [
102 "libbacktrace",
103 "libbase",
104 "libprocinfo",
105 "libunwindstack",
106 ],
107 compile_multilib: "both",
108 multilib: {
109 lib32: {
110 suffix: "32",
111 },
112 lib64: {
113 suffix: "64",
114 },
115 },
116
117 data: [
118 "testdata/*",
119 ],
120}
diff --git a/libprocinfo/include/procinfo/process_map.h b/libprocinfo/include/procinfo/process_map.h
new file mode 100644
index 000000000..3771f9f88
--- /dev/null
+++ b/libprocinfo/include/procinfo/process_map.h
@@ -0,0 +1,151 @@
1/*
2 * Copyright (C) 2018 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#pragma once
18
19#include <stdlib.h>
20#include <sys/mman.h>
21#include <sys/types.h>
22
23#include <functional>
24#include <string>
25
26#include <android-base/file.h>
27
28namespace android {
29namespace procinfo {
30
31template <class CallbackType>
32bool ReadMapFileContent(char* content, const CallbackType& callback) {
33 uint64_t start_addr;
34 uint64_t end_addr;
35 uint16_t flags;
36 uint64_t pgoff;
37 char* next_line = content;
38 char* p;
39
40 auto pass_space = [&]() {
41 if (*p != ' ') {
42 return false;
43 }
44 while (*p == ' ') {
45 p++;
46 }
47 return true;
48 };
49
50 auto pass_xdigit = [&]() {
51 if (!isxdigit(*p)) {
52 return false;
53 }
54 do {
55 p++;
56 } while (isxdigit(*p));
57 return true;
58 };
59
60 while (next_line != nullptr && *next_line != '\0') {
61 p = next_line;
62 next_line = strchr(next_line, '\n');
63 if (next_line != nullptr) {
64 *next_line = '\0';
65 next_line++;
66 }
67 // Parse line like: 00400000-00409000 r-xp 00000000 fc:00 426998 /usr/lib/gvfs/gvfsd-http
68 char* end;
69 // start_addr
70 start_addr = strtoull(p, &end, 16);
71 if (end == p || *end != '-') {
72 return false;
73 }
74 p = end + 1;
75 // end_addr
76 end_addr = strtoull(p, &end, 16);
77 if (end == p) {
78 return false;
79 }
80 p = end;
81 if (!pass_space()) {
82 return false;
83 }
84 // flags
85 flags = 0;
86 if (*p == 'r') {
87 flags |= PROT_READ;
88 } else if (*p != '-') {
89 return false;
90 }
91 p++;
92 if (*p == 'w') {
93 flags |= PROT_WRITE;
94 } else if (*p != '-') {
95 return false;
96 }
97 p++;
98 if (*p == 'x') {
99 flags |= PROT_EXEC;
100 } else if (*p != '-') {
101 return false;
102 }
103 p++;
104 if (*p != 'p' && *p != 's') {
105 return false;
106 }
107 p++;
108 if (!pass_space()) {
109 return false;
110 }
111 // pgoff
112 pgoff = strtoull(p, &end, 16);
113 if (end == p) {
114 return false;
115 }
116 p = end;
117 if (!pass_space()) {
118 return false;
119 }
120 // major:minor
121 if (!pass_xdigit() || *p++ != ':' || !pass_xdigit() || !pass_space()) {
122 return false;
123 }
124 // inode
125 if (!pass_xdigit() || (*p != '\0' && !pass_space())) {
126 return false;
127 }
128 // filename
129 callback(start_addr, end_addr, flags, pgoff, p);
130 }
131 return true;
132}
133
134inline bool ReadMapFile(
135 const std::string& map_file,
136 const std::function<void(uint64_t, uint64_t, uint16_t, uint64_t, const char*)>& callback) {
137 std::string content;
138 if (!android::base::ReadFileToString(map_file, &content)) {
139 return false;
140 }
141 return ReadMapFileContent(&content[0], callback);
142}
143
144inline bool ReadProcessMaps(
145 pid_t pid,
146 const std::function<void(uint64_t, uint64_t, uint16_t, uint64_t, const char*)>& callback) {
147 return ReadMapFile("/proc/" + std::to_string(pid) + "/maps", callback);
148}
149
150} /* namespace procinfo */
151} /* namespace android */
diff --git a/libprocinfo/process_map_benchmark.cpp b/libprocinfo/process_map_benchmark.cpp
new file mode 100644
index 000000000..d9e8a4dee
--- /dev/null
+++ b/libprocinfo/process_map_benchmark.cpp
@@ -0,0 +1,85 @@
1/*
2 * Copyright (C) 2018 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include <procinfo/process_map.h>
18
19#include <string.h>
20
21#include <string>
22
23#include <android-base/file.h>
24#include <android-base/logging.h>
25#include <backtrace/BacktraceMap.h>
26#include <unwindstack/Maps.h>
27
28#include <benchmark/benchmark.h>
29
30struct MapInfo {
31 uint64_t start;
32 uint64_t end;
33 uint16_t flags;
34 uint64_t pgoff;
35 const std::string name;
36
37 MapInfo(uint64_t start, uint64_t end, uint16_t flags, uint64_t pgoff, const char* name)
38 : start(start), end(end), flags(flags), pgoff(pgoff), name(name) {}
39};
40
41static void BM_ReadMapFile(benchmark::State& state) {
42 std::string map_file = android::base::GetExecutableDirectory() + "/testdata/maps";
43 for (auto _ : state) {
44 std::vector<MapInfo> maps;
45 android::procinfo::ReadMapFile(
46 map_file, [&](uint64_t start, uint64_t end, uint16_t flags, uint64_t pgoff,
47 const char* name) { maps.emplace_back(start, end, flags, pgoff, name); });
48 CHECK_EQ(maps.size(), 2043u);
49 }
50}
51BENCHMARK(BM_ReadMapFile);
52
53static void BM_unwindstack_FileMaps(benchmark::State& state) {
54 std::string map_file = android::base::GetExecutableDirectory() + "/testdata/maps";
55 for (auto _ : state) {
56 unwindstack::FileMaps maps(map_file);
57 maps.Parse();
58 CHECK_EQ(maps.Total(), 2043u);
59 }
60}
61BENCHMARK(BM_unwindstack_FileMaps);
62
63static void BM_unwindstack_BufferMaps(benchmark::State& state) {
64 std::string map_file = android::base::GetExecutableDirectory() + "/testdata/maps";
65 std::string content;
66 CHECK(android::base::ReadFileToString(map_file, &content));
67 for (auto _ : state) {
68 unwindstack::BufferMaps maps(content.c_str());
69 maps.Parse();
70 CHECK_EQ(maps.Total(), 2043u);
71 }
72}
73BENCHMARK(BM_unwindstack_BufferMaps);
74
75static void BM_backtrace_BacktraceMap(benchmark::State& state) {
76 pid_t pid = getpid();
77 for (auto _ : state) {
78 BacktraceMap* map = BacktraceMap::Create(pid, true);
79 CHECK(map != nullptr);
80 delete map;
81 }
82}
83BENCHMARK(BM_backtrace_BacktraceMap);
84
85BENCHMARK_MAIN();
diff --git a/libprocinfo/process_map_test.cpp b/libprocinfo/process_map_test.cpp
new file mode 100644
index 000000000..900fd85d1
--- /dev/null
+++ b/libprocinfo/process_map_test.cpp
@@ -0,0 +1,60 @@
1/*
2 * Copyright (C) 2018 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include <procinfo/process_map.h>
18
19#include <string>
20
21#include <android-base/file.h>
22
23#include <gtest/gtest.h>
24
25struct MapInfo {
26 uint64_t start;
27 uint64_t end;
28 uint16_t flags;
29 uint64_t pgoff;
30 const std::string name;
31
32 MapInfo(uint64_t start, uint64_t end, uint16_t flags, uint64_t pgoff, const char* name)
33 : start(start), end(end), flags(flags), pgoff(pgoff), name(name) {}
34};
35
36TEST(process_map, smoke) {
37 std::string map_file = android::base::GetExecutableDirectory() + "/testdata/maps";
38 std::vector<MapInfo> maps;
39 ASSERT_TRUE(android::procinfo::ReadMapFile(
40 map_file, [&](uint64_t start, uint64_t end, uint16_t flags, uint64_t pgoff,
41 const char* name) { maps.emplace_back(start, end, flags, pgoff, name); }));
42 ASSERT_EQ(2043u, maps.size());
43 ASSERT_EQ(maps[0].start, 0x12c00000ULL);
44 ASSERT_EQ(maps[0].end, 0x2ac00000ULL);
45 ASSERT_EQ(maps[0].flags, PROT_READ | PROT_WRITE);
46 ASSERT_EQ(maps[0].pgoff, 0ULL);
47 ASSERT_EQ(maps[0].name, "/dev/ashmem/dalvik-main space (region space) (deleted)");
48 ASSERT_EQ(maps[876].start, 0x70e6c4f000ULL);
49 ASSERT_EQ(maps[876].end, 0x70e6c6b000ULL);
50 ASSERT_EQ(maps[876].flags, PROT_READ | PROT_EXEC);
51 ASSERT_EQ(maps[876].pgoff, 0ULL);
52 ASSERT_EQ(maps[876].name, "/system/lib64/libutils.so");
53 ASSERT_EQ(maps[1260].start, 0x70e96fa000ULL);
54 ASSERT_EQ(maps[1260].end, 0x70e96fb000ULL);
55 ASSERT_EQ(maps[1260].flags, PROT_READ);
56 ASSERT_EQ(maps[1260].pgoff, 0ULL);
57 ASSERT_EQ(maps[1260].name,
58 "/dev/ashmem/dalvik-classes.dex extracted in memory from "
59 "/data/app/com.google.sample.tunnel-HGGRU03Gu1Mwkf_-RnFmvw==/base.apk (deleted)");
60}
diff --git a/libprocinfo/testdata/maps b/libprocinfo/testdata/maps
new file mode 100644
index 000000000..3b312e308
--- /dev/null
+++ b/libprocinfo/testdata/maps
@@ -0,0 +1,2043 @@
112c00000-2ac00000 rw-p 00000000 00:05 10267643 /dev/ashmem/dalvik-main space (region space) (deleted)
26fb5d000-6fd6e000 rw-p 00000000 103:1d 639511 /data/dalvik-cache/arm64/system@framework@boot.art
36fd6e000-6fd82000 r--p 00211000 103:1d 639511 /data/dalvik-cache/arm64/system@framework@boot.art
46fd82000-6fe47000 rw-p 00000000 103:1d 639514 /data/dalvik-cache/arm64/system@framework@boot-core-libart.art
56fe47000-6fe52000 r--p 000c5000 103:1d 639514 /data/dalvik-cache/arm64/system@framework@boot-core-libart.art
66fe52000-6fe84000 rw-p 00000000 103:1d 639517 /data/dalvik-cache/arm64/system@framework@boot-conscrypt.art
76fe84000-6fe87000 r--p 00032000 103:1d 639517 /data/dalvik-cache/arm64/system@framework@boot-conscrypt.art
86fe87000-6feb2000 rw-p 00000000 103:1d 639520 /data/dalvik-cache/arm64/system@framework@boot-okhttp.art
96feb2000-6feb5000 r--p 0002b000 103:1d 639520 /data/dalvik-cache/arm64/system@framework@boot-okhttp.art
106feb5000-6fef4000 rw-p 00000000 103:1d 639523 /data/dalvik-cache/arm64/system@framework@boot-bouncycastle.art
116fef4000-6fefb000 r--p 0003f000 103:1d 639523 /data/dalvik-cache/arm64/system@framework@boot-bouncycastle.art
126fefb000-6ff3f000 rw-p 00000000 103:1d 639526 /data/dalvik-cache/arm64/system@framework@boot-apache-xml.art
136ff3f000-6ff45000 r--p 00044000 103:1d 639526 /data/dalvik-cache/arm64/system@framework@boot-apache-xml.art
146ff45000-6ff7a000 rw-p 00000000 103:1d 639529 /data/dalvik-cache/arm64/system@framework@boot-ext.art
156ff7a000-6ff85000 r--p 00035000 103:1d 639529 /data/dalvik-cache/arm64/system@framework@boot-ext.art
166ff85000-70594000 rw-p 00000000 103:1d 639532 /data/dalvik-cache/arm64/system@framework@boot-framework.art
1770594000-705cb000 r--p 0060f000 103:1d 639532 /data/dalvik-cache/arm64/system@framework@boot-framework.art
18705cb000-7061f000 rw-p 00000000 103:1d 639535 /data/dalvik-cache/arm64/system@framework@boot-telephony-common.art
197061f000-70629000 r--p 00054000 103:1d 639535 /data/dalvik-cache/arm64/system@framework@boot-telephony-common.art
2070629000-70635000 rw-p 00000000 103:1d 639538 /data/dalvik-cache/arm64/system@framework@boot-voip-common.art
2170635000-70636000 r--p 0000c000 103:1d 639538 /data/dalvik-cache/arm64/system@framework@boot-voip-common.art
2270636000-70644000 rw-p 00000000 103:1d 639541 /data/dalvik-cache/arm64/system@framework@boot-ims-common.art
2370644000-70645000 r--p 0000e000 103:1d 639541 /data/dalvik-cache/arm64/system@framework@boot-ims-common.art
2470645000-70648000 rw-p 00000000 103:1d 639544 /data/dalvik-cache/arm64/system@framework@boot-android.hidl.base-V1.0-java.art
2570648000-7064c000 rw-p 00000000 103:1d 639547 /data/dalvik-cache/arm64/system@framework@boot-android.hidl.manager-V1.0-java.art
267064c000-7064d000 r--p 00004000 103:1d 639547 /data/dalvik-cache/arm64/system@framework@boot-android.hidl.manager-V1.0-java.art
277064d000-7064e000 rw-p 00000000 103:1d 639550 /data/dalvik-cache/arm64/system@framework@boot-framework-oahl-backward-compatibility.art
287064e000-70652000 rw-p 00000000 103:1d 639553 /data/dalvik-cache/arm64/system@framework@boot-android.test.base.art
2970652000-70653000 r--p 00004000 103:1d 639553 /data/dalvik-cache/arm64/system@framework@boot-android.test.base.art
3070653000-70654000 rw-p 00000000 103:1d 639556 /data/dalvik-cache/arm64/system@framework@boot-com.google.vr.platform.art
3170654000-70655000 r--p 00001000 103:1d 639556 /data/dalvik-cache/arm64/system@framework@boot-com.google.vr.platform.art
3270655000-70731000 r--p 00000000 fc:00 940 /system/framework/arm64/boot.oat
3370731000-709ca000 r-xp 000dc000 fc:00 940 /system/framework/arm64/boot.oat
34709ca000-709cb000 rw-p 00000000 00:00 0 [anon:.bss]
35709cb000-70e4c000 r--s 00000000 fc:00 961 /system/framework/boot.vdex
3670e4c000-70e4d000 r--p 00375000 fc:00 940 /system/framework/arm64/boot.oat
3770e4d000-70e4e000 rw-p 00376000 fc:00 940 /system/framework/arm64/boot.oat
3870e4e000-70eab000 r--p 00000000 fc:00 916 /system/framework/arm64/boot-core-libart.oat
3970eab000-70fad000 r-xp 0005d000 fc:00 916 /system/framework/arm64/boot-core-libart.oat
4070fad000-70fae000 rw-p 00000000 00:00 0 [anon:.bss]
4170fae000-712a9000 r--s 00000000 fc:00 702 /system/framework/boot-core-libart.vdex
42712a9000-712aa000 r--p 0015f000 fc:00 916 /system/framework/arm64/boot-core-libart.oat
43712aa000-712ab000 rw-p 00160000 fc:00 916 /system/framework/arm64/boot-core-libart.oat
44712ab000-712bb000 r--p 00000000 fc:00 941 /system/framework/arm64/boot-conscrypt.oat
45712bb000-712e4000 r-xp 00010000 fc:00 941 /system/framework/arm64/boot-conscrypt.oat
46712e4000-712e5000 rw-p 00000000 00:00 0 [anon:.bss]
47712e5000-71346000 r--s 00000000 fc:00 970 /system/framework/boot-conscrypt.vdex
4871346000-71347000 r--p 00039000 fc:00 941 /system/framework/arm64/boot-conscrypt.oat
4971347000-71348000 rw-p 0003a000 fc:00 941 /system/framework/arm64/boot-conscrypt.oat
5071348000-71361000 r--p 00000000 fc:00 908 /system/framework/arm64/boot-okhttp.oat
5171361000-713a3000 r-xp 00019000 fc:00 908 /system/framework/arm64/boot-okhttp.oat
52713a3000-713a4000 rw-p 00000000 00:00 0 [anon:.bss]
53713a4000-71403000 r--s 00000000 fc:00 886 /system/framework/boot-okhttp.vdex
5471403000-71404000 r--p 0005b000 fc:00 908 /system/framework/arm64/boot-okhttp.oat
5571404000-71405000 rw-p 0005c000 fc:00 908 /system/framework/arm64/boot-okhttp.oat
5671405000-71415000 r--p 00000000 fc:00 936 /system/framework/arm64/boot-bouncycastle.oat
5771415000-71437000 r-xp 00010000 fc:00 936 /system/framework/arm64/boot-bouncycastle.oat
5871437000-71438000 rw-p 00000000 00:00 0 [anon:.bss]
5971438000-7157b000 r--s 00000000 fc:00 1006 /system/framework/boot-bouncycastle.vdex
607157b000-7157c000 r--p 00032000 fc:00 936 /system/framework/arm64/boot-bouncycastle.oat
617157c000-7157d000 rw-p 00033000 fc:00 936 /system/framework/arm64/boot-bouncycastle.oat
627157d000-71583000 r--p 00000000 fc:00 932 /system/framework/arm64/boot-apache-xml.oat
6371583000-71584000 r-xp 00006000 fc:00 932 /system/framework/arm64/boot-apache-xml.oat
6471584000-716a7000 r--s 00000000 fc:00 883 /system/framework/boot-apache-xml.vdex
65716a7000-716a8000 r--p 00007000 fc:00 932 /system/framework/arm64/boot-apache-xml.oat
66716a8000-716a9000 rw-p 00008000 fc:00 932 /system/framework/arm64/boot-apache-xml.oat
67716a9000-716b5000 r--p 00000000 fc:00 891 /system/framework/arm64/boot-ext.oat
68716b5000-716cc000 r-xp 0000c000 fc:00 891 /system/framework/arm64/boot-ext.oat
69716cc000-716cd000 rw-p 00000000 00:00 0 [anon:.bss]
70716cd000-717b8000 r--s 00000000 fc:00 879 /system/framework/boot-ext.vdex
71717b8000-717b9000 r--p 00023000 fc:00 891 /system/framework/arm64/boot-ext.oat
72717b9000-717ba000 rw-p 00024000 fc:00 891 /system/framework/arm64/boot-ext.oat
73717ba000-71aeb000 r--p 00000000 fc:00 943 /system/framework/arm64/boot-framework.oat
7471aeb000-72390000 r-xp 00331000 fc:00 943 /system/framework/arm64/boot-framework.oat
7572390000-72396000 rw-p 00000000 00:00 0 [anon:.bss]
7672396000-73746000 r--s 00000000 fc:00 985 /system/framework/boot-framework.vdex
7773746000-73747000 r--p 00bd6000 fc:00 943 /system/framework/arm64/boot-framework.oat
7873747000-73748000 rw-p 00bd7000 fc:00 943 /system/framework/arm64/boot-framework.oat
7973748000-73780000 r--p 00000000 fc:00 893 /system/framework/arm64/boot-telephony-common.oat
8073780000-73818000 r-xp 00038000 fc:00 893 /system/framework/arm64/boot-telephony-common.oat
8173818000-7381a000 rw-p 00000000 00:00 0 [anon:.bss]
827381a000-73af0000 r--s 00000000 fc:00 697 /system/framework/boot-telephony-common.vdex
8373af0000-73af1000 r--p 000d0000 fc:00 893 /system/framework/arm64/boot-telephony-common.oat
8473af1000-73af2000 rw-p 000d1000 fc:00 893 /system/framework/arm64/boot-telephony-common.oat
8573af2000-73af6000 r--p 00000000 fc:00 922 /system/framework/arm64/boot-voip-common.oat
8673af6000-73af8000 r-xp 00004000 fc:00 922 /system/framework/arm64/boot-voip-common.oat
8773af8000-73af9000 rw-p 00000000 00:00 0 [anon:.bss]
8873af9000-73b1e000 r--s 00000000 fc:00 959 /system/framework/boot-voip-common.vdex
8973b1e000-73b1f000 r--p 00006000 fc:00 922 /system/framework/arm64/boot-voip-common.oat
9073b1f000-73b20000 rw-p 00007000 fc:00 922 /system/framework/arm64/boot-voip-common.oat
9173b20000-73b23000 r--p 00000000 fc:00 918 /system/framework/arm64/boot-ims-common.oat
9273b23000-73b25000 r-xp 00003000 fc:00 918 /system/framework/arm64/boot-ims-common.oat
9373b25000-73b26000 rw-p 00000000 00:00 0 [anon:.bss]
9473b26000-73b48000 r--s 00000000 fc:00 957 /system/framework/boot-ims-common.vdex
9573b48000-73b49000 r--p 00005000 fc:00 918 /system/framework/arm64/boot-ims-common.oat
9673b49000-73b4a000 rw-p 00006000 fc:00 918 /system/framework/arm64/boot-ims-common.oat
9773b4a000-73b4d000 r--p 00000000 fc:00 909 /system/framework/arm64/boot-android.hidl.base-V1.0-java.oat
9873b4d000-73b4e000 r-xp 00003000 fc:00 909 /system/framework/arm64/boot-android.hidl.base-V1.0-java.oat
9973b4e000-73b55000 r--s 00000000 fc:00 972 /system/framework/boot-android.hidl.base-V1.0-java.vdex
10073b55000-73b56000 r--p 00004000 fc:00 909 /system/framework/arm64/boot-android.hidl.base-V1.0-java.oat
10173b56000-73b57000 rw-p 00005000 fc:00 909 /system/framework/arm64/boot-android.hidl.base-V1.0-java.oat
10273b57000-73b5a000 r--p 00000000 fc:00 954 /system/framework/arm64/boot-android.hidl.manager-V1.0-java.oat
10373b5a000-73b5c000 r-xp 00003000 fc:00 954 /system/framework/arm64/boot-android.hidl.manager-V1.0-java.oat
10473b5c000-73b5d000 rw-p 00000000 00:00 0 [anon:.bss]
10573b5d000-73b68000 r--s 00000000 fc:00 704 /system/framework/boot-android.hidl.manager-V1.0-java.vdex
10673b68000-73b69000 r--p 00005000 fc:00 954 /system/framework/arm64/boot-android.hidl.manager-V1.0-java.oat
10773b69000-73b6a000 rw-p 00006000 fc:00 954 /system/framework/arm64/boot-android.hidl.manager-V1.0-java.oat
10873b6a000-73b6d000 r--p 00000000 fc:00 904 /system/framework/arm64/boot-framework-oahl-backward-compatibility.oat
10973b6d000-73b6e000 r-xp 00003000 fc:00 904 /system/framework/arm64/boot-framework-oahl-backward-compatibility.oat
11073b6e000-73b6f000 r--s 00000000 fc:00 994 /system/framework/boot-framework-oahl-backward-compatibility.vdex
11173b6f000-73b70000 r--p 00004000 fc:00 904 /system/framework/arm64/boot-framework-oahl-backward-compatibility.oat
11273b70000-73b71000 rw-p 00005000 fc:00 904 /system/framework/arm64/boot-framework-oahl-backward-compatibility.oat
11373b71000-73b75000 r--p 00000000 fc:00 896 /system/framework/arm64/boot-android.test.base.oat
11473b75000-73b79000 r-xp 00004000 fc:00 896 /system/framework/arm64/boot-android.test.base.oat
11573b79000-73b7a000 rw-p 00000000 00:00 0 [anon:.bss]
11673b7a000-73b82000 r--s 00000000 fc:00 706 /system/framework/boot-android.test.base.vdex
11773b82000-73b83000 r--p 00008000 fc:00 896 /system/framework/arm64/boot-android.test.base.oat
11873b83000-73b84000 rw-p 00009000 fc:00 896 /system/framework/arm64/boot-android.test.base.oat
11973b84000-73b87000 r--p 00000000 fc:00 899 /system/framework/arm64/boot-com.google.vr.platform.oat
12073b87000-73b88000 r-xp 00003000 fc:00 899 /system/framework/arm64/boot-com.google.vr.platform.oat
12173b88000-73b89000 r--s 00000000 fc:00 884 /system/framework/boot-com.google.vr.platform.vdex
12273b89000-73b8a000 r--p 00004000 fc:00 899 /system/framework/arm64/boot-com.google.vr.platform.oat
12373b8a000-73b8b000 rw-p 00005000 fc:00 899 /system/framework/arm64/boot-com.google.vr.platform.oat
12473b8b000-73b93000 rw-p 00000000 00:05 10267640 /dev/ashmem/dalvik-non moving space (deleted)
12573b93000-77b8b000 ---p 00008000 00:05 10267640 /dev/ashmem/dalvik-non moving space (deleted)
12677b8b000-97b8b000 rw-p 00000000 00:05 10267645 /dev/ashmem/dalvik-free list large object space (deleted)
12797b8b000-99b8b000 rw-p 00000000 00:05 10270989 /dev/ashmem/dalvik-data-code-cache (deleted)
12899b8b000-9bb8b000 r-xp 00000000 00:05 10270990 /dev/ashmem/dalvik-jit-code-cache (deleted)
129ebad6000-ebad7000 ---p 00000000 00:05 10269717 /dev/ashmem/dalvik-Sentinel fault page (deleted)
1307ffb6e000-7ffb76000 rw-s 000e5000 00:10 20630 /dev/kgsl-3d0
1317ffb76000-7ffb78000 rw-s 000e0000 00:10 20630 /dev/kgsl-3d0
1327ffbc3000-7ffbc4000 rw-s 000e8000 00:10 20630 /dev/kgsl-3d0
1337ffbc4000-7ffbc5000 rw-s 000e7000 00:10 20630 /dev/kgsl-3d0
1347ffbc6000-7ffbce000 rw-s 000e4000 00:10 20630 /dev/kgsl-3d0
1357ffbd0000-7ffbd2000 rw-s 000df000 00:10 20630 /dev/kgsl-3d0
1367ffbd2000-7ffbd4000 rw-s 000de000 00:10 20630 /dev/kgsl-3d0
1377ffbd4000-7ffbd6000 rw-s 000dd000 00:10 20630 /dev/kgsl-3d0
1387ffbd6000-7ffbd8000 rw-s 000dc000 00:10 20630 /dev/kgsl-3d0
1397ffbd8000-7ffbda000 rw-s 000db000 00:10 20630 /dev/kgsl-3d0
1407ffbda000-7ffbdc000 rw-s 000da000 00:10 20630 /dev/kgsl-3d0
1417ffbdd000-7ffbde000 rw-s 000ec000 00:10 20630 /dev/kgsl-3d0
1427ffbde000-7ffbe0000 rw-s 000d8000 00:10 20630 /dev/kgsl-3d0
1437ffce1000-7ffce2000 rw-s 000e6000 00:10 20630 /dev/kgsl-3d0
1447ffce2000-7ffce4000 rw-s 000d9000 00:10 20630 /dev/kgsl-3d0
1457ffce4000-7ffce8000 rw-s 000d4000 00:10 20630 /dev/kgsl-3d0
1467ffce8000-7ffcf8000 rw-s 000d2000 00:10 20630 /dev/kgsl-3d0
1477ffcf8000-7ffd08000 rw-s 000d1000 00:10 20630 /dev/kgsl-3d0
1487ffd08000-7ffd10000 rw-s 000d0000 00:10 20630 /dev/kgsl-3d0
1497ffd14000-7ffd18000 rw-s 000cd000 00:10 20630 /dev/kgsl-3d0
1507ffd18000-7ffd28000 rw-s 000cc000 00:10 20630 /dev/kgsl-3d0
1517ffd28000-7ffd38000 rw-s 000cb000 00:10 20630 /dev/kgsl-3d0
1527ffd38000-7ffd48000 rw-s 000ca000 00:10 20630 /dev/kgsl-3d0
1537ffd48000-7ffd58000 rw-s 000c9000 00:10 20630 /dev/kgsl-3d0
1547ffd58000-7ffd68000 rw-s 000c8000 00:10 20630 /dev/kgsl-3d0
1557ffd68000-7ffd6c000 rw-s 000c7000 00:10 20630 /dev/kgsl-3d0
1567ffdb1000-7ffdb2000 rw-s 000e3000 00:10 20630 /dev/kgsl-3d0
1577ffdb4000-7ffdb5000 rw-s 000e2000 00:10 20630 /dev/kgsl-3d0
1587ffdb5000-7ffdb7000 rw-s 000d7000 00:10 20630 /dev/kgsl-3d0
1597ffdb7000-7ffdb8000 rw-s 000c2000 00:10 20630 /dev/kgsl-3d0
1607ffdb8000-7ffdbc000 rw-s 000c0000 00:10 20630 /dev/kgsl-3d0
1617ffdbc000-7ffdc0000 rw-s 000be000 00:10 20630 /dev/kgsl-3d0
1627ffdc0000-7ffe00000 rw-s 000bb000 00:10 20630 /dev/kgsl-3d0
1637ffe00000-7ffe20000 rw-s 000ba000 00:10 20630 /dev/kgsl-3d0
1647ffe20000-7ffee0000 rw-s 000b9000 00:10 20630 /dev/kgsl-3d0
1657ffee1000-7ffee3000 rw-s 000c1000 00:10 20630 /dev/kgsl-3d0
1667ffee3000-7ffee4000 rw-s 000bf000 00:10 20630 /dev/kgsl-3d0
1677ffee4000-7ffee8000 rw-s 000bd000 00:10 20630 /dev/kgsl-3d0
1687ffee8000-7ffee9000 rw-s 000bc000 00:10 20630 /dev/kgsl-3d0
1697ffeea000-7ffeeb000 rw-s 000e1000 00:10 20630 /dev/kgsl-3d0
1707ffeeb000-7ffeec000 rw-s 000b6000 00:10 20630 /dev/kgsl-3d0
1717ffeec000-7ffeed000 rw-s 000b5000 00:10 20630 /dev/kgsl-3d0
1727ffeed000-7ffeee000 rw-s 000b4000 00:10 20630 /dev/kgsl-3d0
1737ffeee000-7ffeef000 rw-s 000b3000 00:10 20630 /dev/kgsl-3d0
1747ffeef000-7ffef0000 rw-s 000b2000 00:10 20630 /dev/kgsl-3d0
1757ffef0000-7ffef1000 rw-s 000b1000 00:10 20630 /dev/kgsl-3d0
1767ffef1000-7ffef2000 rw-s 000b0000 00:10 20630 /dev/kgsl-3d0
1777ffef2000-7ffef3000 rw-s 000af000 00:10 20630 /dev/kgsl-3d0
1787ffef3000-7ffef4000 rw-s 000ae000 00:10 20630 /dev/kgsl-3d0
1797ffef4000-7ffef5000 rw-s 000ad000 00:10 20630 /dev/kgsl-3d0
1807ffef5000-7ffef6000 rw-s 000ac000 00:10 20630 /dev/kgsl-3d0
1817ffef6000-7ffef7000 rw-s 000ab000 00:10 20630 /dev/kgsl-3d0
1827ffef7000-7ffef8000 rw-s 000aa000 00:10 20630 /dev/kgsl-3d0
1837ffef8000-7ffef9000 rw-s 000a9000 00:10 20630 /dev/kgsl-3d0
1847ffef9000-7ffefa000 rw-s 000a8000 00:10 20630 /dev/kgsl-3d0
1857ffefa000-7ffefb000 rw-s 000a7000 00:10 20630 /dev/kgsl-3d0
1867ffefb000-7ffefc000 rw-s 000a6000 00:10 20630 /dev/kgsl-3d0
1877ffefc000-7ffefd000 rw-s 000a5000 00:10 20630 /dev/kgsl-3d0
1887ffefd000-7ffefe000 rw-s 000a4000 00:10 20630 /dev/kgsl-3d0
1897ffefe000-7ffeff000 rw-s 000a3000 00:10 20630 /dev/kgsl-3d0
1907ffeff000-7fff00000 rw-s 000a2000 00:10 20630 /dev/kgsl-3d0
1917fff00000-7fff01000 rw-s 000a1000 00:10 20630 /dev/kgsl-3d0
1927fff01000-7fff02000 rw-s 000a0000 00:10 20630 /dev/kgsl-3d0
1937fff02000-7fff03000 rw-s 0009f000 00:10 20630 /dev/kgsl-3d0
1947fff03000-7fff04000 rw-s 0009e000 00:10 20630 /dev/kgsl-3d0
1957fff04000-7fff05000 rw-s 0009d000 00:10 20630 /dev/kgsl-3d0
1967fff05000-7fff06000 rw-s 0009c000 00:10 20630 /dev/kgsl-3d0
1977fff06000-7fff07000 rw-s 0009b000 00:10 20630 /dev/kgsl-3d0
1987fff07000-7fff08000 rw-s 0009a000 00:10 20630 /dev/kgsl-3d0
1997fff08000-7fff09000 rw-s 00099000 00:10 20630 /dev/kgsl-3d0
2007fff09000-7fff0a000 rw-s 00098000 00:10 20630 /dev/kgsl-3d0
2017fff0a000-7fff0b000 rw-s 00097000 00:10 20630 /dev/kgsl-3d0
2027fff0b000-7fff0c000 rw-s 00096000 00:10 20630 /dev/kgsl-3d0
2037fff0c000-7fff0d000 rw-s 00095000 00:10 20630 /dev/kgsl-3d0
2047fff0d000-7fff0e000 rw-s 00094000 00:10 20630 /dev/kgsl-3d0
2057fff0e000-7fff0f000 rw-s 00093000 00:10 20630 /dev/kgsl-3d0
2067fff0f000-7fff10000 rw-s 00092000 00:10 20630 /dev/kgsl-3d0
2077fff10000-7fff11000 rw-s 00091000 00:10 20630 /dev/kgsl-3d0
2087fff11000-7fff12000 rw-s 00090000 00:10 20630 /dev/kgsl-3d0
2097fff12000-7fff13000 rw-s 0008f000 00:10 20630 /dev/kgsl-3d0
2107fff13000-7fff14000 rw-s 0008e000 00:10 20630 /dev/kgsl-3d0
2117fff14000-7fff15000 rw-s 0008d000 00:10 20630 /dev/kgsl-3d0
2127fff15000-7fff16000 rw-s 0008c000 00:10 20630 /dev/kgsl-3d0
2137fff16000-7fff17000 rw-s 0008b000 00:10 20630 /dev/kgsl-3d0
2147fff17000-7fff18000 rw-s 0008a000 00:10 20630 /dev/kgsl-3d0
2157fff18000-7fff19000 rw-s 00089000 00:10 20630 /dev/kgsl-3d0
2167fff19000-7fff1a000 rw-s 00088000 00:10 20630 /dev/kgsl-3d0
2177fff1a000-7fff1b000 rw-s 00087000 00:10 20630 /dev/kgsl-3d0
2187fff1b000-7fff1c000 rw-s 00086000 00:10 20630 /dev/kgsl-3d0
2197fff1c000-7fff1d000 rw-s 00085000 00:10 20630 /dev/kgsl-3d0
2207fff1d000-7fff1e000 rw-s 00084000 00:10 20630 /dev/kgsl-3d0
2217fff1e000-7fff1f000 rw-s 00083000 00:10 20630 /dev/kgsl-3d0
2227fff1f000-7fff20000 rw-s 00082000 00:10 20630 /dev/kgsl-3d0
2237fff20000-7fff21000 rw-s 00081000 00:10 20630 /dev/kgsl-3d0
2247fff21000-7fff22000 rw-s 00080000 00:10 20630 /dev/kgsl-3d0
2257fff22000-7fff23000 rw-s 0007f000 00:10 20630 /dev/kgsl-3d0
2267fff23000-7fff24000 rw-s 0007e000 00:10 20630 /dev/kgsl-3d0
2277fff24000-7fff25000 rw-s 0007d000 00:10 20630 /dev/kgsl-3d0
2287fff25000-7fff26000 rw-s 0007c000 00:10 20630 /dev/kgsl-3d0
2297fff26000-7fff27000 rw-s 0007b000 00:10 20630 /dev/kgsl-3d0
2307fff27000-7fff28000 rw-s 0007a000 00:10 20630 /dev/kgsl-3d0
2317fff28000-7fff29000 rw-s 00079000 00:10 20630 /dev/kgsl-3d0
2327fff29000-7fff2a000 rw-s 00078000 00:10 20630 /dev/kgsl-3d0
2337fff2a000-7fff2b000 rw-s 00077000 00:10 20630 /dev/kgsl-3d0
2347fff2b000-7fff2c000 rw-s 00076000 00:10 20630 /dev/kgsl-3d0
2357fff2c000-7fff2d000 rw-s 00075000 00:10 20630 /dev/kgsl-3d0
2367fff2d000-7fff2e000 rw-s 00074000 00:10 20630 /dev/kgsl-3d0
2377fff2e000-7fff2f000 rw-s 00073000 00:10 20630 /dev/kgsl-3d0
2387fff2f000-7fff30000 rw-s 00072000 00:10 20630 /dev/kgsl-3d0
2397fff30000-7fff31000 rw-s 00071000 00:10 20630 /dev/kgsl-3d0
2407fff31000-7fff32000 rw-s 00070000 00:10 20630 /dev/kgsl-3d0
2417fff32000-7fff33000 rw-s 0006f000 00:10 20630 /dev/kgsl-3d0
2427fff33000-7fff34000 rw-s 0006e000 00:10 20630 /dev/kgsl-3d0
2437fff34000-7fff35000 rw-s 0006d000 00:10 20630 /dev/kgsl-3d0
2447fff35000-7fff36000 rw-s 0006c000 00:10 20630 /dev/kgsl-3d0
2457fff36000-7fff37000 rw-s 0006b000 00:10 20630 /dev/kgsl-3d0
2467fff37000-7fff38000 rw-s 0006a000 00:10 20630 /dev/kgsl-3d0
2477fff38000-7fff39000 rw-s 00069000 00:10 20630 /dev/kgsl-3d0
2487fff39000-7fff3a000 rw-s 00068000 00:10 20630 /dev/kgsl-3d0
2497fff3a000-7fff3b000 rw-s 00067000 00:10 20630 /dev/kgsl-3d0
2507fff3b000-7fff3c000 rw-s 00066000 00:10 20630 /dev/kgsl-3d0
2517fff3c000-7fff3d000 rw-s 00065000 00:10 20630 /dev/kgsl-3d0
2527fff3d000-7fff3e000 rw-s 00064000 00:10 20630 /dev/kgsl-3d0
2537fff3e000-7fff3f000 rw-s 00063000 00:10 20630 /dev/kgsl-3d0
2547fff3f000-7fff40000 rw-s 00062000 00:10 20630 /dev/kgsl-3d0
2557fff40000-7fff41000 rw-s 00061000 00:10 20630 /dev/kgsl-3d0
2567fff41000-7fff42000 rw-s 00060000 00:10 20630 /dev/kgsl-3d0
2577fff42000-7fff43000 rw-s 0005f000 00:10 20630 /dev/kgsl-3d0
2587fff43000-7fff44000 rw-s 0005e000 00:10 20630 /dev/kgsl-3d0
2597fff44000-7fff45000 rw-s 0005d000 00:10 20630 /dev/kgsl-3d0
2607fff45000-7fff46000 rw-s 0005c000 00:10 20630 /dev/kgsl-3d0
2617fff46000-7fff47000 rw-s 0005b000 00:10 20630 /dev/kgsl-3d0
2627fff47000-7fff48000 rw-s 0005a000 00:10 20630 /dev/kgsl-3d0
2637fff48000-7fff49000 rw-s 00059000 00:10 20630 /dev/kgsl-3d0
2647fff49000-7fff4a000 rw-s 00058000 00:10 20630 /dev/kgsl-3d0
2657fff4a000-7fff4b000 rw-s 00057000 00:10 20630 /dev/kgsl-3d0
2667fff4b000-7fff4c000 rw-s 00056000 00:10 20630 /dev/kgsl-3d0
2677fff4c000-7fff4d000 rw-s 00055000 00:10 20630 /dev/kgsl-3d0
2687fff4d000-7fff4e000 rw-s 00054000 00:10 20630 /dev/kgsl-3d0
2697fff4e000-7fff4f000 rw-s 00053000 00:10 20630 /dev/kgsl-3d0
2707fff4f000-7fff50000 rw-s 00052000 00:10 20630 /dev/kgsl-3d0
2717fff50000-7fff51000 rw-s 00051000 00:10 20630 /dev/kgsl-3d0
2727fff51000-7fff52000 rw-s 00050000 00:10 20630 /dev/kgsl-3d0
2737fff52000-7fff53000 rw-s 0004f000 00:10 20630 /dev/kgsl-3d0
2747fff53000-7fff54000 rw-s 0004e000 00:10 20630 /dev/kgsl-3d0
2757fff54000-7fff55000 rw-s 0004d000 00:10 20630 /dev/kgsl-3d0
2767fff55000-7fff56000 rw-s 0004c000 00:10 20630 /dev/kgsl-3d0
2777fff56000-7fff57000 rw-s 0004b000 00:10 20630 /dev/kgsl-3d0
2787fff57000-7fff58000 rw-s 0004a000 00:10 20630 /dev/kgsl-3d0
2797fff58000-7fff59000 rw-s 00049000 00:10 20630 /dev/kgsl-3d0
2807fff59000-7fff5a000 rw-s 00048000 00:10 20630 /dev/kgsl-3d0
2817fff5a000-7fff5b000 rw-s 00047000 00:10 20630 /dev/kgsl-3d0
2827fff5b000-7fff5c000 rw-s 00046000 00:10 20630 /dev/kgsl-3d0
2837fff5c000-7fff5d000 rw-s 00045000 00:10 20630 /dev/kgsl-3d0
2847fff5d000-7fff5e000 rw-s 00044000 00:10 20630 /dev/kgsl-3d0
2857fff5e000-7fff5f000 rw-s 00043000 00:10 20630 /dev/kgsl-3d0
2867fff5f000-7fff60000 rw-s 00042000 00:10 20630 /dev/kgsl-3d0
2877fff60000-7fff61000 rw-s 00041000 00:10 20630 /dev/kgsl-3d0
2887fff61000-7fff62000 rw-s 00040000 00:10 20630 /dev/kgsl-3d0
2897fff62000-7fff63000 rw-s 0003f000 00:10 20630 /dev/kgsl-3d0
2907fff63000-7fff64000 rw-s 0003e000 00:10 20630 /dev/kgsl-3d0
2917fff64000-7fff65000 rw-s 0003d000 00:10 20630 /dev/kgsl-3d0
2927fff65000-7fff66000 rw-s 0003c000 00:10 20630 /dev/kgsl-3d0
2937fff66000-7fff67000 rw-s 0003b000 00:10 20630 /dev/kgsl-3d0
2947fff67000-7fff68000 rw-s 0003a000 00:10 20630 /dev/kgsl-3d0
2957fff68000-7fff69000 rw-s 00039000 00:10 20630 /dev/kgsl-3d0
2967fff69000-7fff6a000 rw-s 00038000 00:10 20630 /dev/kgsl-3d0
2977fff6a000-7fff6b000 rw-s 00037000 00:10 20630 /dev/kgsl-3d0
2987fff6b000-7fff6c000 rw-s 00036000 00:10 20630 /dev/kgsl-3d0
2997fff6c000-7fff6d000 rw-s 00035000 00:10 20630 /dev/kgsl-3d0
3007fff6d000-7fff6e000 rw-s 00034000 00:10 20630 /dev/kgsl-3d0
3017fff6e000-7fff6f000 rw-s 00033000 00:10 20630 /dev/kgsl-3d0
3027fff6f000-7fff70000 rw-s 00032000 00:10 20630 /dev/kgsl-3d0
3037fff70000-7fff71000 rw-s 00031000 00:10 20630 /dev/kgsl-3d0
3047fff71000-7fff72000 rw-s 00030000 00:10 20630 /dev/kgsl-3d0
3057fff72000-7fff73000 rw-s 0002f000 00:10 20630 /dev/kgsl-3d0
3067fff73000-7fff74000 rw-s 0002e000 00:10 20630 /dev/kgsl-3d0
3077fff74000-7fff75000 rw-s 0002d000 00:10 20630 /dev/kgsl-3d0
3087fff75000-7fff76000 rw-s 0002c000 00:10 20630 /dev/kgsl-3d0
3097fff76000-7fff77000 rw-s 0002b000 00:10 20630 /dev/kgsl-3d0
3107fff77000-7fff78000 rw-s 0002a000 00:10 20630 /dev/kgsl-3d0
3117fff78000-7fff79000 rw-s 00029000 00:10 20630 /dev/kgsl-3d0
3127fff79000-7fff7a000 rw-s 00028000 00:10 20630 /dev/kgsl-3d0
3137fff7a000-7fff7b000 rw-s 00027000 00:10 20630 /dev/kgsl-3d0
3147fff7b000-7fff7c000 rw-s 00026000 00:10 20630 /dev/kgsl-3d0
3157fff7c000-7fff7d000 rw-s 00025000 00:10 20630 /dev/kgsl-3d0
3167fff7d000-7fff7e000 rw-s 00024000 00:10 20630 /dev/kgsl-3d0
3177fff7e000-7fff7f000 rw-s 00023000 00:10 20630 /dev/kgsl-3d0
3187fff7f000-7fff80000 rw-s 00022000 00:10 20630 /dev/kgsl-3d0
3197fff80000-7fff90000 rw-s 00019000 00:10 20630 /dev/kgsl-3d0
3207fff90000-7fffb0000 rw-s 00018000 00:10 20630 /dev/kgsl-3d0
3217fffb1000-7fffb2000 rw-s 00021000 00:10 20630 /dev/kgsl-3d0
3227fffb2000-7fffb3000 rw-s 00020000 00:10 20630 /dev/kgsl-3d0
3237fffb3000-7fffb4000 rw-s 0001f000 00:10 20630 /dev/kgsl-3d0
3247fffba000-7fffbe000 rw-s 0001b000 00:10 20630 /dev/kgsl-3d0
3257fffbe000-7fffbf000 rw-s 0001a000 00:10 20630 /dev/kgsl-3d0
3267fffbf000-7fffc0000 rw-s 00017000 00:10 20630 /dev/kgsl-3d0
3277fffc0000-7fffe0000 rw-s 00016000 00:10 20630 /dev/kgsl-3d0
3287fffe0000-7fffe1000 rw-s 00014000 00:10 20630 /dev/kgsl-3d0
3297fffe1000-7fffe5000 rw-s 00013000 00:10 20630 /dev/kgsl-3d0
3307fffe5000-7fffe6000 rw-s 00012000 00:10 20630 /dev/kgsl-3d0
3317fffe6000-7fffe7000 rw-s 00011000 00:10 20630 /dev/kgsl-3d0
3327fffe7000-7fffe8000 rw-s 00010000 00:10 20630 /dev/kgsl-3d0
3337fffe8000-7fffe9000 rw-s 0000f000 00:10 20630 /dev/kgsl-3d0
3347fffe9000-7fffea000 rw-s 0000e000 00:10 20630 /dev/kgsl-3d0
3357fffea000-7fffeb000 rw-s 0000d000 00:10 20630 /dev/kgsl-3d0
3367fffeb000-7fffec000 rw-s 0000c000 00:10 20630 /dev/kgsl-3d0
3377fffec000-7ffff0000 rw-s 0000b000 00:10 20630 /dev/kgsl-3d0
3387ffff0000-7ffff1000 rw-s 0000a000 00:10 20630 /dev/kgsl-3d0
3397ffff1000-7ffff5000 rw-s 00009000 00:10 20630 /dev/kgsl-3d0
3407ffff5000-7ffff6000 rw-s 00008000 00:10 20630 /dev/kgsl-3d0
3417ffff6000-7ffff7000 rw-s 00007000 00:10 20630 /dev/kgsl-3d0
3427ffff7000-7ffff8000 rw-s 00006000 00:10 20630 /dev/kgsl-3d0
3437ffff8000-7ffff9000 rw-s 00005000 00:10 20630 /dev/kgsl-3d0
3447ffff9000-7ffffa000 rw-s 00004000 00:10 20630 /dev/kgsl-3d0
3457ffffa000-7ffffb000 rw-s 00003000 00:10 20630 /dev/kgsl-3d0
3467ffffb000-7ffffc000 rw-s 00002000 00:10 20630 /dev/kgsl-3d0
3477ffffc000-800000000 rw-s 00001000 00:10 20630 /dev/kgsl-3d0
3485ff1d4f000-5ff1d54000 r-xp 00000000 fc:00 3419 /system/bin/app_process64
3495ff1d6e000-5ff1d6f000 r--p 0000f000 fc:00 3419 /system/bin/app_process64
3505ff1d6f000-5ff1d71000 rw-p 00000000 00:00 0
351704defa000-704defb000 ---p 00000000 00:00 0 [anon:thread stack guard]
352704defb000-704defc000 ---p 00000000 00:00 0
353704defc000-704e000000 rw-p 00000000 00:00 0
354704e000000-704e400000 rw-p 00000000 00:00 0 [anon:libc_malloc]
355704e455000-704e456000 ---p 00000000 00:00 0 [anon:thread stack guard]
356704e456000-704e457000 ---p 00000000 00:00 0
357704e457000-704e553000 rw-p 00000000 00:00 0
358704e553000-704e651000 r--p 00000000 00:10 16029 /dev/hwbinder
359704e651000-704e65f000 r-xp 00000000 fc:01 1040 /vendor/lib64/egl/eglSubDriverAndroid.so
360704e65f000-704e660000 r--p 0000e000 fc:01 1040 /vendor/lib64/egl/eglSubDriverAndroid.so
361704e660000-704e661000 rw-p 0000f000 fc:01 1040 /vendor/lib64/egl/eglSubDriverAndroid.so
362704e69d000-704e69e000 ---p 00000000 00:00 0 [anon:thread stack guard]
363704e69e000-704e79b000 rw-p 00000000 00:00 0
364704e79b000-704f79b000 rw-s 00000000 00:05 10271021 /dev/ashmem/AudioFlinger::Client(29312) (deleted)
365704f79b000-704f79c000 ---p 00000000 00:00 0 [anon:thread stack guard]
366704f79c000-704f899000 rw-p 00000000 00:00 0
367704f899000-704f89a000 ---p 00000000 00:00 0 [anon:thread stack guard]
368704f89a000-704f89b000 ---p 00000000 00:00 0
369704f89b000-704f997000 rw-p 00000000 00:00 0
370704f997000-704f9ee000 r-xp 00000000 103:1d 1737338 /data/app/com.google.sample.tunnel-HGGRU03Gu1Mwkf_-RnFmvw==/lib/arm64/libgame.so
371704f9ee000-704f9fd000 ---p 00000000 00:00 0
372704f9fd000-704fa00000 r--p 00056000 103:1d 1737338 /data/app/com.google.sample.tunnel-HGGRU03Gu1Mwkf_-RnFmvw==/lib/arm64/libgame.so
373704fa00000-704fa01000 rw-p 00059000 103:1d 1737338 /data/app/com.google.sample.tunnel-HGGRU03Gu1Mwkf_-RnFmvw==/lib/arm64/libgame.so
374704fa01000-704fa19000 rw-p 00000000 00:00 0 [anon:.bss]
375704fa40000-70507e7000 r-xp 00000000 fc:01 1026 /vendor/lib64/libllvm-glnext.so
37670507e7000-70507fc000 ---p 00000000 00:00 0
37770507fc000-7050835000 r--p 00da7000 fc:01 1026 /vendor/lib64/libllvm-glnext.so
3787050835000-705083a000 rw-p 00de0000 fc:01 1026 /vendor/lib64/libllvm-glnext.so
379705083a000-7050855000 rw-p 00000000 00:00 0 [anon:.bss]
380705089b000-7050f19000 r-xp 00000000 fc:01 1039 /vendor/lib64/egl/libGLESv2_adreno.so
3817050f19000-7050f22000 r--p 0067e000 fc:01 1039 /vendor/lib64/egl/libGLESv2_adreno.so
3827050f22000-7050f29000 rw-p 00687000 fc:01 1039 /vendor/lib64/egl/libGLESv2_adreno.so
3837050f29000-7050f2c000 rw-p 00000000 00:00 0 [anon:.bss]
3847050f83000-7050fbc000 r-xp 00000000 fc:01 1041 /vendor/lib64/egl/libGLESv1_CM_adreno.so
3857050fbc000-7050fbd000 r--p 00039000 fc:01 1041 /vendor/lib64/egl/libGLESv1_CM_adreno.so
3867050fbd000-7050fbe000 rw-p 0003a000 fc:01 1041 /vendor/lib64/egl/libGLESv1_CM_adreno.so
3877050fbe000-7050fbf000 rw-p 00000000 00:00 0 [anon:.bss]
3887050fc6000-705111d000 r-xp 00000000 fc:01 865 /vendor/lib64/libgsl.so
389705111d000-705111e000 r--p 00157000 fc:01 865 /vendor/lib64/libgsl.so
390705111e000-705111f000 rw-p 00158000 fc:01 865 /vendor/lib64/libgsl.so
391705111f000-7051120000 rw-p 00000000 00:00 0 [anon:.bss]
3927051146000-705115d000 r-xp 00000000 fc:00 2587 /system/lib64/vndk-sp-28/libz.so
393705115d000-7051175000 ---p 00000000 00:00 0
3947051175000-7051176000 r--p 0001f000 fc:00 2587 /system/lib64/vndk-sp-28/libz.so
3957051176000-7051177000 rw-p 00020000 fc:00 2587 /system/lib64/vndk-sp-28/libz.so
396705119f000-70511ac000 r-xp 00000000 fc:01 886 /vendor/lib64/libadreno_utils.so
39770511ac000-70511ad000 r--p 0000d000 fc:01 886 /vendor/lib64/libadreno_utils.so
39870511ad000-70511ae000 rw-p 0000e000 fc:01 886 /vendor/lib64/libadreno_utils.so
39970511ae000-70511b0000 rw-p 00000000 00:00 0 [anon:.bss]
40070511c0000-70511d7000 r-xp 00000000 fc:01 1044 /vendor/lib64/egl/libEGL_adreno.so
40170511d7000-70511d8000 r--p 00017000 fc:01 1044 /vendor/lib64/egl/libEGL_adreno.so
40270511d8000-70511d9000 rw-p 00018000 fc:01 1044 /vendor/lib64/egl/libEGL_adreno.so
40370511d9000-70511da000 rw-p 00000000 00:00 0 [anon:.bss]
404705120a000-705120d000 r-xp 00000000 fc:01 972 /vendor/lib64/libdrmutils.so
405705120d000-7051229000 ---p 00000000 00:00 0
4067051229000-705122a000 r--p 0000f000 fc:01 972 /vendor/lib64/libdrmutils.so
407705122a000-705122b000 rw-p 00010000 fc:01 972 /vendor/lib64/libdrmutils.so
408705125a000-705125c000 r-xp 00000000 fc:01 1046 /vendor/lib64/libqdMetaData.so
409705125c000-7051279000 ---p 00000000 00:00 0
4107051279000-705127a000 r--p 0000f000 fc:01 1046 /vendor/lib64/libqdMetaData.so
411705127a000-705127b000 rw-p 00010000 fc:01 1046 /vendor/lib64/libqdMetaData.so
4127051286000-7051297000 r-xp 00000000 fc:01 1024 /vendor/lib64/libdrm.so
4137051297000-70512b5000 ---p 00000000 00:00 0
41470512b5000-70512b6000 r--p 0001f000 fc:01 1024 /vendor/lib64/libdrm.so
41570512b6000-70512b7000 rw-p 00020000 fc:01 1024 /vendor/lib64/libdrm.so
41670512cb000-70512de000 r-xp 00000000 fc:01 1008 /vendor/lib64/hw/gralloc.msm8998.so
41770512de000-70512fa000 ---p 00000000 00:00 0
41870512fa000-70512fb000 r--p 0001f000 fc:01 1008 /vendor/lib64/hw/gralloc.msm8998.so
41970512fb000-70512fc000 rw-p 00020000 fc:01 1008 /vendor/lib64/hw/gralloc.msm8998.so
4207051326000-7051327000 ---p 00000000 00:00 0 [anon:thread stack guard]
4217051327000-7051328000 ---p 00000000 00:00 0
4227051328000-7051424000 rw-p 00000000 00:00 0
4237051424000-705143d000 r--p 00000000 fc:00 739 /system/framework/oat/arm64/org.apache.http.legacy.boot.odex
424705143d000-7051480000 r-xp 00019000 fc:00 739 /system/framework/oat/arm64/org.apache.http.legacy.boot.odex
4257051480000-7051494000 r--p 00211000 103:1d 639511 /data/dalvik-cache/arm64/system@framework@boot.art
4267051494000-705149f000 r--p 000c5000 103:1d 639514 /data/dalvik-cache/arm64/system@framework@boot-core-libart.art
427705149f000-70514a2000 r--p 00032000 103:1d 639517 /data/dalvik-cache/arm64/system@framework@boot-conscrypt.art
42870514a2000-70514a5000 r--p 0002b000 103:1d 639520 /data/dalvik-cache/arm64/system@framework@boot-okhttp.art
42970514a5000-70514ac000 r--p 0003f000 103:1d 639523 /data/dalvik-cache/arm64/system@framework@boot-bouncycastle.art
43070514ac000-70514b2000 r--p 00044000 103:1d 639526 /data/dalvik-cache/arm64/system@framework@boot-apache-xml.art
43170514b2000-70514bd000 r--p 00035000 103:1d 639529 /data/dalvik-cache/arm64/system@framework@boot-ext.art
43270514bd000-70514f4000 r--p 0060f000 103:1d 639532 /data/dalvik-cache/arm64/system@framework@boot-framework.art
43370514f4000-70514fe000 r--p 00054000 103:1d 639535 /data/dalvik-cache/arm64/system@framework@boot-telephony-common.art
43470514fe000-70514ff000 r--p 0000c000 103:1d 639538 /data/dalvik-cache/arm64/system@framework@boot-voip-common.art
43570514ff000-7051500000 r--p 0000e000 103:1d 639541 /data/dalvik-cache/arm64/system@framework@boot-ims-common.art
4367051500000-7051501000 r--p 00004000 103:1d 639547 /data/dalvik-cache/arm64/system@framework@boot-android.hidl.manager-V1.0-java.art
4377051501000-7051502000 r--p 00004000 103:1d 639553 /data/dalvik-cache/arm64/system@framework@boot-android.test.base.art
4387051502000-7051503000 r--p 00001000 103:1d 639556 /data/dalvik-cache/arm64/system@framework@boot-com.google.vr.platform.art
4397051503000-7051504000 rw-p 00000000 00:00 0 [anon:.bss]
4407051504000-7051579000 r--s 00000000 fc:00 790 /system/framework/oat/arm64/org.apache.http.legacy.boot.vdex
4417051579000-705157a000 r--p 0005c000 fc:00 739 /system/framework/oat/arm64/org.apache.http.legacy.boot.odex
442705157a000-705157b000 rw-p 0005d000 fc:00 739 /system/framework/oat/arm64/org.apache.http.legacy.boot.odex
443705158b000-7057f4d000 ---p 00000000 00:00 0
4447057f4d000-7057f4f000 r-xp 00000000 fc:00 2646 /system/lib64/libwebviewchromium_loader.so
4457057f4f000-7057f6c000 ---p 00000000 00:00 0
4467057f6c000-7057f6d000 r--p 0000f000 fc:00 2646 /system/lib64/libwebviewchromium_loader.so
4477057f6d000-7057f6e000 rw-p 00010000 fc:00 2646 /system/lib64/libwebviewchromium_loader.so
4487057f76000-7057f96000 r--s 00000000 00:10 16615 /dev/__properties__/u:object_r:hwservicemanager_prop:s0
4497057f96000-7057fb6000 r--s 00000000 00:10 16639 /dev/__properties__/u:object_r:public_vendor_default_prop:s0
4507057fb6000-7058004000 r--s 00000000 fc:00 1112 /system/usr/hyphen-data/hyph-hu.hyb
4517058004000-7058024000 r-xp 00000000 fc:00 2354 /system/lib64/libcompiler_rt.so
4527058024000-7058043000 ---p 00000000 00:00 0
4537058043000-7058044000 r--p 0002f000 fc:00 2354 /system/lib64/libcompiler_rt.so
4547058044000-7058045000 rw-p 00030000 fc:00 2354 /system/lib64/libcompiler_rt.so
4557058045000-70580b2000 rw-p 00000000 00:00 0 [anon:.bss]
45670580bd000-70580dd000 rw-p 00000000 00:05 10265386 /dev/ashmem/dalvik-LinearAlloc (deleted)
45770580dd000-70580df000 r-xp 00000000 fc:00 2597 /system/lib64/vndk-sp-28/libhardware.so
45870580df000-70580fc000 ---p 00000000 00:00 0
45970580fc000-70580fd000 r--p 0000f000 fc:00 2597 /system/lib64/vndk-sp-28/libhardware.so
46070580fd000-70580fe000 rw-p 00010000 fc:00 2597 /system/lib64/vndk-sp-28/libhardware.so
461705810e000-705811f000 r-xp 00000000 fc:00 2589 /system/lib64/vndk-sp-28/libbase.so
462705811f000-705813d000 ---p 00000000 00:00 0
463705813d000-705813e000 r--p 0001f000 fc:00 2589 /system/lib64/vndk-sp-28/libbase.so
464705813e000-705813f000 rw-p 00020000 fc:00 2589 /system/lib64/vndk-sp-28/libbase.so
4657058140000-7058167000 r-xp 00000000 fc:00 2572 /system/lib64/vndk-sp-28/libhwbinder.so
4667058167000-705817d000 ---p 00000000 00:00 0
467705817d000-705817f000 r--p 0002e000 fc:00 2572 /system/lib64/vndk-sp-28/libhwbinder.so
468705817f000-7058180000 rw-p 00030000 fc:00 2572 /system/lib64/vndk-sp-28/libhwbinder.so
469705818c000-705818d000 r-xp 00000000 fc:00 2584 /system/lib64/vndk-sp-28/android.hardware.graphics.common@1.0.so
470705818d000-70581ab000 ---p 00000000 00:00 0
47170581ab000-70581ac000 r--p 0000f000 fc:00 2584 /system/lib64/vndk-sp-28/android.hardware.graphics.common@1.0.so
47270581ac000-70581ad000 rw-p 00010000 fc:00 2584 /system/lib64/vndk-sp-28/android.hardware.graphics.common@1.0.so
47370581b7000-70581d7000 r--s 00000000 00:10 16619 /dev/__properties__/u:object_r:log_prop:s0
47470581d7000-7058237000 r-xp 00000000 fc:00 2574 /system/lib64/vndk-sp-28/libhidltransport.so
4757058237000-7058255000 ---p 00000000 00:00 0
4767058255000-705825d000 r--p 00068000 fc:00 2574 /system/lib64/vndk-sp-28/libhidltransport.so
477705825d000-705825e000 rw-p 00070000 fc:00 2574 /system/lib64/vndk-sp-28/libhidltransport.so
4787058260000-7058284000 r--s 00000000 fc:00 1138 /system/usr/hyphen-data/hyph-nn.hyb
4797058284000-70582a0000 r-xp 00000000 fc:00 2576 /system/lib64/vndk-sp-28/libutils.so
48070582a0000-70582b3000 ---p 00000000 00:00 0
48170582b3000-70582b4000 r--p 0001f000 fc:00 2576 /system/lib64/vndk-sp-28/libutils.so
48270582b4000-70582b5000 rw-p 00020000 fc:00 2576 /system/lib64/vndk-sp-28/libutils.so
48370582c4000-7058391000 r-xp 00000000 fc:00 2568 /system/lib64/vndk-sp-28/libc++.so
4847058391000-70583ad000 ---p 00000000 00:00 0
48570583ad000-70583b7000 r--p 000d6000 fc:00 2568 /system/lib64/vndk-sp-28/libc++.so
48670583b7000-70583b8000 rw-p 000e0000 fc:00 2568 /system/lib64/vndk-sp-28/libc++.so
48770583b8000-70583bb000 rw-p 00000000 00:00 0 [anon:.bss]
48870583cd000-70583e4000 r-xp 00000000 fc:00 2580 /system/lib64/vndk-sp-28/android.hardware.graphics.mapper@2.0.so
48970583e4000-70583f9000 ---p 00000000 00:00 0
49070583f9000-70583fb000 r--p 0001e000 fc:00 2580 /system/lib64/vndk-sp-28/android.hardware.graphics.mapper@2.0.so
49170583fb000-70583fc000 rw-p 00020000 fc:00 2580 /system/lib64/vndk-sp-28/android.hardware.graphics.mapper@2.0.so
492705841b000-7058421000 r-xp 00000000 fc:01 1001 /vendor/lib64/hw/android.hardware.graphics.mapper@2.0-impl.so
4937058421000-705843a000 ---p 00000000 00:00 0
494705843a000-705843b000 r--p 0000f000 fc:01 1001 /vendor/lib64/hw/android.hardware.graphics.mapper@2.0-impl.so
495705843b000-705843c000 rw-p 00010000 fc:01 1001 /vendor/lib64/hw/android.hardware.graphics.mapper@2.0-impl.so
496705844f000-7058473000 r--s 00000000 fc:00 1150 /system/usr/hyphen-data/hyph-nb.hyb
4977058473000-7058495000 r-xp 00000000 fc:00 2582 /system/lib64/vndk-sp-28/libhidlbase.so
4987058495000-70584b1000 ---p 00000000 00:00 0
49970584b1000-70584b3000 r--p 0002e000 fc:00 2582 /system/lib64/vndk-sp-28/libhidlbase.so
50070584b3000-70584b4000 rw-p 00030000 fc:00 2582 /system/lib64/vndk-sp-28/libhidlbase.so
50170584cd000-70584df000 r-xp 00000000 fc:00 2595 /system/lib64/vndk-sp-28/libcutils.so
50270584df000-70584fb000 ---p 00000000 00:00 0
50370584fb000-70584fd000 r--p 0001e000 fc:00 2595 /system/lib64/vndk-sp-28/libcutils.so
50470584fd000-70584fe000 rw-p 00020000 fc:00 2595 /system/lib64/vndk-sp-28/libcutils.so
5057058519000-7058537000 r--s 00000000 fc:00 1124 /system/usr/hyphen-data/hyph-de-ch-1901.hyb
5067058537000-7059fd1000 r--s 0070b000 fc:00 989 /system/framework/framework-res.apk
5077059fd1000-705a013000 r-xp 00000000 fc:00 2610 /system/lib64/libjavacrypto.so
508705a013000-705a02b000 ---p 00000000 00:00 0
509705a02b000-705a02d000 r--p 0004e000 fc:00 2610 /system/lib64/libjavacrypto.so
510705a02d000-705a02f000 rw-p 00050000 fc:00 2610 /system/lib64/libjavacrypto.so
511705a041000-705a05f000 r--s 00000000 fc:00 1128 /system/usr/hyphen-data/hyph-de-1996.hyb
512705a05f000-705a06a000 r-xp 00000000 fc:00 2917 /system/lib64/libsoundpool.so
513705a06a000-705a07e000 ---p 00000000 00:00 0
514705a07e000-705a07f000 r--p 0000f000 fc:00 2917 /system/lib64/libsoundpool.so
515705a07f000-705a080000 rw-p 00010000 fc:00 2917 /system/lib64/libsoundpool.so
516705a087000-705a102000 r--s 00000000 fc:00 1246 /system/usr/share/zoneinfo/tzdata
517705a102000-705a863000 r--s 00000000 fc:00 101 /system/fonts/NotoColorEmoji.ttf
518705a863000-705c000000 r--s 00000000 fc:00 251 /system/fonts/NotoSerifCJK-Regular.ttc
519705c000000-705c200000 rw-p 00000000 00:00 0 [anon:libc_malloc]
520705c209000-705c227000 r--s 00000000 fc:00 1077 /system/usr/hyphen-data/hyph-de-1901.hyb
521705c227000-705c26e000 r--s 02284000 fc:00 989 /system/framework/framework-res.apk
522705c26e000-705d43e000 r--s 00000000 fc:00 95 /system/fonts/NotoSansCJK-Regular.ttc
523705d43e000-705d4ec000 r--s 00000000 fc:00 278 /system/fonts/NotoSansSymbols-Regular-Subsetted.ttf
524705d4ec000-705d548000 r--s 00000000 fc:00 233 /system/fonts/NotoSansTibetan-Bold.ttf
525705d548000-705d5ab000 r--s 00000000 fc:00 177 /system/fonts/NotoSansTibetan-Regular.ttf
526705d5ab000-705d627000 r--s 00000000 fc:00 197 /system/fonts/NotoSansEgyptianHieroglyphs-Regular.ttf
527705d627000-705d6a2000 r--s 00000000 fc:00 76 /system/fonts/NotoSansCuneiform-Regular.ttf
528705d6a2000-705d6f3000 r--s 00000000 fc:00 67 /system/fonts/RobotoCondensed-BoldItalic.ttf
529705d6f3000-705d73e000 r--s 00000000 fc:00 199 /system/fonts/RobotoCondensed-Bold.ttf
530705d73e000-705d78f000 r--s 00000000 fc:00 230 /system/fonts/RobotoCondensed-MediumItalic.ttf
531705d78f000-705d7da000 r--s 00000000 fc:00 92 /system/fonts/RobotoCondensed-Medium.ttf
532705d7da000-705d82b000 r--s 00000000 fc:00 128 /system/fonts/RobotoCondensed-Italic.ttf
533705d82b000-705d875000 r--s 00000000 fc:00 164 /system/fonts/RobotoCondensed-Regular.ttf
534705d875000-705d8c7000 r--s 00000000 fc:00 292 /system/fonts/RobotoCondensed-LightItalic.ttf
535705d8c7000-705d919000 r--s 00000000 fc:00 85 /system/fonts/Roboto-BoldItalic.ttf
536705d919000-705d964000 r--s 00000000 fc:00 175 /system/fonts/Roboto-Bold.ttf
537705d964000-705d9b5000 r--s 00000000 fc:00 266 /system/fonts/Roboto-BlackItalic.ttf
538705d9b5000-705da00000 r--s 00000000 fc:00 187 /system/fonts/Roboto-Black.ttf
539705da00000-705dc00000 rw-p 00000000 00:00 0 [anon:libc_malloc]
540705dc1d000-705dc6e000 r--s 00000000 fc:00 148 /system/fonts/Roboto-MediumItalic.ttf
541705dc6e000-705dcb9000 r--s 00000000 fc:00 284 /system/fonts/Roboto-Medium.ttf
542705dcb9000-705dd0a000 r--s 00000000 fc:00 105 /system/fonts/Roboto-Italic.ttf
543705dd0a000-705dd55000 r--s 00000000 fc:00 156 /system/fonts/Roboto-Regular.ttf
544705dd55000-705dda7000 r--s 00000000 fc:00 217 /system/fonts/Roboto-LightItalic.ttf
545705dda7000-705ddf8000 r--s 00000000 fc:00 166 /system/fonts/Roboto-ThinItalic.ttf
546705ddf8000-705ddf9000 ---p 00000000 00:00 0 [anon:thread stack guard]
547705ddf9000-705ddfa000 ---p 00000000 00:00 0
548705ddfa000-705def6000 rw-p 00000000 00:00 0
549705def6000-705f5ec000 r--s 00000000 fc:00 1350 /system/usr/icu/icudt60l.dat
550705f5ec000-705f5ed000 ---p 00000000 00:00 0 [anon:thread stack guard]
551705f5ed000-705f5ee000 ---p 00000000 00:00 0
552705f5ee000-705f6ea000 rw-p 00000000 00:00 0
553705f6ea000-705f7e8000 r--p 00000000 00:10 20636 /dev/binder
554705f7e8000-705f7e9000 ---p 00000000 00:00 0 [anon:thread stack guard]
555705f7e9000-705f7ea000 ---p 00000000 00:00 0
556705f7ea000-705f8ee000 rw-p 00000000 00:00 0
557705f8ee000-705f8ef000 ---p 00000000 00:00 0 [anon:thread stack guard]
558705f8ef000-705f8f0000 ---p 00000000 00:00 0
559705f8f0000-705f9f4000 rw-p 00000000 00:00 0
560705f9f4000-705f9f5000 ---p 00000000 00:00 0 [anon:thread stack guard]
561705f9f5000-705f9f6000 ---p 00000000 00:00 0
562705f9f6000-705fafa000 rw-p 00000000 00:00 0
563705fafa000-705fafb000 ---p 00000000 00:00 0 [anon:thread stack guard]
564705fafb000-705fafc000 ---p 00000000 00:00 0
565705fafc000-705fc00000 rw-p 00000000 00:00 0
566705fc00000-705fe00000 rw-p 00000000 00:00 0 [anon:libc_malloc]
567705fe01000-705fe4c000 r--s 00000000 fc:00 97 /system/fonts/Roboto-Light.ttf
568705fe4c000-705fe4d000 ---p 00000000 00:00 0 [anon:thread stack guard]
569705fe4d000-705fe4e000 ---p 00000000 00:00 0
570705fe4e000-705ff4a000 rw-p 00000000 00:00 0
571705ff4a000-705ff4b000 ---p 00000000 00:05 10270991 /dev/ashmem/dalvik-Jit thread pool worker thread 0 (deleted)
572705ff4b000-705ff4c000 ---p 00001000 00:05 10270991 /dev/ashmem/dalvik-Jit thread pool worker thread 0 (deleted)
573705ff4c000-706004b000 rw-p 00002000 00:05 10270991 /dev/ashmem/dalvik-Jit thread pool worker thread 0 (deleted)
574706004b000-706010f000 r-xp 00000000 fc:00 2390 /system/lib64/libvixl-arm64.so
575706010f000-7060120000 ---p 00000000 00:00 0
5767060120000-7060125000 r--p 000cb000 fc:00 2390 /system/lib64/libvixl-arm64.so
5777060125000-7060126000 rw-p 000d0000 fc:00 2390 /system/lib64/libvixl-arm64.so
5787060126000-706012d000 rw-p 00000000 00:00 0 [anon:.bss]
5797060135000-7060151000 r--s 00000000 fc:01 1180 /vendor/overlay/framework-res__auto_generated_rro.apk
5807060151000-7060263000 r-xp 00000000 fc:00 2669 /system/lib64/libvixl-arm.so
5817060263000-7060275000 ---p 00000000 00:00 0
5827060275000-706027a000 r--p 0011b000 fc:00 2669 /system/lib64/libvixl-arm.so
583706027a000-706027b000 rw-p 00120000 fc:00 2669 /system/lib64/libvixl-arm.so
584706028b000-706056c000 r-xp 00000000 fc:00 2972 /system/lib64/libart-compiler.so
585706056c000-7060580000 ---p 00000000 00:00 0
5867060580000-7060598000 r--p 002e8000 fc:00 2972 /system/lib64/libart-compiler.so
5877060598000-7060599000 rw-p 00300000 fc:00 2972 /system/lib64/libart-compiler.so
5887060599000-70605a0000 rw-p 00000000 00:00 0 [anon:.bss]
58970605b0000-70605d0000 r--s 00000000 00:10 16571 /dev/__properties__/u:object_r:config_prop:s0
59070605d0000-7060619000 r-xp 00000000 fc:00 2702 /system/lib64/libssl.so
5917060619000-706062d000 ---p 00000000 00:00 0
592706062d000-7060630000 r--p 0004d000 fc:00 2702 /system/lib64/libssl.so
5937060630000-7060631000 rw-p 00050000 fc:00 2702 /system/lib64/libssl.so
5947060647000-7060667000 r--s 00000000 00:10 16595 /dev/__properties__/u:object_r:exported3_radio_prop:s0
5957060667000-706069d000 r-xp 00000000 fc:00 2371 /system/lib64/libopenjdk.so
596706069d000-70606b2000 ---p 00000000 00:00 0
59770606b2000-70606b4000 r--p 0003e000 fc:00 2371 /system/lib64/libopenjdk.so
59870606b4000-70606b6000 rw-p 00040000 fc:00 2371 /system/lib64/libopenjdk.so
59970606bb000-70606db000 r--s 00000000 00:10 16608 /dev/__properties__/u:object_r:exported_system_prop:s0
60070606db000-70606e3000 r-xp 00000000 fc:00 2538 /system/lib64/libopenjdkjvm.so
60170606e3000-70606fa000 ---p 00000000 00:00 0
60270606fa000-70606fb000 r--p 0000f000 fc:00 2538 /system/lib64/libopenjdkjvm.so
60370606fb000-70606fc000 rw-p 00010000 fc:00 2538 /system/lib64/libopenjdkjvm.so
6047060701000-7060722000 r--s 00000000 fc:00 227 /system/fonts/NotoSansAnatolianHieroglyphs-Regular.otf
6057060722000-7061e18000 r--s 00000000 fc:00 1350 /system/usr/icu/icudt60l.dat
6067061e18000-7061e5d000 r-xp 00000000 fc:00 2368 /system/lib64/libjavacore.so
6077061e5d000-7061e71000 ---p 00000000 00:00 0
6087061e71000-7061e73000 r--p 0004e000 fc:00 2368 /system/lib64/libjavacore.so
6097061e73000-7061e75000 rw-p 00050000 fc:00 2368 /system/lib64/libjavacore.so
6107061e75000-7061e76000 rw-p 00000000 00:00 0 [anon:.bss]
6117061e77000-7061e96000 r--s 00000000 fc:00 186 /system/fonts/NotoSansYi-Regular.ttf
6127061e96000-7061e99000 r-xp 00000000 fc:00 2953 /system/lib64/libwebviewchromium_plat_support.so
6137061e99000-7061eb5000 ---p 00000000 00:00 0
6147061eb5000-7061eb6000 r--p 0000f000 fc:00 2953 /system/lib64/libwebviewchromium_plat_support.so
6157061eb6000-7061eb7000 rw-p 00010000 fc:00 2953 /system/lib64/libwebviewchromium_plat_support.so
6167061ebc000-7061edd000 r--s 00000000 fc:00 100 /system/fonts/NotoSansBamum-Regular.ttf
6177061edd000-7061eed000 r-xp 00000000 fc:00 2945 /system/lib64/libRS.so
6187061eed000-7061efc000 ---p 00000000 00:00 0
6197061efc000-7061efd000 r--p 0000f000 fc:00 2945 /system/lib64/libRS.so
6207061efd000-7061efe000 rw-p 00010000 fc:00 2945 /system/lib64/libRS.so
6217061f05000-7061f6b000 r-xp 00000000 fc:00 2423 /system/lib64/android.hardware.renderscript@1.0.so
6227061f6b000-7061f7a000 ---p 00000000 00:00 0
6237061f7a000-7061f7f000 r--p 0006b000 fc:00 2423 /system/lib64/android.hardware.renderscript@1.0.so
6247061f7f000-7061f80000 rw-p 00070000 fc:00 2423 /system/lib64/android.hardware.renderscript@1.0.so
6257061f99000-7061f9b000 r-xp 00000000 fc:00 2614 /system/lib64/libOpenSLES.so
6267061f9b000-7061fb8000 ---p 00000000 00:00 0
6277061fb8000-7061fb9000 r--p 0000f000 fc:00 2614 /system/lib64/libOpenSLES.so
6287061fb9000-7061fba000 rw-p 00010000 fc:00 2614 /system/lib64/libOpenSLES.so
6297061fc6000-7061fc8000 r-xp 00000000 fc:00 2963 /system/lib64/libOpenMAXAL.so
6307061fc8000-7061fe5000 ---p 00000000 00:00 0
6317061fe5000-7061fe6000 r--p 0000f000 fc:00 2963 /system/lib64/libOpenMAXAL.so
6327061fe6000-7061fe7000 rw-p 00010000 fc:00 2963 /system/lib64/libOpenMAXAL.so
6337061fe7000-7062000000 r--s 00000000 fc:00 143 /system/fonts/NotoSansBhaiksuki-Regular.otf
6347062000000-7062003000 r-xp 00000000 fc:00 2447 /system/lib64/libtextclassifier_hash.so
6357062003000-706201f000 ---p 00000000 00:00 0
636706201f000-7062020000 r--p 0000f000 fc:00 2447 /system/lib64/libtextclassifier_hash.so
6377062020000-7062021000 rw-p 00010000 fc:00 2447 /system/lib64/libtextclassifier_hash.so
6387062022000-7062042000 rw-p 00000000 00:05 10269731 /dev/ashmem/dalvik-CompilerMetadata (deleted)
6397062042000-7062077000 r-xp 00000000 fc:00 2372 /system/lib64/android.hardware.neuralnetworks@1.0.so
6407062077000-7062095000 ---p 00000000 00:00 0
6417062095000-706209b000 r--p 0003a000 fc:00 2372 /system/lib64/android.hardware.neuralnetworks@1.0.so
642706209b000-706209c000 rw-p 00040000 fc:00 2372 /system/lib64/android.hardware.neuralnetworks@1.0.so
64370620a9000-70620c9000 rw-p 00000000 00:05 10269730 /dev/ashmem/dalvik-CompilerMetadata (deleted)
64470620c9000-70620e3000 r-xp 00000000 fc:00 2956 /system/lib64/android.hardware.neuralnetworks@1.1.so
64570620e3000-70620f4000 ---p 00000000 00:00 0
64670620f4000-70620f7000 r--p 0001d000 fc:00 2956 /system/lib64/android.hardware.neuralnetworks@1.1.so
64770620f7000-70620f8000 rw-p 00020000 fc:00 2956 /system/lib64/android.hardware.neuralnetworks@1.1.so
648706210b000-70621d0000 r-xp 00000000 fc:00 2387 /system/lib64/libneuralnetworks.so
64970621d0000-70621e3000 ---p 00000000 00:00 0
65070621e3000-70621e5000 r--p 000ce000 fc:00 2387 /system/lib64/libneuralnetworks.so
65170621e5000-70621e7000 rw-p 000d0000 fc:00 2387 /system/lib64/libneuralnetworks.so
65270621e7000-7062372000 rw-p 00000000 00:00 0 [anon:.bss]
6537062373000-7062395000 r--s 00000000 fc:00 274 /system/fonts/NotoSerifMyanmar-Bold.otf
6547062395000-7062398000 r-xp 00000000 fc:00 2937 /system/lib64/libjnigraphics.so
6557062398000-70623b4000 ---p 00000000 00:00 0
65670623b4000-70623b5000 r--p 0000f000 fc:00 2937 /system/lib64/libjnigraphics.so
65770623b5000-70623b6000 rw-p 00010000 fc:00 2937 /system/lib64/libjnigraphics.so
65870623c8000-70623e0000 r-xp 00000000 fc:00 2662 /system/lib64/libGLESv3.so
65970623e0000-70623f7000 ---p 00000000 00:00 0
66070623f7000-70623f8000 r--p 0001f000 fc:00 2662 /system/lib64/libGLESv3.so
66170623f8000-70623f9000 rw-p 00020000 fc:00 2662 /system/lib64/libGLESv3.so
66270623fc000-706241c000 rw-p 00000000 00:05 10269729 /dev/ashmem/dalvik-CompilerMetadata (deleted)
663706241c000-7062444000 r-xp 00000000 fc:00 2603 /system/lib64/libexif.so
6647062444000-706245f000 ---p 00000000 00:00 0
665706245f000-7062472000 r--p 0002d000 fc:00 2603 /system/lib64/libexif.so
6667062472000-7062473000 rw-p 00040000 fc:00 2603 /system/lib64/libexif.so
6677062474000-7062490000 r--s 00000000 fc:00 286 /system/fonts/NotoSansMongolian-Regular.ttf
6687062490000-7062491000 r-xp 00000000 fc:00 2357 /system/lib64/libasyncio.so
6697062491000-70624af000 ---p 00000000 00:00 0
67070624af000-70624b0000 r--p 0000f000 fc:00 2357 /system/lib64/libasyncio.so
67170624b0000-70624b1000 rw-p 00010000 fc:00 2357 /system/lib64/libasyncio.so
67270624b5000-70624cf000 r--s 00000000 fc:00 221 /system/fonts/NotoSansMyanmarUI-Bold.ttf
67370624cf000-7062508000 r-xp 00000000 fc:00 2401 /system/lib64/libmtp.so
6747062508000-7062522000 ---p 00000000 00:00 0
6757062522000-7062525000 r--p 0003d000 fc:00 2401 /system/lib64/libmtp.so
6767062525000-706252c000 rw-p 00040000 fc:00 2401 /system/lib64/libmtp.so
6777062530000-7062550000 rw-p 00000000 00:05 10269728 /dev/ashmem/dalvik-CompilerMetadata (deleted)
6787062550000-7062572000 r--s 00000000 fc:00 234 /system/fonts/NotoSerifMyanmar-Regular.otf
6797062572000-706259e000 r-xp 00000000 fc:00 2620 /system/lib64/libmediandk.so
680706259e000-70625b9000 ---p 00000000 00:00 0
68170625b9000-70625bc000 r--p 0002d000 fc:00 2620 /system/lib64/libmediandk.so
68270625bc000-70625c0000 rw-p 00030000 fc:00 2620 /system/lib64/libmediandk.so
68370625c2000-70625d1000 r-xp 00000000 fc:00 2613 /system/lib64/libmidi.so
68470625d1000-70625ef000 ---p 00000000 00:00 0
68570625ef000-70625f1000 r--p 0000e000 fc:00 2613 /system/lib64/libmidi.so
68670625f1000-70625f2000 rw-p 00010000 fc:00 2613 /system/lib64/libmidi.so
6877062600000-7062621000 r-xp 00000000 fc:00 2366 /system/lib64/libmediadrmmetrics_lite.so
6887062621000-706263d000 ---p 00000000 00:00 0
689706263d000-706263f000 r--p 0002e000 fc:00 2366 /system/lib64/libmediadrmmetrics_lite.so
690706263f000-7062640000 rw-p 00030000 fc:00 2366 /system/lib64/libmediadrmmetrics_lite.so
691706264b000-706266b000 rw-p 00000000 00:05 10269727 /dev/ashmem/dalvik-CompilerMetadata (deleted)
692706266b000-70626d4000 r-xp 00000000 fc:00 2727 /system/lib64/libmedia_jni.so
69370626d4000-70626eb000 ---p 00000000 00:00 0
69470626eb000-70626f2000 r--p 00069000 fc:00 2727 /system/lib64/libmedia_jni.so
69570626f2000-70626f3000 rw-p 00070000 fc:00 2727 /system/lib64/libmedia_jni.so
6967062703000-7062732000 r-xp 00000000 fc:00 2399 /system/lib64/libcamera2ndk.so
6977062732000-7062748000 ---p 00000000 00:00 0
6987062748000-706274b000 r--p 0003d000 fc:00 2399 /system/lib64/libcamera2ndk.so
699706274b000-7062750000 rw-p 00040000 fc:00 2399 /system/lib64/libcamera2ndk.so
7007062768000-7062788000 rw-p 00000000 00:05 10269726 /dev/ashmem/dalvik-CompilerMetadata (deleted)
7017062788000-70627ee000 r-xp 00000000 fc:00 2974 /system/lib64/android.hardware.drm@1.0.so
70270627ee000-7062805000 ---p 00000000 00:00 0
7037062805000-706280d000 r--p 00068000 fc:00 2974 /system/lib64/android.hardware.drm@1.0.so
704706280d000-706280e000 rw-p 00070000 fc:00 2974 /system/lib64/android.hardware.drm@1.0.so
705706281a000-706281b000 ---p 00000000 00:00 0 [anon:thread signal stack guard]
706706281b000-706281f000 rw-p 00000000 00:00 0 [anon:thread signal stack]
707706281f000-7062843000 r--s 00000000 fc:00 142 /system/fonts/NotoSansKhmer-VF.ttf
7087062843000-7062886000 r-xp 00000000 fc:00 2637 /system/lib64/android.hardware.drm@1.1.so
7097062886000-70628a5000 ---p 00000000 00:00 0
71070628a5000-70628ab000 r--p 0004a000 fc:00 2637 /system/lib64/android.hardware.drm@1.1.so
71170628ab000-70628ac000 rw-p 00050000 fc:00 2637 /system/lib64/android.hardware.drm@1.1.so
71270628b0000-70628b1000 ---p 00000000 00:00 0 [anon:thread signal stack guard]
71370628b1000-70628b5000 rw-p 00000000 00:00 0 [anon:thread signal stack]
71470628b5000-70628db000 r--s 00000000 fc:00 137 /system/fonts/NotoSansSinhala-Bold.ttf
71570628db000-7062907000 r-xp 00000000 fc:00 2478 /system/lib64/libmediadrm.so
7167062907000-7062918000 ---p 00000000 00:00 0
7177062918000-7062920000 r--p 00038000 fc:00 2478 /system/lib64/libmediadrm.so
7187062920000-7062921000 rw-p 00040000 fc:00 2478 /system/lib64/libmediadrm.so
7197062922000-7062929000 rw-p 00000000 fc:00 583 /system/etc/event-log-tags
7207062929000-7062951000 r--s 00000000 fc:00 296 /system/fonts/NotoSansSinhala-Regular.ttf
7217062951000-7062997000 r-xp 00000000 fc:00 2448 /system/lib64/libaaudio.so
7227062997000-70629ac000 ---p 00000000 00:00 0
72370629ac000-70629b2000 r--p 0004a000 fc:00 2448 /system/lib64/libaaudio.so
72470629b2000-70629ba000 rw-p 00050000 fc:00 2448 /system/lib64/libaaudio.so
72570629ba000-70629bb000 ---p 00000000 00:00 0 [anon:thread signal stack guard]
72670629bb000-70629bf000 rw-p 00000000 00:00 0 [anon:thread signal stack]
72770629bf000-70629c0000 ---p 00000000 00:00 0 [anon:bionic TLS guard]
72870629c0000-70629c3000 rw-p 00000000 00:00 0 [anon:bionic TLS]
72970629c3000-70629c4000 ---p 00000000 00:00 0 [anon:bionic TLS guard]
73070629c4000-70629c5000 ---p 00000000 00:00 0 [anon:thread signal stack guard]
73170629c5000-70629c9000 rw-p 00000000 00:00 0 [anon:thread signal stack]
73270629c9000-70629e3000 r-xp 00000000 fc:00 2940 /system/lib64/libandroid.so
73370629e3000-70629f3000 ---p 00000000 00:00 0
73470629f3000-70629f6000 r--p 0001d000 fc:00 2940 /system/lib64/libandroid.so
73570629f6000-70629f7000 rw-p 00020000 fc:00 2940 /system/lib64/libandroid.so
73670629f8000-70629f9000 ---p 00000000 00:00 0 [anon:bionic TLS guard]
73770629f9000-70629fc000 rw-p 00000000 00:00 0 [anon:bionic TLS]
73870629fc000-70629fd000 ---p 00000000 00:00 0 [anon:bionic TLS guard]
73970629fd000-7062a3e000 r--s 00000000 fc:00 216 /system/fonts/NotoSerif-BoldItalic.ttf
7407062a3e000-7062b06000 rw-p 00000000 00:05 10270984 /dev/ashmem/dalvik-indirect ref table (deleted)
7417062b06000-7062bce000 rw-p 00000000 00:05 10270983 /dev/ashmem/dalvik-indirect ref table (deleted)
7427062bce000-7062dce000 rw-p 00000000 00:05 10270726 /dev/ashmem/dalvik-rb copying gc mark stack (deleted)
7437062dce000-70635ce000 rw-p 00000000 00:05 10270725 /dev/ashmem/dalvik-concurrent copying gc mark stack (deleted)
74470635ce000-7063dcf000 rw-p 00000000 00:05 10270724 /dev/ashmem/dalvik-live stack (deleted)
7457063dcf000-70645d0000 rw-p 00000000 00:05 10270723 /dev/ashmem/dalvik-allocation stack (deleted)
74670645d0000-70649d1000 rw-p 00000000 00:05 10270721 /dev/ashmem/dalvik-card table (deleted)
74770649d1000-7064ad1000 rw-p 00000000 00:05 10267648 /dev/ashmem/dalvik-large object free list space allocation info map (deleted)
7487064ad1000-7065ad1000 rw-p 00000000 00:05 10267644 /dev/ashmem/dalvik-region space live bitmap (deleted)
7497065ad1000-7065bd1000 rw-p 00000000 00:05 10267642 /dev/ashmem/dalvik-allocspace zygote / non moving space mark-bitmap 0 (deleted)
7507065bd1000-7065cd1000 rw-p 00000000 00:05 10267641 /dev/ashmem/dalvik-allocspace zygote / non moving space live-bitmap 0 (deleted)
7517065cd1000-7065cd2000 r-xp 00000000 fc:00 2946 /system/lib64/libsigchain.so
7527065cd2000-7065cf0000 ---p 00000000 00:00 0
7537065cf0000-7065cf1000 r--p 0000f000 fc:00 2946 /system/lib64/libsigchain.so
7547065cf1000-7065cf2000 rw-p 00010000 fc:00 2946 /system/lib64/libsigchain.so
7557065cf4000-7065d0f000 r--s 00000000 fc:00 190 /system/fonts/NotoSansMyanmar-Bold.ttf
7567065d0f000-7065d22000 r-xp 00000000 fc:00 2405 /system/lib64/liblz4.so
7577065d22000-7065d3e000 ---p 00000000 00:00 0
7587065d3e000-7065d3f000 r--p 0001f000 fc:00 2405 /system/lib64/liblz4.so
7597065d3f000-7065d40000 rw-p 00020000 fc:00 2405 /system/lib64/liblz4.so
7607065d40000-7065d5a000 r--s 00000000 fc:00 222 /system/fonts/NotoSansMyanmarUI-Regular.ttf
7617065d5a000-7065d5e000 r-xp 00000000 fc:00 2609 /system/lib64/libtombstoned_client.so
7627065d5e000-7065d79000 ---p 00000000 00:00 0
7637065d79000-7065d7a000 r--p 0000f000 fc:00 2609 /system/lib64/libtombstoned_client.so
7647065d7a000-7065d7b000 rw-p 00010000 fc:00 2609 /system/lib64/libtombstoned_client.so
7657065d7f000-7065d80000 ---p 00000000 00:00 0 [anon:thread signal stack guard]
7667065d80000-7065d84000 rw-p 00000000 00:00 0 [anon:thread signal stack]
7677065d84000-706636e000 r-xp 00000000 fc:00 2671 /system/lib64/libart.so
768706636e000-706638d000 ---p 00000000 00:00 0
769706638d000-706639e000 r--p 005ef000 fc:00 2671 /system/lib64/libart.so
770706639e000-70663a1000 rw-p 00600000 fc:00 2671 /system/lib64/libart.so
77170663a1000-70663a4000 rw-p 00000000 00:00 0 [anon:.bss]
77270663a6000-70663c6000 rw-p 00000000 00:05 10269725 /dev/ashmem/dalvik-CompilerMetadata (deleted)
77370663c6000-70663c8000 r-xp 00000000 fc:00 2673 /system/lib64/libmetricslogger.so
77470663c8000-70663e5000 ---p 00000000 00:00 0
77570663e5000-70663e6000 r--p 0000f000 fc:00 2673 /system/lib64/libmetricslogger.so
77670663e6000-70663e7000 rw-p 00010000 fc:00 2673 /system/lib64/libmetricslogger.so
77770663e7000-7066400000 r--s 00000000 fc:00 110 /system/fonts/NotoSansLepcha-Regular.ttf
7787066400000-7066800000 rw-p 00000000 00:00 0 [anon:libc_malloc]
7797066803000-706681e000 r--s 00000000 fc:00 297 /system/fonts/NotoSansMyanmar-Regular.ttf
780706681e000-7066821000 r--p 00000000 00:00 0 [anon:cfi shadow]
7817066821000-7066822000 r--p 00000000 00:00 0 [anon:cfi shadow]
7827066822000-7066b1d000 r--p 00000000 00:00 0 [anon:cfi shadow]
7837066b1d000-7066b1e000 r--p 00000000 00:00 0 [anon:cfi shadow]
7847066b1e000-7066ba0000 r--p 00000000 00:00 0 [anon:cfi shadow]
7857066ba0000-7066ba1000 r--p 00000000 00:00 0 [anon:cfi shadow]
7867066ba1000-7066ba2000 r--p 00000000 00:00 0 [anon:cfi shadow]
7877066ba2000-7066ba5000 r--p 00000000 00:00 0 [anon:cfi shadow]
7887066ba5000-7066ba6000 r--p 00000000 00:00 0 [anon:cfi shadow]
7897066ba6000-70e681e000 r--p 00000000 00:00 0 [anon:cfi shadow]
79070e681e000-70e6854000 r-xp 00000000 fc:00 2431 /system/lib64/libstagefright_foundation.so
79170e6854000-70e6865000 ---p 00000000 00:00 0
79270e6865000-70e6867000 r--p 0003e000 fc:00 2431 /system/lib64/libstagefright_foundation.so
79370e6867000-70e686c000 rw-p 00040000 fc:00 2431 /system/lib64/libstagefright_foundation.so
79470e686d000-70e686e000 ---p 00000000 00:00 0 [anon:bionic TLS guard]
79570e686e000-70e6871000 rw-p 00000000 00:00 0 [anon:bionic TLS]
79670e6871000-70e6873000 ---p 00000000 00:00 0 [anon:bionic TLS guard]
79770e6873000-70e6876000 rw-p 00000000 00:00 0 [anon:bionic TLS]
79870e6876000-70e6877000 ---p 00000000 00:00 0 [anon:bionic TLS guard]
79970e6877000-70e688c000 r--s 00000000 fc:00 301 /system/fonts/NotoSansSinhalaUI-Bold.otf
80070e688c000-70e688e000 r-xp 00000000 fc:00 2943 /system/lib64/libion.so
80170e688e000-70e68ab000 ---p 00000000 00:00 0
80270e68ab000-70e68ac000 r--p 0000f000 fc:00 2943 /system/lib64/libion.so
80370e68ac000-70e68ad000 rw-p 00010000 fc:00 2943 /system/lib64/libion.so
80470e68ad000-70e68af000 rw-p 00000000 00:05 10282496 /dev/ashmem/dalvik-indirect ref table (deleted)
80570e68af000-70e68b1000 rw-p 00000000 00:05 10282493 /dev/ashmem/dalvik-indirect ref table (deleted)
80670e68b1000-70e68ee000 r--s 00000000 fc:00 256 /system/fonts/NotoSerif-Italic.ttf
80770e68ee000-70e6910000 r-xp 00000000 fc:00 2502 /system/lib64/libhidlbase.so
80870e6910000-70e692c000 ---p 00000000 00:00 0
80970e692c000-70e692e000 r--p 0002e000 fc:00 2502 /system/lib64/libhidlbase.so
81070e692e000-70e692f000 rw-p 00030000 fc:00 2502 /system/lib64/libhidlbase.so
81170e6930000-70e693f000 r--s 00000000 fc:00 1082 /system/usr/hyphen-data/hyph-en-us.hyb
81270e693f000-70e6954000 r--s 00000000 fc:00 138 /system/fonts/NotoSansSinhalaUI-Regular.otf
81370e6954000-70e6978000 r-xp 00000000 fc:00 2482 /system/lib64/libui.so
81470e6978000-70e6992000 ---p 00000000 00:00 0
81570e6992000-70e6994000 r--p 0002e000 fc:00 2482 /system/lib64/libui.so
81670e6994000-70e6995000 rw-p 00030000 fc:00 2482 /system/lib64/libui.so
81770e6996000-70e69a2000 r--s 00000000 fc:00 1117 /system/usr/hyphen-data/hyph-en-gb.hyb
81870e69a2000-70e69b7000 r--s 00000000 fc:00 202 /system/fonts/NotoSerifSinhala-Bold.otf
81970e69b7000-70e69cb000 r--s 00000000 fc:00 124 /system/fonts/NotoSansOriyaUI-Bold.ttf
82070e69cb000-70e69e1000 r-xp 00000000 fc:00 2537 /system/lib64/liblog.so
82170e69e1000-70e69fa000 ---p 00000000 00:00 0
82270e69fa000-70e69fb000 r--p 0001f000 fc:00 2537 /system/lib64/liblog.so
82370e69fb000-70e69fc000 rw-p 00020000 fc:00 2537 /system/lib64/liblog.so
82470e69fc000-70e69fe000 rw-p 00000000 00:05 10266158 /dev/ashmem/dalvik-indirect ref table (deleted)
82570e69fe000-70e69ff000 ---p 00000000 00:00 0 [anon:bionic TLS guard]
82670e69ff000-70e6a02000 rw-p 00000000 00:00 0 [anon:bionic TLS]
82770e6a02000-70e6a03000 ---p 00000000 00:00 0 [anon:bionic TLS guard]
82870e6a03000-70e6a05000 r-xp 00000000 fc:00 2489 /system/lib64/android.hidl.token@1.0-utils.so
82970e6a05000-70e6a22000 ---p 00000000 00:00 0
83070e6a22000-70e6a23000 r--p 0000f000 fc:00 2489 /system/lib64/android.hidl.token@1.0-utils.so
83170e6a23000-70e6a24000 rw-p 00010000 fc:00 2489 /system/lib64/android.hidl.token@1.0-utils.so
83270e6a25000-70e6a2e000 r--s 00000000 fc:00 1120 /system/usr/hyphen-data/hyph-ga.hyb
83370e6a2e000-70e6a42000 r--s 00000000 fc:00 109 /system/fonts/NotoSansOriyaUI-Regular.ttf
83470e6a42000-70e6a59000 r-xp 00000000 fc:00 2446 /system/lib64/android.hardware.graphics.mapper@2.0.so
83570e6a59000-70e6a6e000 ---p 00000000 00:00 0
83670e6a6e000-70e6a70000 r--p 0001e000 fc:00 2446 /system/lib64/android.hardware.graphics.mapper@2.0.so
83770e6a70000-70e6a71000 rw-p 00020000 fc:00 2446 /system/lib64/android.hardware.graphics.mapper@2.0.so
83870e6a72000-70e6a78000 r--s 00000000 fc:00 1084 /system/usr/hyphen-data/hyph-et.hyb
83970e6a78000-70e6a9d000 r--s 00000000 fc:00 207 /system/fonts/NotoSerifTelugu-Bold.ttf
84070e6a9d000-70e6a9f000 r-xp 00000000 fc:00 2330 /system/lib64/android.hardware.configstore-utils.so
84170e6a9f000-70e6abc000 ---p 00000000 00:00 0
84270e6abc000-70e6abd000 r--p 0000f000 fc:00 2330 /system/lib64/android.hardware.configstore-utils.so
84370e6abd000-70e6abe000 rw-p 00010000 fc:00 2330 /system/lib64/android.hardware.configstore-utils.so
84470e6abe000-70e6ac0000 r--s f8042000 00:10 20630 /dev/kgsl-3d0
84570e6ac0000-70e6adc000 r--s 00000000 fc:00 172 /system/fonts/NotoSansTeluguUI-Bold.ttf
84670e6adc000-70e6ae0000 r-xp 00000000 fc:00 2555 /system/lib64/libstagefright_omx_utils.so
84770e6ae0000-70e6afb000 ---p 00000000 00:00 0
84870e6afb000-70e6afc000 r--p 0000f000 fc:00 2555 /system/lib64/libstagefright_omx_utils.so
84970e6afc000-70e6afd000 rw-p 00010000 fc:00 2555 /system/lib64/libstagefright_omx_utils.so
85070e6afd000-70e6afe000 ---p 00000000 00:00 0 [anon:thread signal stack guard]
85170e6afe000-70e6b02000 rw-p 00000000 00:00 0 [anon:thread signal stack]
85270e6b02000-70e6b27000 r--s 00000000 fc:00 271 /system/fonts/NotoSerifTelugu-Regular.ttf
85370e6b27000-70e6b61000 r-xp 00000000 fc:00 2695 /system/lib64/libdexfile.so
85470e6b61000-70e6b73000 ---p 00000000 00:00 0
85570e6b73000-70e6b75000 r--p 0003e000 fc:00 2695 /system/lib64/libdexfile.so
85670e6b75000-70e6b76000 rw-p 00040000 fc:00 2695 /system/lib64/libdexfile.so
85770e6b76000-70e6b78000 rw-p 00000000 00:05 10253452 /dev/ashmem/dalvik-indirect ref table (deleted)
85870e6b78000-70e6b85000 r--s 00000000 fc:00 1080 /system/usr/hyphen-data/hyph-cu.hyb
85970e6b85000-70e6b96000 r-xp 00000000 fc:00 2957 /system/lib64/libaudioutils.so
86070e6b96000-70e6bb4000 ---p 00000000 00:00 0
86170e6bb4000-70e6bb5000 r--p 0001f000 fc:00 2957 /system/lib64/libaudioutils.so
86270e6bb5000-70e6bb6000 rw-p 00020000 fc:00 2957 /system/lib64/libaudioutils.so
86370e6bb6000-70e6bb7000 ---p 00000000 00:00 0 [anon:bionic TLS guard]
86470e6bb7000-70e6bba000 rw-p 00000000 00:00 0 [anon:bionic TLS]
86570e6bba000-70e6bbb000 ---p 00000000 00:00 0 [anon:bionic TLS guard]
86670e6bbb000-70e6bd7000 r--s 00000000 fc:00 132 /system/fonts/NotoSansTeluguUI-Regular.ttf
86770e6bd7000-70e6bdc000 r-xp 00000000 fc:00 2409 /system/lib64/libprocessgroup.so
86870e6bdc000-70e6bf6000 ---p 00000000 00:00 0
86970e6bf6000-70e6bf7000 r--p 0000f000 fc:00 2409 /system/lib64/libprocessgroup.so
87070e6bf7000-70e6bf8000 rw-p 00010000 fc:00 2409 /system/lib64/libprocessgroup.so
87170e6bf8000-70e6c09000 r--s 00000000 fc:00 79 /system/fonts/NotoSansNewa-Regular.otf
87270e6c09000-70e6c1c000 r-xp 00000000 fc:00 2329 /system/lib64/android.hidl.memory.token@1.0.so
87370e6c1c000-70e6c36000 ---p 00000000 00:00 0
87470e6c36000-70e6c38000 r--p 0001e000 fc:00 2329 /system/lib64/android.hidl.memory.token@1.0.so
87570e6c38000-70e6c39000 rw-p 00020000 fc:00 2329 /system/lib64/android.hidl.memory.token@1.0.so
87670e6c3a000-70e6c4f000 r--s 00000000 fc:00 253 /system/fonts/NotoSansOriya-Bold.ttf
87770e6c4f000-70e6c6b000 r-xp 00000000 fc:00 2407 /system/lib64/libutils.so
87870e6c6b000-70e6c7e000 ---p 00000000 00:00 0
87970e6c7e000-70e6c7f000 r--p 0001f000 fc:00 2407 /system/lib64/libutils.so
88070e6c7f000-70e6c80000 rw-p 00020000 fc:00 2407 /system/lib64/libutils.so
88170e6c80000-70e6c9d000 r-xp 00000000 fc:00 2934 /system/lib64/libtinyxml2.so
88270e6c9d000-70e6cba000 ---p 00000000 00:00 0
88370e6cba000-70e6cbc000 r--p 0001e000 fc:00 2934 /system/lib64/libtinyxml2.so
88470e6cbc000-70e6cbf000 rw-p 00020000 fc:00 2934 /system/lib64/libtinyxml2.so
88570e6cbf000-70e6ccf000 r--s 00000000 fc:00 80 /system/fonts/NotoSansMarchen-Regular.otf
88670e6ccf000-70e6ce0000 r-xp 00000000 fc:00 2655 /system/lib64/libbase.so
88770e6ce0000-70e6cfe000 ---p 00000000 00:00 0
88870e6cfe000-70e6cff000 r--p 0001f000 fc:00 2655 /system/lib64/libbase.so
88970e6cff000-70e6d00000 rw-p 00020000 fc:00 2655 /system/lib64/libbase.so
89070e6d00000-70e6d09000 r--s 00000000 fc:00 1113 /system/usr/hyphen-data/hyph-cy.hyb
89170e6d09000-70e6d50000 r-xp 00000000 fc:00 2495 /system/lib64/libRScpp.so
89270e6d50000-70e6d68000 ---p 00000000 00:00 0
89370e6d68000-70e6d69000 r--p 0004f000 fc:00 2495 /system/lib64/libRScpp.so
89470e6d69000-70e6d6a000 rw-p 00050000 fc:00 2495 /system/lib64/libRScpp.so
89570e6d6b000-70e6d6d000 r--s 00088000 103:1d 1736830 /data/app/com.google.sample.tunnel-HGGRU03Gu1Mwkf_-RnFmvw==/base.apk
89670e6d6d000-70e6d7d000 r--s 00000000 fc:00 238 /system/fonts/NotoSansVai-Regular.ttf
89770e6d7d000-70e6d98000 r--s 00000000 fc:00 276 /system/fonts/NotoSansTelugu-Bold.ttf
89870e6d98000-70e6f2b000 r-xp 00000000 fc:00 2961 /system/lib64/libicuuc.so
89970e6f2b000-70e6f47000 ---p 00000000 00:00 0
90070e6f47000-70e6f5c000 r--p 0019b000 fc:00 2961 /system/lib64/libicuuc.so
90170e6f5c000-70e6f5d000 rw-p 001b0000 fc:00 2961 /system/lib64/libicuuc.so
90270e6f5d000-70e6f5e000 rw-p 00000000 00:00 0 [anon:.bss]
90370e6f5f000-70e6f68000 r--s 00000000 fc:00 159 /system/fonts/NotoSansLinearA-Regular.otf
90470e6f68000-70e6f84000 r--s 00000000 fc:00 170 /system/fonts/NotoSansTelugu-Regular.ttf
90570e6f84000-70e7058000 r-xp 00000000 fc:00 2356 /system/lib64/libc.so
90670e7058000-70e706e000 ---p 00000000 00:00 0
90770e706e000-70e7074000 r--p 000da000 fc:00 2356 /system/lib64/libc.so
90870e7074000-70e7076000 rw-p 000e0000 fc:00 2356 /system/lib64/libc.so
90970e7076000-70e7077000 rw-p 00000000 00:00 0 [anon:.bss]
91070e7077000-70e7078000 r--p 00000000 00:00 0 [anon:.bss]
91170e7078000-70e7080000 rw-p 00000000 00:00 0 [anon:.bss]
91270e7080000-70e7087000 r--s 00000000 fc:00 102 /system/fonts/NotoSansSharada-Regular.otf
91370e7087000-70e708e000 r-xp 00000000 fc:00 2378 /system/lib64/libheif.so
91470e708e000-70e70a4000 ---p 00000000 00:00 0
91570e70a4000-70e70a6000 r--p 0000e000 fc:00 2378 /system/lib64/libheif.so
91670e70a6000-70e70a7000 rw-p 00010000 fc:00 2378 /system/lib64/libheif.so
91770e70a7000-70e70a9000 r--s 00000000 fc:00 1116 /system/usr/hyphen-data/hyph-sl.hyb
91870e70a9000-70e70ab000 r--s 00000000 fc:00 1147 /system/usr/hyphen-data/hyph-mn-cyrl.hyb
91970e70ab000-70e70c5000 r--s 00000000 fc:00 291 /system/fonts/NotoSansBengaliUI-Bold.ttf
92070e70c5000-70e70ea000 r-xp 00000000 fc:00 2545 /system/lib64/libEGL.so
92170e70ea000-70e7109000 ---p 00000000 00:00 0
92270e7109000-70e710d000 r--p 0002c000 fc:00 2545 /system/lib64/libEGL.so
92370e710d000-70e710e000 rw-p 00030000 fc:00 2545 /system/lib64/libEGL.so
92470e710e000-70e7115000 rw-p 00000000 00:00 0 [anon:.bss]
92570e7115000-70e7119000 r--s 00000000 fc:00 1143 /system/usr/hyphen-data/hyph-es.hyb
92670e7119000-70e712e000 r--s 00000000 fc:00 71 /system/fonts/NotoSansOriya-Regular.ttf
92770e712e000-70e717a000 r--s 00000000 fc:00 272 /system/fonts/Roboto-Thin.ttf
92870e717a000-70e71db000 r-xp 00000000 fc:00 2393 /system/lib64/libpdx_default_transport.so
92970e71db000-70e71f7000 ---p 00000000 00:00 0
93070e71f7000-70e71f9000 r--p 0006e000 fc:00 2393 /system/lib64/libpdx_default_transport.so
93170e71f9000-70e71fa000 rw-p 00070000 fc:00 2393 /system/lib64/libpdx_default_transport.so
93270e71fa000-70e71fb000 rw-p 00000000 00:00 0 [anon:.bss]
93370e71fc000-70e71fe000 r--s 00000000 fc:00 1107 /system/usr/hyphen-data/hyph-fr.hyb
93470e71fe000-70e7200000 r--s 00000000 fc:00 1097 /system/usr/hyphen-data/hyph-da.hyb
93570e7200000-70e7223000 r-xp 00000000 fc:00 2380 /system/lib64/libminikin.so
93670e7223000-70e723e000 ---p 00000000 00:00 0
93770e723e000-70e723f000 r--p 0002f000 fc:00 2380 /system/lib64/libminikin.so
93870e723f000-70e7240000 rw-p 00030000 fc:00 2380 /system/lib64/libminikin.so
93970e7241000-70e724d000 r--s 00000000 fc:00 179 /system/fonts/NotoSansTaiTham-Regular.ttf
94070e724d000-70e725c000 r-xp 00000000 fc:00 2527 /system/lib64/libmediautils.so
94170e725c000-70e7279000 ---p 00000000 00:00 0
94270e7279000-70e727b000 r--p 0001e000 fc:00 2527 /system/lib64/libmediautils.so
94370e727b000-70e727c000 rw-p 00020000 fc:00 2527 /system/lib64/libmediautils.so
94470e727d000-70e7283000 r--s 00000000 fc:00 136 /system/fonts/NotoSansMiao-Regular.otf
94570e7283000-70e74d2000 r-xp 00000000 fc:00 2349 /system/lib64/libicui18n.so
94670e74d2000-70e74e6000 ---p 00000000 00:00 0
94770e74e6000-70e74fa000 r--p 0025c000 fc:00 2349 /system/lib64/libicui18n.so
94870e74fa000-70e74fb000 rw-p 00270000 fc:00 2349 /system/lib64/libicui18n.so
94970e74fc000-70e74ff000 r--s 00000000 103:1d 1474562 /data/resource-cache/vendor@overlay@framework-res__auto_generated_rro.apk@idmap
95070e74ff000-70e750c000 r--s 00000000 fc:00 126 /system/fonts/NotoSansSyriacWestern-Regular.ttf
95170e750c000-70e751b000 r-xp 00000000 fc:00 2466 /system/lib64/libmediaextractor.so
95270e751b000-70e753a000 ---p 00000000 00:00 0
95370e753a000-70e753b000 r--p 0000f000 fc:00 2466 /system/lib64/libmediaextractor.so
95470e753b000-70e753c000 rw-p 00010000 fc:00 2466 /system/lib64/libmediaextractor.so
95570e753d000-70e7540000 r--s 00000000 fc:00 107 /system/fonts/NotoSansPauCinHau-Regular.otf
95670e7540000-70e7593000 r-xp 00000000 fc:00 2363 /system/lib64/libandroidfw.so
95770e7593000-70e75ac000 ---p 00000000 00:00 0
95870e75ac000-70e75af000 r--p 0005d000 fc:00 2363 /system/lib64/libandroidfw.so
95970e75af000-70e75b0000 rw-p 00060000 fc:00 2363 /system/lib64/libandroidfw.so
96070e75b0000-70e75b2000 r--s 00000000 fc:00 1083 /system/usr/hyphen-data/hyph-be.hyb
96170e75b2000-70e75cd000 r--s 00000000 fc:00 270 /system/fonts/NotoSansBengaliUI-Regular.ttf
96270e75cd000-70e75cf000 r-xp 00000000 fc:00 2701 /system/lib64/libmemtrack.so
96370e75cf000-70e75ec000 ---p 00000000 00:00 0
96470e75ec000-70e75ed000 r--p 0000f000 fc:00 2701 /system/lib64/libmemtrack.so
96570e75ed000-70e75ee000 rw-p 00010000 fc:00 2701 /system/lib64/libmemtrack.so
96670e75ee000-70e75f0000 r--s 00000000 fc:00 209 /system/fonts/NotoSansSoraSompeng-Regular.otf
96770e75f0000-70e760d000 r--s 00000000 fc:00 243 /system/fonts/NotoSerifBengali-Bold.ttf
96870e760d000-70e7613000 r-xp 00000000 fc:00 2667 /system/lib64/libutilscallstack.so
96970e7613000-70e762c000 ---p 00000000 00:00 0
97070e762c000-70e762d000 r--p 0000f000 fc:00 2667 /system/lib64/libutilscallstack.so
97170e762d000-70e762e000 rw-p 00010000 fc:00 2667 /system/lib64/libutilscallstack.so
97270e762e000-70e7632000 r--s 00000000 fc:00 99 /system/fonts/NotoSansPahawhHmong-Regular.otf
97370e7632000-70e764f000 r--s 00000000 fc:00 205 /system/fonts/NotoSerifBengali-Regular.ttf
97470e764f000-70e7661000 r-xp 00000000 fc:00 2710 /system/lib64/libcutils.so
97570e7661000-70e767d000 ---p 00000000 00:00 0
97670e767d000-70e767f000 r--p 0001e000 fc:00 2710 /system/lib64/libcutils.so
97770e767f000-70e7680000 rw-p 00020000 fc:00 2710 /system/lib64/libcutils.so
97870e7680000-70e7683000 r--s 00000000 fc:00 257 /system/fonts/NotoSansPalmyrene-Regular.otf
97970e7683000-70e7697000 r--s 00000000 fc:00 78 /system/fonts/NotoSansKannadaUI-Bold.ttf
98070e7697000-70e769a000 r-xp 00000000 fc:00 2362 /system/lib64/libstagefright_http_support.so
98170e769a000-70e76b6000 ---p 00000000 00:00 0
98270e76b6000-70e76b7000 r--p 0000f000 fc:00 2362 /system/lib64/libstagefright_http_support.so
98370e76b7000-70e76b8000 rw-p 00010000 fc:00 2362 /system/lib64/libstagefright_http_support.so
98470e76b8000-70e76b9000 rw-p 00000000 00:00 0 [anon:linker_alloc_lob]
98570e76b9000-70e76be000 r--s 00000000 fc:00 165 /system/fonts/NotoSansMeroitic-Regular.otf
98670e76be000-70e76cb000 r--s 00000000 fc:00 112 /system/fonts/NotoSansSyriacEastern-Regular.ttf
98770e76cb000-70e76de000 r-xp 00000000 fc:00 2343 /system/lib64/libsensor.so
98870e76de000-70e76f5000 ---p 00000000 00:00 0
98970e76f5000-70e76f8000 r--p 0001d000 fc:00 2343 /system/lib64/libsensor.so
99070e76f8000-70e76f9000 rw-p 00020000 fc:00 2343 /system/lib64/libsensor.so
99170e76f9000-70e76fc000 r--s 00000000 fc:00 157 /system/fonts/NotoSansOldPermic-Regular.otf
99270e76fc000-70e7708000 r--s 00000000 fc:00 189 /system/fonts/NotoSansSyriacEstrangela-Regular.ttf
99370e7708000-70e771d000 r-xp 00000000 fc:00 2339 /system/lib64/android.hidl.token@1.0.so
99470e771d000-70e7735000 ---p 00000000 00:00 0
99570e7735000-70e7737000 r--p 0001e000 fc:00 2339 /system/lib64/android.hidl.token@1.0.so
99670e7737000-70e7738000 rw-p 00020000 fc:00 2339 /system/lib64/android.hidl.token@1.0.so
99770e7738000-70e7739000 r--p 00000000 00:00 0 [anon:linker_alloc]
99870e7739000-70e773b000 r--s 00000000 fc:00 267 /system/fonts/NotoSansOldNorthArabian-Regular.otf
99970e773b000-70e7740000 r--s 00000000 fc:00 208 /system/fonts/NotoSansManichaean-Regular.otf
100070e7740000-70e775c000 r--s 00000000 fc:00 118 /system/fonts/NotoSansGujaratiUI-Bold.ttf
100170e775c000-70e7767000 r-xp 00000000 fc:00 2525 /system/lib64/libappfuse.so
100270e7767000-70e777b000 ---p 00000000 00:00 0
100370e777b000-70e777c000 r--p 0000f000 fc:00 2525 /system/lib64/libappfuse.so
100470e777c000-70e777d000 rw-p 00010000 fc:00 2525 /system/lib64/libappfuse.so
100570e777e000-70e7795000 r--s 00000000 fc:00 250 /system/fonts/NotoSerifKannada-Bold.ttf
100670e7795000-70e7798000 r-xp 00000000 fc:00 2413 /system/lib64/libpackagelistparser.so
100770e7798000-70e77b4000 ---p 00000000 00:00 0
100870e77b4000-70e77b5000 r--p 0000f000 fc:00 2413 /system/lib64/libpackagelistparser.so
100970e77b5000-70e77b6000 rw-p 00010000 fc:00 2413 /system/lib64/libpackagelistparser.so
101070e77b6000-70e77b8000 r--s 00000000 fc:00 147 /system/fonts/NotoSansNabataean-Regular.otf
101170e77b8000-70e77ba000 r--s 00000000 fc:00 146 /system/fonts/NotoSansMultani-Regular.otf
101270e77ba000-70e77c1000 r--s 00000000 fc:00 214 /system/fonts/NotoSansPhagsPa-Regular.ttf
101370e77c1000-70e77de000 r--s 00000000 fc:00 90 /system/fonts/NotoSansGujaratiUI-Regular.ttf
101470e77de000-70e77e0000 r-xp 00000000 fc:00 2430 /system/lib64/libdl.so
101570e77e0000-70e77fd000 ---p 00000000 00:00 0
101670e77fd000-70e77fe000 r--p 0000f000 fc:00 2430 /system/lib64/libdl.so
101770e77fe000-70e77ff000 r--p 00000000 00:00 0 [anon:.bss]
101870e7800000-70e7809000 r--s 00000000 fc:00 258 /system/fonts/NotoSansSymbols-Regular-Subsetted2.ttf
101970e7809000-70e7857000 r-xp 00000000 fc:00 2560 /system/lib64/libjpeg.so
102070e7857000-70e7868000 ---p 00000000 00:00 0
102170e7868000-70e7869000 r--p 0004f000 fc:00 2560 /system/lib64/libjpeg.so
102270e7869000-70e786a000 rw-p 00050000 fc:00 2560 /system/lib64/libjpeg.so
102370e786a000-70e7887000 r--s 00000000 fc:00 237 /system/fonts/NotoSansGujarati-Bold.ttf
102470e7887000-70e788a000 r-xp 00000000 fc:00 2608 /system/lib64/libnetd_client.so
102570e788a000-70e78a6000 ---p 00000000 00:00 0
102670e78a6000-70e78a7000 r--p 0000f000 fc:00 2608 /system/lib64/libnetd_client.so
102770e78a7000-70e78a8000 rw-p 00010000 fc:00 2608 /system/lib64/libnetd_client.so
102870e78a8000-70e78aa000 r--s 00000000 fc:00 290 /system/fonts/NotoSansMro-Regular.otf
102970e78aa000-70e78b9000 r--s 00000000 fc:00 84 /system/fonts/NotoSansLinearB-Regular.ttf
103070e78b9000-70e78d7000 r--s 00000000 fc:00 287 /system/fonts/NotoSansGujarati-Regular.ttf
103170e78d7000-70e78d8000 r-xp 00000000 fc:00 2651 /system/lib64/libvndksupport.so
103270e78d8000-70e78f6000 ---p 00000000 00:00 0
103370e78f6000-70e78f7000 r--p 0000f000 fc:00 2651 /system/lib64/libvndksupport.so
103470e78f7000-70e78f8000 rw-p 00010000 fc:00 2651 /system/lib64/libvndksupport.so
103570e78f9000-70e78fc000 r--s 00000000 fc:00 178 /system/fonts/NotoSansTaiLe-Regular.ttf
103670e78fc000-70e7900000 r--s 00000000 fc:00 163 /system/fonts/NotoSansTifinagh-Regular.ttf
103770e7900000-70e7906000 r-xp 00000000 fc:00 2659 /system/lib64/libnativeloader.so
103870e7906000-70e791f000 ---p 00000000 00:00 0
103970e791f000-70e7920000 r--p 0000f000 fc:00 2659 /system/lib64/libnativeloader.so
104070e7920000-70e7921000 rw-p 00010000 fc:00 2659 /system/lib64/libnativeloader.so
104170e7921000-70e7923000 r--s 00000000 fc:00 268 /system/fonts/NotoSansHatran-Regular.otf
104270e7923000-70e7927000 r--s 00000000 fc:00 195 /system/fonts/NotoSansTaiViet-Regular.ttf
104370e7927000-70e7945000 r--s 00000000 fc:00 139 /system/fonts/NotoSansDevanagariUI-Bold.ttf
104470e7945000-70e79a3000 r-xp 00000000 fc:00 2450 /system/lib64/libharfbuzz_ng.so
104570e79a3000-70e79b3000 ---p 00000000 00:00 0
104670e79b3000-70e79b5000 r--p 0005e000 fc:00 2450 /system/lib64/libharfbuzz_ng.so
104770e79b5000-70e79b6000 rw-p 00060000 fc:00 2450 /system/lib64/libharfbuzz_ng.so
104870e79b6000-70e79c5000 r--s 00000000 fc:00 111 /system/fonts/NotoSansKaithi-Regular.ttf
104970e79c5000-70e7a92000 r-xp 00000000 fc:00 2332 /system/lib64/libc++.so
105070e7a92000-70e7aae000 ---p 00000000 00:00 0
105170e7aae000-70e7ab8000 r--p 000d6000 fc:00 2332 /system/lib64/libc++.so
105270e7ab8000-70e7ab9000 rw-p 000e0000 fc:00 2332 /system/lib64/libc++.so
105370e7ab9000-70e7abc000 rw-p 00000000 00:00 0 [anon:.bss]
105470e7abc000-70e7abe000 r--s 00000000 fc:00 73 /system/fonts/NotoSansBassaVah-Regular.otf
105570e7abe000-70e7ac8000 r--s 00000000 fc:00 254 /system/fonts/NotoSansJavanese-Regular.ttf
105670e7ac8000-70e7acb000 r-xp 00000000 fc:00 2660 /system/lib64/libnativebridge.so
105770e7acb000-70e7ae7000 ---p 00000000 00:00 0
105870e7ae7000-70e7ae8000 r--p 0000f000 fc:00 2660 /system/lib64/libnativebridge.so
105970e7ae8000-70e7ae9000 rw-p 00010000 fc:00 2660 /system/lib64/libnativebridge.so
106070e7ae9000-70e7aee000 r--s 00000000 fc:00 158 /system/fonts/NotoSansSaurashtra-Regular.ttf
106170e7aee000-70e7b0f000 r--s 00000000 fc:00 82 /system/fonts/NotoSansDevanagari-Bold.ttf
106270e7b0f000-70e7b2e000 r-xp 00000000 fc:00 2612 /system/lib64/libpcre2.so
106370e7b2e000-70e7b3e000 ---p 00000000 00:00 0
106470e7b3e000-70e7b3f000 r--p 0001f000 fc:00 2612 /system/lib64/libpcre2.so
106570e7b3f000-70e7b40000 rw-p 00020000 fc:00 2612 /system/lib64/libpcre2.so
106670e7b40000-70e7bcc000 r-xp 00000000 fc:00 2975 /system/lib64/libgui.so
106770e7bcc000-70e7be2000 ---p 00000000 00:00 0
106870e7be2000-70e7bf5000 r--p 0008d000 fc:00 2975 /system/lib64/libgui.so
106970e7bf5000-70e7bf6000 rw-p 000a0000 fc:00 2975 /system/lib64/libgui.so
107070e7bf6000-70e7bf7000 r--p 00000000 00:00 0 [anon:linker_alloc]
107170e7bf7000-70e7bf9000 r--s 00000000 fc:00 228 /system/fonts/NotoSansUgaritic-Regular.ttf
107270e7bf9000-70e7c08000 r--s 00000000 fc:00 89 /system/fonts/NotoSansCherokee-Regular.ttf
107370e7c08000-70e7dea000 r-xp 00000000 fc:00 2441 /system/lib64/libandroid_runtime.so
107470e7dea000-70e7e04000 ---p 00000000 00:00 0
107570e7e04000-70e7e23000 r--p 001e1000 fc:00 2441 /system/lib64/libandroid_runtime.so
107670e7e23000-70e7e24000 rw-p 00200000 fc:00 2441 /system/lib64/libandroid_runtime.so
107770e7e24000-70e7e28000 rw-p 00000000 00:00 0 [anon:.bss]
107870e7e29000-70e7e66000 r--s 00000000 fc:00 74 /system/fonts/NotoSerif-Bold.ttf
107970e7e66000-70e7ed0000 r-xp 00000000 fc:00 2547 /system/lib64/libclang_rt.ubsan_standalone-aarch64-android.so
108070e7ed0000-70e7edf000 ---p 00000000 00:00 0
108170e7edf000-70e7ee1000 r--p 00069000 fc:00 2547 /system/lib64/libclang_rt.ubsan_standalone-aarch64-android.so
108270e7ee1000-70e7ee4000 rw-p 0006b000 fc:00 2547 /system/lib64/libclang_rt.ubsan_standalone-aarch64-android.so
108370e7ee4000-70e89f6000 rw-p 00000000 00:00 0 [anon:.bss]
108470e89f6000-70e89fa000 r--s 00000000 fc:00 127 /system/fonts/NotoSansSylotiNagri-Regular.ttf
108570e89fa000-70e8a06000 r--s 00000000 fc:00 93 /system/fonts/NotoSansCanadianAboriginal-Regular.ttf
108670e8a06000-70e8a1b000 r-xp 00000000 fc:00 2460 /system/lib64/android.hardware.graphics.allocator@2.0.so
108770e8a1b000-70e8a33000 ---p 00000000 00:00 0
108870e8a33000-70e8a35000 r--p 0001e000 fc:00 2460 /system/lib64/android.hardware.graphics.allocator@2.0.so
108970e8a35000-70e8a36000 rw-p 00020000 fc:00 2460 /system/lib64/android.hardware.graphics.allocator@2.0.so
109070e8a36000-70e8a55000 r--s 00000000 fc:00 145 /system/fonts/NotoSansDevanagariUI-Regular.ttf
109170e8a55000-70e8a61000 r-xp 00000000 fc:00 2540 /system/lib64/libstagefright_xmlparser.so
109270e8a61000-70e8a74000 ---p 00000000 00:00 0
109370e8a74000-70e8a75000 r--p 0000f000 fc:00 2540 /system/lib64/libstagefright_xmlparser.so
109470e8a75000-70e8a76000 rw-p 00010000 fc:00 2540 /system/lib64/libstagefright_xmlparser.so
109570e8a76000-70e8a78000 r--s 00000000 fc:00 293 /system/fonts/NotoSansTagbanwa-Regular.ttf
109670e8a78000-70e8a8f000 r--s 00000000 fc:00 161 /system/fonts/NotoSerifKannada-Regular.ttf
109770e8a8f000-70e8b23000 r-xp 00000000 fc:00 2633 /system/lib64/libaudioclient.so
109870e8b23000-70e8b37000 ---p 00000000 00:00 0
109970e8b37000-70e8b49000 r--p 0009e000 fc:00 2633 /system/lib64/libaudioclient.so
110070e8b49000-70e8b55000 rw-p 000b0000 fc:00 2633 /system/lib64/libaudioclient.so
110170e8b55000-70e8b9f000 r--s 00000000 fc:00 83 /system/fonts/RobotoCondensed-Light.ttf
110270e8b9f000-70e8ba1000 r-xp 00000000 fc:00 2520 /system/lib64/libhardware_legacy.so
110370e8ba1000-70e8bbe000 ---p 00000000 00:00 0
110470e8bbe000-70e8bbf000 r--p 0000f000 fc:00 2520 /system/lib64/libhardware_legacy.so
110570e8bbf000-70e8bc0000 rw-p 00010000 fc:00 2520 /system/lib64/libhardware_legacy.so
110670e8bc0000-70e8be0000 r-xp 00000000 fc:00 2410 /system/lib64/android.hidl.memory@1.0.so
110770e8be0000-70e8bfa000 ---p 00000000 00:00 0
110870e8bfa000-70e8bfd000 r--p 0002d000 fc:00 2410 /system/lib64/android.hidl.memory@1.0.so
110970e8bfd000-70e8bfe000 rw-p 00030000 fc:00 2410 /system/lib64/android.hidl.memory@1.0.so
111070e8bfe000-70e8bff000 r--p 00000000 00:00 0 [anon:linker_alloc]
111170e8bff000-70e8c02000 r--s 00000000 fc:00 273 /system/fonts/NotoSansSundanese-Regular.ttf
111270e8c02000-70e8c0f000 r--s 00000000 fc:00 115 /system/fonts/NotoSansAdlam-Regular.ttf
111370e8c0f000-70e8c18000 r-xp 00000000 fc:00 2350 /system/lib64/libnetdutils.so
111470e8c18000-70e8c2e000 ---p 00000000 00:00 0
111570e8c2e000-70e8c2f000 r--p 0000f000 fc:00 2350 /system/lib64/libnetdutils.so
111670e8c2f000-70e8c30000 rw-p 00010000 fc:00 2350 /system/lib64/libnetdutils.so
111770e8c30000-70e8c44000 r--s 00000000 fc:00 283 /system/fonts/NotoSansKannadaUI-Regular.ttf
111870e8c44000-70e8c45000 r-xp 00000000 fc:00 2926 /system/lib64/libhidlallocatorutils.so
111970e8c45000-70e8c63000 ---p 00000000 00:00 0
112070e8c63000-70e8c64000 r--p 0000f000 fc:00 2926 /system/lib64/libhidlallocatorutils.so
112170e8c64000-70e8c65000 rw-p 00010000 fc:00 2926 /system/lib64/libhidlallocatorutils.so
112270e8c65000-70e8c67000 r--s 00000000 fc:00 65 /system/fonts/NotoSansTagalog-Regular.ttf
112370e8c67000-70e8c70000 r--s 00000000 fc:00 294 /system/fonts/NotoSansChakma-Regular.ttf
112470e8c70000-70e8c92000 r--s 00000000 fc:00 116 /system/fonts/NotoSansDevanagari-Regular.ttf
112570e8c92000-70e8c94000 r-xp 00000000 fc:00 2501 /system/lib64/libsync.so
112670e8c94000-70e8cb1000 ---p 00000000 00:00 0
112770e8cb1000-70e8cb2000 r--p 0000f000 fc:00 2501 /system/lib64/libsync.so
112870e8cb2000-70e8cb3000 rw-p 00010000 fc:00 2501 /system/lib64/libsync.so
112970e8cb3000-70e8cc6000 r--s 00000000 fc:00 196 /system/fonts/NotoSerifSinhala-Regular.otf
113070e8cc6000-70e8d5c000 r-xp 00000000 fc:00 2403 /system/lib64/libmedia.so
113170e8d5c000-70e8d70000 ---p 00000000 00:00 0
113270e8d70000-70e8d88000 r--p 00098000 fc:00 2403 /system/lib64/libmedia.so
113370e8d88000-70e8d95000 rw-p 000b0000 fc:00 2403 /system/lib64/libmedia.so
113470e8d95000-70e8d96000 r--p 00000000 00:00 0 [anon:atexit handlers]
113570e8d96000-70e8d99000 r--s 00000000 fc:00 247 /system/fonts/NotoSansSamaritan-Regular.ttf
113670e8d99000-70e8dad000 r--s 00000000 fc:00 108 /system/fonts/NotoSansKannada-Bold.ttf
113770e8dad000-70e8dcd000 r--s 00000000 fc:00 303 /system/fonts/NotoSerifEthiopic-Bold.otf
113870e8dcd000-70e8de5000 r-xp 00000000 fc:00 2954 /system/lib64/libGLESv2.so
113970e8de5000-70e8dfc000 ---p 00000000 00:00 0
114070e8dfc000-70e8dfd000 r--p 0001f000 fc:00 2954 /system/lib64/libGLESv2.so
114170e8dfd000-70e8dfe000 rw-p 00020000 fc:00 2954 /system/lib64/libGLESv2.so
114270e8dfe000-70e8e06000 r--s 00000000 fc:00 265 /system/fonts/NotoSansBalinese-Regular.ttf
114370e8e06000-70e8e0e000 r--s 00000000 fc:00 219 /system/fonts/NotoSansLaoUI-Bold.ttf
114470e8e0e000-70e8e12000 r-xp 00000000 fc:00 2617 /system/lib64/libdebuggerd_client.so
114570e8e12000-70e8e2d000 ---p 00000000 00:00 0
114670e8e2d000-70e8e2e000 r--p 0000f000 fc:00 2617 /system/lib64/libdebuggerd_client.so
114770e8e2e000-70e8e2f000 rw-p 00010000 fc:00 2617 /system/lib64/libdebuggerd_client.so
114870e8e2f000-70e8e4b000 r--s 00000000 fc:00 211 /system/fonts/NotoSerifEthiopic-Regular.otf
114970e8e4b000-70e8e5e000 r-xp 00000000 fc:00 2484 /system/lib64/android.hardware.memtrack@1.0.so
115070e8e5e000-70e8e78000 ---p 00000000 00:00 0
115170e8e78000-70e8e7a000 r--p 0001e000 fc:00 2484 /system/lib64/android.hardware.memtrack@1.0.so
115270e8e7a000-70e8e7b000 rw-p 00020000 fc:00 2484 /system/lib64/android.hardware.memtrack@1.0.so
115370e8e7b000-70e8e7d000 r--s 00000000 fc:00 261 /system/fonts/NotoSansShavian-Regular.ttf
115470e8e7d000-70e8e80000 r--s 00000000 fc:00 204 /system/fonts/NotoSansRunic-Regular.ttf
115570e8e80000-70e8ea1000 r-xp 00000000 fc:00 2512 /system/lib64/android.hardware.configstore@1.0.so
115670e8ea1000-70e8ebb000 ---p 00000000 00:00 0
115770e8ebb000-70e8ebe000 r--p 0002d000 fc:00 2512 /system/lib64/android.hardware.configstore@1.0.so
115870e8ebe000-70e8ebf000 rw-p 00030000 fc:00 2512 /system/lib64/android.hardware.configstore@1.0.so
115970e8ebf000-70e8ee3000 r--s 00000000 fc:00 226 /system/fonts/NotoSansEthiopic-Bold.ttf
116070e8ee3000-70e8f1a000 r-xp 00000000 fc:00 2337 /system/lib64/libm.so
116170e8f1a000-70e8f32000 ---p 00000000 00:00 0
116270e8f32000-70e8f33000 r--p 0003f000 fc:00 2337 /system/lib64/libm.so
116370e8f33000-70e8f34000 rw-p 00040000 fc:00 2337 /system/lib64/libm.so
116470e8f34000-70e8f36000 r--s 00000000 fc:00 133 /system/fonts/NotoSansRejang-Regular.ttf
116570e8f36000-70e8f38000 r--s 00000000 fc:00 69 /system/fonts/NotoSansPhoenician-Regular.ttf
116670e8f38000-70e8f40000 r--s 00000000 fc:00 245 /system/fonts/NotoSansLaoUI-Regular.ttf
116770e8f40000-70e8f45000 r-xp 00000000 fc:00 2341 /system/lib64/libstagefright_codecbase.so
116870e8f45000-70e8f5f000 ---p 00000000 00:00 0
116970e8f5f000-70e8f60000 r--p 0000f000 fc:00 2341 /system/lib64/libstagefright_codecbase.so
117070e8f60000-70e8f61000 rw-p 00010000 fc:00 2341 /system/lib64/libstagefright_codecbase.so
117170e8f61000-70e8f62000 r--p 00000000 00:00 0 [anon:atexit handlers]
117270e8f62000-70e8f66000 r--s 00000000 fc:00 225 /system/fonts/NotoSansOldPersian-Regular.ttf
117370e8f66000-70e8f89000 r--s 00000000 fc:00 167 /system/fonts/NotoSansEthiopic-Regular.ttf
117470e8f89000-70e8f92000 r-xp 00000000 fc:00 2515 /system/lib64/libGLESv1_CM.so
117570e8f92000-70e8fa8000 ---p 00000000 00:00 0
117670e8fa8000-70e8fa9000 r--p 0000f000 fc:00 2515 /system/lib64/libGLESv1_CM.so
117770e8fa9000-70e8faa000 rw-p 00010000 fc:00 2515 /system/lib64/libGLESv1_CM.so
117870e8faa000-70e8fad000 r--s 00000000 fc:00 206 /system/fonts/NotoSansOsage-Regular.ttf
117970e8fad000-70e8fb5000 r--s 00000000 fc:00 121 /system/fonts/NotoSerifLao-Bold.ttf
118070e8fb5000-70e8fd3000 r--s 00000000 fc:00 68 /system/fonts/NotoNaskhArabicUI-Bold.ttf
118170e8fd3000-70e9010000 r-xp 00000000 fc:00 2600 /system/lib64/android.hardware.cas@1.0.so
118270e9010000-70e9026000 ---p 00000000 00:00 0
118370e9026000-70e902c000 r--p 0004a000 fc:00 2600 /system/lib64/android.hardware.cas@1.0.so
118470e902c000-70e902d000 rw-p 00050000 fc:00 2600 /system/lib64/android.hardware.cas@1.0.so
118570e902d000-70e902e000 r--s 00000000 00:05 31475 /dev/ashmem/5c7d41a6-003d-45a5-9e3b-2d34c5829a2d (deleted)
118670e902e000-70e9043000 r--s 00000000 fc:00 120 /system/fonts/NotoSansKannada-Regular.ttf
118770e9043000-70e9067000 r-xp 00000000 fc:00 2729 /system/lib64/libexpat.so
118870e9067000-70e9081000 ---p 00000000 00:00 0
118970e9081000-70e9083000 r--p 0002e000 fc:00 2729 /system/lib64/libexpat.so
119070e9083000-70e9084000 rw-p 00030000 fc:00 2729 /system/lib64/libexpat.so
119170e9084000-70e9086000 r--s 00000000 fc:00 155 /system/fonts/NotoSansOsmanya-Regular.ttf
119270e9086000-70e90c3000 r--s 00000000 fc:00 91 /system/fonts/NotoSerif-Regular.ttf
119370e90c3000-70e91ce000 r-xp 00000000 fc:00 2647 /system/lib64/libcrypto.so
119470e91ce000-70e91e2000 ---p 00000000 00:00 0
119570e91e2000-70e91f3000 r--p 0010f000 fc:00 2647 /system/lib64/libcrypto.so
119670e91f3000-70e91f4000 rw-p 00120000 fc:00 2647 /system/lib64/libcrypto.so
119770e91f4000-70e91f5000 rw-p 00000000 00:00 0 [anon:.bss]
119870e91f5000-70e91fa000 r--s 00000000 fc:00 149 /system/fonts/NotoSansNKo-Regular.ttf
119970e91fa000-70e9202000 r--s 00000000 fc:00 198 /system/fonts/NotoSerifLao-Regular.ttf
120070e9202000-70e921b000 r-xp 00000000 fc:00 2682 /system/lib64/libmedia_helper.so
120170e921b000-70e922d000 ---p 00000000 00:00 0
120270e922d000-70e9230000 r--p 0001d000 fc:00 2682 /system/lib64/libmedia_helper.so
120370e9230000-70e9231000 rw-p 00020000 fc:00 2682 /system/lib64/libmedia_helper.so
120470e9231000-70e924a000 r--s 00000000 fc:00 232 /system/fonts/NotoSansBengali-Bold.ttf
120570e924a000-70e9256000 r-xp 00000000 fc:00 2467 /system/lib64/libsoundtrigger.so
120670e9256000-70e9272000 ---p 00000000 00:00 0
120770e9272000-70e9276000 r--p 0000c000 fc:00 2467 /system/lib64/libsoundtrigger.so
120870e9276000-70e9277000 rw-p 00010000 fc:00 2467 /system/lib64/libsoundtrigger.so
120970e9277000-70e9278000 r--s 00000000 fc:01 1177 /vendor/overlay/Pixel/PixelThemeOverlay.apk
121070e9278000-70e927c000 r--s 00000000 fc:00 215 /system/fonts/NotoSansNewTaiLue-Regular.ttf
121170e927c000-70e929a000 r--s 00000000 fc:00 235 /system/fonts/NotoNaskhArabicUI-Regular.ttf
121270e929a000-70e929b000 r-xp 00000000 fc:00 2375 /system/lib64/android.hardware.graphics.common@1.1.so
121370e929b000-70e92b9000 ---p 00000000 00:00 0
121470e92b9000-70e92ba000 r--p 0000f000 fc:00 2375 /system/lib64/android.hardware.graphics.common@1.1.so
121570e92ba000-70e92bb000 rw-p 00010000 fc:00 2375 /system/lib64/android.hardware.graphics.common@1.1.so
121670e92bb000-70e92da000 r--s 00000000 fc:00 281 /system/fonts/GoogleSans-BoldItalic.ttf
121770e92da000-70e9302000 r-xp 00000000 fc:00 2529 /system/lib64/libinput.so
121870e9302000-70e931b000 ---p 00000000 00:00 0
121970e931b000-70e9322000 r--p 00029000 fc:00 2529 /system/lib64/libinput.so
122070e9322000-70e9323000 rw-p 00030000 fc:00 2529 /system/lib64/libinput.so
122170e9323000-70e9340000 r--s 00000000 fc:00 130 /system/fonts/NotoNaskhArabic-Bold.ttf
122270e9340000-70e934b000 r-xp 00000000 fc:00 2451 /system/lib64/libbpf.so
122370e934b000-70e935f000 ---p 00000000 00:00 0
122470e935f000-70e9360000 r--p 0000f000 fc:00 2451 /system/lib64/libbpf.so
122570e9360000-70e9361000 rw-p 00010000 fc:00 2451 /system/lib64/libbpf.so
122670e9361000-70e9367000 r--s 00000000 fc:00 96 /system/fonts/NotoSansKharoshthi-Regular.ttf
122770e9367000-70e9385000 r--s 00000000 fc:00 151 /system/fonts/GoogleSans-Bold.ttf
122870e9385000-70e93b8000 r-xp 00000000 fc:00 2494 /system/lib64/libpng.so
122970e93b8000-70e93d4000 ---p 00000000 00:00 0
123070e93d4000-70e93d5000 r--p 0003f000 fc:00 2494 /system/lib64/libpng.so
123170e93d5000-70e93d6000 rw-p 00040000 fc:00 2494 /system/lib64/libpng.so
123270e93d6000-70e93d7000 r--s 00004000 fc:01 1177 /vendor/overlay/Pixel/PixelThemeOverlay.apk
123370e93d7000-70e93d9000 r--s 00000000 fc:00 295 /system/fonts/NotoSansOldTurkic-Regular.ttf
123470e93d9000-70e93e5000 r--s 00000000 fc:00 86 /system/fonts/NotoSerifKhmer-Bold.otf
123570e93e5000-70e9404000 r--s 00000000 fc:00 240 /system/fonts/GoogleSans-MediumItalic.ttf
123670e9404000-70e9409000 r-xp 00000000 fc:00 2404 /system/lib64/libhidlmemory.so
123770e9409000-70e9423000 ---p 00000000 00:00 0
123870e9423000-70e9424000 r--p 0000f000 fc:00 2404 /system/lib64/libhidlmemory.so
123970e9424000-70e9425000 rw-p 00010000 fc:00 2404 /system/lib64/libhidlmemory.so
124070e9425000-70e943e000 r--s 00000000 fc:00 185 /system/fonts/NotoSansBengali-Regular.ttf
124170e943e000-70e945c000 r--s 00000000 fc:00 129 /system/fonts/GoogleSans-Medium.ttf
124270e945c000-70e960c000 r-xp 00000000 fc:00 2398 /system/lib64/libstagefright.so
124370e960c000-70e9625000 ---p 00000000 00:00 0
124470e9625000-70e9638000 r--p 001bd000 fc:00 2398 /system/lib64/libstagefright.so
124570e9638000-70e966c000 rw-p 001d0000 fc:00 2398 /system/lib64/libstagefright.so
124670e966c000-70e966d000 rw-p 00000000 00:00 0 [anon:.bss]
124770e966d000-70e966e000 r--s 00000000 103:1d 1474566 /data/resource-cache/vendor@overlay@Pixel@PixelThemeOverlay.apk@idmap
124870e966e000-70e9672000 r--s 00000000 fc:00 241 /system/fonts/NotoSansMeeteiMayek-Regular.ttf
124970e9672000-70e9680000 r--s 00000000 fc:00 150 /system/fonts/NotoSansMalayalamUI-Bold.ttf
125070e9680000-70e96a7000 r-xp 00000000 fc:00 2365 /system/lib64/libhwbinder.so
125170e96a7000-70e96bd000 ---p 00000000 00:00 0
125270e96bd000-70e96bf000 r--p 0002e000 fc:00 2365 /system/lib64/libhwbinder.so
125370e96bf000-70e96c0000 rw-p 00030000 fc:00 2365 /system/lib64/libhwbinder.so
125470e96c0000-70e96c1000 r--s 00088000 103:1d 1736830 /data/app/com.google.sample.tunnel-HGGRU03Gu1Mwkf_-RnFmvw==/base.apk
125570e96c1000-70e96cb000 r--s 00000000 fc:00 94 /system/fonts/NotoSansKhmerUI-Regular.ttf
125670e96cb000-70e96d9000 r--s 00000000 fc:00 275 /system/fonts/NotoSansMalayalamUI-Regular.ttf
125770e96d9000-70e96dd000 r-xp 00000000 fc:00 2386 /system/lib64/libusbhost.so
125870e96dd000-70e96f8000 ---p 00000000 00:00 0
125970e96f8000-70e96f9000 r--p 0000f000 fc:00 2386 /system/lib64/libusbhost.so
126070e96f9000-70e96fa000 rw-p 00010000 fc:00 2386 /system/lib64/libusbhost.so
126170e96fa000-70e96fb000 r--p 00000000 00:05 10266154 /dev/ashmem/dalvik-classes.dex extracted in memory from /data/app/com.google.sample.tunnel-HGGRU03Gu1Mwkf_-RnFmvw==/base.apk (deleted)
126270e96fb000-70e9701000 r--s 00000000 fc:00 280 /system/fonts/NotoSansCoptic-Regular.ttf
126370e9701000-70e9720000 r-xp 00000000 fc:00 2490 /system/lib64/libstagefright_bufferqueue_helper.so
126470e9720000-70e973b000 ---p 00000000 00:00 0
126570e973b000-70e973e000 r--p 0002d000 fc:00 2490 /system/lib64/libstagefright_bufferqueue_helper.so
126670e973e000-70e9740000 rw-p 00030000 fc:00 2490 /system/lib64/libstagefright_bufferqueue_helper.so
126770e9740000-70e9742000 r--s 00000000 fc:00 141 /system/fonts/NotoSansOldSouthArabian-Regular.ttf
126870e9742000-70e974c000 r--s 00000000 fc:00 229 /system/fonts/NotoSerifKhmer-Regular.otf
126970e974c000-70e9759000 r--s 00000000 fc:00 260 /system/fonts/NotoSerifMalayalam-Bold.ttf
127070e9759000-70e97c7000 r-xp 00000000 fc:00 2428 /system/lib64/libstagefright_omx.so
127170e97c7000-70e97dc000 ---p 00000000 00:00 0
127270e97dc000-70e97e6000 r--p 00076000 fc:00 2428 /system/lib64/libstagefright_omx.so
127370e97e6000-70e97ed000 rw-p 00080000 fc:00 2428 /system/lib64/libstagefright_omx.so
127470e97ed000-70e97fa000 r--s 00000000 fc:00 66 /system/fonts/NotoSerifMalayalam-Regular.ttf
127570e97fa000-70e9819000 r--s 00000000 fc:00 183 /system/fonts/GoogleSans-Italic.ttf
127670e9819000-70e9856000 r-xp 00000000 fc:00 2434 /system/lib64/libprotobuf-cpp-lite.so
127770e9856000-70e9867000 ---p 00000000 00:00 0
127870e9867000-70e9869000 r--p 0003e000 fc:00 2434 /system/lib64/libprotobuf-cpp-lite.so
127970e9869000-70e986a000 rw-p 00040000 fc:00 2434 /system/lib64/libprotobuf-cpp-lite.so
128070e986a000-70e9873000 r--s 00000000 fc:00 134 /system/fonts/NotoSansKhmerUI-Bold.ttf
128170e9873000-70e9891000 r--s 00000000 fc:00 81 /system/fonts/GoogleSans-Regular.ttf
128270e9891000-70e989e000 r-xp 00000000 fc:00 2377 /system/lib64/libmediametrics.so
128370e989e000-70e98ae000 ---p 00000000 00:00 0
128470e98ae000-70e98b0000 r--p 0000e000 fc:00 2377 /system/lib64/libmediametrics.so
128570e98b0000-70e98b1000 rw-p 00010000 fc:00 2377 /system/lib64/libmediametrics.so
128670e98b1000-70e98b9000 r--s 00000000 fc:00 152 /system/fonts/NotoSansLao-Bold.ttf
128770e98b9000-70e98c7000 r--s 00000000 fc:00 279 /system/fonts/NotoSansMalayalam-Bold.ttf
128870e98c7000-70e98ca000 r-xp 00000000 fc:00 2952 /system/lib64/libETC1.so
128970e98ca000-70e98e6000 ---p 00000000 00:00 0
129070e98e6000-70e98e7000 r--p 0000f000 fc:00 2952 /system/lib64/libETC1.so
129170e98e7000-70e98e8000 rw-p 00010000 fc:00 2952 /system/lib64/libETC1.so
129270e98e8000-70e98e9000 r--s 00000000 fc:00 1121 /system/usr/hyphen-data/hyph-und-ethi.hyb
129370e98e9000-70e98ef000 r--s 00000000 fc:00 64 /system/fonts/NotoSansBrahmi-Regular.ttf
129470e98ef000-70e990f000 rw-p 00000000 00:05 10271012 /dev/ashmem/dalvik-CompilerMetadata (deleted)
129570e990f000-70e9926000 r-xp 00000000 fc:00 2526 /system/lib64/libbacktrace.so
129670e9926000-70e993e000 ---p 00000000 00:00 0
129770e993e000-70e993f000 r--p 0001f000 fc:00 2526 /system/lib64/libbacktrace.so
129870e993f000-70e9940000 rw-p 00020000 fc:00 2526 /system/lib64/libbacktrace.so
129970e9940000-70e9941000 r--s 00000000 fc:00 1129 /system/usr/hyphen-data/hyph-tk.hyb
130070e9941000-70e99a4000 r-xp 00000000 fc:00 2528 /system/lib64/libcamera_client.so
130170e99a4000-70e99bc000 ---p 00000000 00:00 0
130270e99bc000-70e99c9000 r--p 00063000 fc:00 2528 /system/lib64/libcamera_client.so
130370e99c9000-70e99d0000 rw-p 00070000 fc:00 2528 /system/lib64/libcamera_client.so
130470e99d0000-70e99d1000 r--p 00000000 00:00 0 [anon:linker_alloc]
130570e99d1000-70e99d3000 r--s 00000000 fc:00 200 /system/fonts/NotoSansOldItalic-Regular.ttf
130670e99d3000-70e99e1000 r--s 00000000 fc:00 153 /system/fonts/NotoSansMalayalam-Regular.ttf
130770e99e1000-70e9a01000 rw-p 00000000 00:05 10271011 /dev/ashmem/dalvik-CompilerMetadata (deleted)
130870e9a01000-70e9a1e000 r-xp 00000000 fc:00 2542 /system/lib64/libimg_utils.so
130970e9a1e000-70e9a39000 ---p 00000000 00:00 0
131070e9a39000-70e9a3c000 r--p 0001d000 fc:00 2542 /system/lib64/libimg_utils.so
131170e9a3c000-70e9a3f000 rw-p 00020000 fc:00 2542 /system/lib64/libimg_utils.so
131270e9a3f000-70e9a5c000 r--s 00000000 fc:00 262 /system/fonts/NotoNaskhArabic-Regular.ttf
131370e9a5c000-70e9a69000 r-xp 00000000 fc:00 2706 /system/lib64/libziparchive.so
131470e9a69000-70e9a7b000 ---p 00000000 00:00 0
131570e9a7b000-70e9a7c000 r--p 0000f000 fc:00 2706 /system/lib64/libziparchive.so
131670e9a7c000-70e9a7d000 rw-p 00010000 fc:00 2706 /system/lib64/libziparchive.so
131770e9a7d000-70e9a85000 r--s 00000000 fc:00 119 /system/fonts/NotoSansLao-Regular.ttf
131870e9a85000-70e9a8e000 r--s 00000000 fc:00 77 /system/fonts/NotoSansTamilUI-Bold.ttf
131970e9a8e000-70e9a97000 r--s 00000000 fc:00 160 /system/fonts/NotoSansTamilUI-Regular.ttf
132070e9a97000-70e9a9d000 r-xp 00000000 fc:00 2536 /system/lib64/libnativehelper.so
132170e9a9d000-70e9ab6000 ---p 00000000 00:00 0
132270e9ab6000-70e9ab7000 r--p 0000f000 fc:00 2536 /system/lib64/libnativehelper.so
132370e9ab7000-70e9ab8000 rw-p 00010000 fc:00 2536 /system/lib64/libnativehelper.so
132470e9ab8000-70e9ab9000 r--s 00000000 fc:00 1134 /system/usr/hyphen-data/hyph-te.hyb
132570e9ab9000-70e9ac2000 r--s 00000000 fc:00 246 /system/fonts/NotoSerifTamil-Bold.ttf
132670e9ac2000-70e9acb000 r--s 00000000 fc:00 302 /system/fonts/NotoSerifTamil-Regular.ttf
132770e9acb000-70e9af4000 r-xp 00000000 fc:00 2950 /system/lib64/libmemunreachable.so
132870e9af4000-70e9b09000 ---p 00000000 00:00 0
132970e9b09000-70e9b0b000 r--p 0002e000 fc:00 2950 /system/lib64/libmemunreachable.so
133070e9b0b000-70e9b0c000 rw-p 00030000 fc:00 2950 /system/lib64/libmemunreachable.so
133170e9b0c000-70e9b0d000 r--s 00000000 fc:00 1088 /system/usr/hyphen-data/hyph-ta.hyb
133270e9b0d000-70e9b0f000 r--s 00000000 fc:00 72 /system/fonts/NotoSansOlChiki-Regular.ttf
133370e9b0f000-70e9b2f000 rw-p 00000000 00:05 10271010 /dev/ashmem/dalvik-CompilerMetadata (deleted)
133470e9b2f000-70e9b4f000 r--s 00000000 00:10 16633 /dev/__properties__/u:object_r:persist_debug_prop:s0
133570e9b4f000-70e9b65000 r-xp 00000000 fc:00 2920 /system/lib64/android.hardware.cas.native@1.0.so
133670e9b65000-70e9b7b000 ---p 00000000 00:00 0
133770e9b7b000-70e9b7d000 r--p 0001e000 fc:00 2920 /system/lib64/android.hardware.cas.native@1.0.so
133870e9b7d000-70e9b7e000 rw-p 00020000 fc:00 2920 /system/lib64/android.hardware.cas.native@1.0.so
133970e9b7e000-70e9b7f000 r--s 00000000 fc:00 1145 /system/usr/hyphen-data/hyph-pt.hyb
134070e9b7f000-70e9b83000 r--s 00000000 fc:00 277 /system/fonts/NotoSansMandaic-Regular.ttf
134170e9b83000-70e9bdb000 r-xp 00000000 fc:00 2334 /system/lib64/libsonivox.so
134270e9bdb000-70e9bf2000 ---p 00000000 00:00 0
134370e9bf2000-70e9bf3000 r--p 0005f000 fc:00 2334 /system/lib64/libsonivox.so
134470e9bf3000-70e9bf4000 rw-p 00060000 fc:00 2334 /system/lib64/libsonivox.so
134570e9bf4000-70e9bfb000 rw-p 00000000 00:00 0 [anon:.bss]
134670e9bfb000-70e9c01000 r--s 00000000 fc:00 123 /system/fonts/NotoSansCham-Bold.ttf
134770e9c01000-70e9c0a000 r--s 00000000 fc:00 255 /system/fonts/NotoSansTamil-Bold.ttf
134870e9c0a000-70e9c13000 r--s 00000000 fc:00 135 /system/fonts/NotoSansTamil-Regular.ttf
134970e9c13000-70e9c15000 r-xp 00000000 fc:00 2519 /system/lib64/libgraphicsenv.so
135070e9c15000-70e9c32000 ---p 00000000 00:00 0
135170e9c32000-70e9c33000 r--p 0000f000 fc:00 2519 /system/lib64/libgraphicsenv.so
135270e9c33000-70e9c34000 rw-p 00010000 fc:00 2519 /system/lib64/libgraphicsenv.so
135370e9c34000-70e9c3a000 r--s 00000000 fc:00 259 /system/fonts/NotoSansCham-Regular.ttf
135470e9c3a000-70e9c42000 r--s 00000000 fc:00 114 /system/fonts/NotoSansGurmukhiUI-Bold.ttf
135570e9c42000-70e9c4a000 r--s 00000000 fc:00 122 /system/fonts/NotoSansGurmukhiUI-Regular.ttf
135670e9c4a000-70e9c5f000 r-xp 00000000 fc:00 2348 /system/lib64/android.hidl.allocator@1.0.so
135770e9c5f000-70e9c77000 ---p 00000000 00:00 0
135870e9c77000-70e9c79000 r--p 0001e000 fc:00 2348 /system/lib64/android.hidl.allocator@1.0.so
135970e9c79000-70e9c7a000 rw-p 00020000 fc:00 2348 /system/lib64/android.hidl.allocator@1.0.so
136070e9c7a000-70e9c7b000 r--s 00000000 fc:00 1095 /system/usr/hyphen-data/hyph-pa.hyb
136170e9c7b000-70e9c83000 r--s 00000000 fc:00 298 /system/fonts/NotoSerifGurmukhi-Bold.otf
136270e9c83000-70e9d01000 r-xp 00000000 fc:00 2665 /system/lib64/libbinder.so
136370e9d01000-70e9d1e000 ---p 00000000 00:00 0
136470e9d1e000-70e9d2e000 r--p 00080000 fc:00 2665 /system/lib64/libbinder.so
136570e9d2e000-70e9d2f000 rw-p 00090000 fc:00 2665 /system/lib64/libbinder.so
136670e9d2f000-70e9d4f000 rw-p 00000000 00:05 10271009 /dev/ashmem/dalvik-CompilerMetadata (deleted)
136770e9d4f000-70e9d53000 r-xp 00000000 fc:00 2454 /system/lib64/libaudiomanager.so
136870e9d53000-70e9d6e000 ---p 00000000 00:00 0
136970e9d6e000-70e9d6f000 r--p 0000f000 fc:00 2454 /system/lib64/libaudiomanager.so
137070e9d6f000-70e9d70000 rw-p 00010000 fc:00 2454 /system/lib64/libaudiomanager.so
137170e9d70000-70e9d71000 r--s 00000000 fc:00 1087 /system/usr/hyphen-data/hyph-or.hyb
137270e9d71000-70e9d91000 rw-p 00000000 00:05 10271008 /dev/ashmem/dalvik-CompilerMetadata (deleted)
137370e9d91000-70e9e21000 r-xp 00000000 fc:00 2627 /system/lib64/libft2.so
137470e9e21000-70e9e37000 ---p 00000000 00:00 0
137570e9e37000-70e9e3c000 r--p 0009b000 fc:00 2627 /system/lib64/libft2.so
137670e9e3c000-70e9e3d000 rw-p 000a0000 fc:00 2627 /system/lib64/libft2.so
137770e9e3d000-70e9e3e000 r--s 00000000 fc:00 1142 /system/usr/hyphen-data/hyph-mr.hyb
137870e9e3e000-70e9e45000 r--s 00000000 fc:00 88 /system/fonts/NotoSerifGurmukhi-Regular.otf
137970e9e45000-70e9e65000 r--s 00000000 00:10 16594 /dev/__properties__/u:object_r:exported3_default_prop:s0
138070e9e65000-70e9e7f000 r-xp 00000000 fc:00 2643 /system/lib64/libunwind.so
138170e9e7f000-70e9e94000 ---p 00000000 00:00 0
138270e9e94000-70e9e95000 r--p 0001f000 fc:00 2643 /system/lib64/libunwind.so
138370e9e95000-70e9e96000 rw-p 00020000 fc:00 2643 /system/lib64/libunwind.so
138470e9e96000-70e9eff000 rw-p 00000000 00:00 0 [anon:.bss]
138570e9eff000-70e9f00000 r--s 00000000 fc:00 1130 /system/usr/hyphen-data/hyph-ml.hyb
138670e9f00000-70e9f02000 r--s 00000000 fc:00 75 /system/fonts/NotoSansOgham-Regular.ttf
138770e9f02000-70e9f0a000 r--s 00000000 fc:00 193 /system/fonts/NotoSansGurmukhi-Bold.ttf
138870e9f0a000-70ea022000 r-xp 00000000 fc:00 2328 /system/lib64/libsqlite.so
138970ea022000-70ea033000 ---p 00000000 00:00 0
139070ea033000-70ea036000 r--p 0011d000 fc:00 2328 /system/lib64/libsqlite.so
139170ea036000-70ea038000 rw-p 00120000 fc:00 2328 /system/lib64/libsqlite.so
139270ea038000-70ea03c000 r--s 00000000 fc:00 285 /system/fonts/NotoSansGlagolitic-Regular.ttf
139370ea03c000-70ea04c000 r--s 00000000 fc:00 184 /system/fonts/NotoSerifGujarati-Bold.ttf
139470ea04c000-70ea060000 r-xp 00000000 fc:00 2731 /system/lib64/libstatslog.so
139570ea060000-70ea07b000 ---p 00000000 00:00 0
139670ea07b000-70ea07c000 r--p 0001f000 fc:00 2731 /system/lib64/libstatslog.so
139770ea07c000-70ea07d000 rw-p 00020000 fc:00 2731 /system/lib64/libstatslog.so
139870ea07d000-70ea081000 r--s 00000000 fc:00 182 /system/fonts/NotoSansBatak-Regular.ttf
139970ea081000-70ea091000 r--s 00000000 fc:00 264 /system/fonts/NotoSerifGujarati-Regular.ttf
140070ea091000-70ea160000 r-xp 00000000 fc:00 2728 /system/lib64/libdng_sdk.so
140170ea160000-70ea173000 ---p 00000000 00:00 0
140270ea173000-70ea17a000 r--p 000d9000 fc:00 2728 /system/lib64/libdng_sdk.so
140370ea17a000-70ea17b000 rw-p 000e0000 fc:00 2728 /system/lib64/libdng_sdk.so
140470ea17b000-70ea198000 r--s 00000000 fc:00 223 /system/fonts/DancingScript-Bold.ttf
140570ea198000-70ea19c000 r-xp 00000000 fc:00 2344 /system/lib64/libnativewindow.so
140670ea19c000-70ea1b7000 ---p 00000000 00:00 0
140770ea1b7000-70ea1b8000 r--p 0000f000 fc:00 2344 /system/lib64/libnativewindow.so
140870ea1b8000-70ea1b9000 rw-p 00010000 fc:00 2344 /system/lib64/libnativewindow.so
140970ea1b9000-70ea1bd000 r--s 00000000 fc:00 98 /system/fonts/NotoSansAhom-Regular.otf
141070ea1bd000-70ea1d1000 r--s 00000000 fc:00 104 /system/fonts/NotoSerifDevanagari-Bold.ttf
141170ea1d1000-70ea1d4000 r-xp 00000000 fc:00 2923 /system/lib64/libstdc++.so
141270ea1d4000-70ea1f0000 ---p 00000000 00:00 0
141370ea1f0000-70ea1f1000 r--p 0000f000 fc:00 2923 /system/lib64/libstdc++.so
141470ea1f1000-70ea1f2000 rw-p 00010000 fc:00 2923 /system/lib64/libstdc++.so
141570ea1f2000-70ea1f4000 r--s 00000000 fc:00 117 /system/fonts/NotoSansLydian-Regular.ttf
141670ea1f4000-70ea211000 r--s 00000000 fc:00 239 /system/fonts/DancingScript-Regular.ttf
141770ea211000-70ea24a000 r-xp 00000000 fc:00 2933 /system/lib64/android.hardware.graphics.bufferqueue@1.0.so
141870ea24a000-70ea268000 ---p 00000000 00:00 0
141970ea268000-70ea26c000 r--p 0003c000 fc:00 2933 /system/lib64/android.hardware.graphics.bufferqueue@1.0.so
142070ea26c000-70ea26d000 rw-p 00040000 fc:00 2933 /system/lib64/android.hardware.graphics.bufferqueue@1.0.so
142170ea26d000-70ea26f000 r--s 00000000 fc:00 244 /system/fonts/NotoSansLycian-Regular.ttf
142270ea26f000-70ea273000 r--s 00000000 fc:00 173 /system/fonts/NotoSansThaana-Bold.ttf
142370ea273000-70ea287000 r--s 00000000 fc:00 106 /system/fonts/NotoSerifDevanagari-Regular.ttf
142470ea287000-70ea29e000 r-xp 00000000 fc:00 2938 /system/lib64/libpiex.so
142570ea29e000-70ea2b6000 ---p 00000000 00:00 0
142670ea2b6000-70ea2b7000 r--p 0001f000 fc:00 2938 /system/lib64/libpiex.so
142770ea2b7000-70ea2b8000 rw-p 00020000 fc:00 2938 /system/lib64/libpiex.so
142870ea2b8000-70ea2c0000 r--s 00000000 fc:00 113 /system/fonts/NotoSansGurmukhi-Regular.ttf
142970ea2c0000-70ea2c6000 r--s 00000000 fc:00 263 /system/fonts/NotoSerifGeorgian-Bold.ttf
143070ea2c6000-70ea2cc000 r--s 00000000 fc:00 249 /system/fonts/NotoSerifGeorgian-Regular.ttf
143170ea2cc000-70ea9b4000 r-xp 00000000 fc:00 2532 /system/lib64/libhwui.so
143270ea9b4000-70ea9d3000 ---p 00000000 00:00 0
143370ea9d3000-70eaa0b000 r--p 006e8000 fc:00 2532 /system/lib64/libhwui.so
143470eaa0b000-70eaa0c000 rw-p 00720000 fc:00 2532 /system/lib64/libhwui.so
143570eaa0c000-70eaa11000 rw-p 00000000 00:00 0 [anon:.bss]
143670eaa11000-70eaa12000 r--s 00000000 fc:00 1110 /system/usr/hyphen-data/hyph-la.hyb
143770eaa12000-70eaa16000 r--s 00000000 fc:00 87 /system/fonts/NotoSansThaana-Regular.ttf
143870eaa16000-70eaa1b000 r--s 00000000 fc:00 218 /system/fonts/NotoSansGeorgian-Bold.ttf
143970eaa1b000-70eaa20000 r--s 00000000 fc:00 125 /system/fonts/NotoSansGeorgian-Regular.ttf
144070eaa20000-70eaa40000 rw-p 00000000 00:05 10271007 /dev/ashmem/dalvik-CompilerMetadata (deleted)
144170eaa40000-70eaaa0000 r-xp 00000000 fc:00 2384 /system/lib64/libhidltransport.so
144270eaaa0000-70eaabe000 ---p 00000000 00:00 0
144370eaabe000-70eaac6000 r--p 00068000 fc:00 2384 /system/lib64/libhidltransport.so
144470eaac6000-70eaac7000 rw-p 00070000 fc:00 2384 /system/lib64/libhidltransport.so
144570eaac7000-70eaacb000 r--s 00000000 fc:00 192 /system/fonts/NotoSerifArmenian-Bold.ttf
144670eaacb000-70eaad0000 r--s 00000000 fc:00 210 /system/fonts/NotoSansThaiUI-Bold.ttf
144770eaad0000-70eaaf0000 rw-p 00000000 00:05 10271006 /dev/ashmem/dalvik-CompilerMetadata (deleted)
144870eaaf0000-70eab10000 rw-p 00000000 00:05 10271005 /dev/ashmem/dalvik-CompilerMetadata (deleted)
144970eab10000-70eab57000 r-xp 00000000 fc:00 2546 /system/lib64/libmedia_omx.so
145070eab57000-70eab6d000 ---p 00000000 00:00 0
145170eab6d000-70eab7a000 r--p 00053000 fc:00 2546 /system/lib64/libmedia_omx.so
145270eab7a000-70eab7f000 rw-p 00060000 fc:00 2546 /system/lib64/libmedia_omx.so
145370eab7f000-70eab80000 r--s 00000000 fc:00 1119 /system/usr/hyphen-data/hyph-kn.hyb
145470eab80000-70eab86000 r--s 00000000 fc:00 224 /system/fonts/NotoSansThaiUI-Regular.ttf
145570eab86000-70eab8b000 r--s 00000000 fc:00 300 /system/fonts/NotoSerifThai-Bold.ttf
145670eab8b000-70eabab000 rw-p 00000000 00:05 10271004 /dev/ashmem/dalvik-CompilerMetadata (deleted)
145770eabab000-70eac21000 r-xp 00000000 fc:00 2385 /system/lib64/libvintf.so
145870eac21000-70eac31000 ---p 00000000 00:00 0
145970eac31000-70eac36000 r--p 0007b000 fc:00 2385 /system/lib64/libvintf.so
146070eac36000-70eac37000 rw-p 00080000 fc:00 2385 /system/lib64/libvintf.so
146170eac37000-70eac39000 rw-p 00000000 00:00 0 [anon:.bss]
146270eac39000-70eac3a000 r--s 00000000 fc:00 1104 /system/usr/hyphen-data/hyph-hy.hyb
146370eac3a000-70eac3f000 r--s 00000000 fc:00 212 /system/fonts/NotoSerifThai-Regular.ttf
146470eac3f000-70eac44000 r--s 00000000 fc:00 220 /system/fonts/NotoSansThai-Bold.ttf
146570eac44000-70eacb2000 r-xp 00000000 fc:00 2606 /system/lib64/android.hardware.media.omx@1.0.so
146670eacb2000-70eaccf000 ---p 00000000 00:00 0
146770eaccf000-70eacd8000 r--p 00077000 fc:00 2606 /system/lib64/android.hardware.media.omx@1.0.so
146870eacd8000-70eacd9000 rw-p 00080000 fc:00 2606 /system/lib64/android.hardware.media.omx@1.0.so
146970eacd9000-70eacdf000 r--s 00000000 fc:00 169 /system/fonts/NotoSansThai-Regular.ttf
147070eacdf000-70eace9000 r--s 00000000 fc:00 140 /system/fonts/CarroisGothicSC-Regular.ttf
147170eace9000-70ead09000 rw-p 00000000 00:05 10271003 /dev/ashmem/dalvik-CompilerMetadata (deleted)
147270ead09000-70ead22000 r-xp 00000000 fc:00 2539 /system/lib64/android.hardware.graphics.mapper@2.1.so
147370ead22000-70ead34000 ---p 00000000 00:00 0
147470ead34000-70ead37000 r--p 0001d000 fc:00 2539 /system/lib64/android.hardware.graphics.mapper@2.1.so
147570ead37000-70ead38000 rw-p 00020000 fc:00 2539 /system/lib64/android.hardware.graphics.mapper@2.1.so
147670ead38000-70ead47000 r--s 00000000 fc:00 188 /system/fonts/ComingSoon.ttf
147770ead47000-70ead5d000 r-xp 00000000 fc:00 2379 /system/lib64/libselinux.so
147870ead5d000-70ead76000 ---p 00000000 00:00 0
147970ead76000-70ead77000 r--p 0001f000 fc:00 2379 /system/lib64/libselinux.so
148070ead77000-70ead78000 rw-p 00020000 fc:00 2379 /system/lib64/libselinux.so
148170ead78000-70ead79000 rw-p 00000000 00:00 0 [anon:.bss]
148270ead79000-70ead7d000 r--s 00000000 fc:00 282 /system/fonts/NotoSerifArmenian-Regular.ttf
148370ead7d000-70ead82000 r--s 00000000 fc:00 288 /system/fonts/NotoSerifHebrew-Bold.ttf
148470ead82000-70ead83000 r-xp 00000000 fc:00 2680 /system/lib64/android.hardware.media@1.0.so
148570ead83000-70eada1000 ---p 00000000 00:00 0
148670eada1000-70eada2000 r--p 0000f000 fc:00 2680 /system/lib64/android.hardware.media@1.0.so
148770eada2000-70eada3000 rw-p 00010000 fc:00 2680 /system/lib64/android.hardware.media@1.0.so
148870eada3000-70eada8000 r--s 00000000 fc:00 248 /system/fonts/NotoSerifHebrew-Regular.ttf
148970eada8000-70eadb9000 r--s 00000000 fc:00 252 /system/fonts/CutiveMono.ttf
149070eadb9000-70eadd9000 r--s 00000000 00:10 16641 /dev/__properties__/u:object_r:radio_prop:s0
149170eadd9000-70eadda000 r-xp 00000000 fc:00 2533 /system/lib64/android.hardware.graphics.common@1.0.so
149270eadda000-70eadf8000 ---p 00000000 00:00 0
149370eadf8000-70eadf9000 r--p 0000f000 fc:00 2533 /system/lib64/android.hardware.graphics.common@1.0.so
149470eadf9000-70eadfa000 rw-p 00010000 fc:00 2533 /system/lib64/android.hardware.graphics.common@1.0.so
149570eadfa000-70eadfb000 r--s 00000000 fc:00 1126 /system/usr/hyphen-data/hyph-hr.hyb
149670eadfb000-70eadfd000 r--s 00000000 fc:00 194 /system/fonts/NotoSansLisu-Regular.ttf
149770eadfd000-70eae18000 r--s 00000000 fc:00 201 /system/fonts/DroidSansMono.ttf
149870eae18000-70eae3b000 r-xp 00000000 fc:00 2925 /system/lib64/liblzma.so
149970eae3b000-70eae57000 ---p 00000000 00:00 0
150070eae57000-70eae58000 r--p 0002f000 fc:00 2925 /system/lib64/liblzma.so
150170eae58000-70eae59000 rw-p 00030000 fc:00 2925 /system/lib64/liblzma.so
150270eae59000-70eae5f000 rw-p 00000000 00:00 0 [anon:.bss]
150370eae5f000-70eae62000 r--s 00000000 fc:00 103 /system/fonts/NotoSansLimbu-Regular.ttf
150470eae62000-70eae67000 r--s 00000000 fc:00 236 /system/fonts/NotoSansHebrew-Bold.ttf
150570eae67000-70eae84000 r--s 001c2000 fc:00 990 /system/framework/ext.jar
150670eae84000-70eaea4000 rw-p 00000000 00:05 10269720 /dev/ashmem/dalvik-LinearAlloc (deleted)
150770eaea4000-70eaede000 r-xp 00000000 fc:00 2924 /system/lib64/libwilhelm.so
150870eaede000-70eaefa000 ---p 00000000 00:00 0
150970eaefa000-70eaeff000 r--p 0003b000 fc:00 2924 /system/lib64/libwilhelm.so
151070eaeff000-70eaf00000 rw-p 00040000 fc:00 2924 /system/lib64/libwilhelm.so
151170eaf00000-70eaf03000 r--s 00000000 fc:00 242 /system/fonts/NotoSansElbasan-Regular.otf
151270eaf03000-70eaf21000 r-xp 00000000 fc:00 2415 /system/lib64/libdrmframework.so
151370eaf21000-70eaf38000 ---p 00000000 00:00 0
151470eaf38000-70eaf3d000 r--p 0002b000 fc:00 2415 /system/lib64/libdrmframework.so
151570eaf3d000-70eaf3e000 rw-p 00030000 fc:00 2415 /system/lib64/libdrmframework.so
151670eaf3e000-70eaf43000 r--s 00000000 fc:00 70 /system/fonts/NotoSansHebrew-Regular.ttf
151770eaf43000-70eaf44000 ---p 00000000 00:00 0 [anon:thread signal stack guard]
151870eaf44000-70eaf48000 rw-p 00000000 00:00 0 [anon:thread signal stack]
151970eaf48000-70eaf49000 ---p 00000000 00:00 0 [anon:bionic TLS guard]
152070eaf49000-70eaf4c000 rw-p 00000000 00:00 0 [anon:bionic TLS]
152170eaf4c000-70eaf4d000 ---p 00000000 00:00 0 [anon:bionic TLS guard]
152270eaf4d000-70eaf4e000 ---p 00000000 00:00 0 [anon:thread signal stack guard]
152370eaf4e000-70eaf52000 rw-p 00000000 00:00 0 [anon:thread signal stack]
152470eaf52000-70eaf98000 r-xp 00000000 fc:00 2426 /system/lib64/libunwindstack.so
152570eaf98000-70eafb6000 ---p 00000000 00:00 0
152670eafb6000-70eafbd000 r--p 00049000 fc:00 2426 /system/lib64/libunwindstack.so
152770eafbd000-70eafbe000 rw-p 00050000 fc:00 2426 /system/lib64/libunwindstack.so
152870eafbe000-70eafc0000 r--s 00000000 fc:00 162 /system/fonts/NotoSansKayahLi-Regular.ttf
152970eafc0000-70eafe4000 r-xp 00000000 fc:00 2944 /system/lib64/libvulkan.so
153070eafe4000-70eaffc000 ---p 00000000 00:00 0
153170eaffc000-70eaffe000 r--p 0002e000 fc:00 2944 /system/lib64/libvulkan.so
153270eaffe000-70eafff000 rw-p 00030000 fc:00 2944 /system/lib64/libvulkan.so
153370eafff000-70eb001000 r--s 00000000 fc:00 180 /system/fonts/NotoSansInscriptionalParthian-Regular.ttf
153470eb001000-70eb01d000 r-xp 00000000 fc:00 2400 /system/lib64/libbufferhubqueue.so
153570eb01d000-70eb030000 ---p 00000000 00:00 0
153670eb030000-70eb031000 r--p 0001f000 fc:00 2400 /system/lib64/libbufferhubqueue.so
153770eb031000-70eb032000 rw-p 00020000 fc:00 2400 /system/lib64/libbufferhubqueue.so
153870eb032000-70eb036000 r--s 00000000 fc:00 269 /system/fonts/NotoSansArmenian-Bold.ttf
153970eb036000-70eb037000 ---p 00000000 00:00 0 [anon:bionic TLS guard]
154070eb037000-70eb03a000 rw-p 00000000 00:00 0 [anon:bionic TLS]
154170eb03a000-70eb03b000 ---p 00000000 00:00 0 [anon:bionic TLS guard]
154270eb03b000-70eb03c000 ---p 00000000 00:00 0 [anon:thread signal stack guard]
154370eb03c000-70eb040000 rw-p 00000000 00:00 0 [anon:thread signal stack]
154470eb040000-70eb042000 r-xp 00000000 fc:00 2935 /system/lib64/libhardware.so
154570eb042000-70eb05f000 ---p 00000000 00:00 0
154670eb05f000-70eb060000 r--p 0000f000 fc:00 2935 /system/lib64/libhardware.so
154770eb060000-70eb061000 rw-p 00010000 fc:00 2935 /system/lib64/libhardware.so
154870eb061000-70eb063000 r--s 00000000 fc:00 171 /system/fonts/NotoSansInscriptionalPahlavi-Regular.ttf
154970eb063000-70eb064000 ---p 00000000 00:00 0 [anon:bionic TLS guard]
155070eb064000-70eb067000 rw-p 00000000 00:00 0 [anon:bionic TLS]
155170eb067000-70eb068000 ---p 00000000 00:00 0 [anon:bionic TLS guard]
155270eb068000-70eb069000 ---p 00000000 00:00 0 [anon:thread signal stack guard]
155370eb069000-70eb06d000 rw-p 00000000 00:00 0 [anon:thread signal stack]
155470eb06d000-70eb06e000 ---p 00000000 00:00 0 [anon:bionic TLS guard]
155570eb06e000-70eb071000 rw-p 00000000 00:00 0 [anon:bionic TLS]
155670eb071000-70eb072000 ---p 00000000 00:00 0 [anon:bionic TLS guard]
155770eb072000-70eb073000 ---p 00000000 00:00 0 [anon:thread signal stack guard]
155870eb073000-70eb077000 rw-p 00000000 00:00 0 [anon:thread signal stack]
155970eb077000-70eb078000 ---p 00000000 00:00 0 [anon:bionic TLS guard]
156070eb078000-70eb07b000 rw-p 00000000 00:00 0 [anon:bionic TLS]
156170eb07b000-70eb07c000 ---p 00000000 00:00 0 [anon:bionic TLS guard]
156270eb07c000-70eb07d000 ---p 00000000 00:00 0 [anon:thread signal stack guard]
156370eb07d000-70eb081000 rw-p 00000000 00:00 0 [anon:thread signal stack]
156470eb081000-70eb082000 ---p 00000000 00:00 0 [anon:bionic TLS guard]
156570eb082000-70eb085000 rw-p 00000000 00:00 0 [anon:bionic TLS]
156670eb085000-70eb086000 ---p 00000000 00:00 0 [anon:bionic TLS guard]
156770eb086000-70eb09d000 r-xp 00000000 fc:00 2604 /system/lib64/libz.so
156870eb09d000-70eb0b5000 ---p 00000000 00:00 0
156970eb0b5000-70eb0b6000 r--p 0001f000 fc:00 2604 /system/lib64/libz.so
157070eb0b6000-70eb0b7000 rw-p 00020000 fc:00 2604 /system/lib64/libz.so
157170eb0b7000-70eb0bb000 r--s 00000000 fc:00 289 /system/fonts/NotoSansArmenian-Regular.ttf
157270eb0bb000-70eb0bc000 ---p 00000000 00:00 0 [anon:thread signal stack guard]
157370eb0bc000-70eb0c0000 rw-p 00000000 00:00 0 [anon:thread signal stack]
157470eb0c0000-70eb0c1000 ---p 00000000 00:00 0 [anon:bionic TLS guard]
157570eb0c1000-70eb0c4000 rw-p 00000000 00:00 0 [anon:bionic TLS]
157670eb0c4000-70eb0c5000 ---p 00000000 00:00 0 [anon:bionic TLS guard]
157770eb0c5000-70eb0c6000 ---p 00000000 00:00 0 [anon:thread signal stack guard]
157870eb0c6000-70eb0ca000 rw-p 00000000 00:00 0 [anon:thread signal stack]
157970eb0ca000-70eb0cb000 ---p 00000000 00:00 0 [anon:bionic TLS guard]
158070eb0cb000-70eb0ce000 rw-p 00000000 00:00 0 [anon:bionic TLS]
158170eb0ce000-70eb0cf000 ---p 00000000 00:00 0 [anon:bionic TLS guard]
158270eb0cf000-70eb0ef000 rw-p 00000000 00:05 10270988 /dev/ashmem/dalvik-LinearAlloc (deleted)
158370eb0ef000-70eb5bb000 r-xp 00000000 fc:00 2374 /system/lib64/libpdfium.so
158470eb5bb000-70eb5cf000 ---p 00000000 00:00 0
158570eb5cf000-70eb5e6000 r--p 004d9000 fc:00 2374 /system/lib64/libpdfium.so
158670eb5e6000-70eb5ea000 rw-p 004f0000 fc:00 2374 /system/lib64/libpdfium.so
158770eb5ea000-70eb5f1000 rw-p 00000000 00:00 0 [anon:.bss]
158870eb5f1000-70eb5f2000 r--s 00000000 fc:00 1094 /system/usr/hyphen-data/hyph-hi.hyb
158970eb5f2000-70eb5f6000 rw-p 00000000 00:05 10270982 /dev/ashmem/dalvik-thread local mark stack (deleted)
159070eb5f6000-70eb5fa000 rw-p 00000000 00:05 10270981 /dev/ashmem/dalvik-thread local mark stack (deleted)
159170eb5fa000-70eb5fe000 rw-p 00000000 00:05 10270980 /dev/ashmem/dalvik-thread local mark stack (deleted)
159270eb5fe000-70eb602000 rw-p 00000000 00:05 10270979 /dev/ashmem/dalvik-thread local mark stack (deleted)
159370eb602000-70eb606000 rw-p 00000000 00:05 10270978 /dev/ashmem/dalvik-thread local mark stack (deleted)
159470eb606000-70eb60a000 rw-p 00000000 00:05 10270977 /dev/ashmem/dalvik-thread local mark stack (deleted)
159570eb60a000-70eb60e000 rw-p 00000000 00:05 10270976 /dev/ashmem/dalvik-thread local mark stack (deleted)
159670eb60e000-70eb612000 rw-p 00000000 00:05 10270975 /dev/ashmem/dalvik-thread local mark stack (deleted)
159770eb612000-70eb616000 rw-p 00000000 00:05 10270974 /dev/ashmem/dalvik-thread local mark stack (deleted)
159870eb616000-70eb61a000 r-xp 00000000 fc:00 2479 /system/lib64/libspeexresampler.so
159970eb61a000-70eb635000 ---p 00000000 00:00 0
160070eb635000-70eb636000 r--p 0000f000 fc:00 2479 /system/lib64/libspeexresampler.so
160170eb636000-70eb637000 rw-p 00010000 fc:00 2479 /system/lib64/libspeexresampler.so
160270eb637000-70eb639000 r--s 00000000 fc:00 299 /system/fonts/NotoSansImperialAramaic-Regular.ttf
160370eb639000-70eb63d000 rw-p 00000000 00:05 10270973 /dev/ashmem/dalvik-thread local mark stack (deleted)
160470eb63d000-70eb641000 rw-p 00000000 00:05 10270972 /dev/ashmem/dalvik-thread local mark stack (deleted)
160570eb641000-70eb645000 rw-p 00000000 00:05 10270971 /dev/ashmem/dalvik-thread local mark stack (deleted)
160670eb645000-70eb649000 rw-p 00000000 00:05 10270970 /dev/ashmem/dalvik-thread local mark stack (deleted)
160770eb649000-70eb64d000 rw-p 00000000 00:05 10270969 /dev/ashmem/dalvik-thread local mark stack (deleted)
160870eb64d000-70eb651000 rw-p 00000000 00:05 10270968 /dev/ashmem/dalvik-thread local mark stack (deleted)
160970eb651000-70eb655000 rw-p 00000000 00:05 10270967 /dev/ashmem/dalvik-thread local mark stack (deleted)
161070eb655000-70eb659000 rw-p 00000000 00:05 10270966 /dev/ashmem/dalvik-thread local mark stack (deleted)
161170eb659000-70eb65d000 rw-p 00000000 00:05 10270965 /dev/ashmem/dalvik-thread local mark stack (deleted)
161270eb65d000-70eb661000 rw-p 00000000 00:05 10270964 /dev/ashmem/dalvik-thread local mark stack (deleted)
161370eb661000-70eb6c5000 r-xp 00000000 fc:00 2461 /system/lib64/libhidl-gen-utils.so
161470eb6c5000-70eb6df000 ---p 00000000 00:00 0
161570eb6df000-70eb6e1000 r--p 0006e000 fc:00 2461 /system/lib64/libhidl-gen-utils.so
161670eb6e1000-70eb6e2000 rw-p 00070000 fc:00 2461 /system/lib64/libhidl-gen-utils.so
161770eb6e2000-70eb6e6000 rw-p 00000000 00:05 10270963 /dev/ashmem/dalvik-thread local mark stack (deleted)
161870eb6e6000-70eb6ea000 rw-p 00000000 00:05 10270962 /dev/ashmem/dalvik-thread local mark stack (deleted)
161970eb6ea000-70eb6ee000 rw-p 00000000 00:05 10270961 /dev/ashmem/dalvik-thread local mark stack (deleted)
162070eb6ee000-70eb6f2000 rw-p 00000000 00:05 10270960 /dev/ashmem/dalvik-thread local mark stack (deleted)
162170eb6f2000-70eb6f6000 rw-p 00000000 00:05 10270959 /dev/ashmem/dalvik-thread local mark stack (deleted)
162270eb6f6000-70eb6fa000 rw-p 00000000 00:05 10270958 /dev/ashmem/dalvik-thread local mark stack (deleted)
162370eb6fa000-70eb6fe000 rw-p 00000000 00:05 10270957 /dev/ashmem/dalvik-thread local mark stack (deleted)
162470eb6fe000-70eb702000 rw-p 00000000 00:05 10270956 /dev/ashmem/dalvik-thread local mark stack (deleted)
162570eb702000-70eb706000 rw-p 00000000 00:05 10270955 /dev/ashmem/dalvik-thread local mark stack (deleted)
162670eb706000-70eb70a000 rw-p 00000000 00:05 10270954 /dev/ashmem/dalvik-thread local mark stack (deleted)
162770eb70a000-70eb70e000 rw-p 00000000 00:05 10270953 /dev/ashmem/dalvik-thread local mark stack (deleted)
162870eb70e000-70eb712000 rw-p 00000000 00:05 10270952 /dev/ashmem/dalvik-thread local mark stack (deleted)
162970eb712000-70eb71a000 r-xp 00000000 fc:00 2652 /system/lib64/libcamera_metadata.so
163070eb71a000-70eb72f000 ---p 00000000 00:00 0
163170eb72f000-70eb730000 r--p 0000f000 fc:00 2652 /system/lib64/libcamera_metadata.so
163270eb730000-70eb732000 rw-p 00010000 fc:00 2652 /system/lib64/libcamera_metadata.so
163370eb732000-70eb734000 r--s 00000000 fc:00 131 /system/fonts/NotoSansHanunoo-Regular.ttf
163470eb734000-70eb738000 rw-p 00000000 00:05 10270951 /dev/ashmem/dalvik-thread local mark stack (deleted)
163570eb738000-70eb73c000 rw-p 00000000 00:05 10270950 /dev/ashmem/dalvik-thread local mark stack (deleted)
163670eb73c000-70eb740000 rw-p 00000000 00:05 10270949 /dev/ashmem/dalvik-thread local mark stack (deleted)
163770eb740000-70eb744000 rw-p 00000000 00:05 10270948 /dev/ashmem/dalvik-thread local mark stack (deleted)
163870eb744000-70eb748000 rw-p 00000000 00:05 10270947 /dev/ashmem/dalvik-thread local mark stack (deleted)
163970eb748000-70eb74c000 rw-p 00000000 00:05 10270946 /dev/ashmem/dalvik-thread local mark stack (deleted)
164070eb74c000-70eb750000 rw-p 00000000 00:05 10270945 /dev/ashmem/dalvik-thread local mark stack (deleted)
164170eb750000-70eb754000 rw-p 00000000 00:05 10270944 /dev/ashmem/dalvik-thread local mark stack (deleted)
164270eb754000-70eb758000 rw-p 00000000 00:05 10270943 /dev/ashmem/dalvik-thread local mark stack (deleted)
164370eb758000-70eb75c000 rw-p 00000000 00:05 10270942 /dev/ashmem/dalvik-thread local mark stack (deleted)
164470eb75c000-70eb760000 rw-p 00000000 00:05 10270941 /dev/ashmem/dalvik-thread local mark stack (deleted)
164570eb760000-70eb764000 rw-p 00000000 00:05 10270940 /dev/ashmem/dalvik-thread local mark stack (deleted)
164670eb764000-70eb767000 rw-p 00000000 00:00 0 [anon:linker_alloc]
164770eb767000-70eb768000 r--p 00000000 00:00 0 [anon:linker_alloc]
164870eb768000-70eb76c000 rw-p 00000000 00:05 10270939 /dev/ashmem/dalvik-thread local mark stack (deleted)
164970eb76c000-70eb770000 rw-p 00000000 00:05 10270938 /dev/ashmem/dalvik-thread local mark stack (deleted)
165070eb770000-70eb771000 rw-p 00000000 00:00 0 [anon:linker_alloc]
165170eb771000-70eb774000 r--s 00000000 fc:00 231 /system/fonts/NotoSansDeseret-Regular.ttf
165270eb774000-70eb778000 rw-p 00000000 00:05 10270937 /dev/ashmem/dalvik-thread local mark stack (deleted)
165370eb778000-70eb77c000 rw-p 00000000 00:05 10270936 /dev/ashmem/dalvik-thread local mark stack (deleted)
165470eb77c000-70eb780000 rw-p 00000000 00:05 10270935 /dev/ashmem/dalvik-thread local mark stack (deleted)
165570eb780000-70eb784000 rw-p 00000000 00:05 10270934 /dev/ashmem/dalvik-thread local mark stack (deleted)
165670eb784000-70eb788000 rw-p 00000000 00:05 10270933 /dev/ashmem/dalvik-thread local mark stack (deleted)
165770eb788000-70eb78c000 rw-p 00000000 00:05 10270932 /dev/ashmem/dalvik-thread local mark stack (deleted)
165870eb78c000-70eb790000 rw-p 00000000 00:05 10270931 /dev/ashmem/dalvik-thread local mark stack (deleted)
165970eb790000-70eb794000 rw-p 00000000 00:05 10270930 /dev/ashmem/dalvik-thread local mark stack (deleted)
166070eb794000-70eb798000 rw-p 00000000 00:05 10270929 /dev/ashmem/dalvik-thread local mark stack (deleted)
166170eb798000-70eb79c000 rw-p 00000000 00:05 10270928 /dev/ashmem/dalvik-thread local mark stack (deleted)
166270eb79c000-70eb7a0000 rw-p 00000000 00:05 10270927 /dev/ashmem/dalvik-thread local mark stack (deleted)
166370eb7a0000-70eb7a1000 r--p 00000000 00:00 0 [anon:linker_alloc]
166470eb7a1000-70eb7a3000 r--s 00000000 fc:00 176 /system/fonts/NotoSansGothic-Regular.ttf
166570eb7a3000-70eb7a7000 rw-p 00000000 00:05 10270926 /dev/ashmem/dalvik-thread local mark stack (deleted)
166670eb7a7000-70eb7a8000 r--p 00000000 00:00 0 [anon:linker_alloc]
166770eb7a8000-70eb7a9000 r--s 00000000 fc:00 1109 /system/usr/hyphen-data/hyph-gu.hyb
166870eb7a9000-70eb7ad000 rw-p 00000000 00:05 10270925 /dev/ashmem/dalvik-thread local mark stack (deleted)
166970eb7ad000-70eb7ae000 r--p 00000000 00:00 0 [anon:linker_alloc]
167070eb7ae000-70eb7af000 rw-p 00000000 00:00 0 [anon:linker_alloc]
167170eb7af000-70eb7b0000 r--p 00000000 00:00 0 [anon:linker_alloc]
167270eb7b0000-70eb7b2000 r--s 00000000 fc:00 191 /system/fonts/NotoSansCypriot-Regular.ttf
167370eb7b2000-70eb7b6000 rw-p 00000000 00:05 10270924 /dev/ashmem/dalvik-thread local mark stack (deleted)
167470eb7b6000-70eb7ba000 rw-p 00000000 00:05 10270923 /dev/ashmem/dalvik-thread local mark stack (deleted)
167570eb7ba000-70eb7be000 rw-p 00000000 00:05 10270922 /dev/ashmem/dalvik-thread local mark stack (deleted)
167670eb7be000-70eb7c2000 rw-p 00000000 00:05 10270921 /dev/ashmem/dalvik-thread local mark stack (deleted)
167770eb7c2000-70eb7c6000 rw-p 00000000 00:05 10270920 /dev/ashmem/dalvik-thread local mark stack (deleted)
167870eb7c6000-70eb7ca000 rw-p 00000000 00:05 10270919 /dev/ashmem/dalvik-thread local mark stack (deleted)
167970eb7ca000-70eb7ce000 rw-p 00000000 00:05 10270918 /dev/ashmem/dalvik-thread local mark stack (deleted)
168070eb7ce000-70eb7d2000 rw-p 00000000 00:05 10270917 /dev/ashmem/dalvik-thread local mark stack (deleted)
168170eb7d2000-70eb7d6000 rw-p 00000000 00:05 10270916 /dev/ashmem/dalvik-thread local mark stack (deleted)
168270eb7d6000-70eb7d7000 rw-p 00000000 00:00 0 [anon:linker_alloc_small_objects]
168370eb7d7000-70eb7db000 rw-p 00000000 00:05 10270915 /dev/ashmem/dalvik-thread local mark stack (deleted)
168470eb7db000-70eb7df000 rw-p 00000000 00:05 10270914 /dev/ashmem/dalvik-thread local mark stack (deleted)
168570eb7df000-70eb7e3000 rw-p 00000000 00:05 10270913 /dev/ashmem/dalvik-thread local mark stack (deleted)
168670eb7e3000-70eb7e7000 rw-p 00000000 00:05 10270912 /dev/ashmem/dalvik-thread local mark stack (deleted)
168770eb7e7000-70eb7e8000 r--p 00000000 00:00 0 [anon:linker_alloc]
168870eb7e8000-70eb7ea000 r--s 00000000 fc:00 174 /system/fonts/NotoSansCarian-Regular.ttf
168970eb7ea000-70eb7ee000 rw-p 00000000 00:05 10270911 /dev/ashmem/dalvik-thread local mark stack (deleted)
169070eb7ee000-70eb7f2000 rw-p 00000000 00:05 10270910 /dev/ashmem/dalvik-thread local mark stack (deleted)
169170eb7f2000-70eb7f6000 rw-p 00000000 00:05 10270909 /dev/ashmem/dalvik-thread local mark stack (deleted)
169270eb7f6000-70eb7f7000 rw-p 00000000 00:00 0 [anon:linker_alloc]
169370eb7f7000-70eb7f8000 r--s 00000000 fc:00 1096 /system/usr/hyphen-data/hyph-eu.hyb
169470eb7f8000-70eb7fc000 rw-p 00000000 00:05 10270908 /dev/ashmem/dalvik-thread local mark stack (deleted)
169570eb7fc000-70eb800000 rw-p 00000000 00:05 10270907 /dev/ashmem/dalvik-thread local mark stack (deleted)
169670eb800000-70eb804000 rw-p 00000000 00:05 10270906 /dev/ashmem/dalvik-thread local mark stack (deleted)
169770eb804000-70eb808000 rw-p 00000000 00:05 10270905 /dev/ashmem/dalvik-thread local mark stack (deleted)
169870eb808000-70eb80c000 rw-p 00000000 00:05 10270904 /dev/ashmem/dalvik-thread local mark stack (deleted)
169970eb80c000-70eb810000 rw-p 00000000 00:05 10270903 /dev/ashmem/dalvik-thread local mark stack (deleted)
170070eb810000-70eb814000 rw-p 00000000 00:05 10270902 /dev/ashmem/dalvik-thread local mark stack (deleted)
170170eb814000-70eb815000 rw-p 00000000 00:00 0 [anon:linker_alloc_vector]
170270eb815000-70eb819000 rw-p 00000000 00:05 10270901 /dev/ashmem/dalvik-thread local mark stack (deleted)
170370eb819000-70eb81d000 rw-p 00000000 00:05 10270900 /dev/ashmem/dalvik-thread local mark stack (deleted)
170470eb81d000-70eb81e000 rw-p 00000000 00:00 0 [anon:linker_alloc]
170570eb81e000-70eb822000 rw-p 00000000 00:05 10270899 /dev/ashmem/dalvik-thread local mark stack (deleted)
170670eb822000-70eb826000 rw-p 00000000 00:05 10270898 /dev/ashmem/dalvik-thread local mark stack (deleted)
170770eb826000-70eb82a000 rw-p 00000000 00:05 10270897 /dev/ashmem/dalvik-thread local mark stack (deleted)
170870eb82a000-70eb82e000 rw-p 00000000 00:05 10270896 /dev/ashmem/dalvik-thread local mark stack (deleted)
170970eb82e000-70eb832000 rw-p 00000000 00:05 10270895 /dev/ashmem/dalvik-thread local mark stack (deleted)
171070eb832000-70eb836000 rw-p 00000000 00:05 10270894 /dev/ashmem/dalvik-thread local mark stack (deleted)
171170eb836000-70eb837000 r--p 00000000 00:00 0 [anon:linker_alloc]
171270eb837000-70eb83b000 rw-p 00000000 00:05 10270893 /dev/ashmem/dalvik-thread local mark stack (deleted)
171370eb83b000-70eb83f000 rw-p 00000000 00:05 10270892 /dev/ashmem/dalvik-thread local mark stack (deleted)
171470eb83f000-70eb843000 rw-p 00000000 00:05 10270891 /dev/ashmem/dalvik-thread local mark stack (deleted)
171570eb843000-70eb847000 rw-p 00000000 00:05 10270890 /dev/ashmem/dalvik-thread local mark stack (deleted)
171670eb847000-70eb84b000 rw-p 00000000 00:05 10270889 /dev/ashmem/dalvik-thread local mark stack (deleted)
171770eb84b000-70eb84f000 rw-p 00000000 00:05 10270888 /dev/ashmem/dalvik-thread local mark stack (deleted)
171870eb84f000-70eb850000 rw-p 00000000 00:00 0 [anon:linker_alloc]
171970eb850000-70eb854000 rw-p 00000000 00:05 10270887 /dev/ashmem/dalvik-thread local mark stack (deleted)
172070eb854000-70eb858000 rw-p 00000000 00:05 10270886 /dev/ashmem/dalvik-thread local mark stack (deleted)
172170eb858000-70eb85c000 rw-p 00000000 00:05 10270885 /dev/ashmem/dalvik-thread local mark stack (deleted)
172270eb85c000-70eb860000 rw-p 00000000 00:05 10270884 /dev/ashmem/dalvik-thread local mark stack (deleted)
172370eb860000-70eb864000 rw-p 00000000 00:05 10270883 /dev/ashmem/dalvik-thread local mark stack (deleted)
172470eb864000-70eb868000 rw-p 00000000 00:05 10270882 /dev/ashmem/dalvik-thread local mark stack (deleted)
172570eb868000-70eb869000 r--p 00000000 00:00 0 [anon:linker_alloc]
172670eb869000-70eb86d000 rw-p 00000000 00:05 10270881 /dev/ashmem/dalvik-thread local mark stack (deleted)
172770eb86d000-70eb871000 rw-p 00000000 00:05 10270880 /dev/ashmem/dalvik-thread local mark stack (deleted)
172870eb871000-70eb875000 rw-p 00000000 00:05 10270879 /dev/ashmem/dalvik-thread local mark stack (deleted)
172970eb875000-70eb879000 rw-p 00000000 00:05 10270878 /dev/ashmem/dalvik-thread local mark stack (deleted)
173070eb879000-70eb87d000 rw-p 00000000 00:05 10270877 /dev/ashmem/dalvik-thread local mark stack (deleted)
173170eb87d000-70eb881000 rw-p 00000000 00:05 10270876 /dev/ashmem/dalvik-thread local mark stack (deleted)
173270eb881000-70eb885000 rw-p 00000000 00:05 10270875 /dev/ashmem/dalvik-thread local mark stack (deleted)
173370eb885000-70eb889000 rw-p 00000000 00:05 10270874 /dev/ashmem/dalvik-thread local mark stack (deleted)
173470eb889000-70eb88d000 rw-p 00000000 00:05 10270873 /dev/ashmem/dalvik-thread local mark stack (deleted)
173570eb88d000-70eb891000 rw-p 00000000 00:05 10270872 /dev/ashmem/dalvik-thread local mark stack (deleted)
173670eb891000-70eb892000 r--p 00000000 00:00 0 [anon:linker_alloc]
173770eb892000-70eb896000 rw-p 00000000 00:05 10270871 /dev/ashmem/dalvik-thread local mark stack (deleted)
173870eb896000-70eb89a000 rw-p 00000000 00:05 10270870 /dev/ashmem/dalvik-thread local mark stack (deleted)
173970eb89a000-70eb89b000 rw-p 00000000 00:00 0 [anon:linker_alloc_vector]
174070eb89b000-70eb89c000 rw-p 00000000 00:00 0 [anon:linker_alloc_small_objects]
174170eb89c000-70eb8a0000 rw-p 00000000 00:05 10270869 /dev/ashmem/dalvik-thread local mark stack (deleted)
174270eb8a0000-70eb8a4000 rw-p 00000000 00:05 10270868 /dev/ashmem/dalvik-thread local mark stack (deleted)
174370eb8a4000-70eb8a5000 r--p 00000000 00:00 0 [anon:atexit handlers]
174470eb8a5000-70eb8a9000 rw-p 00000000 00:05 10270867 /dev/ashmem/dalvik-thread local mark stack (deleted)
174570eb8a9000-70eb8ad000 rw-p 00000000 00:05 10270866 /dev/ashmem/dalvik-thread local mark stack (deleted)
174670eb8ad000-70eb8b1000 rw-p 00000000 00:05 10270865 /dev/ashmem/dalvik-thread local mark stack (deleted)
174770eb8b1000-70eb8b5000 rw-p 00000000 00:05 10270864 /dev/ashmem/dalvik-thread local mark stack (deleted)
174870eb8b5000-70eb8b9000 rw-p 00000000 00:05 10270863 /dev/ashmem/dalvik-thread local mark stack (deleted)
174970eb8b9000-70eb8bd000 rw-p 00000000 00:05 10270862 /dev/ashmem/dalvik-thread local mark stack (deleted)
175070eb8bd000-70eb8be000 rw-p 00000000 00:00 0 [anon:linker_alloc]
175170eb8be000-70eb8c1000 r--s 00000000 fc:00 168 /system/fonts/NotoSansAvestan-Regular.ttf
175270eb8c1000-70eb8c5000 rw-p 00000000 00:05 10270861 /dev/ashmem/dalvik-thread local mark stack (deleted)
175370eb8c5000-70eb8c9000 rw-p 00000000 00:05 10270860 /dev/ashmem/dalvik-thread local mark stack (deleted)
175470eb8c9000-70eb8cd000 rw-p 00000000 00:05 10270859 /dev/ashmem/dalvik-thread local mark stack (deleted)
175570eb8cd000-70eb8d1000 rw-p 00000000 00:05 10270858 /dev/ashmem/dalvik-thread local mark stack (deleted)
175670eb8d1000-70eb8d5000 rw-p 00000000 00:05 10270857 /dev/ashmem/dalvik-thread local mark stack (deleted)
175770eb8d5000-70eb8d7000 r--p 00000000 00:00 0 [anon:linker_alloc]
175870eb8d7000-70eb8db000 rw-p 00000000 00:05 10270856 /dev/ashmem/dalvik-thread local mark stack (deleted)
175970eb8db000-70eb8df000 rw-p 00000000 00:05 10270855 /dev/ashmem/dalvik-thread local mark stack (deleted)
176070eb8df000-70eb8e3000 rw-p 00000000 00:05 10270854 /dev/ashmem/dalvik-thread local mark stack (deleted)
176170eb8e3000-70eb8e7000 rw-p 00000000 00:05 10270853 /dev/ashmem/dalvik-thread local mark stack (deleted)
176270eb8e7000-70eb8eb000 rw-p 00000000 00:05 10270852 /dev/ashmem/dalvik-thread local mark stack (deleted)
176370eb8eb000-70eb8ec000 r--p 00000000 00:00 0 [anon:linker_alloc]
176470eb8ec000-70eb8ed000 r--s 00000000 fc:00 1099 /system/usr/hyphen-data/hyph-bn.hyb
176570eb8ed000-70eb8f1000 rw-p 00000000 00:05 10270851 /dev/ashmem/dalvik-thread local mark stack (deleted)
176670eb8f1000-70eb8f5000 rw-p 00000000 00:05 10270850 /dev/ashmem/dalvik-thread local mark stack (deleted)
176770eb8f5000-70eb8f9000 rw-p 00000000 00:05 10270849 /dev/ashmem/dalvik-thread local mark stack (deleted)
176870eb8f9000-70eb8fd000 rw-p 00000000 00:05 10270848 /dev/ashmem/dalvik-thread local mark stack (deleted)
176970eb8fd000-70eb901000 rw-p 00000000 00:05 10270847 /dev/ashmem/dalvik-thread local mark stack (deleted)
177070eb901000-70eb905000 rw-p 00000000 00:05 10270846 /dev/ashmem/dalvik-thread local mark stack (deleted)
177170eb905000-70eb909000 rw-p 00000000 00:05 10270845 /dev/ashmem/dalvik-thread local mark stack (deleted)
177270eb909000-70eb90d000 rw-p 00000000 00:05 10270844 /dev/ashmem/dalvik-thread local mark stack (deleted)
177370eb90d000-70eb911000 rw-p 00000000 00:05 10270843 /dev/ashmem/dalvik-thread local mark stack (deleted)
177470eb911000-70eb915000 rw-p 00000000 00:05 10270842 /dev/ashmem/dalvik-thread local mark stack (deleted)
177570eb915000-70eb916000 rw-p 00000000 00:00 0 [anon:linker_alloc]
177670eb916000-70eb917000 r--s 00000000 fc:00 1114 /system/usr/hyphen-data/hyph-bg.hyb
177770eb917000-70eb91b000 rw-p 00000000 00:05 10270841 /dev/ashmem/dalvik-thread local mark stack (deleted)
177870eb91b000-70eb91c000 r--p 00000000 00:00 0 [anon:linker_alloc]
177970eb91c000-70eb91d000 r--s 00000000 fc:00 1133 /system/usr/hyphen-data/hyph-as.hyb
178070eb91d000-70eb921000 rw-p 00000000 00:05 10270840 /dev/ashmem/dalvik-thread local mark stack (deleted)
178170eb921000-70eb925000 rw-p 00000000 00:05 10270839 /dev/ashmem/dalvik-thread local mark stack (deleted)
178270eb925000-70eb926000 rw-p 00000000 00:00 0 [anon:linker_alloc_small_objects]
178370eb926000-70eb927000 r--p 00000000 00:00 0 [anon:linker_alloc]
178470eb927000-70eb929000 r--s 00000000 fc:00 203 /system/fonts/NotoSansBuhid-Regular.ttf
178570eb929000-70eb92d000 rw-p 00000000 00:05 10270838 /dev/ashmem/dalvik-thread local mark stack (deleted)
178670eb92d000-70eb931000 rw-p 00000000 00:05 10270837 /dev/ashmem/dalvik-thread local mark stack (deleted)
178770eb931000-70eb935000 rw-p 00000000 00:05 10270836 /dev/ashmem/dalvik-thread local mark stack (deleted)
178870eb935000-70eb939000 rw-p 00000000 00:05 10270835 /dev/ashmem/dalvik-thread local mark stack (deleted)
178970eb939000-70eb93d000 rw-p 00000000 00:05 10270834 /dev/ashmem/dalvik-thread local mark stack (deleted)
179070eb93d000-70eb941000 rw-p 00000000 00:05 10270833 /dev/ashmem/dalvik-thread local mark stack (deleted)
179170eb941000-70eb945000 rw-p 00000000 00:05 10270832 /dev/ashmem/dalvik-thread local mark stack (deleted)
179270eb945000-70eb949000 rw-p 00000000 00:05 10270831 /dev/ashmem/dalvik-thread local mark stack (deleted)
179370eb949000-70eb94d000 rw-p 00000000 00:05 10270830 /dev/ashmem/dalvik-thread local mark stack (deleted)
179470eb94d000-70eb951000 rw-p 00000000 00:05 10270829 /dev/ashmem/dalvik-thread local mark stack (deleted)
179570eb951000-70eb991000 rw-p 00000000 00:05 10270722 /dev/ashmem/dalvik-mark stack (deleted)
179670eb991000-70eb992000 rw-p 00000000 00:00 0 [anon:linker_alloc]
179770eb992000-70eb996000 rw-p 00000000 00:05 10270828 /dev/ashmem/dalvik-thread local mark stack (deleted)
179870eb996000-70eb99a000 rw-p 00000000 00:05 10270827 /dev/ashmem/dalvik-thread local mark stack (deleted)
179970eb99a000-70eb99e000 rw-p 00000000 00:05 10270826 /dev/ashmem/dalvik-thread local mark stack (deleted)
180070eb99e000-70eb9a2000 rw-p 00000000 00:05 10270825 /dev/ashmem/dalvik-thread local mark stack (deleted)
180170eb9a2000-70eb9a4000 r--p 00000000 00:00 0 [anon:linker_alloc]
180270eb9a4000-70eb9a8000 rw-p 00000000 00:05 10270824 /dev/ashmem/dalvik-thread local mark stack (deleted)
180370eb9a8000-70eb9ac000 rw-p 00000000 00:05 10270823 /dev/ashmem/dalvik-thread local mark stack (deleted)
180470eb9ac000-70eb9b0000 rw-p 00000000 00:05 10270822 /dev/ashmem/dalvik-thread local mark stack (deleted)
180570eb9b0000-70eb9b1000 r--p 00000000 00:00 0 [anon:linker_alloc]
180670eb9b1000-70eb9b2000 r--s 00021000 fc:01 1180 /vendor/overlay/framework-res__auto_generated_rro.apk
180770eb9b2000-70eb9b6000 rw-p 00000000 00:05 10270821 /dev/ashmem/dalvik-thread local mark stack (deleted)
180870eb9b6000-70eb9ba000 rw-p 00000000 00:05 10270820 /dev/ashmem/dalvik-thread local mark stack (deleted)
180970eb9ba000-70eb9be000 rw-p 00000000 00:05 10270819 /dev/ashmem/dalvik-thread local mark stack (deleted)
181070eb9be000-70eb9c2000 rw-p 00000000 00:05 10270818 /dev/ashmem/dalvik-thread local mark stack (deleted)
181170eb9c2000-70eb9c6000 rw-p 00000000 00:05 10270817 /dev/ashmem/dalvik-thread local mark stack (deleted)
181270eb9c6000-70eb9ca000 rw-p 00000000 00:05 10270816 /dev/ashmem/dalvik-thread local mark stack (deleted)
181370eb9ca000-70eb9ce000 rw-p 00000000 00:05 10270815 /dev/ashmem/dalvik-thread local mark stack (deleted)
181470eb9ce000-70eb9cf000 rw-p 00000000 00:00 0 [anon:linker_alloc]
181570eb9cf000-70eb9d1000 r--s 00000000 fc:00 213 /system/fonts/NotoSansBuginese-Regular.ttf
181670eb9d1000-70eb9d5000 rw-p 00000000 00:05 10270814 /dev/ashmem/dalvik-thread local mark stack (deleted)
181770eb9d5000-70eb9d9000 rw-p 00000000 00:05 10270813 /dev/ashmem/dalvik-thread local mark stack (deleted)
181870eb9d9000-70eb9dd000 rw-p 00000000 00:05 10270812 /dev/ashmem/dalvik-thread local mark stack (deleted)
181970eb9dd000-70eb9e1000 rw-p 00000000 00:05 10270811 /dev/ashmem/dalvik-thread local mark stack (deleted)
182070eb9e1000-70eb9e5000 rw-p 00000000 00:05 10270810 /dev/ashmem/dalvik-thread local mark stack (deleted)
182170eb9e5000-70eb9e9000 rw-p 00000000 00:05 10270809 /dev/ashmem/dalvik-thread local mark stack (deleted)
182270eb9e9000-70eb9ed000 rw-p 00000000 00:05 10270808 /dev/ashmem/dalvik-thread local mark stack (deleted)
182370eb9ed000-70eb9f1000 rw-p 00000000 00:05 10270807 /dev/ashmem/dalvik-thread local mark stack (deleted)
182470eb9f1000-70eb9f5000 rw-p 00000000 00:05 10270806 /dev/ashmem/dalvik-thread local mark stack (deleted)
182570eb9f5000-70eb9f6000 r--p 00000000 00:00 0 [anon:linker_alloc]
182670eb9f6000-70eb9f8000 rw-p 00000000 00:05 10271002 /dev/ashmem/dalvik-indirect ref table (deleted)
182770eb9f8000-70eb9fc000 rw-p 00000000 00:05 10270805 /dev/ashmem/dalvik-thread local mark stack (deleted)
182870eb9fc000-70eb9fd000 rw-p 00000000 00:00 0 [anon:linker_alloc]
182970eb9fd000-70eb9ff000 rw-p 00000000 00:05 10270999 /dev/ashmem/dalvik-indirect ref table (deleted)
183070eb9ff000-70eba00000 r--s 00000000 fc:00 983 /system/framework/com.google.vr.platform.jar
183170eba00000-70eba04000 rw-p 00000000 00:05 10270804 /dev/ashmem/dalvik-thread local mark stack (deleted)
183270eba04000-70eba08000 rw-p 00000000 00:05 10270803 /dev/ashmem/dalvik-thread local mark stack (deleted)
183370eba08000-70eba0c000 rw-p 00000000 00:05 10270802 /dev/ashmem/dalvik-thread local mark stack (deleted)
183470eba0c000-70eba10000 rw-p 00000000 00:05 10270801 /dev/ashmem/dalvik-thread local mark stack (deleted)
183570eba10000-70eba14000 rw-p 00000000 00:05 10270800 /dev/ashmem/dalvik-thread local mark stack (deleted)
183670eba14000-70eba18000 rw-p 00000000 00:05 10270799 /dev/ashmem/dalvik-thread local mark stack (deleted)
183770eba18000-70eba1c000 rw-p 00000000 00:05 10270798 /dev/ashmem/dalvik-thread local mark stack (deleted)
183870eba1c000-70eba20000 rw-p 00000000 00:05 10270797 /dev/ashmem/dalvik-thread local mark stack (deleted)
183970eba20000-70eba24000 rw-p 00000000 00:05 10270796 /dev/ashmem/dalvik-thread local mark stack (deleted)
184070eba24000-70eba28000 rw-p 00000000 00:05 10270795 /dev/ashmem/dalvik-thread local mark stack (deleted)
184170eba28000-70eba2c000 rw-p 00000000 00:05 10270794 /dev/ashmem/dalvik-thread local mark stack (deleted)
184270eba2c000-70eba2d000 rw-p 00000000 00:00 0 [anon:linker_alloc]
184370eba2d000-70eba2e000 r--s 00000000 fc:00 881 /system/framework/android.test.base.jar
184470eba2e000-70eba2f000 r--s 00000000 fc:00 707 /system/framework/framework-oahl-backward-compatibility.jar
184570eba2f000-70eba30000 r--s 00000000 fc:00 705 /system/framework/android.hidl.manager-V1.0-java.jar
184670eba30000-70eba34000 rw-p 00000000 00:05 10270793 /dev/ashmem/dalvik-thread local mark stack (deleted)
184770eba34000-70eba38000 rw-p 00000000 00:05 10270792 /dev/ashmem/dalvik-thread local mark stack (deleted)
184870eba38000-70eba3c000 rw-p 00000000 00:05 10270791 /dev/ashmem/dalvik-thread local mark stack (deleted)
184970eba3c000-70eba40000 rw-p 00000000 00:05 10270790 /dev/ashmem/dalvik-thread local mark stack (deleted)
185070eba40000-70eba44000 rw-p 00000000 00:05 10270789 /dev/ashmem/dalvik-thread local mark stack (deleted)
185170eba44000-70eba48000 rw-p 00000000 00:05 10270788 /dev/ashmem/dalvik-thread local mark stack (deleted)
185270eba48000-70eba4c000 rw-p 00000000 00:05 10270787 /dev/ashmem/dalvik-thread local mark stack (deleted)
185370eba4c000-70eba50000 rw-p 00000000 00:05 10270786 /dev/ashmem/dalvik-thread local mark stack (deleted)
185470eba50000-70eba52000 r--p 00000000 00:00 0 [anon:linker_alloc]
185570eba52000-70eba53000 r--s 00000000 fc:00 971 /system/framework/android.hidl.base-V1.0-java.jar
185670eba53000-70eba57000 rw-p 00000000 00:05 10270785 /dev/ashmem/dalvik-thread local mark stack (deleted)
185770eba57000-70eba5b000 rw-p 00000000 00:05 10270784 /dev/ashmem/dalvik-thread local mark stack (deleted)
185870eba5b000-70eba5f000 rw-p 00000000 00:05 10270783 /dev/ashmem/dalvik-thread local mark stack (deleted)
185970eba5f000-70eba63000 rw-p 00000000 00:05 10270782 /dev/ashmem/dalvik-thread local mark stack (deleted)
186070eba63000-70eba64000 rw-p 00000000 00:00 0 [anon:linker_alloc]
186170eba64000-70eba65000 r--s 00000000 fc:00 889 /system/framework/ims-common.jar
186270eba65000-70eba69000 rw-p 00000000 00:05 10270781 /dev/ashmem/dalvik-thread local mark stack (deleted)
186370eba69000-70eba6d000 rw-p 00000000 00:05 10270780 /dev/ashmem/dalvik-thread local mark stack (deleted)
186470eba6d000-70eba71000 rw-p 00000000 00:05 10270779 /dev/ashmem/dalvik-thread local mark stack (deleted)
186570eba71000-70eba75000 rw-p 00000000 00:05 10270778 /dev/ashmem/dalvik-thread local mark stack (deleted)
186670eba75000-70eba95000 rw-p 00000000 00:05 10267647 /dev/ashmem/dalvik-large marked objects (deleted)
186770eba95000-70ebab5000 rw-p 00000000 00:05 10267646 /dev/ashmem/dalvik-large live objects (deleted)
186870ebab5000-70ebab6000 r--p 00000000 00:00 0 [anon:linker_alloc]
186970ebab6000-70ebab7000 rw-p 00000000 00:00 0 [anon:linker_alloc]
187070ebab7000-70ebabb000 rw-p 00000000 00:05 10270777 /dev/ashmem/dalvik-thread local mark stack (deleted)
187170ebabb000-70ebadb000 r--s 00000000 00:10 16603 /dev/__properties__/u:object_r:exported_fingerprint_prop:s0
187270ebadb000-70ebadc000 r--p 00000000 00:00 0 [anon:linker_alloc]
187370ebadc000-70ebadd000 r--s 00000000 fc:00 878 /system/framework/voip-common.jar
187470ebadd000-70ebadf000 rw-p 00000000 00:05 10270995 /dev/ashmem/dalvik-indirect ref table (deleted)
187570ebadf000-70ebae3000 rw-p 00000000 00:05 10270776 /dev/ashmem/dalvik-thread local mark stack (deleted)
187670ebae3000-70ebae7000 rw-p 00000000 00:05 10270775 /dev/ashmem/dalvik-thread local mark stack (deleted)
187770ebae7000-70ebaeb000 rw-p 00000000 00:05 10270774 /dev/ashmem/dalvik-thread local mark stack (deleted)
187870ebaeb000-70ebaef000 rw-p 00000000 00:05 10270773 /dev/ashmem/dalvik-thread local mark stack (deleted)
187970ebaef000-70ebb0f000 r--s 00000000 00:10 16582 /dev/__properties__/u:object_r:debug_prop:s0
188070ebb0f000-70ebb10000 rw-p 00000000 00:00 0 [anon:linker_alloc]
188170ebb10000-70ebb11000 r--s 00000000 fc:00 703 /system/framework/telephony-common.jar
188270ebb11000-70ebb13000 rw-p 00000000 00:05 10270994 /dev/ashmem/dalvik-indirect ref table (deleted)
188370ebb13000-70ebb17000 rw-p 00000000 00:05 10270772 /dev/ashmem/dalvik-thread local mark stack (deleted)
188470ebb17000-70ebb19000 r--p 00000000 00:00 0 [anon:linker_alloc]
188570ebb19000-70ebb1d000 rw-p 00000000 00:05 10270771 /dev/ashmem/dalvik-thread local mark stack (deleted)
188670ebb1d000-70ebb3d000 r--s 00000000 00:10 16600 /dev/__properties__/u:object_r:exported_default_prop:s0
188770ebb3d000-70ebb5d000 r--s 00000000 00:10 16650 /dev/__properties__/u:object_r:system_prop:s0
188870ebb5d000-70ebb7d000 r--s 00000000 00:10 16610 /dev/__properties__/u:object_r:exported_vold_prop:s0
188970ebb7d000-70ebb9d000 r--s 00000000 00:10 16598 /dev/__properties__/u:object_r:exported_config_prop:s0
189070ebb9d000-70ebb9e000 rw-p 00000000 00:00 0 [anon:linker_alloc]
189170ebb9e000-70ebba2000 rw-p 00000000 00:05 10270770 /dev/ashmem/dalvik-thread local mark stack (deleted)
189270ebba2000-70ebba6000 rw-p 00000000 00:05 10270769 /dev/ashmem/dalvik-thread local mark stack (deleted)
189370ebba6000-70ebba7000 r--p 00000000 00:00 0 [anon:linker_alloc]
189470ebba7000-70ebba8000 r--s 00000000 fc:00 1004 /system/framework/framework.jar
189570ebba8000-70ebbac000 rw-p 00000000 00:05 10270768 /dev/ashmem/dalvik-thread local mark stack (deleted)
189670ebbac000-70ebbb0000 rw-p 00000000 00:05 10270767 /dev/ashmem/dalvik-thread local mark stack (deleted)
189770ebbb0000-70ebbb4000 rw-p 00000000 00:05 10270766 /dev/ashmem/dalvik-thread local mark stack (deleted)
189870ebbb4000-70ebbb8000 rw-p 00000000 00:05 10270765 /dev/ashmem/dalvik-thread local mark stack (deleted)
189970ebbb8000-70ebbbc000 rw-p 00000000 00:05 10270764 /dev/ashmem/dalvik-thread local mark stack (deleted)
190070ebbbc000-70ebbc0000 rw-p 00000000 00:05 10270763 /dev/ashmem/dalvik-thread local mark stack (deleted)
190170ebbc0000-70ebbc4000 rw-p 00000000 00:05 10270762 /dev/ashmem/dalvik-thread local mark stack (deleted)
190270ebbc4000-70ebbe4000 r--s 00000000 00:10 16581 /dev/__properties__/u:object_r:dalvik_prop:s0
190370ebbe4000-70ebbe5000 rw-p 00000000 00:00 0 [anon:linker_alloc]
190470ebbe5000-70ebbe6000 r--s 00004000 fc:00 877 /system/framework/apache-xml.jar
190570ebbe6000-70ebbe8000 rw-p 00000000 00:05 10270993 /dev/ashmem/dalvik-indirect ref table (deleted)
190670ebbe8000-70ebbec000 rw-p 00000000 00:05 10270761 /dev/ashmem/dalvik-thread local mark stack (deleted)
190770ebbec000-70ebbf0000 rw-p 00000000 00:05 10270760 /dev/ashmem/dalvik-thread local mark stack (deleted)
190870ebbf0000-70ebbf4000 rw-p 00000000 00:05 10270759 /dev/ashmem/dalvik-thread local mark stack (deleted)
190970ebbf4000-70ebbf8000 rw-p 00000000 00:05 10270758 /dev/ashmem/dalvik-thread local mark stack (deleted)
191070ebbf8000-70ebbf9000 r--p 00000000 00:00 0 [anon:linker_alloc]
191170ebbf9000-70ebbfa000 r--s 00000000 fc:00 968 /system/framework/bouncycastle.jar
191270ebbfa000-70ebbfc000 rw-p 00000000 00:05 10270992 /dev/ashmem/dalvik-indirect ref table (deleted)
191370ebbfc000-70ebc00000 rw-p 00000000 00:05 10270757 /dev/ashmem/dalvik-thread local mark stack (deleted)
191470ebc00000-70ebc04000 rw-p 00000000 00:05 10270756 /dev/ashmem/dalvik-thread local mark stack (deleted)
191570ebc04000-70ebc08000 rw-p 00000000 00:05 10270755 /dev/ashmem/dalvik-thread local mark stack (deleted)
191670ebc08000-70ebc0c000 rw-p 00000000 00:05 10270754 /dev/ashmem/dalvik-thread local mark stack (deleted)
191770ebc0c000-70ebc10000 rw-p 00000000 00:05 10270753 /dev/ashmem/dalvik-thread local mark stack (deleted)
191870ebc10000-70ebc14000 rw-p 00000000 00:05 10270752 /dev/ashmem/dalvik-thread local mark stack (deleted)
191970ebc14000-70ebc15000 rw-p 00000000 00:00 0 [anon:linker_alloc]
192070ebc15000-70ebc16000 r--s 00000000 fc:00 960 /system/framework/okhttp.jar
192170ebc16000-70ebc1a000 rw-p 00000000 00:05 10270751 /dev/ashmem/dalvik-thread local mark stack (deleted)
192270ebc1a000-70ebc1e000 rw-p 00000000 00:05 10270750 /dev/ashmem/dalvik-thread local mark stack (deleted)
192370ebc1e000-70ebc3e000 r--s 00000000 00:10 16584 /dev/__properties__/u:object_r:default_prop:s0
192470ebc3e000-70ebc3f000 r--p 00000000 00:00 0 [anon:linker_alloc]
192570ebc3f000-70ebc40000 r--s 00000000 fc:00 974 /system/framework/conscrypt.jar
192670ebc40000-70ebc42000 rw-p 00000000 00:05 10269719 /dev/ashmem/dalvik-indirect ref table (deleted)
192770ebc42000-70ebc46000 rw-p 00000000 00:05 10270749 /dev/ashmem/dalvik-thread local mark stack (deleted)
192870ebc46000-70ebc4a000 rw-p 00000000 00:05 10270748 /dev/ashmem/dalvik-thread local mark stack (deleted)
192970ebc4a000-70ebc4e000 rw-p 00000000 00:05 10270747 /dev/ashmem/dalvik-thread local mark stack (deleted)
193070ebc4e000-70ebc4f000 rw-p 00000000 00:00 0 [anon:linker_alloc]
193170ebc4f000-70ebc51000 rw-p 00000000 00:05 10269718 /dev/ashmem/dalvik-indirect ref table (deleted)
193270ebc51000-70ebc55000 rw-p 00000000 00:05 10270746 /dev/ashmem/dalvik-thread local mark stack (deleted)
193370ebc55000-70ebc59000 rw-p 00000000 00:05 10270745 /dev/ashmem/dalvik-thread local mark stack (deleted)
193470ebc59000-70ebc5d000 rw-p 00000000 00:05 10270744 /dev/ashmem/dalvik-thread local mark stack (deleted)
193570ebc5d000-70ebc7d000 r--s 00000000 00:10 16599 /dev/__properties__/u:object_r:exported_dalvik_prop:s0
193670ebc7d000-70ebc7e000 rw-p 00000000 00:00 0 [anon:linker_alloc]
193770ebc7e000-70ebc7f000 r--p 00000000 00:00 0 [anon:linker_alloc]
193870ebc7f000-70ebc80000 r--s 00004000 fc:00 963 /system/framework/core-libart.jar
193970ebc80000-70ebc81000 r--p 00000000 00:00 0 [anon:linker_alloc]
194070ebc81000-70ebc85000 rw-p 00000000 00:05 10270743 /dev/ashmem/dalvik-thread local mark stack (deleted)
194170ebc85000-70ebc89000 rw-p 00000000 00:05 10270742 /dev/ashmem/dalvik-thread local mark stack (deleted)
194270ebc89000-70ebc8a000 rw-p 00000000 00:00 0 [anon:linker_alloc_small_objects]
194370ebc8a000-70ebc8c000 r--p 00000000 00:00 0 [anon:linker_alloc]
194470ebc8c000-70ebc8d000 r--s 0001e000 fc:00 699 /system/framework/core-oj.jar
194570ebc8d000-70ebc91000 rw-p 00000000 00:05 10270741 /dev/ashmem/dalvik-thread local mark stack (deleted)
194670ebc91000-70ebc95000 rw-p 00000000 00:05 10270740 /dev/ashmem/dalvik-thread local mark stack (deleted)
194770ebc95000-70ebc99000 rw-p 00000000 00:05 10270739 /dev/ashmem/dalvik-thread local mark stack (deleted)
194870ebc99000-70ebc9b000 r--p 00000000 00:00 0 [anon:linker_alloc]
194970ebc9b000-70ebc9c000 rw-p 00000000 00:00 0 [anon:linker_alloc]
195070ebc9c000-70ebca0000 rw-p 00000000 00:05 10270738 /dev/ashmem/dalvik-thread local mark stack (deleted)
195170ebca0000-70ebca4000 rw-p 00000000 00:05 10270737 /dev/ashmem/dalvik-thread local mark stack (deleted)
195270ebca4000-70ebca8000 rw-p 00000000 00:05 10270736 /dev/ashmem/dalvik-thread local mark stack (deleted)
195370ebca8000-70ebcac000 rw-p 00000000 00:05 10270735 /dev/ashmem/dalvik-thread local mark stack (deleted)
195470ebcac000-70ebcb0000 rw-p 00000000 00:05 10270734 /dev/ashmem/dalvik-thread local mark stack (deleted)
195570ebcb0000-70ebcd0000 r--s 00000000 00:10 16592 /dev/__properties__/u:object_r:exported2_system_prop:s0
195670ebcd0000-70ebcd1000 rw-p 00000000 00:00 0 [anon:linker_alloc]
195770ebcd1000-70ebcd5000 rw-p 00000000 00:05 10270733 /dev/ashmem/dalvik-thread local mark stack (deleted)
195870ebcd5000-70ebcd9000 rw-p 00000000 00:05 10270732 /dev/ashmem/dalvik-thread local mark stack (deleted)
195970ebcd9000-70ebcdd000 rw-p 00000000 00:05 10270731 /dev/ashmem/dalvik-thread local mark stack (deleted)
196070ebcdd000-70ebce1000 rw-p 00000000 00:05 10270730 /dev/ashmem/dalvik-thread local mark stack (deleted)
196170ebce1000-70ebce5000 rw-p 00000000 00:05 10270729 /dev/ashmem/dalvik-thread local mark stack (deleted)
196270ebce5000-70ebce9000 rw-p 00000000 00:05 10270728 /dev/ashmem/dalvik-thread local mark stack (deleted)
196370ebce9000-70ebcea000 r--p 00000000 00:00 0 [anon:linker_alloc]
196470ebcea000-70ebcec000 rw-p 00000000 00:05 10270987 /dev/ashmem/dalvik-indirect ref table (deleted)
196570ebcec000-70ebcf9000 r--p 00646000 103:1d 639532 /data/dalvik-cache/arm64/system@framework@boot-framework.art
196670ebcf9000-70ebd19000 r--s 00000000 00:10 16620 /dev/__properties__/u:object_r:log_tag_prop:s0
196770ebd19000-70ebd39000 r--s 00000000 00:10 16621 /dev/__properties__/u:object_r:logd_prop:s0
196870ebd39000-70ebd3a000 rw-p 00000000 00:00 0 [anon:linker_alloc]
196970ebd3a000-70ebd3b000 r--p 00000000 00:00 0 [anon:linker_alloc]
197070ebd3b000-70ebd3f000 rw-p 00000000 00:05 10270727 /dev/ashmem/dalvik-thread local mark stack (deleted)
197170ebd3f000-70ebd40000 r--p 00002000 103:1d 639556 /data/dalvik-cache/arm64/system@framework@boot-com.google.vr.platform.art
197270ebd40000-70ebd41000 r--p 00005000 103:1d 639553 /data/dalvik-cache/arm64/system@framework@boot-android.test.base.art
197370ebd41000-70ebd42000 r--p 00000000 00:00 0 [anon:linker_alloc]
197470ebd42000-70ebd43000 r--p 00001000 103:1d 639550 /data/dalvik-cache/arm64/system@framework@boot-framework-oahl-backward-compatibility.art
197570ebd43000-70ebd44000 r--p 00005000 103:1d 639547 /data/dalvik-cache/arm64/system@framework@boot-android.hidl.manager-V1.0-java.art
197670ebd44000-70ebd45000 r--p 00003000 103:1d 639544 /data/dalvik-cache/arm64/system@framework@boot-android.hidl.base-V1.0-java.art
197770ebd45000-70ebd46000 r--p 00000000 00:00 0 [anon:linker_alloc]
197870ebd46000-70ebd47000 r--p 0000f000 103:1d 639541 /data/dalvik-cache/arm64/system@framework@boot-ims-common.art
197970ebd47000-70ebd48000 r--p 0000d000 103:1d 639538 /data/dalvik-cache/arm64/system@framework@boot-voip-common.art
198070ebd48000-70ebd4a000 r--p 0005e000 103:1d 639535 /data/dalvik-cache/arm64/system@framework@boot-telephony-common.art
198170ebd4a000-70ebd4b000 r--p 00040000 103:1d 639529 /data/dalvik-cache/arm64/system@framework@boot-ext.art
198270ebd4b000-70ebd4c000 r--p 0004a000 103:1d 639526 /data/dalvik-cache/arm64/system@framework@boot-apache-xml.art
198370ebd4c000-70ebd4d000 r--p 00046000 103:1d 639523 /data/dalvik-cache/arm64/system@framework@boot-bouncycastle.art
198470ebd4d000-70ebd4e000 r--p 00000000 00:00 0 [anon:linker_alloc]
198570ebd4e000-70ebd53000 r--p 00225000 103:1d 639511 /data/dalvik-cache/arm64/system@framework@boot.art
198670ebd53000-70ebd5a000 rw-p 00000000 fc:00 583 /system/etc/event-log-tags
198770ebd5a000-70ebd5b000 r--p 00000000 00:00 0 [anon:linker_alloc]
198870ebd5b000-70ebd5c000 r--p 0002e000 103:1d 639520 /data/dalvik-cache/arm64/system@framework@boot-okhttp.art
198970ebd5c000-70ebd5d000 r--p 00035000 103:1d 639517 /data/dalvik-cache/arm64/system@framework@boot-conscrypt.art
199070ebd5d000-70ebd5f000 r--p 000d0000 103:1d 639514 /data/dalvik-cache/arm64/system@framework@boot-core-libart.art
199170ebd5f000-70ebd62000 r--p 00000000 00:00 0 [anon:atexit handlers]
199270ebd62000-70ebd63000 rw-p 00000000 00:00 0
199370ebd63000-70ebd83000 r--s 00000000 00:10 16590 /dev/__properties__/u:object_r:exported2_default_prop:s0
199470ebd83000-70ebd84000 rw-p 00000000 00:00 0 [anon:linker_alloc]
199570ebd84000-70ebd89000 rw-p 00000000 00:00 0
199670ebd89000-70ebda9000 r--s 00000000 00:10 16669 /dev/__properties__/properties_serial
199770ebda9000-70ebdb3000 r--s 00000000 00:10 16560 /dev/__properties__/property_info
199870ebdb3000-70ebdb4000 rw-p 00000000 00:00 0 [anon:linker_alloc_vector]
199970ebdb4000-70ebdb5000 rw-p 00000000 00:00 0 [anon:linker_alloc_small_objects]
200070ebdb5000-70ebdb7000 rw-p 00000000 00:00 0 [anon:System property context nodes]
200170ebdb7000-70ebdb8000 rw-p 00000000 00:00 0 [anon:linker_alloc_vector]
200270ebdb8000-70ebdba000 rw-p 00000000 00:00 0 [anon:linker_alloc_small_objects]
200370ebdba000-70ebdbb000 rw-p 00000000 00:00 0 [anon:linker_alloc]
200470ebdbb000-70ebdbd000 rw-p 00000000 00:00 0 [anon:linker_alloc_small_objects]
200570ebdbd000-70ebdbe000 r--p 00000000 00:00 0 [anon:atexit handlers]
200670ebdbe000-70ebdbf000 r--p 00000000 00:00 0 [anon:linker_alloc]
200770ebdbf000-70ebdc0000 rw-p 00000000 00:00 0 [anon:linker_alloc_small_objects]
200870ebdc0000-70ebdc1000 rw-p 00000000 00:00 0 [anon:linker_alloc_vector]
200970ebdc1000-70ebdc2000 rw-p 00000000 00:00 0 [anon:linker_alloc_small_objects]
201070ebdc2000-70ebdc3000 rw-p 00000000 00:00 0 [anon:linker_alloc_vector]
201170ebdc3000-70ebdc5000 rw-p 00000000 00:00 0 [anon:linker_alloc_small_objects]
201270ebdc5000-70ebde5000 r--s 00000000 00:10 16600 /dev/__properties__/u:object_r:exported_default_prop:s0
201370ebde5000-70ebde6000 rw-p 00000000 00:00 0 [anon:linker_alloc_small_objects]
201470ebde6000-70ebde8000 r--p 00000000 00:00 0 [anon:linker_alloc]
201570ebde8000-70ebe08000 r--s 00000000 00:10 16582 /dev/__properties__/u:object_r:debug_prop:s0
201670ebe08000-70ebe09000 ---p 00000000 00:00 0
201770ebe09000-70ebe0a000 rw-p 00000000 00:00 0
201870ebe0a000-70ebe0b000 ---p 00000000 00:00 0
201970ebe0b000-70ebe2b000 r--s 00000000 00:10 16669 /dev/__properties__/properties_serial
202070ebe2b000-70ebe2d000 rw-p 00000000 00:00 0 [anon:System property context nodes]
202170ebe2d000-70ebf55000 r-xp 00000000 fc:00 3184 /system/bin/linker64
202270ebf55000-70ebf5f000 r--s 00000000 00:10 16560 /dev/__properties__/property_info
202370ebf5f000-70ebf60000 r--p 00000000 00:00 0 [anon:linker_alloc]
202470ebf60000-70ebf61000 rw-p 00000000 00:00 0 [anon:linker_alloc_vector]
202570ebf61000-70ebf62000 rw-p 00000000 00:00 0 [anon:linker_alloc_small_objects]
202670ebf62000-70ebf63000 rw-p 00000000 00:00 0 [anon:arc4random data]
202770ebf63000-70ebf64000 rw-p 00000000 00:00 0 [anon:linker_alloc_small_objects]
202870ebf64000-70ebf65000 r--p 00000000 00:00 0 [anon:atexit handlers]
202970ebf65000-70ebf66000 ---p 00000000 00:00 0 [anon:thread signal stack guard]
203070ebf66000-70ebf6a000 rw-p 00000000 00:00 0 [anon:thread signal stack]
203170ebf6a000-70ebf6b000 rw-p 00000000 00:00 0 [anon:arc4random data]
203270ebf6b000-70ebf6c000 ---p 00000000 00:00 0 [anon:bionic TLS guard]
203370ebf6c000-70ebf6f000 rw-p 00000000 00:00 0 [anon:bionic TLS]
203470ebf6f000-70ebf70000 ---p 00000000 00:00 0 [anon:bionic TLS guard]
203570ebf70000-70ebf71000 r--p 00000000 00:00 0 [vvar]
203670ebf71000-70ebf72000 r-xp 00000000 00:00 0 [vdso]
203770ebf72000-70ebf7d000 r--p 00135000 fc:00 3184 /system/bin/linker64
203870ebf7d000-70ebf7e000 rw-p 00140000 fc:00 3184 /system/bin/linker64
203970ebf7e000-70ebf81000 rw-p 00000000 00:00 0
204070ebf81000-70ebf82000 r--p 00000000 00:00 0
204170ebf82000-70ebf89000 rw-p 00000000 00:00 0
20427fc7df1000-7fc7df2000 ---p 00000000 00:00 0
20437fc7df2000-7fc85f1000 rw-p 00000000 00:00 0 [stack]
diff --git a/libstats/Android.bp b/libstats/Android.bp
new file mode 100644
index 000000000..d58f29417
--- /dev/null
+++ b/libstats/Android.bp
@@ -0,0 +1,37 @@
1//
2// Copyright (C) 2018 The Android Open Source Project
3//
4// Licensed under the Apache License, Version 2.0 (the "License");
5// you may not use this file except in compliance with the License.
6// You may obtain a copy of the License at
7//
8// http://www.apache.org/licenses/LICENSE-2.0
9//
10// Unless required by applicable law or agreed to in writing, software
11// distributed under the License is distributed on an "AS IS" BASIS,
12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13// See the License for the specific language governing permissions and
14// limitations under the License.
15//
16
17// ==========================================================
18// Native library to write stats log to statsd socket
19// ==========================================================
20cc_library_static {
21 name: "libstatssocket",
22 srcs: [
23 "stats_event_list.c",
24 "statsd_writer.c",
25 ],
26 cflags: [
27 "-Wall",
28 "-Werror",
29 "-DLIBLOG_LOG_TAG=1006",
30 "-DWRITE_TO_STATSD=1",
31 "-DWRITE_TO_LOGD=0",
32 ],
33 export_include_dirs: ["include"],
34 shared_libs: [
35 "liblog",
36 ],
37}
diff --git a/libstats/OWNERS b/libstats/OWNERS
new file mode 100644
index 000000000..ed06fbc81
--- /dev/null
+++ b/libstats/OWNERS
@@ -0,0 +1,4 @@
1bookatz@google.com
2joeo@google.com
3yaochen@google.com
4yanglu@google.com
diff --git a/libstats/include/stats_event_list.h b/libstats/include/stats_event_list.h
new file mode 100644
index 000000000..5d174ae03
--- /dev/null
+++ b/libstats/include/stats_event_list.h
@@ -0,0 +1,250 @@
1/*
2 * Copyright (C) 2018, The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#ifndef ANDROID_STATS_LOG_STATS_EVENT_LIST_H
18#define ANDROID_STATS_LOG_STATS_EVENT_LIST_H
19
20#include <log/log_event_list.h>
21
22#ifdef __cplusplus
23extern "C" {
24#endif
25void reset_log_context(android_log_context ctx);
26int write_to_logger(android_log_context context, log_id_t id);
27
28#ifdef __cplusplus
29}
30#endif
31
32#ifdef __cplusplus
33/**
34 * A copy of android_log_event_list class.
35 *
36 * android_log_event_list is going to be deprecated soon, so copy it here to
37 * avoid creating dependency on upstream code. TODO(b/78304629): Rewrite this
38 * code.
39 */
40class stats_event_list {
41 private:
42 android_log_context ctx;
43 int ret;
44
45 stats_event_list(const stats_event_list&) = delete;
46 void operator=(const stats_event_list&) = delete;
47
48 public:
49 explicit stats_event_list(int tag) : ret(0) {
50 ctx = create_android_logger(static_cast<uint32_t>(tag));
51 }
52 explicit stats_event_list(log_msg& log_msg) : ret(0) {
53 ctx = create_android_log_parser(log_msg.msg() + sizeof(uint32_t),
54 log_msg.entry.len - sizeof(uint32_t));
55 }
56 ~stats_event_list() { android_log_destroy(&ctx); }
57
58 int close() {
59 int retval = android_log_destroy(&ctx);
60 if (retval < 0) {
61 ret = retval;
62 }
63 return retval;
64 }
65
66 /* To allow above C calls to use this class as parameter */
67 operator android_log_context() const { return ctx; }
68
69 /* return errors or transmit status */
70 int status() const { return ret; }
71
72 int begin() {
73 int retval = android_log_write_list_begin(ctx);
74 if (retval < 0) {
75 ret = retval;
76 }
77 return ret;
78 }
79 int end() {
80 int retval = android_log_write_list_end(ctx);
81 if (retval < 0) {
82 ret = retval;
83 }
84 return ret;
85 }
86
87 stats_event_list& operator<<(int32_t value) {
88 int retval = android_log_write_int32(ctx, value);
89 if (retval < 0) {
90 ret = retval;
91 }
92 return *this;
93 }
94
95 stats_event_list& operator<<(uint32_t value) {
96 int retval = android_log_write_int32(ctx, static_cast<int32_t>(value));
97 if (retval < 0) {
98 ret = retval;
99 }
100 return *this;
101 }
102
103 stats_event_list& operator<<(bool value) {
104 int retval = android_log_write_int32(ctx, value ? 1 : 0);
105 if (retval < 0) {
106 ret = retval;
107 }
108 return *this;
109 }
110
111 stats_event_list& operator<<(int64_t value) {
112 int retval = android_log_write_int64(ctx, value);
113 if (retval < 0) {
114 ret = retval;
115 }
116 return *this;
117 }
118
119 stats_event_list& operator<<(uint64_t value) {
120 int retval = android_log_write_int64(ctx, static_cast<int64_t>(value));
121 if (retval < 0) {
122 ret = retval;
123 }
124 return *this;
125 }
126
127 stats_event_list& operator<<(const char* value) {
128 int retval = android_log_write_string8(ctx, value);
129 if (retval < 0) {
130 ret = retval;
131 }
132 return *this;
133 }
134
135#if defined(_USING_LIBCXX)
136 stats_event_list& operator<<(const std::string& value) {
137 int retval = android_log_write_string8_len(ctx, value.data(), value.length());
138 if (retval < 0) {
139 ret = retval;
140 }
141 return *this;
142 }
143#endif
144
145 stats_event_list& operator<<(float value) {
146 int retval = android_log_write_float32(ctx, value);
147 if (retval < 0) {
148 ret = retval;
149 }
150 return *this;
151 }
152
153 int write(log_id_t id = LOG_ID_EVENTS) {
154 /* facilitate -EBUSY retry */
155 if ((ret == -EBUSY) || (ret > 0)) {
156 ret = 0;
157 }
158 int retval = write_to_logger(ctx, id);
159 /* existing errors trump transmission errors */
160 if (!ret) {
161 ret = retval;
162 }
163 return ret;
164 }
165
166 /*
167 * Append<Type> methods removes any integer promotion
168 * confusion, and adds access to string with length.
169 * Append methods are also added for all types for
170 * convenience.
171 */
172
173 bool AppendInt(int32_t value) {
174 int retval = android_log_write_int32(ctx, value);
175 if (retval < 0) {
176 ret = retval;
177 }
178 return ret >= 0;
179 }
180
181 bool AppendLong(int64_t value) {
182 int retval = android_log_write_int64(ctx, value);
183 if (retval < 0) {
184 ret = retval;
185 }
186 return ret >= 0;
187 }
188
189 bool AppendString(const char* value) {
190 int retval = android_log_write_string8(ctx, value);
191 if (retval < 0) {
192 ret = retval;
193 }
194 return ret >= 0;
195 }
196
197 bool AppendString(const char* value, size_t len) {
198 int retval = android_log_write_string8_len(ctx, value, len);
199 if (retval < 0) {
200 ret = retval;
201 }
202 return ret >= 0;
203 }
204
205#if defined(_USING_LIBCXX)
206 bool AppendString(const std::string& value) {
207 int retval = android_log_write_string8_len(ctx, value.data(), value.length());
208 if (retval < 0) {
209 ret = retval;
210 }
211 return ret;
212 }
213
214 bool Append(const std::string& value) {
215 int retval = android_log_write_string8_len(ctx, value.data(), value.length());
216 if (retval < 0) {
217 ret = retval;
218 }
219 return ret;
220 }
221#endif
222
223 bool AppendFloat(float value) {
224 int retval = android_log_write_float32(ctx, value);
225 if (retval < 0) {
226 ret = retval;
227 }
228 return ret >= 0;
229 }
230
231 template <typename Tvalue>
232 bool Append(Tvalue value) {
233 *this << value;
234 return ret >= 0;
235 }
236
237 bool Append(const char* value, size_t len) {
238 int retval = android_log_write_string8_len(ctx, value, len);
239 if (retval < 0) {
240 ret = retval;
241 }
242 return ret >= 0;
243 }
244
245 android_log_list_element read() { return android_log_read_next(ctx); }
246 android_log_list_element peek() { return android_log_peek_next(ctx); }
247};
248
249#endif
250#endif // ANDROID_STATS_LOG_STATS_EVENT_LIST_H
diff --git a/libstats/stats_event_list.c b/libstats/stats_event_list.c
new file mode 100644
index 000000000..966bb08a2
--- /dev/null
+++ b/libstats/stats_event_list.c
@@ -0,0 +1,181 @@
1/*
2 * Copyright (C) 2018, The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include "include/stats_event_list.h"
18
19#include <string.h>
20#include "statsd_writer.h"
21
22#define MAX_EVENT_PAYLOAD (LOGGER_ENTRY_MAX_PAYLOAD - sizeof(int32_t))
23
24typedef struct {
25 uint32_t tag;
26 unsigned pos; /* Read/write position into buffer */
27 unsigned count[ANDROID_MAX_LIST_NEST_DEPTH + 1]; /* Number of elements */
28 unsigned list[ANDROID_MAX_LIST_NEST_DEPTH + 1]; /* pos for list counter */
29 unsigned list_nest_depth;
30 unsigned len; /* Length or raw buffer. */
31 bool overflow;
32 bool list_stop; /* next call decrement list_nest_depth and issue a stop */
33 enum {
34 kAndroidLoggerRead = 1,
35 kAndroidLoggerWrite = 2,
36 } read_write_flag;
37 uint8_t storage[LOGGER_ENTRY_MAX_PAYLOAD];
38} android_log_context_internal;
39
40extern struct android_log_transport_write statsdLoggerWrite;
41
42static int __write_to_statsd_init(struct iovec* vec, size_t nr);
43static int (*write_to_statsd)(struct iovec* vec, size_t nr) = __write_to_statsd_init;
44
45// Similar to create_android_logger(), but instead of allocation a new buffer,
46// this function resets the buffer for resuse.
47void reset_log_context(android_log_context ctx) {
48 if (!ctx) {
49 return;
50 }
51 android_log_context_internal* context = (android_log_context_internal*)(ctx);
52 uint32_t tag = context->tag;
53 memset(context, 0, sizeof(android_log_context_internal));
54
55 context->tag = tag;
56 context->read_write_flag = kAndroidLoggerWrite;
57 size_t needed = sizeof(uint8_t) + sizeof(uint8_t);
58 if ((context->pos + needed) > MAX_EVENT_PAYLOAD) {
59 context->overflow = true;
60 }
61 /* Everything is a list */
62 context->storage[context->pos + 0] = EVENT_TYPE_LIST;
63 context->list[0] = context->pos + 1;
64 context->pos += needed;
65}
66
67int stats_write_list(android_log_context ctx) {
68 android_log_context_internal* context;
69 const char* msg;
70 ssize_t len;
71
72 context = (android_log_context_internal*)(ctx);
73 if (!context || (kAndroidLoggerWrite != context->read_write_flag)) {
74 return -EBADF;
75 }
76
77 if (context->list_nest_depth) {
78 return -EIO;
79 }
80
81 /* NB: if there was overflow, then log is truncated. Nothing reported */
82 context->storage[1] = context->count[0];
83 len = context->len = context->pos;
84 msg = (const char*)context->storage;
85 /* it's not a list */
86 if (context->count[0] <= 1) {
87 len -= sizeof(uint8_t) + sizeof(uint8_t);
88 if (len < 0) {
89 len = 0;
90 }
91 msg += sizeof(uint8_t) + sizeof(uint8_t);
92 }
93
94 struct iovec vec[2];
95 vec[0].iov_base = &context->tag;
96 vec[0].iov_len = sizeof(context->tag);
97 vec[1].iov_base = (void*)msg;
98 vec[1].iov_len = len;
99 return write_to_statsd(vec, 2);
100}
101
102int write_to_logger(android_log_context ctx, log_id_t id) {
103 int retValue = 0;
104
105 if (WRITE_TO_LOGD) {
106 retValue = android_log_write_list(ctx, id);
107 }
108
109 if (WRITE_TO_STATSD) {
110 // log_event_list's cast operator is overloaded.
111 int ret = stats_write_list(ctx);
112 // In debugging phase, we may write to both logd and statsd. Prefer to
113 // return statsd socket write error code here.
114 if (ret < 0) {
115 retValue = ret;
116 }
117 }
118
119 return retValue;
120}
121
122/* log_init_lock assumed */
123static int __write_to_statsd_initialize_locked() {
124 if (!statsdLoggerWrite.open || ((*statsdLoggerWrite.open)() < 0)) {
125 if (statsdLoggerWrite.close) {
126 (*statsdLoggerWrite.close)();
127 return -ENODEV;
128 }
129 }
130 return 1;
131}
132
133static int __write_to_stats_daemon(struct iovec* vec, size_t nr) {
134 int ret, save_errno;
135 struct timespec ts;
136 size_t len, i;
137
138 for (len = i = 0; i < nr; ++i) {
139 len += vec[i].iov_len;
140 }
141 if (!len) {
142 return -EINVAL;
143 }
144
145 save_errno = errno;
146 clock_gettime(CLOCK_REALTIME, &ts);
147
148 ret = 0;
149
150 ssize_t retval;
151 retval = (*statsdLoggerWrite.write)(&ts, vec, nr);
152 if (ret >= 0) {
153 ret = retval;
154 }
155
156 errno = save_errno;
157 return ret;
158}
159
160static int __write_to_statsd_init(struct iovec* vec, size_t nr) {
161 int ret, save_errno = errno;
162
163 statsd_writer_init_lock();
164
165 if (write_to_statsd == __write_to_statsd_init) {
166 ret = __write_to_statsd_initialize_locked();
167 if (ret < 0) {
168 statsd_writer_init_unlock();
169 errno = save_errno;
170 return ret;
171 }
172
173 write_to_statsd = __write_to_stats_daemon;
174 }
175
176 statsd_writer_init_unlock();
177
178 ret = write_to_statsd(vec, nr);
179 errno = save_errno;
180 return ret;
181} \ No newline at end of file
diff --git a/libstats/statsd_writer.c b/libstats/statsd_writer.c
new file mode 100644
index 000000000..9953bba2e
--- /dev/null
+++ b/libstats/statsd_writer.c
@@ -0,0 +1,260 @@
1/*
2 * Copyright (C) 2018, The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16#include "statsd_writer.h"
17
18#include <cutils/sockets.h>
19#include <endian.h>
20#include <errno.h>
21#include <fcntl.h>
22#include <inttypes.h>
23#include <poll.h>
24#include <private/android_filesystem_config.h>
25#include <private/android_logger.h>
26#include <stdarg.h>
27#include <stdatomic.h>
28#include <stdio.h>
29#include <stdlib.h>
30#include <string.h>
31#include <sys/stat.h>
32#include <sys/types.h>
33#include <sys/un.h>
34#include <time.h>
35#include <unistd.h>
36
37/* branchless on many architectures. */
38#define min(x, y) ((y) ^ (((x) ^ (y)) & -((x) < (y))))
39
40static pthread_mutex_t log_init_lock = PTHREAD_MUTEX_INITIALIZER;
41
42void statsd_writer_init_lock() {
43 /*
44 * If we trigger a signal handler in the middle of locked activity and the
45 * signal handler logs a message, we could get into a deadlock state.
46 */
47 pthread_mutex_lock(&log_init_lock);
48}
49
50int statd_writer_trylock() {
51 return pthread_mutex_trylock(&log_init_lock);
52}
53
54void statsd_writer_init_unlock() {
55 pthread_mutex_unlock(&log_init_lock);
56}
57
58static int statsdAvailable();
59static int statsdOpen();
60static void statsdClose();
61static int statsdWrite(struct timespec* ts, struct iovec* vec, size_t nr);
62
63struct android_log_transport_write statsdLoggerWrite = {
64 .name = "statsd",
65 .sock = -EBADF,
66 .available = statsdAvailable,
67 .open = statsdOpen,
68 .close = statsdClose,
69 .write = statsdWrite,
70};
71
72/* log_init_lock assumed */
73static int statsdOpen() {
74 int i, ret = 0;
75
76 i = atomic_load(&statsdLoggerWrite.sock);
77 if (i < 0) {
78 int sock = TEMP_FAILURE_RETRY(socket(PF_UNIX, SOCK_DGRAM | SOCK_CLOEXEC | SOCK_NONBLOCK, 0));
79 if (sock < 0) {
80 ret = -errno;
81 } else {
82 struct sockaddr_un un;
83 memset(&un, 0, sizeof(struct sockaddr_un));
84 un.sun_family = AF_UNIX;
85 strcpy(un.sun_path, "/dev/socket/statsdw");
86
87 if (TEMP_FAILURE_RETRY(
88 connect(sock, (struct sockaddr*)&un, sizeof(struct sockaddr_un))) < 0) {
89 ret = -errno;
90 switch (ret) {
91 case -ENOTCONN:
92 case -ECONNREFUSED:
93 case -ENOENT:
94 i = atomic_exchange(&statsdLoggerWrite.sock, ret);
95 /* FALLTHRU */
96 default:
97 break;
98 }
99 close(sock);
100 } else {
101 ret = atomic_exchange(&statsdLoggerWrite.sock, sock);
102 if ((ret >= 0) && (ret != sock)) {
103 close(ret);
104 }
105 ret = 0;
106 }
107 }
108 }
109
110 return ret;
111}
112
113static void __statsdClose(int negative_errno) {
114 int sock = atomic_exchange(&statsdLoggerWrite.sock, negative_errno);
115 if (sock >= 0) {
116 close(sock);
117 }
118}
119
120static void statsdClose() {
121 __statsdClose(-EBADF);
122}
123
124static int statsdAvailable() {
125 if (atomic_load(&statsdLoggerWrite.sock) < 0) {
126 if (access("/dev/socket/statsdw", W_OK) == 0) {
127 return 0;
128 }
129 return -EBADF;
130 }
131 return 1;
132}
133
134static int statsdWrite(struct timespec* ts, struct iovec* vec, size_t nr) {
135 ssize_t ret;
136 int sock;
137 static const unsigned headerLength = 1;
138 struct iovec newVec[nr + headerLength];
139 android_log_header_t header;
140 size_t i, payloadSize;
141 static atomic_int dropped;
142
143 sock = atomic_load(&statsdLoggerWrite.sock);
144 if (sock < 0) switch (sock) {
145 case -ENOTCONN:
146 case -ECONNREFUSED:
147 case -ENOENT:
148 break;
149 default:
150 return -EBADF;
151 }
152 /*
153 * struct {
154 * // what we provide to socket
155 * android_log_header_t header;
156 * // caller provides
157 * union {
158 * struct {
159 * char prio;
160 * char payload[];
161 * } string;
162 * struct {
163 * uint32_t tag
164 * char payload[];
165 * } binary;
166 * };
167 * };
168 */
169
170 header.tid = gettid();
171 header.realtime.tv_sec = ts->tv_sec;
172 header.realtime.tv_nsec = ts->tv_nsec;
173
174 newVec[0].iov_base = (unsigned char*)&header;
175 newVec[0].iov_len = sizeof(header);
176
177 // If we dropped events before, try to tell statsd.
178 if (sock >= 0) {
179 int32_t snapshot = atomic_exchange_explicit(&dropped, 0, memory_order_relaxed);
180 if (snapshot) {
181 android_log_event_int_t buffer;
182 header.id = LOG_ID_STATS;
183 buffer.header.tag = htole32(LIBLOG_LOG_TAG);
184 buffer.payload.type = EVENT_TYPE_INT;
185 buffer.payload.data = htole32(snapshot);
186
187 newVec[headerLength].iov_base = &buffer;
188 newVec[headerLength].iov_len = sizeof(buffer);
189
190 ret = TEMP_FAILURE_RETRY(writev(sock, newVec, 2));
191 if (ret != (ssize_t)(sizeof(header) + sizeof(buffer))) {
192 atomic_fetch_add_explicit(&dropped, snapshot, memory_order_relaxed);
193 }
194 }
195 }
196
197 header.id = LOG_ID_STATS;
198
199 for (payloadSize = 0, i = headerLength; i < nr + headerLength; i++) {
200 newVec[i].iov_base = vec[i - headerLength].iov_base;
201 payloadSize += newVec[i].iov_len = vec[i - headerLength].iov_len;
202
203 if (payloadSize > LOGGER_ENTRY_MAX_PAYLOAD) {
204 newVec[i].iov_len -= payloadSize - LOGGER_ENTRY_MAX_PAYLOAD;
205 if (newVec[i].iov_len) {
206 ++i;
207 }
208 break;
209 }
210 }
211
212 /*
213 * The write below could be lost, but will never block.
214 *
215 * ENOTCONN occurs if statsd has died.
216 * ENOENT occurs if statsd is not running and socket is missing.
217 * ECONNREFUSED occurs if we can not reconnect to statsd.
218 * EAGAIN occurs if statsd is overloaded.
219 */
220 if (sock < 0) {
221 ret = sock;
222 } else {
223 ret = TEMP_FAILURE_RETRY(writev(sock, newVec, i));
224 if (ret < 0) {
225 ret = -errno;
226 }
227 }
228 switch (ret) {
229 case -ENOTCONN:
230 case -ECONNREFUSED:
231 case -ENOENT:
232 if (statd_writer_trylock()) {
233 return ret; /* in a signal handler? try again when less stressed
234 */
235 }
236 __statsdClose(ret);
237 ret = statsdOpen();
238 statsd_writer_init_unlock();
239
240 if (ret < 0) {
241 return ret;
242 }
243
244 ret = TEMP_FAILURE_RETRY(writev(atomic_load(&statsdLoggerWrite.sock), newVec, i));
245 if (ret < 0) {
246 ret = -errno;
247 }
248 /* FALLTHRU */
249 default:
250 break;
251 }
252
253 if (ret > (ssize_t)sizeof(header)) {
254 ret -= sizeof(header);
255 } else if (ret == -EAGAIN) {
256 atomic_fetch_add_explicit(&dropped, 1, memory_order_relaxed);
257 }
258
259 return ret;
260}
diff --git a/libstats/statsd_writer.h b/libstats/statsd_writer.h
new file mode 100644
index 000000000..82e14e04f
--- /dev/null
+++ b/libstats/statsd_writer.h
@@ -0,0 +1,43 @@
1/*
2 * Copyright (C) 2018, The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#ifndef ANDROID_STATS_LOG_STATS_WRITER_H
18#define ANDROID_STATS_LOG_STATS_WRITER_H
19
20#include <pthread.h>
21#include <stdatomic.h>
22#include <sys/socket.h>
23
24/**
25 * Internal lock should not be exposed. This is bad design.
26 * TODO: rewrite it in c++ code and encapsulate the functionality in a
27 * StatsdWriter class.
28 */
29void statsd_writer_init_lock();
30int statsd_writer_init_trylock();
31void statsd_writer_init_unlock();
32
33struct android_log_transport_write {
34 const char* name; /* human name to describe the transport */
35 atomic_int sock;
36 int (*available)(); /* Does not cause resources to be taken */
37 int (*open)(); /* can be called multiple times, reusing current resources */
38 void (*close)(); /* free up resources */
39 /* write log to transport, returns number of bytes propagated, or -errno */
40 int (*write)(struct timespec* ts, struct iovec* vec, size_t nr);
41};
42
43#endif // ANDROID_STATS_LOG_STATS_WRITER_H
diff --git a/libsystem/Android.bp b/libsystem/Android.bp
index 82bf1bce0..2e22b435f 100644
--- a/libsystem/Android.bp
+++ b/libsystem/Android.bp
@@ -1,6 +1,7 @@
1cc_library_headers { 1cc_library_headers {
2 name: "libsystem_headers", 2 name: "libsystem_headers",
3 vendor_available: true, 3 vendor_available: true,
4 recovery_available: true,
4 host_supported: true, 5 host_supported: true,
5 export_include_dirs: ["include"], 6 export_include_dirs: ["include"],
6 7
diff --git a/libunwindstack/Android.bp b/libunwindstack/Android.bp
index d411cee7f..82f2e7301 100644
--- a/libunwindstack/Android.bp
+++ b/libunwindstack/Android.bp
@@ -110,6 +110,10 @@ cc_library {
110 }, 110 },
111 }, 111 },
112 112
113 static_libs: [
114 "libprocinfo",
115 ],
116
113 shared_libs: [ 117 shared_libs: [
114 "libbase", 118 "libbase",
115 "libdexfile", 119 "libdexfile",
@@ -198,6 +202,7 @@ cc_test {
198 "tests/files/offline/jit_debug_x86/*", 202 "tests/files/offline/jit_debug_x86/*",
199 "tests/files/offline/jit_map_arm/*", 203 "tests/files/offline/jit_map_arm/*",
200 "tests/files/offline/gnu_debugdata_arm/*", 204 "tests/files/offline/gnu_debugdata_arm/*",
205 "tests/files/offline/offset_arm/*",
201 "tests/files/offline/straddle_arm/*", 206 "tests/files/offline/straddle_arm/*",
202 "tests/files/offline/straddle_arm64/*", 207 "tests/files/offline/straddle_arm64/*",
203 ], 208 ],
diff --git a/libunwindstack/Elf.cpp b/libunwindstack/Elf.cpp
index 02f8a9ae0..3762107d6 100644
--- a/libunwindstack/Elf.cpp
+++ b/libunwindstack/Elf.cpp
@@ -160,14 +160,14 @@ uint64_t Elf::GetLastErrorAddress() {
160} 160}
161 161
162// The relative pc is always relative to the start of the map from which it comes. 162// The relative pc is always relative to the start of the map from which it comes.
163bool Elf::Step(uint64_t rel_pc, uint64_t adjusted_rel_pc, uint64_t elf_offset, Regs* regs, 163bool Elf::Step(uint64_t rel_pc, uint64_t adjusted_rel_pc, Regs* regs, Memory* process_memory,
164 Memory* process_memory, bool* finished) { 164 bool* finished) {
165 if (!valid_) { 165 if (!valid_) {
166 return false; 166 return false;
167 } 167 }
168 168
169 // The relative pc expectd by StepIfSignalHandler is relative to the start of the elf. 169 // The relative pc expectd by StepIfSignalHandler is relative to the start of the elf.
170 if (regs->StepIfSignalHandler(rel_pc + elf_offset, this, process_memory)) { 170 if (regs->StepIfSignalHandler(rel_pc, this, process_memory)) {
171 *finished = false; 171 *finished = false;
172 return true; 172 return true;
173 } 173 }
diff --git a/libunwindstack/ElfInterface.cpp b/libunwindstack/ElfInterface.cpp
index 10afe33be..4c05a1bcc 100644
--- a/libunwindstack/ElfInterface.cpp
+++ b/libunwindstack/ElfInterface.cpp
@@ -87,8 +87,8 @@ Memory* ElfInterface::CreateGnuDebugdataMemory() {
87 87
88 ISzAlloc alloc; 88 ISzAlloc alloc;
89 CXzUnpacker state; 89 CXzUnpacker state;
90 alloc.Alloc = [](void*, size_t size) { return malloc(size); }; 90 alloc.Alloc = [](ISzAllocPtr, size_t size) { return malloc(size); };
91 alloc.Free = [](void*, void* ptr) { return free(ptr); }; 91 alloc.Free = [](ISzAllocPtr, void* ptr) { return free(ptr); };
92 92
93 XzUnpacker_Construct(&state, &alloc); 93 XzUnpacker_Construct(&state, &alloc);
94 94
@@ -106,7 +106,7 @@ Memory* ElfInterface::CreateGnuDebugdataMemory() {
106 dst_remaining += 2 * gnu_debugdata_size_; 106 dst_remaining += 2 * gnu_debugdata_size_;
107 } 107 }
108 return_val = XzUnpacker_Code(&state, dst->GetPtr(dst_offset), &dst_remaining, &src[src_offset], 108 return_val = XzUnpacker_Code(&state, dst->GetPtr(dst_offset), &dst_remaining, &src[src_offset],
109 &src_remaining, CODER_FINISH_ANY, &status); 109 &src_remaining, true, CODER_FINISH_ANY, &status);
110 src_offset += src_remaining; 110 src_offset += src_remaining;
111 dst_offset += dst_remaining; 111 dst_offset += dst_remaining;
112 } while (return_val == SZ_OK && status == CODER_STATUS_NOT_FINISHED); 112 } while (return_val == SZ_OK && status == CODER_STATUS_NOT_FINISHED);
diff --git a/libunwindstack/Maps.cpp b/libunwindstack/Maps.cpp
index e1a1a7144..bb682ea69 100644
--- a/libunwindstack/Maps.cpp
+++ b/libunwindstack/Maps.cpp
@@ -24,6 +24,7 @@
24#include <unistd.h> 24#include <unistd.h>
25 25
26#include <android-base/unique_fd.h> 26#include <android-base/unique_fd.h>
27#include <procinfo/process_map.h>
27 28
28#include <algorithm> 29#include <algorithm>
29#include <cctype> 30#include <cctype>
@@ -57,150 +58,16 @@ MapInfo* Maps::Find(uint64_t pc) {
57 return nullptr; 58 return nullptr;
58} 59}
59 60
60// Assumes that line does not end in '\n'.
61static MapInfo* InternalParseLine(const char* line) {
62 // Do not use a sscanf implementation since it is not performant.
63
64 // Example linux /proc/<pid>/maps lines:
65 // 6f000000-6f01e000 rwxp 00000000 00:0c 16389419 /system/lib/libcomposer.so
66 char* str;
67 const char* old_str = line;
68 uint64_t start = strtoull(old_str, &str, 16);
69 if (old_str == str || *str++ != '-') {
70 return nullptr;
71 }
72
73 old_str = str;
74 uint64_t end = strtoull(old_str, &str, 16);
75 if (old_str == str || !std::isspace(*str++)) {
76 return nullptr;
77 }
78
79 while (std::isspace(*str)) {
80 str++;
81 }
82
83 // Parse permissions data.
84 if (*str == '\0') {
85 return nullptr;
86 }
87 uint16_t flags = 0;
88 if (*str == 'r') {
89 flags |= PROT_READ;
90 } else if (*str != '-') {
91 return nullptr;
92 }
93 str++;
94 if (*str == 'w') {
95 flags |= PROT_WRITE;
96 } else if (*str != '-') {
97 return nullptr;
98 }
99 str++;
100 if (*str == 'x') {
101 flags |= PROT_EXEC;
102 } else if (*str != '-') {
103 return nullptr;
104 }
105 str++;
106 if (*str != 'p' && *str != 's') {
107 return nullptr;
108 }
109 str++;
110
111 if (!std::isspace(*str++)) {
112 return nullptr;
113 }
114
115 old_str = str;
116 uint64_t offset = strtoull(old_str, &str, 16);
117 if (old_str == str || !std::isspace(*str)) {
118 return nullptr;
119 }
120
121 // Ignore the 00:00 values.
122 old_str = str;
123 (void)strtoull(old_str, &str, 16);
124 if (old_str == str || *str++ != ':') {
125 return nullptr;
126 }
127 if (std::isspace(*str)) {
128 return nullptr;
129 }
130
131 // Skip the inode.
132 old_str = str;
133 (void)strtoull(str, &str, 16);
134 if (old_str == str || !std::isspace(*str++)) {
135 return nullptr;
136 }
137
138 // Skip decimal digit.
139 old_str = str;
140 (void)strtoull(old_str, &str, 10);
141 if (old_str == str || (!std::isspace(*str) && *str != '\0')) {
142 return nullptr;
143 }
144
145 while (std::isspace(*str)) {
146 str++;
147 }
148 if (*str == '\0') {
149 return new MapInfo(start, end, offset, flags, "");
150 }
151
152 // Save the name data.
153 std::string name(str);
154
155 // Mark a device map in /dev/ and not in /dev/ashmem/ specially.
156 if (name.substr(0, 5) == "/dev/" && name.substr(5, 7) != "ashmem/") {
157 flags |= MAPS_FLAGS_DEVICE_MAP;
158 }
159 return new MapInfo(start, end, offset, flags, name);
160}
161
162bool Maps::Parse() { 61bool Maps::Parse() {
163 int fd = open(GetMapsFile().c_str(), O_RDONLY | O_CLOEXEC); 62 return android::procinfo::ReadMapFile(
164 if (fd == -1) { 63 GetMapsFile(),
165 return false; 64 [&](uint64_t start, uint64_t end, uint16_t flags, uint64_t pgoff, const char* name) {
166 } 65 // Mark a device map in /dev/ and not in /dev/ashmem/ specially.
167 66 if (strncmp(name, "/dev/", 5) == 0 && strncmp(name + 5, "ashmem/", 7) != 0) {
168 bool return_value = true; 67 flags |= unwindstack::MAPS_FLAGS_DEVICE_MAP;
169 char buffer[2048]; 68 }
170 size_t leftover = 0; 69 maps_.push_back(new MapInfo(start, end, pgoff, flags, name));
171 while (true) { 70 });
172 ssize_t bytes = read(fd, &buffer[leftover], 2048 - leftover);
173 if (bytes == -1) {
174 return_value = false;
175 break;
176 }
177 if (bytes == 0) {
178 break;
179 }
180 bytes += leftover;
181 char* line = buffer;
182 while (bytes > 0) {
183 char* newline = static_cast<char*>(memchr(line, '\n', bytes));
184 if (newline == nullptr) {
185 memmove(buffer, line, bytes);
186 break;
187 }
188 *newline = '\0';
189
190 MapInfo* map_info = InternalParseLine(line);
191 if (map_info == nullptr) {
192 return_value = false;
193 break;
194 }
195 maps_.push_back(map_info);
196
197 bytes -= newline - line + 1;
198 line = newline + 1;
199 }
200 leftover = bytes;
201 }
202 close(fd);
203 return return_value;
204} 71}
205 72
206void Maps::Add(uint64_t start, uint64_t end, uint64_t offset, uint64_t flags, 73void Maps::Add(uint64_t start, uint64_t end, uint64_t offset, uint64_t flags,
@@ -222,26 +89,16 @@ Maps::~Maps() {
222} 89}
223 90
224bool BufferMaps::Parse() { 91bool BufferMaps::Parse() {
225 const char* start_of_line = buffer_; 92 std::string content(buffer_);
226 do { 93 return android::procinfo::ReadMapFileContent(
227 std::string line; 94 &content[0],
228 const char* end_of_line = strchr(start_of_line, '\n'); 95 [&](uint64_t start, uint64_t end, uint16_t flags, uint64_t pgoff, const char* name) {
229 if (end_of_line == nullptr) { 96 // Mark a device map in /dev/ and not in /dev/ashmem/ specially.
230 line = start_of_line; 97 if (strncmp(name, "/dev/", 5) == 0 && strncmp(name + 5, "ashmem/", 7) != 0) {
231 } else { 98 flags |= unwindstack::MAPS_FLAGS_DEVICE_MAP;
232 line = std::string(start_of_line, end_of_line - start_of_line); 99 }
233 end_of_line++; 100 maps_.push_back(new MapInfo(start, end, pgoff, flags, name));
234 } 101 });
235
236 MapInfo* map_info = InternalParseLine(line.c_str());
237 if (map_info == nullptr) {
238 return false;
239 }
240 maps_.push_back(map_info);
241
242 start_of_line = end_of_line;
243 } while (start_of_line != nullptr && *start_of_line != '\0');
244 return true;
245} 102}
246 103
247const std::string RemoteMaps::GetMapsFile() const { 104const std::string RemoteMaps::GetMapsFile() const {
diff --git a/libunwindstack/Unwinder.cpp b/libunwindstack/Unwinder.cpp
index 9a6c6dfe2..099cc9e9a 100644
--- a/libunwindstack/Unwinder.cpp
+++ b/libunwindstack/Unwinder.cpp
@@ -220,8 +220,7 @@ void Unwinder::Unwind(const std::vector<std::string>* initial_map_names_to_skip,
220 in_device_map = true; 220 in_device_map = true;
221 } else { 221 } else {
222 bool finished; 222 bool finished;
223 stepped = elf->Step(rel_pc, step_pc, map_info->elf_offset, regs_, process_memory_.get(), 223 stepped = elf->Step(rel_pc, step_pc, regs_, process_memory_.get(), &finished);
224 &finished);
225 elf->GetLastError(&last_error_); 224 elf->GetLastError(&last_error_);
226 if (stepped && finished) { 225 if (stepped && finished) {
227 break; 226 break;
diff --git a/libunwindstack/include/unwindstack/Elf.h b/libunwindstack/include/unwindstack/Elf.h
index 385973e9f..f4cdbdaf4 100644
--- a/libunwindstack/include/unwindstack/Elf.h
+++ b/libunwindstack/include/unwindstack/Elf.h
@@ -65,8 +65,8 @@ class Elf {
65 65
66 uint64_t GetRelPc(uint64_t pc, const MapInfo* map_info); 66 uint64_t GetRelPc(uint64_t pc, const MapInfo* map_info);
67 67
68 bool Step(uint64_t rel_pc, uint64_t adjusted_rel_pc, uint64_t elf_offset, Regs* regs, 68 bool Step(uint64_t rel_pc, uint64_t adjusted_rel_pc, Regs* regs, Memory* process_memory,
69 Memory* process_memory, bool* finished); 69 bool* finished);
70 70
71 ElfInterface* CreateInterfaceFromMemory(Memory* memory); 71 ElfInterface* CreateInterfaceFromMemory(Memory* memory);
72 72
diff --git a/libunwindstack/include/unwindstack/MapInfo.h b/libunwindstack/include/unwindstack/MapInfo.h
index a57fe68e9..ac0df41a4 100644
--- a/libunwindstack/include/unwindstack/MapInfo.h
+++ b/libunwindstack/include/unwindstack/MapInfo.h
@@ -34,6 +34,13 @@ class Memory;
34struct MapInfo { 34struct MapInfo {
35 MapInfo() = default; 35 MapInfo() = default;
36 MapInfo(uint64_t start, uint64_t end) : start(start), end(end) {} 36 MapInfo(uint64_t start, uint64_t end) : start(start), end(end) {}
37 MapInfo(uint64_t start, uint64_t end, uint64_t offset, uint64_t flags, const char* name)
38 : start(start),
39 end(end),
40 offset(offset),
41 flags(flags),
42 name(name),
43 load_bias(static_cast<uint64_t>(-1)) {}
37 MapInfo(uint64_t start, uint64_t end, uint64_t offset, uint64_t flags, const std::string& name) 44 MapInfo(uint64_t start, uint64_t end, uint64_t offset, uint64_t flags, const std::string& name)
38 : start(start), 45 : start(start),
39 end(end), 46 end(end),
diff --git a/libunwindstack/tests/ElfTest.cpp b/libunwindstack/tests/ElfTest.cpp
index f9028c4a5..aecbf6dcb 100644
--- a/libunwindstack/tests/ElfTest.cpp
+++ b/libunwindstack/tests/ElfTest.cpp
@@ -133,7 +133,7 @@ TEST_F(ElfTest, elf_invalid) {
133 ASSERT_FALSE(elf.GetFunctionName(0, &name, &func_offset)); 133 ASSERT_FALSE(elf.GetFunctionName(0, &name, &func_offset));
134 134
135 bool finished; 135 bool finished;
136 ASSERT_FALSE(elf.Step(0, 0, 0, nullptr, nullptr, &finished)); 136 ASSERT_FALSE(elf.Step(0, 0, nullptr, nullptr, &finished));
137} 137}
138 138
139TEST_F(ElfTest, elf32_invalid_machine) { 139TEST_F(ElfTest, elf32_invalid_machine) {
@@ -330,7 +330,7 @@ TEST_F(ElfTest, step_in_signal_map) {
330 elf.FakeSetValid(true); 330 elf.FakeSetValid(true);
331 elf.FakeSetLoadBias(0); 331 elf.FakeSetLoadBias(0);
332 bool finished; 332 bool finished;
333 ASSERT_TRUE(elf.Step(0x1000, 0x1000, 0x2000, &regs, &process_memory, &finished)); 333 ASSERT_TRUE(elf.Step(0x3000, 0x1000, &regs, &process_memory, &finished));
334 EXPECT_FALSE(finished); 334 EXPECT_FALSE(finished);
335 EXPECT_EQ(15U, regs.pc()); 335 EXPECT_EQ(15U, regs.pc());
336 EXPECT_EQ(13U, regs.sp()); 336 EXPECT_EQ(13U, regs.sp());
@@ -370,7 +370,7 @@ TEST_F(ElfTest, step_in_interface) {
370 EXPECT_CALL(*interface, Step(0x1000, 0, &regs, &process_memory, &finished)) 370 EXPECT_CALL(*interface, Step(0x1000, 0, &regs, &process_memory, &finished))
371 .WillOnce(::testing::Return(true)); 371 .WillOnce(::testing::Return(true));
372 372
373 ASSERT_TRUE(elf.Step(0x1004, 0x1000, 0x2000, &regs, &process_memory, &finished)); 373 ASSERT_TRUE(elf.Step(0x1004, 0x1000, &regs, &process_memory, &finished));
374} 374}
375 375
376TEST_F(ElfTest, step_in_interface_non_zero_load_bias) { 376TEST_F(ElfTest, step_in_interface_non_zero_load_bias) {
@@ -388,7 +388,7 @@ TEST_F(ElfTest, step_in_interface_non_zero_load_bias) {
388 EXPECT_CALL(*interface, Step(0x7300, 0x4000, &regs, &process_memory, &finished)) 388 EXPECT_CALL(*interface, Step(0x7300, 0x4000, &regs, &process_memory, &finished))
389 .WillOnce(::testing::Return(true)); 389 .WillOnce(::testing::Return(true));
390 390
391 ASSERT_TRUE(elf.Step(0x7304, 0x7300, 0x2000, &regs, &process_memory, &finished)); 391 ASSERT_TRUE(elf.Step(0x7304, 0x7300, &regs, &process_memory, &finished));
392} 392}
393 393
394TEST_F(ElfTest, get_global_invalid_elf) { 394TEST_F(ElfTest, get_global_invalid_elf) {
diff --git a/libunwindstack/tests/UnwindOfflineTest.cpp b/libunwindstack/tests/UnwindOfflineTest.cpp
index 2b8f0c265..285fc9e27 100644
--- a/libunwindstack/tests/UnwindOfflineTest.cpp
+++ b/libunwindstack/tests/UnwindOfflineTest.cpp
@@ -46,6 +46,12 @@
46 46
47namespace unwindstack { 47namespace unwindstack {
48 48
49static void AddMemory(std::string file_name, MemoryOfflineParts* parts) {
50 MemoryOffline* memory = new MemoryOffline;
51 ASSERT_TRUE(memory->Init(file_name.c_str(), 0));
52 parts->Add(memory);
53}
54
49class UnwindOfflineTest : public ::testing::Test { 55class UnwindOfflineTest : public ::testing::Test {
50 protected: 56 protected:
51 void TearDown() override { 57 void TearDown() override {
@@ -64,9 +70,24 @@ class UnwindOfflineTest : public ::testing::Test {
64 maps_.reset(new BufferMaps(data.c_str())); 70 maps_.reset(new BufferMaps(data.c_str()));
65 ASSERT_TRUE(maps_->Parse()); 71 ASSERT_TRUE(maps_->Parse());
66 72
67 std::unique_ptr<MemoryOffline> stack_memory(new MemoryOffline); 73 std::string stack_name(dir_ + "stack.data");
68 ASSERT_TRUE(stack_memory->Init((dir_ + "stack.data").c_str(), 0)); 74 struct stat st;
69 process_memory_.reset(stack_memory.release()); 75 if (stat(stack_name.c_str(), &st) == 0 && S_ISREG(st.st_mode)) {
76 std::unique_ptr<MemoryOffline> stack_memory(new MemoryOffline);
77 ASSERT_TRUE(stack_memory->Init((dir_ + "stack.data").c_str(), 0));
78 process_memory_.reset(stack_memory.release());
79 } else {
80 std::unique_ptr<MemoryOfflineParts> stack_memory(new MemoryOfflineParts);
81 for (size_t i = 0;; i++) {
82 stack_name = dir_ + "stack" + std::to_string(i) + ".data";
83 if (stat(stack_name.c_str(), &st) == -1 || !S_ISREG(st.st_mode)) {
84 ASSERT_TRUE(i != 0) << "No stack data files found.";
85 break;
86 }
87 AddMemory(stack_name, stack_memory.get());
88 }
89 process_memory_.reset(stack_memory.release());
90 }
70 91
71 switch (arch) { 92 switch (arch) {
72 case ARCH_ARM: { 93 case ARCH_ARM: {
@@ -180,7 +201,7 @@ static std::string DumpFrames(Unwinder& unwinder) {
180} 201}
181 202
182TEST_F(UnwindOfflineTest, pc_straddle_arm) { 203TEST_F(UnwindOfflineTest, pc_straddle_arm) {
183 Init("straddle_arm/", ARCH_ARM); 204 ASSERT_NO_FATAL_FAILURE(Init("straddle_arm/", ARCH_ARM));
184 205
185 Unwinder unwinder(128, maps_.get(), regs_.get(), process_memory_); 206 Unwinder unwinder(128, maps_.get(), regs_.get(), process_memory_);
186 unwinder.Unwind(); 207 unwinder.Unwind();
@@ -204,7 +225,7 @@ TEST_F(UnwindOfflineTest, pc_straddle_arm) {
204} 225}
205 226
206TEST_F(UnwindOfflineTest, pc_in_gnu_debugdata_arm) { 227TEST_F(UnwindOfflineTest, pc_in_gnu_debugdata_arm) {
207 Init("gnu_debugdata_arm/", ARCH_ARM); 228 ASSERT_NO_FATAL_FAILURE(Init("gnu_debugdata_arm/", ARCH_ARM));
208 229
209 Unwinder unwinder(128, maps_.get(), regs_.get(), process_memory_); 230 Unwinder unwinder(128, maps_.get(), regs_.get(), process_memory_);
210 unwinder.Unwind(); 231 unwinder.Unwind();
@@ -224,7 +245,7 @@ TEST_F(UnwindOfflineTest, pc_in_gnu_debugdata_arm) {
224} 245}
225 246
226TEST_F(UnwindOfflineTest, pc_straddle_arm64) { 247TEST_F(UnwindOfflineTest, pc_straddle_arm64) {
227 Init("straddle_arm64/", ARCH_ARM64); 248 ASSERT_NO_FATAL_FAILURE(Init("straddle_arm64/", ARCH_ARM64));
228 249
229 Unwinder unwinder(128, maps_.get(), regs_.get(), process_memory_); 250 Unwinder unwinder(128, maps_.get(), regs_.get(), process_memory_);
230 unwinder.Unwind(); 251 unwinder.Unwind();
@@ -255,14 +276,8 @@ TEST_F(UnwindOfflineTest, pc_straddle_arm64) {
255 EXPECT_EQ(0x7fe0d84110U, unwinder.frames()[5].sp); 276 EXPECT_EQ(0x7fe0d84110U, unwinder.frames()[5].sp);
256} 277}
257 278
258static void AddMemory(std::string file_name, MemoryOfflineParts* parts) {
259 MemoryOffline* memory = new MemoryOffline;
260 ASSERT_TRUE(memory->Init(file_name.c_str(), 0));
261 parts->Add(memory);
262}
263
264TEST_F(UnwindOfflineTest, jit_debug_x86) { 279TEST_F(UnwindOfflineTest, jit_debug_x86) {
265 Init("jit_debug_x86/", ARCH_X86); 280 ASSERT_NO_FATAL_FAILURE(Init("jit_debug_x86/", ARCH_X86));
266 281
267 MemoryOfflineParts* memory = new MemoryOfflineParts; 282 MemoryOfflineParts* memory = new MemoryOfflineParts;
268 AddMemory(dir_ + "descriptor.data", memory); 283 AddMemory(dir_ + "descriptor.data", memory);
@@ -555,7 +570,7 @@ TEST_F(UnwindOfflineTest, jit_debug_x86) {
555} 570}
556 571
557TEST_F(UnwindOfflineTest, jit_debug_arm) { 572TEST_F(UnwindOfflineTest, jit_debug_arm) {
558 Init("jit_debug_arm/", ARCH_ARM); 573 ASSERT_NO_FATAL_FAILURE(Init("jit_debug_arm/", ARCH_ARM));
559 574
560 MemoryOfflineParts* memory = new MemoryOfflineParts; 575 MemoryOfflineParts* memory = new MemoryOfflineParts;
561 AddMemory(dir_ + "descriptor.data", memory); 576 AddMemory(dir_ + "descriptor.data", memory);
@@ -873,7 +888,7 @@ TEST_F(UnwindOfflineTest, jit_debug_arm) {
873// fallback to iterating over the cies/fdes and ignore the eh_frame_hdr. 888// fallback to iterating over the cies/fdes and ignore the eh_frame_hdr.
874// No .gnu_debugdata section in the elf file, so no symbols. 889// No .gnu_debugdata section in the elf file, so no symbols.
875TEST_F(UnwindOfflineTest, bad_eh_frame_hdr_arm64) { 890TEST_F(UnwindOfflineTest, bad_eh_frame_hdr_arm64) {
876 Init("bad_eh_frame_hdr_arm64/", ARCH_ARM64); 891 ASSERT_NO_FATAL_FAILURE(Init("bad_eh_frame_hdr_arm64/", ARCH_ARM64));
877 892
878 Unwinder unwinder(128, maps_.get(), regs_.get(), process_memory_); 893 Unwinder unwinder(128, maps_.get(), regs_.get(), process_memory_);
879 unwinder.Unwind(); 894 unwinder.Unwind();
@@ -902,7 +917,7 @@ TEST_F(UnwindOfflineTest, bad_eh_frame_hdr_arm64) {
902// The elf has bad eh_frame unwind information for the pcs. If eh_frame 917// The elf has bad eh_frame unwind information for the pcs. If eh_frame
903// is used first, the unwind will not match the expected output. 918// is used first, the unwind will not match the expected output.
904TEST_F(UnwindOfflineTest, debug_frame_first_x86) { 919TEST_F(UnwindOfflineTest, debug_frame_first_x86) {
905 Init("debug_frame_first_x86/", ARCH_X86); 920 ASSERT_NO_FATAL_FAILURE(Init("debug_frame_first_x86/", ARCH_X86));
906 921
907 Unwinder unwinder(128, maps_.get(), regs_.get(), process_memory_); 922 Unwinder unwinder(128, maps_.get(), regs_.get(), process_memory_);
908 unwinder.Unwind(); 923 unwinder.Unwind();
@@ -930,7 +945,7 @@ TEST_F(UnwindOfflineTest, debug_frame_first_x86) {
930 945
931// Make sure that a pc that is at the beginning of an fde unwinds correctly. 946// Make sure that a pc that is at the beginning of an fde unwinds correctly.
932TEST_F(UnwindOfflineTest, eh_frame_hdr_begin_x86_64) { 947TEST_F(UnwindOfflineTest, eh_frame_hdr_begin_x86_64) {
933 Init("eh_frame_hdr_begin_x86_64/", ARCH_X86_64); 948 ASSERT_NO_FATAL_FAILURE(Init("eh_frame_hdr_begin_x86_64/", ARCH_X86_64));
934 949
935 Unwinder unwinder(128, maps_.get(), regs_.get(), process_memory_); 950 Unwinder unwinder(128, maps_.get(), regs_.get(), process_memory_);
936 unwinder.Unwind(); 951 unwinder.Unwind();
@@ -957,7 +972,7 @@ TEST_F(UnwindOfflineTest, eh_frame_hdr_begin_x86_64) {
957} 972}
958 973
959TEST_F(UnwindOfflineTest, art_quick_osr_stub_arm) { 974TEST_F(UnwindOfflineTest, art_quick_osr_stub_arm) {
960 Init("art_quick_osr_stub_arm/", ARCH_ARM); 975 ASSERT_NO_FATAL_FAILURE(Init("art_quick_osr_stub_arm/", ARCH_ARM));
961 976
962 MemoryOfflineParts* memory = new MemoryOfflineParts; 977 MemoryOfflineParts* memory = new MemoryOfflineParts;
963 AddMemory(dir_ + "descriptor.data", memory); 978 AddMemory(dir_ + "descriptor.data", memory);
@@ -1072,7 +1087,7 @@ TEST_F(UnwindOfflineTest, art_quick_osr_stub_arm) {
1072} 1087}
1073 1088
1074TEST_F(UnwindOfflineTest, jit_map_arm) { 1089TEST_F(UnwindOfflineTest, jit_map_arm) {
1075 Init("jit_map_arm/", ARCH_ARM); 1090 ASSERT_NO_FATAL_FAILURE(Init("jit_map_arm/", ARCH_ARM));
1076 1091
1077 maps_->Add(0xd025c788, 0xd025c9f0, 0, PROT_READ | PROT_EXEC | MAPS_FLAGS_JIT_SYMFILE_MAP, 1092 maps_->Add(0xd025c788, 0xd025c9f0, 0, PROT_READ | PROT_EXEC | MAPS_FLAGS_JIT_SYMFILE_MAP,
1078 "jit_map0.so", 0); 1093 "jit_map0.so", 0);
@@ -1111,4 +1126,78 @@ TEST_F(UnwindOfflineTest, jit_map_arm) {
1111 EXPECT_EQ(0xcd4ff960U, unwinder.frames()[5].sp); 1126 EXPECT_EQ(0xcd4ff960U, unwinder.frames()[5].sp);
1112} 1127}
1113 1128
1129TEST_F(UnwindOfflineTest, offset_arm) {
1130 ASSERT_NO_FATAL_FAILURE(Init("offset_arm/", ARCH_ARM));
1131
1132 Unwinder unwinder(128, maps_.get(), regs_.get(), process_memory_);
1133 unwinder.Unwind();
1134
1135 std::string frame_info(DumpFrames(unwinder));
1136 ASSERT_EQ(19U, unwinder.NumFrames()) << "Unwind:\n" << frame_info;
1137 EXPECT_EQ(
1138 " #00 pc 0032bfa0 (offset 0x42000) libunwindstack_test (SignalInnerFunction+40)\n"
1139 " #01 pc 0032bfeb (offset 0x42000) libunwindstack_test (SignalMiddleFunction+2)\n"
1140 " #02 pc 0032bff3 (offset 0x42000) libunwindstack_test (SignalOuterFunction+2)\n"
1141 " #03 pc 0032fed3 (offset 0x42000) libunwindstack_test "
1142 "(_ZN11unwindstackL19SignalCallerHandlerEiP7siginfoPv+26)\n"
1143 " #04 pc 00026528 (offset 0x25000) libc.so\n"
1144 " #05 pc 00000000 <unknown>\n"
1145 " #06 pc 0032c2d9 (offset 0x42000) libunwindstack_test (InnerFunction+736)\n"
1146 " #07 pc 0032cc4f (offset 0x42000) libunwindstack_test (MiddleFunction+42)\n"
1147 " #08 pc 0032cc81 (offset 0x42000) libunwindstack_test (OuterFunction+42)\n"
1148 " #09 pc 0032e547 (offset 0x42000) libunwindstack_test "
1149 "(_ZN11unwindstackL19RemoteThroughSignalEij+270)\n"
1150 " #10 pc 0032ed99 (offset 0x42000) libunwindstack_test "
1151 "(_ZN11unwindstack55UnwindTest_remote_through_signal_with_invalid_func_Test8TestBodyEv+16)\n"
1152 " #11 pc 00354453 (offset 0x42000) libunwindstack_test (_ZN7testing4Test3RunEv+154)\n"
1153 " #12 pc 00354de7 (offset 0x42000) libunwindstack_test (_ZN7testing8TestInfo3RunEv+194)\n"
1154 " #13 pc 00355105 (offset 0x42000) libunwindstack_test (_ZN7testing8TestCase3RunEv+180)\n"
1155 " #14 pc 0035a215 (offset 0x42000) libunwindstack_test "
1156 "(_ZN7testing8internal12UnitTestImpl11RunAllTestsEv+664)\n"
1157 " #15 pc 00359f4f (offset 0x42000) libunwindstack_test (_ZN7testing8UnitTest3RunEv+110)\n"
1158 " #16 pc 0034d3db (offset 0x42000) libunwindstack_test (main+38)\n"
1159 " #17 pc 00092c0d (offset 0x25000) libc.so (__libc_init+48)\n"
1160 " #18 pc 0004202f (offset 0x42000) libunwindstack_test (_start_main+38)\n",
1161 frame_info);
1162
1163 EXPECT_EQ(0x2e55fa0U, unwinder.frames()[0].pc);
1164 EXPECT_EQ(0xf43d2cccU, unwinder.frames()[0].sp);
1165 EXPECT_EQ(0x2e55febU, unwinder.frames()[1].pc);
1166 EXPECT_EQ(0xf43d2ce0U, unwinder.frames()[1].sp);
1167 EXPECT_EQ(0x2e55ff3U, unwinder.frames()[2].pc);
1168 EXPECT_EQ(0xf43d2ce8U, unwinder.frames()[2].sp);
1169 EXPECT_EQ(0x2e59ed3U, unwinder.frames()[3].pc);
1170 EXPECT_EQ(0xf43d2cf0U, unwinder.frames()[3].sp);
1171 EXPECT_EQ(0xf4136528U, unwinder.frames()[4].pc);
1172 EXPECT_EQ(0xf43d2d10U, unwinder.frames()[4].sp);
1173 EXPECT_EQ(0U, unwinder.frames()[5].pc);
1174 EXPECT_EQ(0xffcc0ee0U, unwinder.frames()[5].sp);
1175 EXPECT_EQ(0x2e562d9U, unwinder.frames()[6].pc);
1176 EXPECT_EQ(0xffcc0ee0U, unwinder.frames()[6].sp);
1177 EXPECT_EQ(0x2e56c4fU, unwinder.frames()[7].pc);
1178 EXPECT_EQ(0xffcc1060U, unwinder.frames()[7].sp);
1179 EXPECT_EQ(0x2e56c81U, unwinder.frames()[8].pc);
1180 EXPECT_EQ(0xffcc1078U, unwinder.frames()[8].sp);
1181 EXPECT_EQ(0x2e58547U, unwinder.frames()[9].pc);
1182 EXPECT_EQ(0xffcc1090U, unwinder.frames()[9].sp);
1183 EXPECT_EQ(0x2e58d99U, unwinder.frames()[10].pc);
1184 EXPECT_EQ(0xffcc1438U, unwinder.frames()[10].sp);
1185 EXPECT_EQ(0x2e7e453U, unwinder.frames()[11].pc);
1186 EXPECT_EQ(0xffcc1448U, unwinder.frames()[11].sp);
1187 EXPECT_EQ(0x2e7ede7U, unwinder.frames()[12].pc);
1188 EXPECT_EQ(0xffcc1458U, unwinder.frames()[12].sp);
1189 EXPECT_EQ(0x2e7f105U, unwinder.frames()[13].pc);
1190 EXPECT_EQ(0xffcc1490U, unwinder.frames()[13].sp);
1191 EXPECT_EQ(0x2e84215U, unwinder.frames()[14].pc);
1192 EXPECT_EQ(0xffcc14c0U, unwinder.frames()[14].sp);
1193 EXPECT_EQ(0x2e83f4fU, unwinder.frames()[15].pc);
1194 EXPECT_EQ(0xffcc1510U, unwinder.frames()[15].sp);
1195 EXPECT_EQ(0x2e773dbU, unwinder.frames()[16].pc);
1196 EXPECT_EQ(0xffcc1528U, unwinder.frames()[16].sp);
1197 EXPECT_EQ(0xf41a2c0dU, unwinder.frames()[17].pc);
1198 EXPECT_EQ(0xffcc1540U, unwinder.frames()[17].sp);
1199 EXPECT_EQ(0x2b6c02fU, unwinder.frames()[18].pc);
1200 EXPECT_EQ(0xffcc1558U, unwinder.frames()[18].sp);
1201}
1202
1114} // namespace unwindstack 1203} // namespace unwindstack
diff --git a/libunwindstack/tests/files/offline/offset_arm/libc.so b/libunwindstack/tests/files/offline/offset_arm/libc.so
new file mode 100644
index 000000000..9f5c8ca44
--- /dev/null
+++ b/libunwindstack/tests/files/offline/offset_arm/libc.so
Binary files differ
diff --git a/libunwindstack/tests/files/offline/offset_arm/libunwindstack_test b/libunwindstack/tests/files/offline/offset_arm/libunwindstack_test
new file mode 100644
index 000000000..7a30bfa44
--- /dev/null
+++ b/libunwindstack/tests/files/offline/offset_arm/libunwindstack_test
Binary files differ
diff --git a/libunwindstack/tests/files/offline/offset_arm/maps.txt b/libunwindstack/tests/files/offline/offset_arm/maps.txt
new file mode 100644
index 000000000..62244645e
--- /dev/null
+++ b/libunwindstack/tests/files/offline/offset_arm/maps.txt
@@ -0,0 +1,2 @@
12b6c000-2e92000 r-xp 42000 00:00 0 libunwindstack_test
2f4135000-f41a9000 r-xp 25000 00:00 0 libc.so
diff --git a/libunwindstack/tests/files/offline/offset_arm/regs.txt b/libunwindstack/tests/files/offline/offset_arm/regs.txt
new file mode 100644
index 000000000..1f4ac8f7b
--- /dev/null
+++ b/libunwindstack/tests/files/offline/offset_arm/regs.txt
@@ -0,0 +1,16 @@
1r0: 5
2r1: 5
3r2: 4
4r3: 1
5r4: 73804b6b
6r5: f3c9c000
7r6: 2ea09ac
8r7: 10624dd3
9r8: f41b5d8c
10r9: f3c9c000
11r10: 6f17
12r11: f3c94048
13ip: 2ea0807
14sp: f43d2ccc
15lr: 2e55fef
16pc: 2e55fa0
diff --git a/libunwindstack/tests/files/offline/offset_arm/stack0.data b/libunwindstack/tests/files/offline/offset_arm/stack0.data
new file mode 100644
index 000000000..23a987415
--- /dev/null
+++ b/libunwindstack/tests/files/offline/offset_arm/stack0.data
Binary files differ
diff --git a/libunwindstack/tests/files/offline/offset_arm/stack1.data b/libunwindstack/tests/files/offline/offset_arm/stack1.data
new file mode 100644
index 000000000..49bdd1e26
--- /dev/null
+++ b/libunwindstack/tests/files/offline/offset_arm/stack1.data
Binary files differ
diff --git a/libunwindstack/tools/unwind_for_offline.cpp b/libunwindstack/tools/unwind_for_offline.cpp
index 74868d43d..640992f62 100644
--- a/libunwindstack/tools/unwind_for_offline.cpp
+++ b/libunwindstack/tools/unwind_for_offline.cpp
@@ -30,6 +30,7 @@
30#include <memory> 30#include <memory>
31#include <string> 31#include <string>
32#include <unordered_map> 32#include <unordered_map>
33#include <utility>
33#include <vector> 34#include <vector>
34 35
35#include <unwindstack/Elf.h> 36#include <unwindstack/Elf.h>
@@ -68,7 +69,7 @@ static bool Attach(pid_t pid) {
68bool SaveRegs(unwindstack::Regs* regs) { 69bool SaveRegs(unwindstack::Regs* regs) {
69 std::unique_ptr<FILE, decltype(&fclose)> fp(fopen("regs.txt", "w+"), &fclose); 70 std::unique_ptr<FILE, decltype(&fclose)> fp(fopen("regs.txt", "w+"), &fclose);
70 if (fp == nullptr) { 71 if (fp == nullptr) {
71 printf("Failed to create file regs.txt.\n"); 72 perror("Failed to create file regs.txt");
72 return false; 73 return false;
73 } 74 }
74 regs->IterateRegisters([&fp](const char* name, uint64_t value) { 75 regs->IterateRegisters([&fp](const char* name, uint64_t value) {
@@ -78,30 +79,45 @@ bool SaveRegs(unwindstack::Regs* regs) {
78 return true; 79 return true;
79} 80}
80 81
81bool SaveStack(pid_t pid, uint64_t sp_start, uint64_t sp_end) { 82bool SaveStack(pid_t pid, const std::vector<std::pair<uint64_t, uint64_t>>& stacks) {
82 std::unique_ptr<FILE, decltype(&fclose)> fp(fopen("stack.data", "w+"), &fclose); 83 for (size_t i = 0; i < stacks.size(); i++) {
83 if (fp == nullptr) { 84 std::string file_name;
84 printf("Failed to create stack.data.\n"); 85 if (stacks.size() != 1) {
85 return false; 86 file_name = "stack" + std::to_string(i) + ".data";
86 } 87 } else {
88 file_name = "stack.data";
89 }
87 90
88 size_t bytes = fwrite(&sp_start, 1, sizeof(sp_start), fp.get()); 91 // Do this first, so if it fails, we don't create the file.
89 if (bytes != sizeof(sp_start)) { 92 uint64_t sp_start = stacks[i].first;
90 perror("Failed to write all data."); 93 uint64_t sp_end = stacks[i].second;
91 return false; 94 std::vector<uint8_t> buffer(sp_end - sp_start);
92 } 95 auto process_memory = unwindstack::Memory::CreateProcessMemory(pid);
96 if (!process_memory->Read(sp_start, buffer.data(), buffer.size())) {
97 printf("Unable to read stack data.\n");
98 return false;
99 }
93 100
94 std::vector<uint8_t> buffer(sp_end - sp_start); 101 printf("Saving the stack 0x%" PRIx64 "-0x%" PRIx64 "\n", sp_start, sp_end);
95 auto process_memory = unwindstack::Memory::CreateProcessMemory(pid);
96 if (!process_memory->Read(sp_start, buffer.data(), buffer.size())) {
97 printf("Unable to read stack data.\n");
98 return false;
99 }
100 102
101 bytes = fwrite(buffer.data(), 1, buffer.size(), fp.get()); 103 std::unique_ptr<FILE, decltype(&fclose)> fp(fopen(file_name.c_str(), "w+"), &fclose);
102 if (bytes != buffer.size()) { 104 if (fp == nullptr) {
103 printf("Failed to write all stack data: stack size %zu, written %zu\n", buffer.size(), bytes); 105 perror("Failed to create stack.data");
104 return 1; 106 return false;
107 }
108
109 size_t bytes = fwrite(&sp_start, 1, sizeof(sp_start), fp.get());
110 if (bytes != sizeof(sp_start)) {
111 printf("Failed to write sp_start data: sizeof(sp_start) %zu, written %zu\n", sizeof(sp_start),
112 bytes);
113 return false;
114 }
115
116 bytes = fwrite(buffer.data(), 1, buffer.size(), fp.get());
117 if (bytes != buffer.size()) {
118 printf("Failed to write all stack data: stack size %zu, written %zu\n", buffer.size(), bytes);
119 return false;
120 }
105 } 121 }
106 122
107 return true; 123 return true;
@@ -110,17 +126,11 @@ bool SaveStack(pid_t pid, uint64_t sp_start, uint64_t sp_end) {
110bool CreateElfFromMemory(std::shared_ptr<unwindstack::Memory>& memory, map_info_t* info) { 126bool CreateElfFromMemory(std::shared_ptr<unwindstack::Memory>& memory, map_info_t* info) {
111 std::string cur_name; 127 std::string cur_name;
112 if (info->name.empty()) { 128 if (info->name.empty()) {
113 cur_name = android::base::StringPrintf("anonymous:%" PRIx64, info->start); 129 cur_name = android::base::StringPrintf("anonymous_%" PRIx64, info->start);
114 } else { 130 } else {
115 cur_name = basename(info->name.c_str()); 131 cur_name = android::base::StringPrintf("%s_%" PRIx64, basename(info->name.c_str()), info->start);
116 cur_name = android::base::StringPrintf("%s:%" PRIx64, basename(info->name.c_str()), info->start);
117 } 132 }
118 133
119 std::unique_ptr<FILE, decltype(&fclose)> output(fopen(cur_name.c_str(), "w+"), &fclose);
120 if (output == nullptr) {
121 printf("Cannot create %s\n", cur_name.c_str());
122 return false;
123 }
124 std::vector<uint8_t> buffer(info->end - info->start); 134 std::vector<uint8_t> buffer(info->end - info->start);
125 // If this is a mapped in file, it might not be possible to read the entire 135 // If this is a mapped in file, it might not be possible to read the entire
126 // map, so read all that is readable. 136 // map, so read all that is readable.
@@ -129,6 +139,13 @@ bool CreateElfFromMemory(std::shared_ptr<unwindstack::Memory>& memory, map_info_
129 printf("Cannot read data from address %" PRIx64 " length %zu\n", info->start, buffer.size()); 139 printf("Cannot read data from address %" PRIx64 " length %zu\n", info->start, buffer.size());
130 return false; 140 return false;
131 } 141 }
142
143 std::unique_ptr<FILE, decltype(&fclose)> output(fopen(cur_name.c_str(), "w+"), &fclose);
144 if (output == nullptr) {
145 perror((std::string("Cannot create ") + cur_name).c_str());
146 return false;
147 }
148
132 size_t bytes_written = fwrite(buffer.data(), 1, bytes, output.get()); 149 size_t bytes_written = fwrite(buffer.data(), 1, bytes, output.get());
133 if (bytes_written != bytes) { 150 if (bytes_written != bytes) {
134 printf("Failed to write all data to file: bytes read %zu, written %zu\n", bytes, bytes_written); 151 printf("Failed to write all data to file: bytes read %zu, written %zu\n", bytes, bytes_written);
@@ -144,13 +161,14 @@ bool CreateElfFromMemory(std::shared_ptr<unwindstack::Memory>& memory, map_info_
144bool CopyElfFromFile(map_info_t* info) { 161bool CopyElfFromFile(map_info_t* info) {
145 std::unique_ptr<FILE, decltype(&fclose)> fp(fopen(info->name.c_str(), "r"), &fclose); 162 std::unique_ptr<FILE, decltype(&fclose)> fp(fopen(info->name.c_str(), "r"), &fclose);
146 if (fp == nullptr) { 163 if (fp == nullptr) {
164 perror((std::string("Cannot open ") + info->name).c_str());
147 return false; 165 return false;
148 } 166 }
149 167
150 std::string cur_name = basename(info->name.c_str()); 168 std::string cur_name = basename(info->name.c_str());
151 std::unique_ptr<FILE, decltype(&fclose)> output(fopen(cur_name.c_str(), "w+"), &fclose); 169 std::unique_ptr<FILE, decltype(&fclose)> output(fopen(cur_name.c_str(), "w+"), &fclose);
152 if (output == nullptr) { 170 if (output == nullptr) {
153 printf("Cannot create file %s\n", cur_name.c_str()); 171 perror((std::string("Cannot create file " + cur_name)).c_str());
154 return false; 172 return false;
155 } 173 }
156 std::vector<uint8_t> buffer(10000); 174 std::vector<uint8_t> buffer(10000);
@@ -198,9 +216,21 @@ int SaveData(pid_t pid) {
198 unwinder.Unwind(); 216 unwinder.Unwind();
199 217
200 std::unordered_map<uint64_t, map_info_t> maps_by_start; 218 std::unordered_map<uint64_t, map_info_t> maps_by_start;
201 uint64_t last_sp; 219 std::vector<std::pair<uint64_t, uint64_t>> stacks;
220 uint64_t sp_map_start = 0;
221 unwindstack::MapInfo* map_info = maps.Find(sp);
222 if (map_info != nullptr) {
223 stacks.emplace_back(std::make_pair(sp, map_info->end));
224 sp_map_start = map_info->start;
225 }
226
202 for (auto frame : unwinder.frames()) { 227 for (auto frame : unwinder.frames()) {
203 last_sp = frame.sp; 228 map_info = maps.Find(frame.sp);
229 if (map_info != nullptr && sp_map_start != map_info->start) {
230 stacks.emplace_back(std::make_pair(frame.sp, map_info->end));
231 sp_map_start = map_info->start;
232 }
233
204 if (maps_by_start.count(frame.map_start) == 0) { 234 if (maps_by_start.count(frame.map_start) == 0) {
205 auto info = &maps_by_start[frame.map_start]; 235 auto info = &maps_by_start[frame.map_start];
206 info->start = frame.map_start; 236 info->start = frame.map_start;
@@ -211,7 +241,12 @@ int SaveData(pid_t pid) {
211 // Try to create the elf from memory, this will handle cases where 241 // Try to create the elf from memory, this will handle cases where
212 // the data only exists in memory such as vdso data on x86. 242 // the data only exists in memory such as vdso data on x86.
213 if (!CreateElfFromMemory(process_memory, info)) { 243 if (!CreateElfFromMemory(process_memory, info)) {
214 return 1; 244 printf("Ignoring map ");
245 if (!info->name.empty()) {
246 printf("%s\n", info->name.c_str());
247 } else {
248 printf("anonymous:%" PRIx64 "\n", info->start);
249 }
215 } 250 }
216 } 251 }
217 } 252 }
@@ -221,7 +256,7 @@ int SaveData(pid_t pid) {
221 printf("%s\n", unwinder.FormatFrame(i).c_str()); 256 printf("%s\n", unwinder.FormatFrame(i).c_str());
222 } 257 }
223 258
224 if (!SaveStack(pid, sp, last_sp)) { 259 if (!SaveStack(pid, stacks)) {
225 return 1; 260 return 1;
226 } 261 }
227 262
@@ -232,7 +267,7 @@ int SaveData(pid_t pid) {
232 267
233 std::unique_ptr<FILE, decltype(&fclose)> fp(fopen("maps.txt", "w+"), &fclose); 268 std::unique_ptr<FILE, decltype(&fclose)> fp(fopen("maps.txt", "w+"), &fclose);
234 if (fp == nullptr) { 269 if (fp == nullptr) {
235 printf("Failed to create maps.txt.\n"); 270 perror("Failed to create maps.txt");
236 return false; 271 return false;
237 } 272 }
238 273
diff --git a/libutils/Android.bp b/libutils/Android.bp
index 0d7925a4a..9395ef807 100644
--- a/libutils/Android.bp
+++ b/libutils/Android.bp
@@ -15,6 +15,7 @@
15cc_library_headers { 15cc_library_headers {
16 name: "libutils_headers", 16 name: "libutils_headers",
17 vendor_available: true, 17 vendor_available: true,
18 recovery_available: true,
18 host_supported: true, 19 host_supported: true,
19 20
20 header_libs: [ 21 header_libs: [
diff --git a/lmkd/lmkd.c b/lmkd/lmkd.c
index 80711bcfc..1cfef34ff 100644
--- a/lmkd/lmkd.c
+++ b/lmkd/lmkd.c
@@ -472,46 +472,49 @@ static void cmd_procprio(LMKD_CTRL_PACKET packet) {
472 return; 472 return;
473 } 473 }
474 474
475 if (params.oomadj >= 900) { 475 if (low_ram_device) {
476 soft_limit_mult = 0; 476 if (params.oomadj >= 900) {
477 } else if (params.oomadj >= 800) { 477 soft_limit_mult = 0;
478 soft_limit_mult = 0; 478 } else if (params.oomadj >= 800) {
479 } else if (params.oomadj >= 700) { 479 soft_limit_mult = 0;
480 soft_limit_mult = 0; 480 } else if (params.oomadj >= 700) {
481 } else if (params.oomadj >= 600) { 481 soft_limit_mult = 0;
482 // Launcher should be perceptible, don't kill it. 482 } else if (params.oomadj >= 600) {
483 params.oomadj = 200; 483 // Launcher should be perceptible, don't kill it.
484 soft_limit_mult = 1; 484 params.oomadj = 200;
485 } else if (params.oomadj >= 500) { 485 soft_limit_mult = 1;
486 soft_limit_mult = 0; 486 } else if (params.oomadj >= 500) {
487 } else if (params.oomadj >= 400) { 487 soft_limit_mult = 0;
488 soft_limit_mult = 0; 488 } else if (params.oomadj >= 400) {
489 } else if (params.oomadj >= 300) { 489 soft_limit_mult = 0;
490 soft_limit_mult = 1; 490 } else if (params.oomadj >= 300) {
491 } else if (params.oomadj >= 200) { 491 soft_limit_mult = 1;
492 soft_limit_mult = 2; 492 } else if (params.oomadj >= 200) {
493 } else if (params.oomadj >= 100) { 493 soft_limit_mult = 2;
494 soft_limit_mult = 10; 494 } else if (params.oomadj >= 100) {
495 } else if (params.oomadj >= 0) { 495 soft_limit_mult = 10;
496 soft_limit_mult = 20; 496 } else if (params.oomadj >= 0) {
497 } else { 497 soft_limit_mult = 20;
498 // Persistent processes will have a large 498 } else {
499 // soft limit 512MB. 499 // Persistent processes will have a large
500 soft_limit_mult = 64; 500 // soft limit 512MB.
501 } 501 soft_limit_mult = 64;
502 }
502 503
503 snprintf(path, sizeof(path), MEMCG_SYSFS_PATH "apps/uid_%d/pid_%d/memory.soft_limit_in_bytes", 504 snprintf(path, sizeof(path), MEMCG_SYSFS_PATH
504 params.uid, params.pid); 505 "apps/uid_%d/pid_%d/memory.soft_limit_in_bytes",
505 snprintf(val, sizeof(val), "%d", soft_limit_mult * EIGHT_MEGA); 506 params.uid, params.pid);
507 snprintf(val, sizeof(val), "%d", soft_limit_mult * EIGHT_MEGA);
506 508
507 /* 509 /*
508 * system_server process has no memcg under /dev/memcg/apps but should be 510 * system_server process has no memcg under /dev/memcg/apps but should be
509 * registered with lmkd. This is the best way so far to identify it. 511 * registered with lmkd. This is the best way so far to identify it.
510 */ 512 */
511 is_system_server = (params.oomadj == SYSTEM_ADJ && 513 is_system_server = (params.oomadj == SYSTEM_ADJ &&
512 (pwdrec = getpwnam("system")) != NULL && 514 (pwdrec = getpwnam("system")) != NULL &&
513 params.uid == pwdrec->pw_uid); 515 params.uid == pwdrec->pw_uid);
514 writefilestring(path, val, !is_system_server); 516 writefilestring(path, val, !is_system_server);
517 }
515 518
516 procp = pid_lookup(params.pid); 519 procp = pid_lookup(params.pid);
517 if (!procp) { 520 if (!procp) {
@@ -1150,8 +1153,15 @@ static void mp_event_common(int data, uint32_t events __unused) {
1150 } 1153 }
1151 } 1154 }
1152 1155
1153 if (min_score_adj == OOM_SCORE_ADJ_MAX + 1) 1156 if (min_score_adj == OOM_SCORE_ADJ_MAX + 1) {
1157 if (debug_process_killing) {
1158 ALOGI("Ignore %s memory pressure event "
1159 "(free memory=%ldkB, cache=%ldkB, limit=%ldkB)",
1160 level_name[level], other_free * page_k, other_file * page_k,
1161 (long)lowmem_minfree[lowmem_targets_size - 1] * page_k);
1162 }
1154 return; 1163 return;
1164 }
1155 1165
1156 /* Free up enough pages to push over the highest minfree level */ 1166 /* Free up enough pages to push over the highest minfree level */
1157 pages_to_free = lowmem_minfree[lowmem_targets_size - 1] - 1167 pages_to_free = lowmem_minfree[lowmem_targets_size - 1] -
diff --git a/logcat/event.logtags b/logcat/event.logtags
index 7c40a777a..750761f42 100644
--- a/logcat/event.logtags
+++ b/logcat/event.logtags
@@ -67,8 +67,9 @@
67# ZygoteInit class preloading ends: 67# ZygoteInit class preloading ends:
683030 boot_progress_preload_end (time|2|3) 683030 boot_progress_preload_end (time|2|3)
69 69
70# Dalvik VM 70# Dalvik VM / ART
7120003 dvm_lock_sample (process|3),(main|1|5),(thread|3),(time|1|3),(file|3),(line|1|5),(ownerfile|3),(ownerline|1|5),(sample_percent|1|6) 7120003 dvm_lock_sample (process|3),(main|1|5),(thread|3),(time|1|3),(file|3),(line|1|5),(ownerfile|3),(ownerline|1|5),(sample_percent|1|6)
7220004 art_hidden_api_access (access_method|1),(flags|1),(class|3),(member|3),(type_signature|3)
72 73
7375000 sqlite_mem_alarm_current (current|1|2) 7475000 sqlite_mem_alarm_current (current|1|2)
7475001 sqlite_mem_alarm_max (max|1|2) 7575001 sqlite_mem_alarm_max (max|1|2)
diff --git a/logd/main.cpp b/logd/main.cpp
index 4af0d21f1..606aa6341 100644
--- a/logd/main.cpp
+++ b/logd/main.cpp
@@ -33,7 +33,6 @@
33#include <syslog.h> 33#include <syslog.h>
34#include <unistd.h> 34#include <unistd.h>
35 35
36#include <cstdbool>
37#include <memory> 36#include <memory>
38 37
39#include <android-base/macros.h> 38#include <android-base/macros.h>
diff --git a/property_service/libpropertyinfoparser/Android.bp b/property_service/libpropertyinfoparser/Android.bp
index ea9b968b6..70f6faab5 100644
--- a/property_service/libpropertyinfoparser/Android.bp
+++ b/property_service/libpropertyinfoparser/Android.bp
@@ -2,6 +2,7 @@ cc_library_static {
2 name: "libpropertyinfoparser", 2 name: "libpropertyinfoparser",
3 host_supported: true, 3 host_supported: true,
4 vendor_available: true, 4 vendor_available: true,
5 recovery_available: true,
5 srcs: ["property_info_parser.cpp"], 6 srcs: ["property_info_parser.cpp"],
6 7
7 cpp_std: "experimental", 8 cpp_std: "experimental",
diff --git a/rootdir/Android.mk b/rootdir/Android.mk
index f488ed5a4..3c9e5f3c5 100644
--- a/rootdir/Android.mk
+++ b/rootdir/Android.mk
@@ -147,13 +147,10 @@ $(LOCAL_BUILT_MODULE): $(LOCAL_PATH)/init.environ.rc.in $(bcp_dep)
147bcp_md5 := 147bcp_md5 :=
148bcp_dep := 148bcp_dep :=
149 149
150# If BOARD_VNDK_VERSION is defined, append PLATFORM_VNDK_VERSION to base name. 150# Append PLATFORM_VNDK_VERSION to base name.
151define append_vndk_version 151define append_vndk_version
152$(strip \ 152$(strip \
153 $(if $(BOARD_VNDK_VERSION), \ 153 $(basename $(1)).$(PLATFORM_VNDK_VERSION)$(suffix $(1)) \
154 $(basename $(1)).$(PLATFORM_VNDK_VERSION)$(suffix $(1)), \
155 $(1) \
156 ) \
157) 154)
158endef 155endef
159 156
@@ -215,31 +212,46 @@ sanitizer_runtime_libraries :=
215vndk_version_suffix := 212vndk_version_suffix :=
216endef # update_and_install_ld_config 213endef # update_and_install_ld_config
217 214
215
216#######################################
217# ld.config.txt selection variables
218#
219_enforce_vndk_at_runtime := false
220ifdef BOARD_VNDK_VERSION
221 ifneq ($(BOARD_VNDK_RUNTIME_DISABLE),true)
222 _enforce_vndk_at_runtime := true
223 endif
224endif
225
226_enforce_vndk_lite_at_runtime := false
227ifeq ($(_enforce_vndk_at_runtime),false)
228 ifeq ($(PRODUCT_TREBLE_LINKER_NAMESPACES)|$(SANITIZE_TARGET),true|)
229 _enforce_vndk_lite_at_runtime := true
230 endif
231endif
232
218####################################### 233#######################################
219# ld.config.txt 234# ld.config.txt
220# 235#
221# For VNDK enforced devices that have defined BOARD_VNDK_VERSION, use 236# For VNDK enforced devices that have defined BOARD_VNDK_VERSION, use
222# "ld.config.txt" as a source file. This configuration includes strict VNDK 237# "ld.config.txt" as a source file. This configuration includes strict VNDK
223# run-time restrictions for vendor process. 238# run-time restrictions for vendor process.
239#
224# Other treblized devices, that have not defined BOARD_VNDK_VERSION or that 240# Other treblized devices, that have not defined BOARD_VNDK_VERSION or that
225# have set BOARD_VNDK_RUNTIME_DISABLE to true, use "ld.config.vndk_lite.txt" 241# have set BOARD_VNDK_RUNTIME_DISABLE to true, use "ld.config.vndk_lite.txt"
226# as a source file. This configuration does not have strict VNDK run-time 242# as a source file. This configuration does not have strict VNDK run-time
227# restrictions. 243# restrictions.
244#
228# If the device is not treblized, use "ld.config.legacy.txt" for legacy 245# If the device is not treblized, use "ld.config.legacy.txt" for legacy
229# namespace configuration. 246# namespace configuration.
247#
230include $(CLEAR_VARS) 248include $(CLEAR_VARS)
231LOCAL_MODULE := ld.config.txt 249LOCAL_MODULE := ld.config.txt
232LOCAL_MODULE_CLASS := ETC 250LOCAL_MODULE_CLASS := ETC
233LOCAL_MODULE_PATH := $(TARGET_OUT_ETC) 251LOCAL_MODULE_PATH := $(TARGET_OUT_ETC)
234 252
235_enforce_vndk_at_runtime := false
236ifdef BOARD_VNDK_VERSION
237ifneq ($(BOARD_VNDK_RUNTIME_DISABLE),true)
238 _enforce_vndk_at_runtime := true
239endif
240endif
241
242ifeq ($(_enforce_vndk_at_runtime),true) 253ifeq ($(_enforce_vndk_at_runtime),true)
254
243# for VNDK enforced devices 255# for VNDK enforced devices
244LOCAL_MODULE_STEM := $(call append_vndk_version,$(LOCAL_MODULE)) 256LOCAL_MODULE_STEM := $(call append_vndk_version,$(LOCAL_MODULE))
245include $(BUILD_SYSTEM)/base_rules.mk 257include $(BUILD_SYSTEM)/base_rules.mk
@@ -248,37 +260,36 @@ $(eval $(call update_and_install_ld_config,\
248 $(LOCAL_BUILT_MODULE),\ 260 $(LOCAL_BUILT_MODULE),\
249 $(PLATFORM_VNDK_VERSION))) 261 $(PLATFORM_VNDK_VERSION)))
250 262
251else ifeq ($(PRODUCT_TREBLE_LINKER_NAMESPACES)|$(SANITIZE_TARGET),true|) 263else ifeq ($(_enforce_vndk_lite_at_runtime),true)
252# for treblized but VNDK non-enforced devices 264
253LOCAL_MODULE_STEM := $(call append_vndk_version,$(LOCAL_MODULE)) 265# for treblized but VNDK lightly enforced devices
266LOCAL_MODULE_STEM := ld.config.vndk_lite.txt
254include $(BUILD_SYSTEM)/base_rules.mk 267include $(BUILD_SYSTEM)/base_rules.mk
255$(eval $(call update_and_install_ld_config,\ 268$(eval $(call update_and_install_ld_config,\
256 $(LOCAL_PATH)/etc/ld.config.vndk_lite.txt,\ 269 $(LOCAL_PATH)/etc/ld.config.vndk_lite.txt,\
257 $(LOCAL_BUILT_MODULE),\ 270 $(LOCAL_BUILT_MODULE),\
258 $(if $(BOARD_VNDK_VERSION),$(PLATFORM_VNDK_VERSION)),\ 271 $(PLATFORM_VNDK_VERSION),\
259 true)) 272 true))
260 273
261else 274else
275
262# for legacy non-treblized devices 276# for legacy non-treblized devices
263LOCAL_SRC_FILES := etc/ld.config.legacy.txt
264LOCAL_MODULE_STEM := $(LOCAL_MODULE) 277LOCAL_MODULE_STEM := $(LOCAL_MODULE)
278LOCAL_SRC_FILES := etc/ld.config.legacy.txt
265include $(BUILD_PREBUILT) 279include $(BUILD_PREBUILT)
266 280
267endif # if _enforce_vndk_at_runtime is true 281endif # ifeq ($(_enforce_vndk_at_runtime),true)
268 282
269_enforce_vndk_at_runtime :=
270 283
271####################################### 284#######################################
272# ld.config.noenforce.txt 285# ld.config.vndk_lite.txt
273# 286#
274# This file is a temporary configuration file only for GSI. Originally GSI has 287# This module is only for GSI.
275# BOARD_VNDK_VERSION defined and has strict VNDK enforcing rule based on 288#
276# "ld.config.txt". However for the devices, that have not defined 289ifeq ($(_enforce_vndk_lite_at_runtime),false)
277# BOARD_VNDK_VERSION, GSI provides this configuration file which is based on 290
278# "ld.config.vndk_lite.txt".
279# Do not install this file for the devices other than GSI.
280include $(CLEAR_VARS) 291include $(CLEAR_VARS)
281LOCAL_MODULE := ld.config.noenforce.txt 292LOCAL_MODULE := ld.config.vndk_lite.txt
282LOCAL_MODULE_CLASS := ETC 293LOCAL_MODULE_CLASS := ETC
283LOCAL_MODULE_PATH := $(TARGET_OUT_ETC) 294LOCAL_MODULE_PATH := $(TARGET_OUT_ETC)
284LOCAL_MODULE_STEM := $(LOCAL_MODULE) 295LOCAL_MODULE_STEM := $(LOCAL_MODULE)
@@ -289,6 +300,11 @@ $(eval $(call update_and_install_ld_config,\
289 $(PLATFORM_VNDK_VERSION),\ 300 $(PLATFORM_VNDK_VERSION),\
290 true)) 301 true))
291 302
303endif # ifeq ($(_enforce_vndk_lite_at_runtime),false)
304
305_enforce_vndk_at_runtime :=
306_enforce_vndk_lite_at_runtime :=
307
292####################################### 308#######################################
293# llndk.libraries.txt 309# llndk.libraries.txt
294include $(CLEAR_VARS) 310include $(CLEAR_VARS)
diff --git a/rootdir/init.rc b/rootdir/init.rc
index d3504ad82..197047d9c 100644
--- a/rootdir/init.rc
+++ b/rootdir/init.rc
@@ -419,6 +419,7 @@ on post-fs-data
419 mkdir /data/misc/radio 0770 system radio 419 mkdir /data/misc/radio 0770 system radio
420 mkdir /data/misc/sms 0770 system radio 420 mkdir /data/misc/sms 0770 system radio
421 mkdir /data/misc/carrierid 0770 system radio 421 mkdir /data/misc/carrierid 0770 system radio
422 mkdir /data/misc/apns 0770 system radio
422 mkdir /data/misc/zoneinfo 0775 system system 423 mkdir /data/misc/zoneinfo 0775 system system
423 mkdir /data/misc/textclassifier 0771 system system 424 mkdir /data/misc/textclassifier 0771 system system
424 mkdir /data/misc/vpn 0770 system vpn 425 mkdir /data/misc/vpn 0770 system vpn