diff options
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 | ||
223 | cc_binary_host { | 223 | cc_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); |
@@ -95,16 +95,33 @@ enum TransportType { | |||
95 | 95 | ||
96 | enum ConnectionState { | 96 | enum 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 | ||
112 | inline 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 | |||
108 | void print_packet(const char* label, apacket* p); | 125 | void 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 | ||
85 | static bool remount_partition(int fd, const char* dir) { | 90 | static 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 | |||
110 | static 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 | |||
145 | static 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 | ||
239 | static int getMaxPacketSize(int ffs_fd) { | 243 | static 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 | ||
461 | static int usb_ffs_aio_read(usb_handle* h, void* data, int len) { | 464 | static 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 |
39 | def fake_adb_server(protocol=socket.AF_INET, port=0): | 39 | def 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 | ||
100 | class NonApiTest(unittest.TestCase): | 103 | @contextlib.contextmanager |
101 | """Tests for ADB that aren't a part of the AndroidDevice API.""" | 104 | def 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 | ||
123 | def 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 | |||
147 | class 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): | 184 | class 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 | |
268 | class 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 | |||
372 | class 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 | ||
305 | def main(): | 439 | def 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 | ||
314 | if __name__ == '__main__': | 445 | if __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 | ||
53 | static void transport_unref(atransport *t); | 54 | static void register_transport(atransport* transport); |
55 | static void remove_transport(atransport* transport); | ||
56 | static void transport_unref(atransport* transport); | ||
54 | 57 | ||
55 | // TODO: unordered_map<TransportId, atransport*> | 58 | // TODO: unordered_map<TransportId, atransport*> |
56 | static auto& transport_list = *new std::list<atransport*>(); | 59 | static 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. | ||
84 | class 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 | |||
123 | void ReconnectHandler::Start() { | ||
124 | check_main_thread(); | ||
125 | handler_thread_ = std::thread(&ReconnectHandler::Run, this); | ||
126 | } | ||
127 | |||
128 | void 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 | |||
146 | void 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 | |||
158 | void 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 | |||
205 | static auto& reconnect_handler = *new ReconnectHandler(); | ||
206 | |||
80 | } // namespace | 207 | } // namespace |
81 | 208 | ||
82 | TransportId NextTransportId() { | 209 | TransportId 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 | ||
480 | static void remove_transport(atransport*); | ||
481 | |||
482 | static void transport_registration_func(int _fd, unsigned ev, void*) { | 607 | static 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 | ||
686 | void init_reconnect_handler(void) { | ||
687 | reconnect_handler.Start(); | ||
688 | } | ||
689 | |||
557 | void init_transport_registration(void) { | 690 | void 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 | ||
573 | void kick_all_transports() { | 706 | void 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 | ||
602 | static void transport_unref(atransport* t) { | 736 | static 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 | ||
763 | void atransport::Kick() { | 922 | void 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 | ||
1082 | bool 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 | ||
1000 | int register_socket_transport(int s, const char* serial, int port, int local) { | 1166 | int 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 | ||
1080 | void register_usb_transport(usb_handle* usb, const char* serial, const char* devpath, | 1247 | void 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. |
334 | bool iterate_transports(std::function<bool(const atransport*)> fn); | 348 | bool iterate_transports(std::function<bool(const atransport*)> fn); |
335 | 349 | ||
350 | void init_reconnect_handler(void); | ||
336 | void init_transport_registration(void); | 351 | void init_transport_registration(void); |
337 | void init_mdns_transport_discovery(void); | 352 | void init_mdns_transport_discovery(void); |
338 | std::string list_transports(bool long_listing); | 353 | std::string list_transports(bool long_listing); |
@@ -347,7 +362,8 @@ void register_usb_transport(usb_handle* h, const char* serial, | |||
347 | void connect_device(const std::string& address, std::string* response); | 362 | void 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 */ |
350 | int register_socket_transport(int s, const char* serial, int port, int local); | 365 | int 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. |
353 | void unregister_usb_transport(usb_handle* usb); | 369 | void 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 | ||
71 | void connect_device(const std::string& address, std::string* response) { | 71 | std::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 | |||
100 | void 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 { | |||
26 | cc_library_headers { | 26 | cc_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 | |||
312 | init : processing action (ro.boot.bootreason=*) from (/system/etc/init/bootstat.rc | 312 | init : processing action (ro.boot.bootreason=*) from (/system/etc/init/bootstat.rc |
313 | init : processing action (sys.boot_completed=1 && sys.logbootcomplete=1) from (/system/etc/init/bootstat.rc | 313 | init : 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)' |
316 | init : Command 'exec - system log -- /system/bin/bootstat --record_boot_complete' action=sys.boot_completed=1 && sys.logbootcomplete=1 (/system/etc/init/bootstat.rc: | 317 | init : Command 'exec - system log -- /system/bin/bootstat --record_boot_complete' action=sys.boot_completed=1 && sys.logbootcomplete=1 (/system/etc/init/bootstat.rc: |
317 | init : Command 'exec - system log -- /system/bin/bootstat --record_boot_reason' action=sys.boot_completed=1 && sys.logbootcomplete=1 (/system/etc/init/bootstat.rc: | 318 | init : 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 | |||
954 | rescueparty 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" ] | ||
960 | test_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 | ||
953 | Its Just So Hard reboot test: | 968 | Its 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 | ||
86 | static void tombstoned_intercept(pid_t target_pid, unique_fd* intercept_fd, unique_fd* output_fd, | 91 | static 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 | ||
103 | my_dist_files := $(HOST_OUT_EXECUTABLES)/fastboot | 103 | my_dist_files := $(HOST_OUT_EXECUTABLES)/fastboot |
104 | my_dist_files += $(HOST_OUT_EXECUTABLES)/mke2fs$(HOST_EXECUTABLE_SUFFIX) | 104 | my_dist_files += $(HOST_OUT_EXECUTABLES)/mke2fs |
105 | my_dist_files += $(HOST_OUT_EXECUTABLES)/e2fsdroid$(HOST_EXECUTABLE_SUFFIX) | 105 | my_dist_files += $(HOST_OUT_EXECUTABLES)/e2fsdroid |
106 | my_dist_files += $(HOST_OUT_EXECUTABLES)/make_f2fs$(HOST_EXECUTABLE_SUFFIX) | 106 | my_dist_files += $(HOST_OUT_EXECUTABLES)/make_f2fs |
107 | my_dist_files += $(HOST_OUT_EXECUTABLES)/sload_f2fs$(HOST_EXECUTABLE_SUFFIX) | 107 | my_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)) |
109 | ifdef HOST_CROSS_OS | 109 | ifdef 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)) | ||
112 | endif | 111 | endif |
113 | my_dist_files := | 112 | my_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() { | |||
507 | static std::string make_temporary_directory() { | 507 | static 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 | ||
797 | bool 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 | ||
304 | static bool load_verity_table(struct dm_ioctl* io, const std::string& dm_device_name, int fd, | 304 | static 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 | ||
26 | void fs_mgr_verity_ioctl_init(struct dm_ioctl* io, const std::string& name) { | 26 | void 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 | ||
38 | bool fs_mgr_create_verity_device(struct dm_ioctl* io, const std::string& name, int fd) { | 38 | bool 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 | ||
47 | bool fs_mgr_destroy_verity_device(struct dm_ioctl* io, const std::string& name, int fd) { | 47 | bool 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 | ||
56 | bool fs_mgr_get_verity_device_name(struct dm_ioctl* io, const std::string& name, int fd, | 56 | bool 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 | ||
72 | bool fs_mgr_resume_verity_table(struct dm_ioctl* io, const std::string& name, int fd) { | 72 | bool 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 | |||
44 | namespace android { | ||
45 | namespace fs_mgr { | ||
46 | |||
47 | std::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 | |||
70 | static 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 | |||
97 | static 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 | |||
106 | static 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 | |||
121 | bool 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 | |||
136 | std::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 | */ | ||
699 | static 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 | |||
688 | struct fstab *fs_mgr_read_fstab(const char *fstab_path) | 732 | struct 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 | ||
909 | std::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 | |||
864 | int fs_mgr_is_voldmanaged(const struct fstab_rec *fstab) | 926 | int 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 | |||
1010 | int 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 | ||
23 | void fs_mgr_verity_ioctl_init(struct dm_ioctl* io, const std::string& name); | 23 | void fs_mgr_dm_ioctl_init(struct dm_ioctl* io, size_t size, const std::string& name); |
24 | 24 | ||
25 | bool fs_mgr_create_verity_device(struct dm_ioctl* io, const std::string& name, int fd); | 25 | bool fs_mgr_dm_create_device(struct dm_ioctl* io, const std::string& name, int fd); |
26 | 26 | ||
27 | bool fs_mgr_destroy_verity_device(struct dm_ioctl* io, const std::string& name, int fd); | 27 | bool fs_mgr_dm_destroy_device(struct dm_ioctl* io, const std::string& name, int fd); |
28 | 28 | ||
29 | bool fs_mgr_get_verity_device_name(struct dm_ioctl* io, const std::string& name, int fd, | 29 | bool 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 | ||
32 | bool fs_mgr_resume_verity_table(struct dm_ioctl* io, const std::string& name, int fd); | 32 | bool 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) | |||
900 | loaded: | 900 | loaded: |
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 | |||
76 | bool fs_mgr_load_verity_state(int* mode); | 76 | bool fs_mgr_load_verity_state(int* mode); |
77 | bool fs_mgr_update_verity_state(fs_mgr_verity_state_callback callback); | 77 | bool fs_mgr_update_verity_state(fs_mgr_verity_state_callback callback); |
78 | int fs_mgr_swapon_all(struct fstab *fstab); | 78 | int fs_mgr_swapon_all(struct fstab *fstab); |
79 | bool fs_mgr_update_logical_partition(struct fstab_rec* rec); | ||
79 | 80 | ||
80 | int fs_mgr_do_format(struct fstab_rec *fstab, bool reserve_footer); | 81 | int 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 | |||
33 | namespace android { | ||
34 | namespace fs_mgr { | ||
35 | |||
36 | static const uint32_t kPartitionReadonly = 0x1; | ||
37 | |||
38 | class 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 | |||
67 | struct 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 | |||
78 | struct 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. | ||
85 | std::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 | // | ||
94 | bool 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 | ||
38 | struct fstab_rec { | 39 | struct 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); | |||
84 | int fs_mgr_is_nofail(const struct fstab_rec* fstab); | 86 | int fs_mgr_is_nofail(const struct fstab_rec* fstab); |
85 | int fs_mgr_is_latemount(const struct fstab_rec* fstab); | 87 | int fs_mgr_is_latemount(const struct fstab_rec* fstab); |
86 | int fs_mgr_is_quota(const struct fstab_rec* fstab); | 88 | int fs_mgr_is_quota(const struct fstab_rec* fstab); |
89 | int fs_mgr_is_logical(const struct fstab_rec* fstab); | ||
87 | int fs_mgr_has_sysfs_path(const struct fstab_rec* fstab); | 90 | int fs_mgr_has_sysfs_path(const struct fstab_rec* fstab); |
88 | 91 | ||
89 | std::string fs_mgr_get_slot_suffix(); | 92 | std::string fs_mgr_get_slot_suffix(); |
93 | std::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 | ||
243 | static 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 | |||
250 | static 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 | |||
259 | static 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] |
244 | static Result<Success> do_mkdir(const BuiltinArguments& args) { | 267 | static 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 | ||
416 | DeviceHandler::DeviceHandler(std::vector<Permissions> dev_permissions, | 422 | DeviceHandler::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 | ||
425 | DeviceHandler::DeviceHandler() | 433 | DeviceHandler::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 | |||
25 | namespace android { | ||
26 | namespace init { | ||
27 | |||
28 | Epoll::Epoll() {} | ||
29 | |||
30 | Result<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 | |||
40 | Result<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 | |||
58 | Result<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 | |||
68 | Result<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 | |||
29 | namespace android { | ||
30 | namespace init { | ||
31 | |||
32 | class 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 |
52 | bool SelinuxHasVendorInit() { | ||
53 | return true; | ||
54 | } | ||
55 | |||
52 | void SelabelInitialize() {} | 56 | void SelabelInitialize() {} |
53 | 57 | ||
54 | bool SelabelLookupFileContext(const std::string& key, int type, std::string* result) { | 58 | bool 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 | ||
36 | std::string GetProperty(const std::string& key, const std::string& default_value); | 36 | std::string GetProperty(const std::string& key, const std::string& default_value); |
37 | bool GetBoolProperty(const std::string& key, bool default_value); | 37 | bool GetBoolProperty(const std::string& key, bool default_value); |
38 | template <typename T> | ||
39 | T 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 |
54 | bool SelinuxHasVendorInit(); | ||
59 | void SelabelInitialize(); | 55 | void SelabelInitialize(); |
60 | bool SelabelLookupFileContext(const std::string& key, int type, std::string* result); | 56 | bool 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 | ||
64 | using namespace std::chrono_literals; | ||
63 | using namespace std::string_literals; | 65 | using namespace std::string_literals; |
64 | 66 | ||
65 | using android::base::boot_clock; | 67 | using android::base::boot_clock; |
@@ -78,7 +80,6 @@ static char qemu[32]; | |||
78 | 80 | ||
79 | std::string default_console = "/dev/console"; | 81 | std::string default_console = "/dev/console"; |
80 | 82 | ||
81 | static int epoll_fd = -1; | ||
82 | static int signal_fd = -1; | 83 | static int signal_fd = -1; |
83 | 84 | ||
84 | static std::unique_ptr<Timer> waiting_for_prop(nullptr); | 85 | static 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 | ||
133 | void 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 | |||
142 | bool start_waiting_for_property(const char *name, const char *value) | 134 | bool 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 | ||
316 | static Result<Success> wait_for_coldboot_done_action(const BuiltinArguments& args) { | 297 | static 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 | ||
337 | static Result<Success> keychord_init_action(const BuiltinArguments& args) { | ||
338 | keychord_init(); | ||
339 | return Success(); | ||
340 | } | ||
341 | |||
342 | static Result<Success> console_init_action(const BuiltinArguments& args) { | 318 | static 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 | ||
544 | static void InstallSignalFdHandler() { | 520 | static 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 | ||
578 | int main(int argc, char** argv) { | 556 | int 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 | ||
43 | void property_changed(const std::string& name, const std::string& value); | 44 | void property_changed(const std::string& name, const std::string& value); |
44 | 45 | ||
45 | void register_epoll_handler(int fd, void (*fn)()); | ||
46 | |||
47 | bool start_waiting_for_property(const char *name, const char *value); | 46 | bool start_waiting_for_property(const char *name, const char *value); |
48 | 47 | ||
49 | void DumpState(); | 48 | void 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 | ||
40 | using android::base::Timer; | 41 | using android::base::Timer; |
42 | using android::fs_mgr::LogicalPartitionTable; | ||
41 | 43 | ||
42 | namespace android { | 44 | namespace android { |
43 | namespace init { | 45 | namespace 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 | ||
122 | static 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 | // ----------------- |
119 | FirstStageMount::FirstStageMount() | 135 | FirstStageMount::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 | ||
132 | std::unique_ptr<FirstStageMount> FirstStageMount::Create() { | 157 | std::unique_ptr<FirstStageMount> FirstStageMount::Create() { |
@@ -138,7 +163,7 @@ std::unique_ptr<FirstStageMount> FirstStageMount::Create() { | |||
138 | } | 163 | } |
139 | 164 | ||
140 | bool FirstStageMount::DoFirstStageMount() { | 165 | bool 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 | ||
154 | bool FirstStageMount::InitDevices() { | 181 | bool FirstStageMount::InitDevices() { |
155 | return GetRequiredDevices() && InitRequiredDevices(); | 182 | return GetBackingDmLinearDevices() && GetDmVerityDevices() && InitRequiredDevices(); |
183 | } | ||
184 | |||
185 | bool 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 | ||
255 | bool FirstStageMount::CreateLogicalPartitions() { | ||
256 | if (!dm_linear_table_) { | ||
257 | return true; | ||
258 | } | ||
259 | return android::fs_mgr::CreateLogicalPartitions(*dm_linear_table_.get()); | ||
260 | } | ||
261 | |||
213 | ListenerAction FirstStageMount::HandleBlockDevice(const std::string& name, const Uevent& uevent) { | 262 | ListenerAction 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. |
250 | bool FirstStageMount::InitVerityDevice(const std::string& verity_device) { | 299 | bool 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 | ||
280 | bool FirstStageMount::MountPartitions() { | 329 | bool 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 | ||
294 | bool FirstStageMountVBootV1::GetRequiredDevices() { | 351 | bool 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 | ||
374 | bool FirstStageMountVBootV2::GetRequiredDevices() { | 431 | bool 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 | ||
31 | namespace android { | 41 | namespace android { |
32 | namespace init { | 42 | namespace init { |
33 | 43 | ||
34 | static struct input_keychord *keychords = 0; | 44 | namespace { |
35 | static int keychords_count = 0; | 45 | |
36 | static int keychords_length = 0; | 46 | int keychords_count; |
37 | static int keychord_fd = -1; | 47 | Epoll* epoll; |
38 | 48 | ||
39 | void add_service_keycodes(Service* svc) | 49 | struct 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) { | 58 | std::vector<KeychordEntry> keychord_entries; |
49 | PLOG(ERROR) << "could not allocate keychords"; | 59 | |
50 | keychords_length = 0; | 60 | // Bit management |
51 | keychords_count = 0; | 61 | class 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 | ||
69 | static 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 | |||
121 | KeychordMask keychord_current; | ||
122 | |||
123 | constexpr char kDevicePath[] = "/dev/input"; | ||
124 | |||
125 | std::map<std::string, int> keychord_registration; | ||
126 | |||
127 | void 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 | ||
97 | void keychord_init() { | 146 | void 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 | |||
163 | void 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 | |||
171 | bool 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. | 223 | void 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 | |||
237 | void 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 | |||
246 | int inotify_fd = -1; | ||
106 | 247 | ||
107 | keychord_fd = TEMP_FAILURE_RETRY(open("/dev/keychord", O_RDWR | O_CLOEXEC)); | 248 | void 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 | |||
277 | void 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 | |||
302 | void 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); | 314 | void 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 | ||
22 | namespace android { | 22 | namespace android { |
23 | namespace init { | 23 | namespace init { |
24 | 24 | ||
25 | void add_service_keycodes(Service* svc); | 25 | void KeychordInit(Epoll* init_epoll); |
26 | void 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 | ||
65 | using namespace std::literals; | 67 | using namespace std::literals; |
66 | 68 | ||
67 | using android::base::GetIntProperty; | ||
68 | using android::base::ReadFileToString; | 69 | using android::base::ReadFileToString; |
69 | using android::base::Split; | 70 | using android::base::Split; |
70 | using android::base::StartsWith; | 71 | using 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 | ||
811 | void start_property_service() { | 817 | void 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 | |||
24 | namespace android { | 26 | namespace android { |
25 | namespace init { | 27 | namespace init { |
26 | 28 | ||
@@ -40,7 +42,7 @@ void property_init(void); | |||
40 | void property_load_boot_defaults(void); | 42 | void property_load_boot_defaults(void); |
41 | void load_persist_props(void); | 43 | void load_persist_props(void); |
42 | void load_system_props(void); | 44 | void load_system_props(void); |
43 | void start_property_service(void); | 45 | void 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 | ||
65 | using android::base::ParseInt; | ||
64 | using android::base::Timer; | 66 | using android::base::Timer; |
65 | using android::base::unique_fd; | 67 | using 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. | ||
459 | bool 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(); | |||
27 | void SelinuxRestoreContext(); | 27 | void SelinuxRestoreContext(); |
28 | 28 | ||
29 | void SelinuxSetupKernelLogging(); | 29 | void SelinuxSetupKernelLogging(); |
30 | bool SelinuxHasVendorInit(); | ||
30 | 31 | ||
31 | void SelabelInitialize(); | 32 | void SelabelInitialize(); |
32 | bool SelabelLookupFileContext(const std::string& key, int type, std::string* result); | 33 | bool 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; | |||
59 | using android::base::ParseInt; | 60 | using android::base::ParseInt; |
60 | using android::base::StartsWith; | 61 | using android::base::StartsWith; |
61 | using android::base::StringPrintf; | 62 | using android::base::StringPrintf; |
63 | using android::base::unique_fd; | ||
62 | using android::base::WriteStringToFile; | 64 | using android::base::WriteStringToFile; |
63 | 65 | ||
64 | namespace android { | 66 | namespace android { |
65 | namespace init { | 67 | namespace init { |
66 | 68 | ||
67 | static Result<std::string> ComputeContextFromExecutable(std::string& service_name, | 69 | static 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 | ||
104 | static void SetUpPidNamespace(const std::string& service_name) { | 105 | Result<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) { | 140 | Result<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 | |||
173 | Result<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 | ||
158 | static bool ExpandArgsAndExecv(const std::vector<std::string>& args, bool sigstop) { | 186 | static 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 | ||
453 | Result<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 | |||
425 | Result<Success> Service::ParseGroup(const std::vector<std::string>& args) { | 467 | Result<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 | ||
41 | using android::base::GetExecutablePath; | 39 | using android::base::GetExecutablePath; |
42 | using android::base::GetIntProperty; | ||
43 | using android::base::Join; | 40 | using android::base::Join; |
44 | using android::base::Socketpair; | 41 | using android::base::Socketpair; |
45 | using android::base::Split; | 42 | using android::base::Split; |
@@ -357,7 +354,7 @@ Result<std::vector<std::string>> Subcontext::ExpandArgs(const std::vector<std::s | |||
357 | static std::vector<Subcontext> subcontexts; | 354 | static std::vector<Subcontext> subcontexts; |
358 | 355 | ||
359 | std::vector<Subcontext>* InitializeSubcontexts() { | 356 | std::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 | ||
249 | int ueventd_main(int argc, char** argv) { | 251 | int 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 = [ | |||
51 | cc_library_headers { | 51 | cc_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 | ||
63 | bool BacktraceMap::ParseLine(const char* line, backtrace_map_t* map) { | 66 | #if defined(__APPLE__) |
67 | static 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 | ||
111 | bool BacktraceMap::Build() { | 107 | bool 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 = [ | |||
32 | cc_library_headers { | 32 | cc_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 | ||
27 | typedef struct Entry Entry; | 26 | typedef 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 { | |||
65 | cc_library { | 66 | cc_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 | |||
26 | namespace android { | ||
27 | |||
28 | LineBuffer::LineBuffer(int fd, char* buffer, size_t buffer_len) | ||
29 | : fd_(fd), buffer_(buffer), buffer_len_(buffer_len) {} | ||
30 | |||
31 | bool 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 | |||
22 | namespace android { | ||
23 | |||
24 | class 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 | ||
498 | UnreachableMemoryInfo::~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 | |||
498 | std::string GetUnreachableMemoryString(bool log_contents, size_t limit) { | 513 | std::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 | ||
28 | namespace android { | 28 | namespace android { |
29 | 29 | ||
30 | // This function is not re-entrant since it uses a static buffer for | 30 | struct 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 | |||
32 | bool ProcessMappings(pid_t pid, allocator::vector<Mapping>& mappings) { | 41 | bool 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 | ||
22 | namespace android { | 24 | namespace 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 | |||
12 | Usage | 12 | Usage |
13 | ------- | 13 | ------- |
14 | 14 | ||
15 | ### In Android apps ### | ||
16 | |||
17 | libmemunreachble is loaded by zygote and can be triggered with `dumpsys -t 600 meminfo --unreachable [process]`. | ||
18 | |||
19 | To enable malloc\_debug backtraces on allocations for a single app process on a userdebug device, use: | ||
20 | ``` | ||
21 | adb root | ||
22 | adb shell setprop libc.debug.malloc.program app_process | ||
23 | adb shell setprop wrap.[process] "\$\@" | ||
24 | adb shell setprop libc.debug.malloc.options backtrace=4 | ||
25 | ``` | ||
26 | |||
27 | Kill and restart the app, trigger the leak, and then run `dumpsys -t 600 meminfo --unreachable [process]`. | ||
28 | |||
29 | To disable malloc\_debug: | ||
30 | ``` | ||
31 | adb shell setprop libc.debug.malloc.options "''" | ||
32 | adb shell setprop libc.debug.malloc.program "''" | ||
33 | adb 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 | |||
26 | namespace android { | 28 | namespace android { |
27 | 29 | ||
28 | class HiddenPointer { | 30 | class HiddenPointer { |
@@ -48,7 +50,35 @@ static void Ref(void** ptr) { | |||
48 | write(0, ptr, 0); | 50 | write(0, ptr, 0); |
49 | } | 51 | } |
50 | 52 | ||
51 | TEST(MemunreachableTest, clean) { | 53 | class 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 | |||
81 | TEST_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 | ||
60 | TEST(MemunreachableTest, stack) { | 90 | TEST_F(MemunreachableTest, stack) { |
61 | HiddenPointer hidden_ptr; | 91 | HiddenPointer hidden_ptr; |
62 | 92 | ||
63 | { | 93 | { |
@@ -91,7 +121,7 @@ TEST(MemunreachableTest, stack) { | |||
91 | 121 | ||
92 | void* g_ptr; | 122 | void* g_ptr; |
93 | 123 | ||
94 | TEST(MemunreachableTest, global) { | 124 | TEST_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 | ||
125 | TEST(MemunreachableTest, tls) { | 155 | TEST_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 | ||
160 | TEST(MemunreachableTest, twice) { | 190 | TEST_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 | ||
187 | TEST(MemunreachableTest, log) { | 229 | TEST_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 | ||
202 | TEST(MemunreachableTest, notdumpable) { | 244 | TEST_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 | ||
212 | TEST(MemunreachableTest, leak_lots) { | 260 | TEST_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 | ||
33 | cc_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 | // ----------------------------------------------------------------------------- |
34 | cc_library_shared { | 41 | cc_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|. |
33 | void LogMultiAction(int32_t category, int32_t field, const std::string& value); | 34 | void 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. | ||
43 | class 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 |
36 | enum { | 65 | enum { |
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 | ||
49 | enum { | 83 | enum { |
50 | TYPE_ACTION = 4, | 84 | TYPE_ACTION = 4, |
51 | }; | 85 | }; |
52 | 86 | ||
87 | enum { | ||
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 | ||
24 | namespace { | 24 | namespace { |
25 | 25 | ||
26 | #ifdef __ANDROID__ | ||
26 | EventTagMap* kEventTagMap = android_openEventTagMap(nullptr); | 27 | EventTagMap* kEventTagMap = android_openEventTagMap(nullptr); |
27 | const int kSysuiMultiActionTag = android_lookupEventTagNum( | 28 | const 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. | ||
32 | const 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 | ||
61 | ComplexEventLogger::ComplexEventLogger(int category) : logger(kSysuiMultiActionTag) { | ||
62 | logger << LOGBUILDER_CATEGORY << category; | ||
63 | } | ||
64 | |||
65 | void ComplexEventLogger::AddTaggedData(int tag, int32_t value) { | ||
66 | logger << tag << value; | ||
67 | } | ||
68 | |||
69 | void ComplexEventLogger::AddTaggedData(int tag, const std::string& value) { | ||
70 | logger << tag << value; | ||
71 | } | ||
72 | |||
73 | void ComplexEventLogger::AddTaggedData(int tag, int64_t value) { | ||
74 | logger << tag << value; | ||
75 | } | ||
76 | |||
77 | void ComplexEventLogger::AddTaggedData(int tag, float value) { | ||
78 | logger << tag << value; | ||
79 | } | ||
80 | |||
81 | void 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 @@ | |||
1 | cc_library { | 1 | cc_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 | |||
95 | cc_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 | |||
28 | namespace android { | ||
29 | namespace procinfo { | ||
30 | |||
31 | template <class CallbackType> | ||
32 | bool 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 | |||
134 | inline 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 | |||
144 | inline 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 | |||
30 | struct 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 | |||
41 | static 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 | } | ||
51 | BENCHMARK(BM_ReadMapFile); | ||
52 | |||
53 | static 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 | } | ||
61 | BENCHMARK(BM_unwindstack_FileMaps); | ||
62 | |||
63 | static 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 | } | ||
73 | BENCHMARK(BM_unwindstack_BufferMaps); | ||
74 | |||
75 | static 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 | } | ||
83 | BENCHMARK(BM_backtrace_BacktraceMap); | ||
84 | |||
85 | BENCHMARK_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 | |||
25 | struct 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 | |||
36 | TEST(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 @@ | |||
1 | 12c00000-2ac00000 rw-p 00000000 00:05 10267643 /dev/ashmem/dalvik-main space (region space) (deleted) | ||
2 | 6fb5d000-6fd6e000 rw-p 00000000 103:1d 639511 /data/dalvik-cache/arm64/system@framework@boot.art | ||
3 | 6fd6e000-6fd82000 r--p 00211000 103:1d 639511 /data/dalvik-cache/arm64/system@framework@boot.art | ||
4 | 6fd82000-6fe47000 rw-p 00000000 103:1d 639514 /data/dalvik-cache/arm64/system@framework@boot-core-libart.art | ||
5 | 6fe47000-6fe52000 r--p 000c5000 103:1d 639514 /data/dalvik-cache/arm64/system@framework@boot-core-libart.art | ||
6 | 6fe52000-6fe84000 rw-p 00000000 103:1d 639517 /data/dalvik-cache/arm64/system@framework@boot-conscrypt.art | ||
7 | 6fe84000-6fe87000 r--p 00032000 103:1d 639517 /data/dalvik-cache/arm64/system@framework@boot-conscrypt.art | ||
8 | 6fe87000-6feb2000 rw-p 00000000 103:1d 639520 /data/dalvik-cache/arm64/system@framework@boot-okhttp.art | ||
9 | 6feb2000-6feb5000 r--p 0002b000 103:1d 639520 /data/dalvik-cache/arm64/system@framework@boot-okhttp.art | ||
10 | 6feb5000-6fef4000 rw-p 00000000 103:1d 639523 /data/dalvik-cache/arm64/system@framework@boot-bouncycastle.art | ||
11 | 6fef4000-6fefb000 r--p 0003f000 103:1d 639523 /data/dalvik-cache/arm64/system@framework@boot-bouncycastle.art | ||
12 | 6fefb000-6ff3f000 rw-p 00000000 103:1d 639526 /data/dalvik-cache/arm64/system@framework@boot-apache-xml.art | ||
13 | 6ff3f000-6ff45000 r--p 00044000 103:1d 639526 /data/dalvik-cache/arm64/system@framework@boot-apache-xml.art | ||
14 | 6ff45000-6ff7a000 rw-p 00000000 103:1d 639529 /data/dalvik-cache/arm64/system@framework@boot-ext.art | ||
15 | 6ff7a000-6ff85000 r--p 00035000 103:1d 639529 /data/dalvik-cache/arm64/system@framework@boot-ext.art | ||
16 | 6ff85000-70594000 rw-p 00000000 103:1d 639532 /data/dalvik-cache/arm64/system@framework@boot-framework.art | ||
17 | 70594000-705cb000 r--p 0060f000 103:1d 639532 /data/dalvik-cache/arm64/system@framework@boot-framework.art | ||
18 | 705cb000-7061f000 rw-p 00000000 103:1d 639535 /data/dalvik-cache/arm64/system@framework@boot-telephony-common.art | ||
19 | 7061f000-70629000 r--p 00054000 103:1d 639535 /data/dalvik-cache/arm64/system@framework@boot-telephony-common.art | ||
20 | 70629000-70635000 rw-p 00000000 103:1d 639538 /data/dalvik-cache/arm64/system@framework@boot-voip-common.art | ||
21 | 70635000-70636000 r--p 0000c000 103:1d 639538 /data/dalvik-cache/arm64/system@framework@boot-voip-common.art | ||
22 | 70636000-70644000 rw-p 00000000 103:1d 639541 /data/dalvik-cache/arm64/system@framework@boot-ims-common.art | ||
23 | 70644000-70645000 r--p 0000e000 103:1d 639541 /data/dalvik-cache/arm64/system@framework@boot-ims-common.art | ||
24 | 70645000-70648000 rw-p 00000000 103:1d 639544 /data/dalvik-cache/arm64/system@framework@boot-android.hidl.base-V1.0-java.art | ||
25 | 70648000-7064c000 rw-p 00000000 103:1d 639547 /data/dalvik-cache/arm64/system@framework@boot-android.hidl.manager-V1.0-java.art | ||
26 | 7064c000-7064d000 r--p 00004000 103:1d 639547 /data/dalvik-cache/arm64/system@framework@boot-android.hidl.manager-V1.0-java.art | ||
27 | 7064d000-7064e000 rw-p 00000000 103:1d 639550 /data/dalvik-cache/arm64/system@framework@boot-framework-oahl-backward-compatibility.art | ||
28 | 7064e000-70652000 rw-p 00000000 103:1d 639553 /data/dalvik-cache/arm64/system@framework@boot-android.test.base.art | ||
29 | 70652000-70653000 r--p 00004000 103:1d 639553 /data/dalvik-cache/arm64/system@framework@boot-android.test.base.art | ||
30 | 70653000-70654000 rw-p 00000000 103:1d 639556 /data/dalvik-cache/arm64/system@framework@boot-com.google.vr.platform.art | ||
31 | 70654000-70655000 r--p 00001000 103:1d 639556 /data/dalvik-cache/arm64/system@framework@boot-com.google.vr.platform.art | ||
32 | 70655000-70731000 r--p 00000000 fc:00 940 /system/framework/arm64/boot.oat | ||
33 | 70731000-709ca000 r-xp 000dc000 fc:00 940 /system/framework/arm64/boot.oat | ||
34 | 709ca000-709cb000 rw-p 00000000 00:00 0 [anon:.bss] | ||
35 | 709cb000-70e4c000 r--s 00000000 fc:00 961 /system/framework/boot.vdex | ||
36 | 70e4c000-70e4d000 r--p 00375000 fc:00 940 /system/framework/arm64/boot.oat | ||
37 | 70e4d000-70e4e000 rw-p 00376000 fc:00 940 /system/framework/arm64/boot.oat | ||
38 | 70e4e000-70eab000 r--p 00000000 fc:00 916 /system/framework/arm64/boot-core-libart.oat | ||
39 | 70eab000-70fad000 r-xp 0005d000 fc:00 916 /system/framework/arm64/boot-core-libart.oat | ||
40 | 70fad000-70fae000 rw-p 00000000 00:00 0 [anon:.bss] | ||
41 | 70fae000-712a9000 r--s 00000000 fc:00 702 /system/framework/boot-core-libart.vdex | ||
42 | 712a9000-712aa000 r--p 0015f000 fc:00 916 /system/framework/arm64/boot-core-libart.oat | ||
43 | 712aa000-712ab000 rw-p 00160000 fc:00 916 /system/framework/arm64/boot-core-libart.oat | ||
44 | 712ab000-712bb000 r--p 00000000 fc:00 941 /system/framework/arm64/boot-conscrypt.oat | ||
45 | 712bb000-712e4000 r-xp 00010000 fc:00 941 /system/framework/arm64/boot-conscrypt.oat | ||
46 | 712e4000-712e5000 rw-p 00000000 00:00 0 [anon:.bss] | ||
47 | 712e5000-71346000 r--s 00000000 fc:00 970 /system/framework/boot-conscrypt.vdex | ||
48 | 71346000-71347000 r--p 00039000 fc:00 941 /system/framework/arm64/boot-conscrypt.oat | ||
49 | 71347000-71348000 rw-p 0003a000 fc:00 941 /system/framework/arm64/boot-conscrypt.oat | ||
50 | 71348000-71361000 r--p 00000000 fc:00 908 /system/framework/arm64/boot-okhttp.oat | ||
51 | 71361000-713a3000 r-xp 00019000 fc:00 908 /system/framework/arm64/boot-okhttp.oat | ||
52 | 713a3000-713a4000 rw-p 00000000 00:00 0 [anon:.bss] | ||
53 | 713a4000-71403000 r--s 00000000 fc:00 886 /system/framework/boot-okhttp.vdex | ||
54 | 71403000-71404000 r--p 0005b000 fc:00 908 /system/framework/arm64/boot-okhttp.oat | ||
55 | 71404000-71405000 rw-p 0005c000 fc:00 908 /system/framework/arm64/boot-okhttp.oat | ||
56 | 71405000-71415000 r--p 00000000 fc:00 936 /system/framework/arm64/boot-bouncycastle.oat | ||
57 | 71415000-71437000 r-xp 00010000 fc:00 936 /system/framework/arm64/boot-bouncycastle.oat | ||
58 | 71437000-71438000 rw-p 00000000 00:00 0 [anon:.bss] | ||
59 | 71438000-7157b000 r--s 00000000 fc:00 1006 /system/framework/boot-bouncycastle.vdex | ||
60 | 7157b000-7157c000 r--p 00032000 fc:00 936 /system/framework/arm64/boot-bouncycastle.oat | ||
61 | 7157c000-7157d000 rw-p 00033000 fc:00 936 /system/framework/arm64/boot-bouncycastle.oat | ||
62 | 7157d000-71583000 r--p 00000000 fc:00 932 /system/framework/arm64/boot-apache-xml.oat | ||
63 | 71583000-71584000 r-xp 00006000 fc:00 932 /system/framework/arm64/boot-apache-xml.oat | ||
64 | 71584000-716a7000 r--s 00000000 fc:00 883 /system/framework/boot-apache-xml.vdex | ||
65 | 716a7000-716a8000 r--p 00007000 fc:00 932 /system/framework/arm64/boot-apache-xml.oat | ||
66 | 716a8000-716a9000 rw-p 00008000 fc:00 932 /system/framework/arm64/boot-apache-xml.oat | ||
67 | 716a9000-716b5000 r--p 00000000 fc:00 891 /system/framework/arm64/boot-ext.oat | ||
68 | 716b5000-716cc000 r-xp 0000c000 fc:00 891 /system/framework/arm64/boot-ext.oat | ||
69 | 716cc000-716cd000 rw-p 00000000 00:00 0 [anon:.bss] | ||
70 | 716cd000-717b8000 r--s 00000000 fc:00 879 /system/framework/boot-ext.vdex | ||
71 | 717b8000-717b9000 r--p 00023000 fc:00 891 /system/framework/arm64/boot-ext.oat | ||
72 | 717b9000-717ba000 rw-p 00024000 fc:00 891 /system/framework/arm64/boot-ext.oat | ||
73 | 717ba000-71aeb000 r--p 00000000 fc:00 943 /system/framework/arm64/boot-framework.oat | ||
74 | 71aeb000-72390000 r-xp 00331000 fc:00 943 /system/framework/arm64/boot-framework.oat | ||
75 | 72390000-72396000 rw-p 00000000 00:00 0 [anon:.bss] | ||
76 | 72396000-73746000 r--s 00000000 fc:00 985 /system/framework/boot-framework.vdex | ||
77 | 73746000-73747000 r--p 00bd6000 fc:00 943 /system/framework/arm64/boot-framework.oat | ||
78 | 73747000-73748000 rw-p 00bd7000 fc:00 943 /system/framework/arm64/boot-framework.oat | ||
79 | 73748000-73780000 r--p 00000000 fc:00 893 /system/framework/arm64/boot-telephony-common.oat | ||
80 | 73780000-73818000 r-xp 00038000 fc:00 893 /system/framework/arm64/boot-telephony-common.oat | ||
81 | 73818000-7381a000 rw-p 00000000 00:00 0 [anon:.bss] | ||
82 | 7381a000-73af0000 r--s 00000000 fc:00 697 /system/framework/boot-telephony-common.vdex | ||
83 | 73af0000-73af1000 r--p 000d0000 fc:00 893 /system/framework/arm64/boot-telephony-common.oat | ||
84 | 73af1000-73af2000 rw-p 000d1000 fc:00 893 /system/framework/arm64/boot-telephony-common.oat | ||
85 | 73af2000-73af6000 r--p 00000000 fc:00 922 /system/framework/arm64/boot-voip-common.oat | ||
86 | 73af6000-73af8000 r-xp 00004000 fc:00 922 /system/framework/arm64/boot-voip-common.oat | ||
87 | 73af8000-73af9000 rw-p 00000000 00:00 0 [anon:.bss] | ||
88 | 73af9000-73b1e000 r--s 00000000 fc:00 959 /system/framework/boot-voip-common.vdex | ||
89 | 73b1e000-73b1f000 r--p 00006000 fc:00 922 /system/framework/arm64/boot-voip-common.oat | ||
90 | 73b1f000-73b20000 rw-p 00007000 fc:00 922 /system/framework/arm64/boot-voip-common.oat | ||
91 | 73b20000-73b23000 r--p 00000000 fc:00 918 /system/framework/arm64/boot-ims-common.oat | ||
92 | 73b23000-73b25000 r-xp 00003000 fc:00 918 /system/framework/arm64/boot-ims-common.oat | ||
93 | 73b25000-73b26000 rw-p 00000000 00:00 0 [anon:.bss] | ||
94 | 73b26000-73b48000 r--s 00000000 fc:00 957 /system/framework/boot-ims-common.vdex | ||
95 | 73b48000-73b49000 r--p 00005000 fc:00 918 /system/framework/arm64/boot-ims-common.oat | ||
96 | 73b49000-73b4a000 rw-p 00006000 fc:00 918 /system/framework/arm64/boot-ims-common.oat | ||
97 | 73b4a000-73b4d000 r--p 00000000 fc:00 909 /system/framework/arm64/boot-android.hidl.base-V1.0-java.oat | ||
98 | 73b4d000-73b4e000 r-xp 00003000 fc:00 909 /system/framework/arm64/boot-android.hidl.base-V1.0-java.oat | ||
99 | 73b4e000-73b55000 r--s 00000000 fc:00 972 /system/framework/boot-android.hidl.base-V1.0-java.vdex | ||
100 | 73b55000-73b56000 r--p 00004000 fc:00 909 /system/framework/arm64/boot-android.hidl.base-V1.0-java.oat | ||
101 | 73b56000-73b57000 rw-p 00005000 fc:00 909 /system/framework/arm64/boot-android.hidl.base-V1.0-java.oat | ||
102 | 73b57000-73b5a000 r--p 00000000 fc:00 954 /system/framework/arm64/boot-android.hidl.manager-V1.0-java.oat | ||
103 | 73b5a000-73b5c000 r-xp 00003000 fc:00 954 /system/framework/arm64/boot-android.hidl.manager-V1.0-java.oat | ||
104 | 73b5c000-73b5d000 rw-p 00000000 00:00 0 [anon:.bss] | ||
105 | 73b5d000-73b68000 r--s 00000000 fc:00 704 /system/framework/boot-android.hidl.manager-V1.0-java.vdex | ||
106 | 73b68000-73b69000 r--p 00005000 fc:00 954 /system/framework/arm64/boot-android.hidl.manager-V1.0-java.oat | ||
107 | 73b69000-73b6a000 rw-p 00006000 fc:00 954 /system/framework/arm64/boot-android.hidl.manager-V1.0-java.oat | ||
108 | 73b6a000-73b6d000 r--p 00000000 fc:00 904 /system/framework/arm64/boot-framework-oahl-backward-compatibility.oat | ||
109 | 73b6d000-73b6e000 r-xp 00003000 fc:00 904 /system/framework/arm64/boot-framework-oahl-backward-compatibility.oat | ||
110 | 73b6e000-73b6f000 r--s 00000000 fc:00 994 /system/framework/boot-framework-oahl-backward-compatibility.vdex | ||
111 | 73b6f000-73b70000 r--p 00004000 fc:00 904 /system/framework/arm64/boot-framework-oahl-backward-compatibility.oat | ||
112 | 73b70000-73b71000 rw-p 00005000 fc:00 904 /system/framework/arm64/boot-framework-oahl-backward-compatibility.oat | ||
113 | 73b71000-73b75000 r--p 00000000 fc:00 896 /system/framework/arm64/boot-android.test.base.oat | ||
114 | 73b75000-73b79000 r-xp 00004000 fc:00 896 /system/framework/arm64/boot-android.test.base.oat | ||
115 | 73b79000-73b7a000 rw-p 00000000 00:00 0 [anon:.bss] | ||
116 | 73b7a000-73b82000 r--s 00000000 fc:00 706 /system/framework/boot-android.test.base.vdex | ||
117 | 73b82000-73b83000 r--p 00008000 fc:00 896 /system/framework/arm64/boot-android.test.base.oat | ||
118 | 73b83000-73b84000 rw-p 00009000 fc:00 896 /system/framework/arm64/boot-android.test.base.oat | ||
119 | 73b84000-73b87000 r--p 00000000 fc:00 899 /system/framework/arm64/boot-com.google.vr.platform.oat | ||
120 | 73b87000-73b88000 r-xp 00003000 fc:00 899 /system/framework/arm64/boot-com.google.vr.platform.oat | ||
121 | 73b88000-73b89000 r--s 00000000 fc:00 884 /system/framework/boot-com.google.vr.platform.vdex | ||
122 | 73b89000-73b8a000 r--p 00004000 fc:00 899 /system/framework/arm64/boot-com.google.vr.platform.oat | ||
123 | 73b8a000-73b8b000 rw-p 00005000 fc:00 899 /system/framework/arm64/boot-com.google.vr.platform.oat | ||
124 | 73b8b000-73b93000 rw-p 00000000 00:05 10267640 /dev/ashmem/dalvik-non moving space (deleted) | ||
125 | 73b93000-77b8b000 ---p 00008000 00:05 10267640 /dev/ashmem/dalvik-non moving space (deleted) | ||
126 | 77b8b000-97b8b000 rw-p 00000000 00:05 10267645 /dev/ashmem/dalvik-free list large object space (deleted) | ||
127 | 97b8b000-99b8b000 rw-p 00000000 00:05 10270989 /dev/ashmem/dalvik-data-code-cache (deleted) | ||
128 | 99b8b000-9bb8b000 r-xp 00000000 00:05 10270990 /dev/ashmem/dalvik-jit-code-cache (deleted) | ||
129 | ebad6000-ebad7000 ---p 00000000 00:05 10269717 /dev/ashmem/dalvik-Sentinel fault page (deleted) | ||
130 | 7ffb6e000-7ffb76000 rw-s 000e5000 00:10 20630 /dev/kgsl-3d0 | ||
131 | 7ffb76000-7ffb78000 rw-s 000e0000 00:10 20630 /dev/kgsl-3d0 | ||
132 | 7ffbc3000-7ffbc4000 rw-s 000e8000 00:10 20630 /dev/kgsl-3d0 | ||
133 | 7ffbc4000-7ffbc5000 rw-s 000e7000 00:10 20630 /dev/kgsl-3d0 | ||
134 | 7ffbc6000-7ffbce000 rw-s 000e4000 00:10 20630 /dev/kgsl-3d0 | ||
135 | 7ffbd0000-7ffbd2000 rw-s 000df000 00:10 20630 /dev/kgsl-3d0 | ||
136 | 7ffbd2000-7ffbd4000 rw-s 000de000 00:10 20630 /dev/kgsl-3d0 | ||
137 | 7ffbd4000-7ffbd6000 rw-s 000dd000 00:10 20630 /dev/kgsl-3d0 | ||
138 | 7ffbd6000-7ffbd8000 rw-s 000dc000 00:10 20630 /dev/kgsl-3d0 | ||
139 | 7ffbd8000-7ffbda000 rw-s 000db000 00:10 20630 /dev/kgsl-3d0 | ||
140 | 7ffbda000-7ffbdc000 rw-s 000da000 00:10 20630 /dev/kgsl-3d0 | ||
141 | 7ffbdd000-7ffbde000 rw-s 000ec000 00:10 20630 /dev/kgsl-3d0 | ||
142 | 7ffbde000-7ffbe0000 rw-s 000d8000 00:10 20630 /dev/kgsl-3d0 | ||
143 | 7ffce1000-7ffce2000 rw-s 000e6000 00:10 20630 /dev/kgsl-3d0 | ||
144 | 7ffce2000-7ffce4000 rw-s 000d9000 00:10 20630 /dev/kgsl-3d0 | ||
145 | 7ffce4000-7ffce8000 rw-s 000d4000 00:10 20630 /dev/kgsl-3d0 | ||
146 | 7ffce8000-7ffcf8000 rw-s 000d2000 00:10 20630 /dev/kgsl-3d0 | ||
147 | 7ffcf8000-7ffd08000 rw-s 000d1000 00:10 20630 /dev/kgsl-3d0 | ||
148 | 7ffd08000-7ffd10000 rw-s 000d0000 00:10 20630 /dev/kgsl-3d0 | ||
149 | 7ffd14000-7ffd18000 rw-s 000cd000 00:10 20630 /dev/kgsl-3d0 | ||
150 | 7ffd18000-7ffd28000 rw-s 000cc000 00:10 20630 /dev/kgsl-3d0 | ||
151 | 7ffd28000-7ffd38000 rw-s 000cb000 00:10 20630 /dev/kgsl-3d0 | ||
152 | 7ffd38000-7ffd48000 rw-s 000ca000 00:10 20630 /dev/kgsl-3d0 | ||
153 | 7ffd48000-7ffd58000 rw-s 000c9000 00:10 20630 /dev/kgsl-3d0 | ||
154 | 7ffd58000-7ffd68000 rw-s 000c8000 00:10 20630 /dev/kgsl-3d0 | ||
155 | 7ffd68000-7ffd6c000 rw-s 000c7000 00:10 20630 /dev/kgsl-3d0 | ||
156 | 7ffdb1000-7ffdb2000 rw-s 000e3000 00:10 20630 /dev/kgsl-3d0 | ||
157 | 7ffdb4000-7ffdb5000 rw-s 000e2000 00:10 20630 /dev/kgsl-3d0 | ||
158 | 7ffdb5000-7ffdb7000 rw-s 000d7000 00:10 20630 /dev/kgsl-3d0 | ||
159 | 7ffdb7000-7ffdb8000 rw-s 000c2000 00:10 20630 /dev/kgsl-3d0 | ||
160 | 7ffdb8000-7ffdbc000 rw-s 000c0000 00:10 20630 /dev/kgsl-3d0 | ||
161 | 7ffdbc000-7ffdc0000 rw-s 000be000 00:10 20630 /dev/kgsl-3d0 | ||
162 | 7ffdc0000-7ffe00000 rw-s 000bb000 00:10 20630 /dev/kgsl-3d0 | ||
163 | 7ffe00000-7ffe20000 rw-s 000ba000 00:10 20630 /dev/kgsl-3d0 | ||
164 | 7ffe20000-7ffee0000 rw-s 000b9000 00:10 20630 /dev/kgsl-3d0 | ||
165 | 7ffee1000-7ffee3000 rw-s 000c1000 00:10 20630 /dev/kgsl-3d0 | ||
166 | 7ffee3000-7ffee4000 rw-s 000bf000 00:10 20630 /dev/kgsl-3d0 | ||
167 | 7ffee4000-7ffee8000 rw-s 000bd000 00:10 20630 /dev/kgsl-3d0 | ||
168 | 7ffee8000-7ffee9000 rw-s 000bc000 00:10 20630 /dev/kgsl-3d0 | ||
169 | 7ffeea000-7ffeeb000 rw-s 000e1000 00:10 20630 /dev/kgsl-3d0 | ||
170 | 7ffeeb000-7ffeec000 rw-s 000b6000 00:10 20630 /dev/kgsl-3d0 | ||
171 | 7ffeec000-7ffeed000 rw-s 000b5000 00:10 20630 /dev/kgsl-3d0 | ||
172 | 7ffeed000-7ffeee000 rw-s 000b4000 00:10 20630 /dev/kgsl-3d0 | ||
173 | 7ffeee000-7ffeef000 rw-s 000b3000 00:10 20630 /dev/kgsl-3d0 | ||
174 | 7ffeef000-7ffef0000 rw-s 000b2000 00:10 20630 /dev/kgsl-3d0 | ||
175 | 7ffef0000-7ffef1000 rw-s 000b1000 00:10 20630 /dev/kgsl-3d0 | ||
176 | 7ffef1000-7ffef2000 rw-s 000b0000 00:10 20630 /dev/kgsl-3d0 | ||
177 | 7ffef2000-7ffef3000 rw-s 000af000 00:10 20630 /dev/kgsl-3d0 | ||
178 | 7ffef3000-7ffef4000 rw-s 000ae000 00:10 20630 /dev/kgsl-3d0 | ||
179 | 7ffef4000-7ffef5000 rw-s 000ad000 00:10 20630 /dev/kgsl-3d0 | ||
180 | 7ffef5000-7ffef6000 rw-s 000ac000 00:10 20630 /dev/kgsl-3d0 | ||
181 | 7ffef6000-7ffef7000 rw-s 000ab000 00:10 20630 /dev/kgsl-3d0 | ||
182 | 7ffef7000-7ffef8000 rw-s 000aa000 00:10 20630 /dev/kgsl-3d0 | ||
183 | 7ffef8000-7ffef9000 rw-s 000a9000 00:10 20630 /dev/kgsl-3d0 | ||
184 | 7ffef9000-7ffefa000 rw-s 000a8000 00:10 20630 /dev/kgsl-3d0 | ||
185 | 7ffefa000-7ffefb000 rw-s 000a7000 00:10 20630 /dev/kgsl-3d0 | ||
186 | 7ffefb000-7ffefc000 rw-s 000a6000 00:10 20630 /dev/kgsl-3d0 | ||
187 | 7ffefc000-7ffefd000 rw-s 000a5000 00:10 20630 /dev/kgsl-3d0 | ||
188 | 7ffefd000-7ffefe000 rw-s 000a4000 00:10 20630 /dev/kgsl-3d0 | ||
189 | 7ffefe000-7ffeff000 rw-s 000a3000 00:10 20630 /dev/kgsl-3d0 | ||
190 | 7ffeff000-7fff00000 rw-s 000a2000 00:10 20630 /dev/kgsl-3d0 | ||
191 | 7fff00000-7fff01000 rw-s 000a1000 00:10 20630 /dev/kgsl-3d0 | ||
192 | 7fff01000-7fff02000 rw-s 000a0000 00:10 20630 /dev/kgsl-3d0 | ||
193 | 7fff02000-7fff03000 rw-s 0009f000 00:10 20630 /dev/kgsl-3d0 | ||
194 | 7fff03000-7fff04000 rw-s 0009e000 00:10 20630 /dev/kgsl-3d0 | ||
195 | 7fff04000-7fff05000 rw-s 0009d000 00:10 20630 /dev/kgsl-3d0 | ||
196 | 7fff05000-7fff06000 rw-s 0009c000 00:10 20630 /dev/kgsl-3d0 | ||
197 | 7fff06000-7fff07000 rw-s 0009b000 00:10 20630 /dev/kgsl-3d0 | ||
198 | 7fff07000-7fff08000 rw-s 0009a000 00:10 20630 /dev/kgsl-3d0 | ||
199 | 7fff08000-7fff09000 rw-s 00099000 00:10 20630 /dev/kgsl-3d0 | ||
200 | 7fff09000-7fff0a000 rw-s 00098000 00:10 20630 /dev/kgsl-3d0 | ||
201 | 7fff0a000-7fff0b000 rw-s 00097000 00:10 20630 /dev/kgsl-3d0 | ||
202 | 7fff0b000-7fff0c000 rw-s 00096000 00:10 20630 /dev/kgsl-3d0 | ||
203 | 7fff0c000-7fff0d000 rw-s 00095000 00:10 20630 /dev/kgsl-3d0 | ||
204 | 7fff0d000-7fff0e000 rw-s 00094000 00:10 20630 /dev/kgsl-3d0 | ||
205 | 7fff0e000-7fff0f000 rw-s 00093000 00:10 20630 /dev/kgsl-3d0 | ||
206 | 7fff0f000-7fff10000 rw-s 00092000 00:10 20630 /dev/kgsl-3d0 | ||
207 | 7fff10000-7fff11000 rw-s 00091000 00:10 20630 /dev/kgsl-3d0 | ||
208 | 7fff11000-7fff12000 rw-s 00090000 00:10 20630 /dev/kgsl-3d0 | ||
209 | 7fff12000-7fff13000 rw-s 0008f000 00:10 20630 /dev/kgsl-3d0 | ||
210 | 7fff13000-7fff14000 rw-s 0008e000 00:10 20630 /dev/kgsl-3d0 | ||
211 | 7fff14000-7fff15000 rw-s 0008d000 00:10 20630 /dev/kgsl-3d0 | ||
212 | 7fff15000-7fff16000 rw-s 0008c000 00:10 20630 /dev/kgsl-3d0 | ||
213 | 7fff16000-7fff17000 rw-s 0008b000 00:10 20630 /dev/kgsl-3d0 | ||
214 | 7fff17000-7fff18000 rw-s 0008a000 00:10 20630 /dev/kgsl-3d0 | ||
215 | 7fff18000-7fff19000 rw-s 00089000 00:10 20630 /dev/kgsl-3d0 | ||
216 | 7fff19000-7fff1a000 rw-s 00088000 00:10 20630 /dev/kgsl-3d0 | ||
217 | 7fff1a000-7fff1b000 rw-s 00087000 00:10 20630 /dev/kgsl-3d0 | ||
218 | 7fff1b000-7fff1c000 rw-s 00086000 00:10 20630 /dev/kgsl-3d0 | ||
219 | 7fff1c000-7fff1d000 rw-s 00085000 00:10 20630 /dev/kgsl-3d0 | ||
220 | 7fff1d000-7fff1e000 rw-s 00084000 00:10 20630 /dev/kgsl-3d0 | ||
221 | 7fff1e000-7fff1f000 rw-s 00083000 00:10 20630 /dev/kgsl-3d0 | ||
222 | 7fff1f000-7fff20000 rw-s 00082000 00:10 20630 /dev/kgsl-3d0 | ||
223 | 7fff20000-7fff21000 rw-s 00081000 00:10 20630 /dev/kgsl-3d0 | ||
224 | 7fff21000-7fff22000 rw-s 00080000 00:10 20630 /dev/kgsl-3d0 | ||
225 | 7fff22000-7fff23000 rw-s 0007f000 00:10 20630 /dev/kgsl-3d0 | ||
226 | 7fff23000-7fff24000 rw-s 0007e000 00:10 20630 /dev/kgsl-3d0 | ||
227 | 7fff24000-7fff25000 rw-s 0007d000 00:10 20630 /dev/kgsl-3d0 | ||
228 | 7fff25000-7fff26000 rw-s 0007c000 00:10 20630 /dev/kgsl-3d0 | ||
229 | 7fff26000-7fff27000 rw-s 0007b000 00:10 20630 /dev/kgsl-3d0 | ||
230 | 7fff27000-7fff28000 rw-s 0007a000 00:10 20630 /dev/kgsl-3d0 | ||
231 | 7fff28000-7fff29000 rw-s 00079000 00:10 20630 /dev/kgsl-3d0 | ||
232 | 7fff29000-7fff2a000 rw-s 00078000 00:10 20630 /dev/kgsl-3d0 | ||
233 | 7fff2a000-7fff2b000 rw-s 00077000 00:10 20630 /dev/kgsl-3d0 | ||
234 | 7fff2b000-7fff2c000 rw-s 00076000 00:10 20630 /dev/kgsl-3d0 | ||
235 | 7fff2c000-7fff2d000 rw-s 00075000 00:10 20630 /dev/kgsl-3d0 | ||
236 | 7fff2d000-7fff2e000 rw-s 00074000 00:10 20630 /dev/kgsl-3d0 | ||
237 | 7fff2e000-7fff2f000 rw-s 00073000 00:10 20630 /dev/kgsl-3d0 | ||
238 | 7fff2f000-7fff30000 rw-s 00072000 00:10 20630 /dev/kgsl-3d0 | ||
239 | 7fff30000-7fff31000 rw-s 00071000 00:10 20630 /dev/kgsl-3d0 | ||
240 | 7fff31000-7fff32000 rw-s 00070000 00:10 20630 /dev/kgsl-3d0 | ||
241 | 7fff32000-7fff33000 rw-s 0006f000 00:10 20630 /dev/kgsl-3d0 | ||
242 | 7fff33000-7fff34000 rw-s 0006e000 00:10 20630 /dev/kgsl-3d0 | ||
243 | 7fff34000-7fff35000 rw-s 0006d000 00:10 20630 /dev/kgsl-3d0 | ||
244 | 7fff35000-7fff36000 rw-s 0006c000 00:10 20630 /dev/kgsl-3d0 | ||
245 | 7fff36000-7fff37000 rw-s 0006b000 00:10 20630 /dev/kgsl-3d0 | ||
246 | 7fff37000-7fff38000 rw-s 0006a000 00:10 20630 /dev/kgsl-3d0 | ||
247 | 7fff38000-7fff39000 rw-s 00069000 00:10 20630 /dev/kgsl-3d0 | ||
248 | 7fff39000-7fff3a000 rw-s 00068000 00:10 20630 /dev/kgsl-3d0 | ||
249 | 7fff3a000-7fff3b000 rw-s 00067000 00:10 20630 /dev/kgsl-3d0 | ||
250 | 7fff3b000-7fff3c000 rw-s 00066000 00:10 20630 /dev/kgsl-3d0 | ||
251 | 7fff3c000-7fff3d000 rw-s 00065000 00:10 20630 /dev/kgsl-3d0 | ||
252 | 7fff3d000-7fff3e000 rw-s 00064000 00:10 20630 /dev/kgsl-3d0 | ||
253 | 7fff3e000-7fff3f000 rw-s 00063000 00:10 20630 /dev/kgsl-3d0 | ||
254 | 7fff3f000-7fff40000 rw-s 00062000 00:10 20630 /dev/kgsl-3d0 | ||
255 | 7fff40000-7fff41000 rw-s 00061000 00:10 20630 /dev/kgsl-3d0 | ||
256 | 7fff41000-7fff42000 rw-s 00060000 00:10 20630 /dev/kgsl-3d0 | ||
257 | 7fff42000-7fff43000 rw-s 0005f000 00:10 20630 /dev/kgsl-3d0 | ||
258 | 7fff43000-7fff44000 rw-s 0005e000 00:10 20630 /dev/kgsl-3d0 | ||
259 | 7fff44000-7fff45000 rw-s 0005d000 00:10 20630 /dev/kgsl-3d0 | ||
260 | 7fff45000-7fff46000 rw-s 0005c000 00:10 20630 /dev/kgsl-3d0 | ||
261 | 7fff46000-7fff47000 rw-s 0005b000 00:10 20630 /dev/kgsl-3d0 | ||
262 | 7fff47000-7fff48000 rw-s 0005a000 00:10 20630 /dev/kgsl-3d0 | ||
263 | 7fff48000-7fff49000 rw-s 00059000 00:10 20630 /dev/kgsl-3d0 | ||
264 | 7fff49000-7fff4a000 rw-s 00058000 00:10 20630 /dev/kgsl-3d0 | ||
265 | 7fff4a000-7fff4b000 rw-s 00057000 00:10 20630 /dev/kgsl-3d0 | ||
266 | 7fff4b000-7fff4c000 rw-s 00056000 00:10 20630 /dev/kgsl-3d0 | ||
267 | 7fff4c000-7fff4d000 rw-s 00055000 00:10 20630 /dev/kgsl-3d0 | ||
268 | 7fff4d000-7fff4e000 rw-s 00054000 00:10 20630 /dev/kgsl-3d0 | ||
269 | 7fff4e000-7fff4f000 rw-s 00053000 00:10 20630 /dev/kgsl-3d0 | ||
270 | 7fff4f000-7fff50000 rw-s 00052000 00:10 20630 /dev/kgsl-3d0 | ||
271 | 7fff50000-7fff51000 rw-s 00051000 00:10 20630 /dev/kgsl-3d0 | ||
272 | 7fff51000-7fff52000 rw-s 00050000 00:10 20630 /dev/kgsl-3d0 | ||
273 | 7fff52000-7fff53000 rw-s 0004f000 00:10 20630 /dev/kgsl-3d0 | ||
274 | 7fff53000-7fff54000 rw-s 0004e000 00:10 20630 /dev/kgsl-3d0 | ||
275 | 7fff54000-7fff55000 rw-s 0004d000 00:10 20630 /dev/kgsl-3d0 | ||
276 | 7fff55000-7fff56000 rw-s 0004c000 00:10 20630 /dev/kgsl-3d0 | ||
277 | 7fff56000-7fff57000 rw-s 0004b000 00:10 20630 /dev/kgsl-3d0 | ||
278 | 7fff57000-7fff58000 rw-s 0004a000 00:10 20630 /dev/kgsl-3d0 | ||
279 | 7fff58000-7fff59000 rw-s 00049000 00:10 20630 /dev/kgsl-3d0 | ||
280 | 7fff59000-7fff5a000 rw-s 00048000 00:10 20630 /dev/kgsl-3d0 | ||
281 | 7fff5a000-7fff5b000 rw-s 00047000 00:10 20630 /dev/kgsl-3d0 | ||
282 | 7fff5b000-7fff5c000 rw-s 00046000 00:10 20630 /dev/kgsl-3d0 | ||
283 | 7fff5c000-7fff5d000 rw-s 00045000 00:10 20630 /dev/kgsl-3d0 | ||
284 | 7fff5d000-7fff5e000 rw-s 00044000 00:10 20630 /dev/kgsl-3d0 | ||
285 | 7fff5e000-7fff5f000 rw-s 00043000 00:10 20630 /dev/kgsl-3d0 | ||
286 | 7fff5f000-7fff60000 rw-s 00042000 00:10 20630 /dev/kgsl-3d0 | ||
287 | 7fff60000-7fff61000 rw-s 00041000 00:10 20630 /dev/kgsl-3d0 | ||
288 | 7fff61000-7fff62000 rw-s 00040000 00:10 20630 /dev/kgsl-3d0 | ||
289 | 7fff62000-7fff63000 rw-s 0003f000 00:10 20630 /dev/kgsl-3d0 | ||
290 | 7fff63000-7fff64000 rw-s 0003e000 00:10 20630 /dev/kgsl-3d0 | ||
291 | 7fff64000-7fff65000 rw-s 0003d000 00:10 20630 /dev/kgsl-3d0 | ||
292 | 7fff65000-7fff66000 rw-s 0003c000 00:10 20630 /dev/kgsl-3d0 | ||
293 | 7fff66000-7fff67000 rw-s 0003b000 00:10 20630 /dev/kgsl-3d0 | ||
294 | 7fff67000-7fff68000 rw-s 0003a000 00:10 20630 /dev/kgsl-3d0 | ||
295 | 7fff68000-7fff69000 rw-s 00039000 00:10 20630 /dev/kgsl-3d0 | ||
296 | 7fff69000-7fff6a000 rw-s 00038000 00:10 20630 /dev/kgsl-3d0 | ||
297 | 7fff6a000-7fff6b000 rw-s 00037000 00:10 20630 /dev/kgsl-3d0 | ||
298 | 7fff6b000-7fff6c000 rw-s 00036000 00:10 20630 /dev/kgsl-3d0 | ||
299 | 7fff6c000-7fff6d000 rw-s 00035000 00:10 20630 /dev/kgsl-3d0 | ||
300 | 7fff6d000-7fff6e000 rw-s 00034000 00:10 20630 /dev/kgsl-3d0 | ||
301 | 7fff6e000-7fff6f000 rw-s 00033000 00:10 20630 /dev/kgsl-3d0 | ||
302 | 7fff6f000-7fff70000 rw-s 00032000 00:10 20630 /dev/kgsl-3d0 | ||
303 | 7fff70000-7fff71000 rw-s 00031000 00:10 20630 /dev/kgsl-3d0 | ||
304 | 7fff71000-7fff72000 rw-s 00030000 00:10 20630 /dev/kgsl-3d0 | ||
305 | 7fff72000-7fff73000 rw-s 0002f000 00:10 20630 /dev/kgsl-3d0 | ||
306 | 7fff73000-7fff74000 rw-s 0002e000 00:10 20630 /dev/kgsl-3d0 | ||
307 | 7fff74000-7fff75000 rw-s 0002d000 00:10 20630 /dev/kgsl-3d0 | ||
308 | 7fff75000-7fff76000 rw-s 0002c000 00:10 20630 /dev/kgsl-3d0 | ||
309 | 7fff76000-7fff77000 rw-s 0002b000 00:10 20630 /dev/kgsl-3d0 | ||
310 | 7fff77000-7fff78000 rw-s 0002a000 00:10 20630 /dev/kgsl-3d0 | ||
311 | 7fff78000-7fff79000 rw-s 00029000 00:10 20630 /dev/kgsl-3d0 | ||
312 | 7fff79000-7fff7a000 rw-s 00028000 00:10 20630 /dev/kgsl-3d0 | ||
313 | 7fff7a000-7fff7b000 rw-s 00027000 00:10 20630 /dev/kgsl-3d0 | ||
314 | 7fff7b000-7fff7c000 rw-s 00026000 00:10 20630 /dev/kgsl-3d0 | ||
315 | 7fff7c000-7fff7d000 rw-s 00025000 00:10 20630 /dev/kgsl-3d0 | ||
316 | 7fff7d000-7fff7e000 rw-s 00024000 00:10 20630 /dev/kgsl-3d0 | ||
317 | 7fff7e000-7fff7f000 rw-s 00023000 00:10 20630 /dev/kgsl-3d0 | ||
318 | 7fff7f000-7fff80000 rw-s 00022000 00:10 20630 /dev/kgsl-3d0 | ||
319 | 7fff80000-7fff90000 rw-s 00019000 00:10 20630 /dev/kgsl-3d0 | ||
320 | 7fff90000-7fffb0000 rw-s 00018000 00:10 20630 /dev/kgsl-3d0 | ||
321 | 7fffb1000-7fffb2000 rw-s 00021000 00:10 20630 /dev/kgsl-3d0 | ||
322 | 7fffb2000-7fffb3000 rw-s 00020000 00:10 20630 /dev/kgsl-3d0 | ||
323 | 7fffb3000-7fffb4000 rw-s 0001f000 00:10 20630 /dev/kgsl-3d0 | ||
324 | 7fffba000-7fffbe000 rw-s 0001b000 00:10 20630 /dev/kgsl-3d0 | ||
325 | 7fffbe000-7fffbf000 rw-s 0001a000 00:10 20630 /dev/kgsl-3d0 | ||
326 | 7fffbf000-7fffc0000 rw-s 00017000 00:10 20630 /dev/kgsl-3d0 | ||
327 | 7fffc0000-7fffe0000 rw-s 00016000 00:10 20630 /dev/kgsl-3d0 | ||
328 | 7fffe0000-7fffe1000 rw-s 00014000 00:10 20630 /dev/kgsl-3d0 | ||
329 | 7fffe1000-7fffe5000 rw-s 00013000 00:10 20630 /dev/kgsl-3d0 | ||
330 | 7fffe5000-7fffe6000 rw-s 00012000 00:10 20630 /dev/kgsl-3d0 | ||
331 | 7fffe6000-7fffe7000 rw-s 00011000 00:10 20630 /dev/kgsl-3d0 | ||
332 | 7fffe7000-7fffe8000 rw-s 00010000 00:10 20630 /dev/kgsl-3d0 | ||
333 | 7fffe8000-7fffe9000 rw-s 0000f000 00:10 20630 /dev/kgsl-3d0 | ||
334 | 7fffe9000-7fffea000 rw-s 0000e000 00:10 20630 /dev/kgsl-3d0 | ||
335 | 7fffea000-7fffeb000 rw-s 0000d000 00:10 20630 /dev/kgsl-3d0 | ||
336 | 7fffeb000-7fffec000 rw-s 0000c000 00:10 20630 /dev/kgsl-3d0 | ||
337 | 7fffec000-7ffff0000 rw-s 0000b000 00:10 20630 /dev/kgsl-3d0 | ||
338 | 7ffff0000-7ffff1000 rw-s 0000a000 00:10 20630 /dev/kgsl-3d0 | ||
339 | 7ffff1000-7ffff5000 rw-s 00009000 00:10 20630 /dev/kgsl-3d0 | ||
340 | 7ffff5000-7ffff6000 rw-s 00008000 00:10 20630 /dev/kgsl-3d0 | ||
341 | 7ffff6000-7ffff7000 rw-s 00007000 00:10 20630 /dev/kgsl-3d0 | ||
342 | 7ffff7000-7ffff8000 rw-s 00006000 00:10 20630 /dev/kgsl-3d0 | ||
343 | 7ffff8000-7ffff9000 rw-s 00005000 00:10 20630 /dev/kgsl-3d0 | ||
344 | 7ffff9000-7ffffa000 rw-s 00004000 00:10 20630 /dev/kgsl-3d0 | ||
345 | 7ffffa000-7ffffb000 rw-s 00003000 00:10 20630 /dev/kgsl-3d0 | ||
346 | 7ffffb000-7ffffc000 rw-s 00002000 00:10 20630 /dev/kgsl-3d0 | ||
347 | 7ffffc000-800000000 rw-s 00001000 00:10 20630 /dev/kgsl-3d0 | ||
348 | 5ff1d4f000-5ff1d54000 r-xp 00000000 fc:00 3419 /system/bin/app_process64 | ||
349 | 5ff1d6e000-5ff1d6f000 r--p 0000f000 fc:00 3419 /system/bin/app_process64 | ||
350 | 5ff1d6f000-5ff1d71000 rw-p 00000000 00:00 0 | ||
351 | 704defa000-704defb000 ---p 00000000 00:00 0 [anon:thread stack guard] | ||
352 | 704defb000-704defc000 ---p 00000000 00:00 0 | ||
353 | 704defc000-704e000000 rw-p 00000000 00:00 0 | ||
354 | 704e000000-704e400000 rw-p 00000000 00:00 0 [anon:libc_malloc] | ||
355 | 704e455000-704e456000 ---p 00000000 00:00 0 [anon:thread stack guard] | ||
356 | 704e456000-704e457000 ---p 00000000 00:00 0 | ||
357 | 704e457000-704e553000 rw-p 00000000 00:00 0 | ||
358 | 704e553000-704e651000 r--p 00000000 00:10 16029 /dev/hwbinder | ||
359 | 704e651000-704e65f000 r-xp 00000000 fc:01 1040 /vendor/lib64/egl/eglSubDriverAndroid.so | ||
360 | 704e65f000-704e660000 r--p 0000e000 fc:01 1040 /vendor/lib64/egl/eglSubDriverAndroid.so | ||
361 | 704e660000-704e661000 rw-p 0000f000 fc:01 1040 /vendor/lib64/egl/eglSubDriverAndroid.so | ||
362 | 704e69d000-704e69e000 ---p 00000000 00:00 0 [anon:thread stack guard] | ||
363 | 704e69e000-704e79b000 rw-p 00000000 00:00 0 | ||
364 | 704e79b000-704f79b000 rw-s 00000000 00:05 10271021 /dev/ashmem/AudioFlinger::Client(29312) (deleted) | ||
365 | 704f79b000-704f79c000 ---p 00000000 00:00 0 [anon:thread stack guard] | ||
366 | 704f79c000-704f899000 rw-p 00000000 00:00 0 | ||
367 | 704f899000-704f89a000 ---p 00000000 00:00 0 [anon:thread stack guard] | ||
368 | 704f89a000-704f89b000 ---p 00000000 00:00 0 | ||
369 | 704f89b000-704f997000 rw-p 00000000 00:00 0 | ||
370 | 704f997000-704f9ee000 r-xp 00000000 103:1d 1737338 /data/app/com.google.sample.tunnel-HGGRU03Gu1Mwkf_-RnFmvw==/lib/arm64/libgame.so | ||
371 | 704f9ee000-704f9fd000 ---p 00000000 00:00 0 | ||
372 | 704f9fd000-704fa00000 r--p 00056000 103:1d 1737338 /data/app/com.google.sample.tunnel-HGGRU03Gu1Mwkf_-RnFmvw==/lib/arm64/libgame.so | ||
373 | 704fa00000-704fa01000 rw-p 00059000 103:1d 1737338 /data/app/com.google.sample.tunnel-HGGRU03Gu1Mwkf_-RnFmvw==/lib/arm64/libgame.so | ||
374 | 704fa01000-704fa19000 rw-p 00000000 00:00 0 [anon:.bss] | ||
375 | 704fa40000-70507e7000 r-xp 00000000 fc:01 1026 /vendor/lib64/libllvm-glnext.so | ||
376 | 70507e7000-70507fc000 ---p 00000000 00:00 0 | ||
377 | 70507fc000-7050835000 r--p 00da7000 fc:01 1026 /vendor/lib64/libllvm-glnext.so | ||
378 | 7050835000-705083a000 rw-p 00de0000 fc:01 1026 /vendor/lib64/libllvm-glnext.so | ||
379 | 705083a000-7050855000 rw-p 00000000 00:00 0 [anon:.bss] | ||
380 | 705089b000-7050f19000 r-xp 00000000 fc:01 1039 /vendor/lib64/egl/libGLESv2_adreno.so | ||
381 | 7050f19000-7050f22000 r--p 0067e000 fc:01 1039 /vendor/lib64/egl/libGLESv2_adreno.so | ||
382 | 7050f22000-7050f29000 rw-p 00687000 fc:01 1039 /vendor/lib64/egl/libGLESv2_adreno.so | ||
383 | 7050f29000-7050f2c000 rw-p 00000000 00:00 0 [anon:.bss] | ||
384 | 7050f83000-7050fbc000 r-xp 00000000 fc:01 1041 /vendor/lib64/egl/libGLESv1_CM_adreno.so | ||
385 | 7050fbc000-7050fbd000 r--p 00039000 fc:01 1041 /vendor/lib64/egl/libGLESv1_CM_adreno.so | ||
386 | 7050fbd000-7050fbe000 rw-p 0003a000 fc:01 1041 /vendor/lib64/egl/libGLESv1_CM_adreno.so | ||
387 | 7050fbe000-7050fbf000 rw-p 00000000 00:00 0 [anon:.bss] | ||
388 | 7050fc6000-705111d000 r-xp 00000000 fc:01 865 /vendor/lib64/libgsl.so | ||
389 | 705111d000-705111e000 r--p 00157000 fc:01 865 /vendor/lib64/libgsl.so | ||
390 | 705111e000-705111f000 rw-p 00158000 fc:01 865 /vendor/lib64/libgsl.so | ||
391 | 705111f000-7051120000 rw-p 00000000 00:00 0 [anon:.bss] | ||
392 | 7051146000-705115d000 r-xp 00000000 fc:00 2587 /system/lib64/vndk-sp-28/libz.so | ||
393 | 705115d000-7051175000 ---p 00000000 00:00 0 | ||
394 | 7051175000-7051176000 r--p 0001f000 fc:00 2587 /system/lib64/vndk-sp-28/libz.so | ||
395 | 7051176000-7051177000 rw-p 00020000 fc:00 2587 /system/lib64/vndk-sp-28/libz.so | ||
396 | 705119f000-70511ac000 r-xp 00000000 fc:01 886 /vendor/lib64/libadreno_utils.so | ||
397 | 70511ac000-70511ad000 r--p 0000d000 fc:01 886 /vendor/lib64/libadreno_utils.so | ||
398 | 70511ad000-70511ae000 rw-p 0000e000 fc:01 886 /vendor/lib64/libadreno_utils.so | ||
399 | 70511ae000-70511b0000 rw-p 00000000 00:00 0 [anon:.bss] | ||
400 | 70511c0000-70511d7000 r-xp 00000000 fc:01 1044 /vendor/lib64/egl/libEGL_adreno.so | ||
401 | 70511d7000-70511d8000 r--p 00017000 fc:01 1044 /vendor/lib64/egl/libEGL_adreno.so | ||
402 | 70511d8000-70511d9000 rw-p 00018000 fc:01 1044 /vendor/lib64/egl/libEGL_adreno.so | ||
403 | 70511d9000-70511da000 rw-p 00000000 00:00 0 [anon:.bss] | ||
404 | 705120a000-705120d000 r-xp 00000000 fc:01 972 /vendor/lib64/libdrmutils.so | ||
405 | 705120d000-7051229000 ---p 00000000 00:00 0 | ||
406 | 7051229000-705122a000 r--p 0000f000 fc:01 972 /vendor/lib64/libdrmutils.so | ||
407 | 705122a000-705122b000 rw-p 00010000 fc:01 972 /vendor/lib64/libdrmutils.so | ||
408 | 705125a000-705125c000 r-xp 00000000 fc:01 1046 /vendor/lib64/libqdMetaData.so | ||
409 | 705125c000-7051279000 ---p 00000000 00:00 0 | ||
410 | 7051279000-705127a000 r--p 0000f000 fc:01 1046 /vendor/lib64/libqdMetaData.so | ||
411 | 705127a000-705127b000 rw-p 00010000 fc:01 1046 /vendor/lib64/libqdMetaData.so | ||
412 | 7051286000-7051297000 r-xp 00000000 fc:01 1024 /vendor/lib64/libdrm.so | ||
413 | 7051297000-70512b5000 ---p 00000000 00:00 0 | ||
414 | 70512b5000-70512b6000 r--p 0001f000 fc:01 1024 /vendor/lib64/libdrm.so | ||
415 | 70512b6000-70512b7000 rw-p 00020000 fc:01 1024 /vendor/lib64/libdrm.so | ||
416 | 70512cb000-70512de000 r-xp 00000000 fc:01 1008 /vendor/lib64/hw/gralloc.msm8998.so | ||
417 | 70512de000-70512fa000 ---p 00000000 00:00 0 | ||
418 | 70512fa000-70512fb000 r--p 0001f000 fc:01 1008 /vendor/lib64/hw/gralloc.msm8998.so | ||
419 | 70512fb000-70512fc000 rw-p 00020000 fc:01 1008 /vendor/lib64/hw/gralloc.msm8998.so | ||
420 | 7051326000-7051327000 ---p 00000000 00:00 0 [anon:thread stack guard] | ||
421 | 7051327000-7051328000 ---p 00000000 00:00 0 | ||
422 | 7051328000-7051424000 rw-p 00000000 00:00 0 | ||
423 | 7051424000-705143d000 r--p 00000000 fc:00 739 /system/framework/oat/arm64/org.apache.http.legacy.boot.odex | ||
424 | 705143d000-7051480000 r-xp 00019000 fc:00 739 /system/framework/oat/arm64/org.apache.http.legacy.boot.odex | ||
425 | 7051480000-7051494000 r--p 00211000 103:1d 639511 /data/dalvik-cache/arm64/system@framework@boot.art | ||
426 | 7051494000-705149f000 r--p 000c5000 103:1d 639514 /data/dalvik-cache/arm64/system@framework@boot-core-libart.art | ||
427 | 705149f000-70514a2000 r--p 00032000 103:1d 639517 /data/dalvik-cache/arm64/system@framework@boot-conscrypt.art | ||
428 | 70514a2000-70514a5000 r--p 0002b000 103:1d 639520 /data/dalvik-cache/arm64/system@framework@boot-okhttp.art | ||
429 | 70514a5000-70514ac000 r--p 0003f000 103:1d 639523 /data/dalvik-cache/arm64/system@framework@boot-bouncycastle.art | ||
430 | 70514ac000-70514b2000 r--p 00044000 103:1d 639526 /data/dalvik-cache/arm64/system@framework@boot-apache-xml.art | ||
431 | 70514b2000-70514bd000 r--p 00035000 103:1d 639529 /data/dalvik-cache/arm64/system@framework@boot-ext.art | ||
432 | 70514bd000-70514f4000 r--p 0060f000 103:1d 639532 /data/dalvik-cache/arm64/system@framework@boot-framework.art | ||
433 | 70514f4000-70514fe000 r--p 00054000 103:1d 639535 /data/dalvik-cache/arm64/system@framework@boot-telephony-common.art | ||
434 | 70514fe000-70514ff000 r--p 0000c000 103:1d 639538 /data/dalvik-cache/arm64/system@framework@boot-voip-common.art | ||
435 | 70514ff000-7051500000 r--p 0000e000 103:1d 639541 /data/dalvik-cache/arm64/system@framework@boot-ims-common.art | ||
436 | 7051500000-7051501000 r--p 00004000 103:1d 639547 /data/dalvik-cache/arm64/system@framework@boot-android.hidl.manager-V1.0-java.art | ||
437 | 7051501000-7051502000 r--p 00004000 103:1d 639553 /data/dalvik-cache/arm64/system@framework@boot-android.test.base.art | ||
438 | 7051502000-7051503000 r--p 00001000 103:1d 639556 /data/dalvik-cache/arm64/system@framework@boot-com.google.vr.platform.art | ||
439 | 7051503000-7051504000 rw-p 00000000 00:00 0 [anon:.bss] | ||
440 | 7051504000-7051579000 r--s 00000000 fc:00 790 /system/framework/oat/arm64/org.apache.http.legacy.boot.vdex | ||
441 | 7051579000-705157a000 r--p 0005c000 fc:00 739 /system/framework/oat/arm64/org.apache.http.legacy.boot.odex | ||
442 | 705157a000-705157b000 rw-p 0005d000 fc:00 739 /system/framework/oat/arm64/org.apache.http.legacy.boot.odex | ||
443 | 705158b000-7057f4d000 ---p 00000000 00:00 0 | ||
444 | 7057f4d000-7057f4f000 r-xp 00000000 fc:00 2646 /system/lib64/libwebviewchromium_loader.so | ||
445 | 7057f4f000-7057f6c000 ---p 00000000 00:00 0 | ||
446 | 7057f6c000-7057f6d000 r--p 0000f000 fc:00 2646 /system/lib64/libwebviewchromium_loader.so | ||
447 | 7057f6d000-7057f6e000 rw-p 00010000 fc:00 2646 /system/lib64/libwebviewchromium_loader.so | ||
448 | 7057f76000-7057f96000 r--s 00000000 00:10 16615 /dev/__properties__/u:object_r:hwservicemanager_prop:s0 | ||
449 | 7057f96000-7057fb6000 r--s 00000000 00:10 16639 /dev/__properties__/u:object_r:public_vendor_default_prop:s0 | ||
450 | 7057fb6000-7058004000 r--s 00000000 fc:00 1112 /system/usr/hyphen-data/hyph-hu.hyb | ||
451 | 7058004000-7058024000 r-xp 00000000 fc:00 2354 /system/lib64/libcompiler_rt.so | ||
452 | 7058024000-7058043000 ---p 00000000 00:00 0 | ||
453 | 7058043000-7058044000 r--p 0002f000 fc:00 2354 /system/lib64/libcompiler_rt.so | ||
454 | 7058044000-7058045000 rw-p 00030000 fc:00 2354 /system/lib64/libcompiler_rt.so | ||
455 | 7058045000-70580b2000 rw-p 00000000 00:00 0 [anon:.bss] | ||
456 | 70580bd000-70580dd000 rw-p 00000000 00:05 10265386 /dev/ashmem/dalvik-LinearAlloc (deleted) | ||
457 | 70580dd000-70580df000 r-xp 00000000 fc:00 2597 /system/lib64/vndk-sp-28/libhardware.so | ||
458 | 70580df000-70580fc000 ---p 00000000 00:00 0 | ||
459 | 70580fc000-70580fd000 r--p 0000f000 fc:00 2597 /system/lib64/vndk-sp-28/libhardware.so | ||
460 | 70580fd000-70580fe000 rw-p 00010000 fc:00 2597 /system/lib64/vndk-sp-28/libhardware.so | ||
461 | 705810e000-705811f000 r-xp 00000000 fc:00 2589 /system/lib64/vndk-sp-28/libbase.so | ||
462 | 705811f000-705813d000 ---p 00000000 00:00 0 | ||
463 | 705813d000-705813e000 r--p 0001f000 fc:00 2589 /system/lib64/vndk-sp-28/libbase.so | ||
464 | 705813e000-705813f000 rw-p 00020000 fc:00 2589 /system/lib64/vndk-sp-28/libbase.so | ||
465 | 7058140000-7058167000 r-xp 00000000 fc:00 2572 /system/lib64/vndk-sp-28/libhwbinder.so | ||
466 | 7058167000-705817d000 ---p 00000000 00:00 0 | ||
467 | 705817d000-705817f000 r--p 0002e000 fc:00 2572 /system/lib64/vndk-sp-28/libhwbinder.so | ||
468 | 705817f000-7058180000 rw-p 00030000 fc:00 2572 /system/lib64/vndk-sp-28/libhwbinder.so | ||
469 | 705818c000-705818d000 r-xp 00000000 fc:00 2584 /system/lib64/vndk-sp-28/android.hardware.graphics.common@1.0.so | ||
470 | 705818d000-70581ab000 ---p 00000000 00:00 0 | ||
471 | 70581ab000-70581ac000 r--p 0000f000 fc:00 2584 /system/lib64/vndk-sp-28/android.hardware.graphics.common@1.0.so | ||
472 | 70581ac000-70581ad000 rw-p 00010000 fc:00 2584 /system/lib64/vndk-sp-28/android.hardware.graphics.common@1.0.so | ||
473 | 70581b7000-70581d7000 r--s 00000000 00:10 16619 /dev/__properties__/u:object_r:log_prop:s0 | ||
474 | 70581d7000-7058237000 r-xp 00000000 fc:00 2574 /system/lib64/vndk-sp-28/libhidltransport.so | ||
475 | 7058237000-7058255000 ---p 00000000 00:00 0 | ||
476 | 7058255000-705825d000 r--p 00068000 fc:00 2574 /system/lib64/vndk-sp-28/libhidltransport.so | ||
477 | 705825d000-705825e000 rw-p 00070000 fc:00 2574 /system/lib64/vndk-sp-28/libhidltransport.so | ||
478 | 7058260000-7058284000 r--s 00000000 fc:00 1138 /system/usr/hyphen-data/hyph-nn.hyb | ||
479 | 7058284000-70582a0000 r-xp 00000000 fc:00 2576 /system/lib64/vndk-sp-28/libutils.so | ||
480 | 70582a0000-70582b3000 ---p 00000000 00:00 0 | ||
481 | 70582b3000-70582b4000 r--p 0001f000 fc:00 2576 /system/lib64/vndk-sp-28/libutils.so | ||
482 | 70582b4000-70582b5000 rw-p 00020000 fc:00 2576 /system/lib64/vndk-sp-28/libutils.so | ||
483 | 70582c4000-7058391000 r-xp 00000000 fc:00 2568 /system/lib64/vndk-sp-28/libc++.so | ||
484 | 7058391000-70583ad000 ---p 00000000 00:00 0 | ||
485 | 70583ad000-70583b7000 r--p 000d6000 fc:00 2568 /system/lib64/vndk-sp-28/libc++.so | ||
486 | 70583b7000-70583b8000 rw-p 000e0000 fc:00 2568 /system/lib64/vndk-sp-28/libc++.so | ||
487 | 70583b8000-70583bb000 rw-p 00000000 00:00 0 [anon:.bss] | ||
488 | 70583cd000-70583e4000 r-xp 00000000 fc:00 2580 /system/lib64/vndk-sp-28/android.hardware.graphics.mapper@2.0.so | ||
489 | 70583e4000-70583f9000 ---p 00000000 00:00 0 | ||
490 | 70583f9000-70583fb000 r--p 0001e000 fc:00 2580 /system/lib64/vndk-sp-28/android.hardware.graphics.mapper@2.0.so | ||
491 | 70583fb000-70583fc000 rw-p 00020000 fc:00 2580 /system/lib64/vndk-sp-28/android.hardware.graphics.mapper@2.0.so | ||
492 | 705841b000-7058421000 r-xp 00000000 fc:01 1001 /vendor/lib64/hw/android.hardware.graphics.mapper@2.0-impl.so | ||
493 | 7058421000-705843a000 ---p 00000000 00:00 0 | ||
494 | 705843a000-705843b000 r--p 0000f000 fc:01 1001 /vendor/lib64/hw/android.hardware.graphics.mapper@2.0-impl.so | ||
495 | 705843b000-705843c000 rw-p 00010000 fc:01 1001 /vendor/lib64/hw/android.hardware.graphics.mapper@2.0-impl.so | ||
496 | 705844f000-7058473000 r--s 00000000 fc:00 1150 /system/usr/hyphen-data/hyph-nb.hyb | ||
497 | 7058473000-7058495000 r-xp 00000000 fc:00 2582 /system/lib64/vndk-sp-28/libhidlbase.so | ||
498 | 7058495000-70584b1000 ---p 00000000 00:00 0 | ||
499 | 70584b1000-70584b3000 r--p 0002e000 fc:00 2582 /system/lib64/vndk-sp-28/libhidlbase.so | ||
500 | 70584b3000-70584b4000 rw-p 00030000 fc:00 2582 /system/lib64/vndk-sp-28/libhidlbase.so | ||
501 | 70584cd000-70584df000 r-xp 00000000 fc:00 2595 /system/lib64/vndk-sp-28/libcutils.so | ||
502 | 70584df000-70584fb000 ---p 00000000 00:00 0 | ||
503 | 70584fb000-70584fd000 r--p 0001e000 fc:00 2595 /system/lib64/vndk-sp-28/libcutils.so | ||
504 | 70584fd000-70584fe000 rw-p 00020000 fc:00 2595 /system/lib64/vndk-sp-28/libcutils.so | ||
505 | 7058519000-7058537000 r--s 00000000 fc:00 1124 /system/usr/hyphen-data/hyph-de-ch-1901.hyb | ||
506 | 7058537000-7059fd1000 r--s 0070b000 fc:00 989 /system/framework/framework-res.apk | ||
507 | 7059fd1000-705a013000 r-xp 00000000 fc:00 2610 /system/lib64/libjavacrypto.so | ||
508 | 705a013000-705a02b000 ---p 00000000 00:00 0 | ||
509 | 705a02b000-705a02d000 r--p 0004e000 fc:00 2610 /system/lib64/libjavacrypto.so | ||
510 | 705a02d000-705a02f000 rw-p 00050000 fc:00 2610 /system/lib64/libjavacrypto.so | ||
511 | 705a041000-705a05f000 r--s 00000000 fc:00 1128 /system/usr/hyphen-data/hyph-de-1996.hyb | ||
512 | 705a05f000-705a06a000 r-xp 00000000 fc:00 2917 /system/lib64/libsoundpool.so | ||
513 | 705a06a000-705a07e000 ---p 00000000 00:00 0 | ||
514 | 705a07e000-705a07f000 r--p 0000f000 fc:00 2917 /system/lib64/libsoundpool.so | ||
515 | 705a07f000-705a080000 rw-p 00010000 fc:00 2917 /system/lib64/libsoundpool.so | ||
516 | 705a087000-705a102000 r--s 00000000 fc:00 1246 /system/usr/share/zoneinfo/tzdata | ||
517 | 705a102000-705a863000 r--s 00000000 fc:00 101 /system/fonts/NotoColorEmoji.ttf | ||
518 | 705a863000-705c000000 r--s 00000000 fc:00 251 /system/fonts/NotoSerifCJK-Regular.ttc | ||
519 | 705c000000-705c200000 rw-p 00000000 00:00 0 [anon:libc_malloc] | ||
520 | 705c209000-705c227000 r--s 00000000 fc:00 1077 /system/usr/hyphen-data/hyph-de-1901.hyb | ||
521 | 705c227000-705c26e000 r--s 02284000 fc:00 989 /system/framework/framework-res.apk | ||
522 | 705c26e000-705d43e000 r--s 00000000 fc:00 95 /system/fonts/NotoSansCJK-Regular.ttc | ||
523 | 705d43e000-705d4ec000 r--s 00000000 fc:00 278 /system/fonts/NotoSansSymbols-Regular-Subsetted.ttf | ||
524 | 705d4ec000-705d548000 r--s 00000000 fc:00 233 /system/fonts/NotoSansTibetan-Bold.ttf | ||
525 | 705d548000-705d5ab000 r--s 00000000 fc:00 177 /system/fonts/NotoSansTibetan-Regular.ttf | ||
526 | 705d5ab000-705d627000 r--s 00000000 fc:00 197 /system/fonts/NotoSansEgyptianHieroglyphs-Regular.ttf | ||
527 | 705d627000-705d6a2000 r--s 00000000 fc:00 76 /system/fonts/NotoSansCuneiform-Regular.ttf | ||
528 | 705d6a2000-705d6f3000 r--s 00000000 fc:00 67 /system/fonts/RobotoCondensed-BoldItalic.ttf | ||
529 | 705d6f3000-705d73e000 r--s 00000000 fc:00 199 /system/fonts/RobotoCondensed-Bold.ttf | ||
530 | 705d73e000-705d78f000 r--s 00000000 fc:00 230 /system/fonts/RobotoCondensed-MediumItalic.ttf | ||
531 | 705d78f000-705d7da000 r--s 00000000 fc:00 92 /system/fonts/RobotoCondensed-Medium.ttf | ||
532 | 705d7da000-705d82b000 r--s 00000000 fc:00 128 /system/fonts/RobotoCondensed-Italic.ttf | ||
533 | 705d82b000-705d875000 r--s 00000000 fc:00 164 /system/fonts/RobotoCondensed-Regular.ttf | ||
534 | 705d875000-705d8c7000 r--s 00000000 fc:00 292 /system/fonts/RobotoCondensed-LightItalic.ttf | ||
535 | 705d8c7000-705d919000 r--s 00000000 fc:00 85 /system/fonts/Roboto-BoldItalic.ttf | ||
536 | 705d919000-705d964000 r--s 00000000 fc:00 175 /system/fonts/Roboto-Bold.ttf | ||
537 | 705d964000-705d9b5000 r--s 00000000 fc:00 266 /system/fonts/Roboto-BlackItalic.ttf | ||
538 | 705d9b5000-705da00000 r--s 00000000 fc:00 187 /system/fonts/Roboto-Black.ttf | ||
539 | 705da00000-705dc00000 rw-p 00000000 00:00 0 [anon:libc_malloc] | ||
540 | 705dc1d000-705dc6e000 r--s 00000000 fc:00 148 /system/fonts/Roboto-MediumItalic.ttf | ||
541 | 705dc6e000-705dcb9000 r--s 00000000 fc:00 284 /system/fonts/Roboto-Medium.ttf | ||
542 | 705dcb9000-705dd0a000 r--s 00000000 fc:00 105 /system/fonts/Roboto-Italic.ttf | ||
543 | 705dd0a000-705dd55000 r--s 00000000 fc:00 156 /system/fonts/Roboto-Regular.ttf | ||
544 | 705dd55000-705dda7000 r--s 00000000 fc:00 217 /system/fonts/Roboto-LightItalic.ttf | ||
545 | 705dda7000-705ddf8000 r--s 00000000 fc:00 166 /system/fonts/Roboto-ThinItalic.ttf | ||
546 | 705ddf8000-705ddf9000 ---p 00000000 00:00 0 [anon:thread stack guard] | ||
547 | 705ddf9000-705ddfa000 ---p 00000000 00:00 0 | ||
548 | 705ddfa000-705def6000 rw-p 00000000 00:00 0 | ||
549 | 705def6000-705f5ec000 r--s 00000000 fc:00 1350 /system/usr/icu/icudt60l.dat | ||
550 | 705f5ec000-705f5ed000 ---p 00000000 00:00 0 [anon:thread stack guard] | ||
551 | 705f5ed000-705f5ee000 ---p 00000000 00:00 0 | ||
552 | 705f5ee000-705f6ea000 rw-p 00000000 00:00 0 | ||
553 | 705f6ea000-705f7e8000 r--p 00000000 00:10 20636 /dev/binder | ||
554 | 705f7e8000-705f7e9000 ---p 00000000 00:00 0 [anon:thread stack guard] | ||
555 | 705f7e9000-705f7ea000 ---p 00000000 00:00 0 | ||
556 | 705f7ea000-705f8ee000 rw-p 00000000 00:00 0 | ||
557 | 705f8ee000-705f8ef000 ---p 00000000 00:00 0 [anon:thread stack guard] | ||
558 | 705f8ef000-705f8f0000 ---p 00000000 00:00 0 | ||
559 | 705f8f0000-705f9f4000 rw-p 00000000 00:00 0 | ||
560 | 705f9f4000-705f9f5000 ---p 00000000 00:00 0 [anon:thread stack guard] | ||
561 | 705f9f5000-705f9f6000 ---p 00000000 00:00 0 | ||
562 | 705f9f6000-705fafa000 rw-p 00000000 00:00 0 | ||
563 | 705fafa000-705fafb000 ---p 00000000 00:00 0 [anon:thread stack guard] | ||
564 | 705fafb000-705fafc000 ---p 00000000 00:00 0 | ||
565 | 705fafc000-705fc00000 rw-p 00000000 00:00 0 | ||
566 | 705fc00000-705fe00000 rw-p 00000000 00:00 0 [anon:libc_malloc] | ||
567 | 705fe01000-705fe4c000 r--s 00000000 fc:00 97 /system/fonts/Roboto-Light.ttf | ||
568 | 705fe4c000-705fe4d000 ---p 00000000 00:00 0 [anon:thread stack guard] | ||
569 | 705fe4d000-705fe4e000 ---p 00000000 00:00 0 | ||
570 | 705fe4e000-705ff4a000 rw-p 00000000 00:00 0 | ||
571 | 705ff4a000-705ff4b000 ---p 00000000 00:05 10270991 /dev/ashmem/dalvik-Jit thread pool worker thread 0 (deleted) | ||
572 | 705ff4b000-705ff4c000 ---p 00001000 00:05 10270991 /dev/ashmem/dalvik-Jit thread pool worker thread 0 (deleted) | ||
573 | 705ff4c000-706004b000 rw-p 00002000 00:05 10270991 /dev/ashmem/dalvik-Jit thread pool worker thread 0 (deleted) | ||
574 | 706004b000-706010f000 r-xp 00000000 fc:00 2390 /system/lib64/libvixl-arm64.so | ||
575 | 706010f000-7060120000 ---p 00000000 00:00 0 | ||
576 | 7060120000-7060125000 r--p 000cb000 fc:00 2390 /system/lib64/libvixl-arm64.so | ||
577 | 7060125000-7060126000 rw-p 000d0000 fc:00 2390 /system/lib64/libvixl-arm64.so | ||
578 | 7060126000-706012d000 rw-p 00000000 00:00 0 [anon:.bss] | ||
579 | 7060135000-7060151000 r--s 00000000 fc:01 1180 /vendor/overlay/framework-res__auto_generated_rro.apk | ||
580 | 7060151000-7060263000 r-xp 00000000 fc:00 2669 /system/lib64/libvixl-arm.so | ||
581 | 7060263000-7060275000 ---p 00000000 00:00 0 | ||
582 | 7060275000-706027a000 r--p 0011b000 fc:00 2669 /system/lib64/libvixl-arm.so | ||
583 | 706027a000-706027b000 rw-p 00120000 fc:00 2669 /system/lib64/libvixl-arm.so | ||
584 | 706028b000-706056c000 r-xp 00000000 fc:00 2972 /system/lib64/libart-compiler.so | ||
585 | 706056c000-7060580000 ---p 00000000 00:00 0 | ||
586 | 7060580000-7060598000 r--p 002e8000 fc:00 2972 /system/lib64/libart-compiler.so | ||
587 | 7060598000-7060599000 rw-p 00300000 fc:00 2972 /system/lib64/libart-compiler.so | ||
588 | 7060599000-70605a0000 rw-p 00000000 00:00 0 [anon:.bss] | ||
589 | 70605b0000-70605d0000 r--s 00000000 00:10 16571 /dev/__properties__/u:object_r:config_prop:s0 | ||
590 | 70605d0000-7060619000 r-xp 00000000 fc:00 2702 /system/lib64/libssl.so | ||
591 | 7060619000-706062d000 ---p 00000000 00:00 0 | ||
592 | 706062d000-7060630000 r--p 0004d000 fc:00 2702 /system/lib64/libssl.so | ||
593 | 7060630000-7060631000 rw-p 00050000 fc:00 2702 /system/lib64/libssl.so | ||
594 | 7060647000-7060667000 r--s 00000000 00:10 16595 /dev/__properties__/u:object_r:exported3_radio_prop:s0 | ||
595 | 7060667000-706069d000 r-xp 00000000 fc:00 2371 /system/lib64/libopenjdk.so | ||
596 | 706069d000-70606b2000 ---p 00000000 00:00 0 | ||
597 | 70606b2000-70606b4000 r--p 0003e000 fc:00 2371 /system/lib64/libopenjdk.so | ||
598 | 70606b4000-70606b6000 rw-p 00040000 fc:00 2371 /system/lib64/libopenjdk.so | ||
599 | 70606bb000-70606db000 r--s 00000000 00:10 16608 /dev/__properties__/u:object_r:exported_system_prop:s0 | ||
600 | 70606db000-70606e3000 r-xp 00000000 fc:00 2538 /system/lib64/libopenjdkjvm.so | ||
601 | 70606e3000-70606fa000 ---p 00000000 00:00 0 | ||
602 | 70606fa000-70606fb000 r--p 0000f000 fc:00 2538 /system/lib64/libopenjdkjvm.so | ||
603 | 70606fb000-70606fc000 rw-p 00010000 fc:00 2538 /system/lib64/libopenjdkjvm.so | ||
604 | 7060701000-7060722000 r--s 00000000 fc:00 227 /system/fonts/NotoSansAnatolianHieroglyphs-Regular.otf | ||
605 | 7060722000-7061e18000 r--s 00000000 fc:00 1350 /system/usr/icu/icudt60l.dat | ||
606 | 7061e18000-7061e5d000 r-xp 00000000 fc:00 2368 /system/lib64/libjavacore.so | ||
607 | 7061e5d000-7061e71000 ---p 00000000 00:00 0 | ||
608 | 7061e71000-7061e73000 r--p 0004e000 fc:00 2368 /system/lib64/libjavacore.so | ||
609 | 7061e73000-7061e75000 rw-p 00050000 fc:00 2368 /system/lib64/libjavacore.so | ||
610 | 7061e75000-7061e76000 rw-p 00000000 00:00 0 [anon:.bss] | ||
611 | 7061e77000-7061e96000 r--s 00000000 fc:00 186 /system/fonts/NotoSansYi-Regular.ttf | ||
612 | 7061e96000-7061e99000 r-xp 00000000 fc:00 2953 /system/lib64/libwebviewchromium_plat_support.so | ||
613 | 7061e99000-7061eb5000 ---p 00000000 00:00 0 | ||
614 | 7061eb5000-7061eb6000 r--p 0000f000 fc:00 2953 /system/lib64/libwebviewchromium_plat_support.so | ||
615 | 7061eb6000-7061eb7000 rw-p 00010000 fc:00 2953 /system/lib64/libwebviewchromium_plat_support.so | ||
616 | 7061ebc000-7061edd000 r--s 00000000 fc:00 100 /system/fonts/NotoSansBamum-Regular.ttf | ||
617 | 7061edd000-7061eed000 r-xp 00000000 fc:00 2945 /system/lib64/libRS.so | ||
618 | 7061eed000-7061efc000 ---p 00000000 00:00 0 | ||
619 | 7061efc000-7061efd000 r--p 0000f000 fc:00 2945 /system/lib64/libRS.so | ||
620 | 7061efd000-7061efe000 rw-p 00010000 fc:00 2945 /system/lib64/libRS.so | ||
621 | 7061f05000-7061f6b000 r-xp 00000000 fc:00 2423 /system/lib64/android.hardware.renderscript@1.0.so | ||
622 | 7061f6b000-7061f7a000 ---p 00000000 00:00 0 | ||
623 | 7061f7a000-7061f7f000 r--p 0006b000 fc:00 2423 /system/lib64/android.hardware.renderscript@1.0.so | ||
624 | 7061f7f000-7061f80000 rw-p 00070000 fc:00 2423 /system/lib64/android.hardware.renderscript@1.0.so | ||
625 | 7061f99000-7061f9b000 r-xp 00000000 fc:00 2614 /system/lib64/libOpenSLES.so | ||
626 | 7061f9b000-7061fb8000 ---p 00000000 00:00 0 | ||
627 | 7061fb8000-7061fb9000 r--p 0000f000 fc:00 2614 /system/lib64/libOpenSLES.so | ||
628 | 7061fb9000-7061fba000 rw-p 00010000 fc:00 2614 /system/lib64/libOpenSLES.so | ||
629 | 7061fc6000-7061fc8000 r-xp 00000000 fc:00 2963 /system/lib64/libOpenMAXAL.so | ||
630 | 7061fc8000-7061fe5000 ---p 00000000 00:00 0 | ||
631 | 7061fe5000-7061fe6000 r--p 0000f000 fc:00 2963 /system/lib64/libOpenMAXAL.so | ||
632 | 7061fe6000-7061fe7000 rw-p 00010000 fc:00 2963 /system/lib64/libOpenMAXAL.so | ||
633 | 7061fe7000-7062000000 r--s 00000000 fc:00 143 /system/fonts/NotoSansBhaiksuki-Regular.otf | ||
634 | 7062000000-7062003000 r-xp 00000000 fc:00 2447 /system/lib64/libtextclassifier_hash.so | ||
635 | 7062003000-706201f000 ---p 00000000 00:00 0 | ||
636 | 706201f000-7062020000 r--p 0000f000 fc:00 2447 /system/lib64/libtextclassifier_hash.so | ||
637 | 7062020000-7062021000 rw-p 00010000 fc:00 2447 /system/lib64/libtextclassifier_hash.so | ||
638 | 7062022000-7062042000 rw-p 00000000 00:05 10269731 /dev/ashmem/dalvik-CompilerMetadata (deleted) | ||
639 | 7062042000-7062077000 r-xp 00000000 fc:00 2372 /system/lib64/android.hardware.neuralnetworks@1.0.so | ||
640 | 7062077000-7062095000 ---p 00000000 00:00 0 | ||
641 | 7062095000-706209b000 r--p 0003a000 fc:00 2372 /system/lib64/android.hardware.neuralnetworks@1.0.so | ||
642 | 706209b000-706209c000 rw-p 00040000 fc:00 2372 /system/lib64/android.hardware.neuralnetworks@1.0.so | ||
643 | 70620a9000-70620c9000 rw-p 00000000 00:05 10269730 /dev/ashmem/dalvik-CompilerMetadata (deleted) | ||
644 | 70620c9000-70620e3000 r-xp 00000000 fc:00 2956 /system/lib64/android.hardware.neuralnetworks@1.1.so | ||
645 | 70620e3000-70620f4000 ---p 00000000 00:00 0 | ||
646 | 70620f4000-70620f7000 r--p 0001d000 fc:00 2956 /system/lib64/android.hardware.neuralnetworks@1.1.so | ||
647 | 70620f7000-70620f8000 rw-p 00020000 fc:00 2956 /system/lib64/android.hardware.neuralnetworks@1.1.so | ||
648 | 706210b000-70621d0000 r-xp 00000000 fc:00 2387 /system/lib64/libneuralnetworks.so | ||
649 | 70621d0000-70621e3000 ---p 00000000 00:00 0 | ||
650 | 70621e3000-70621e5000 r--p 000ce000 fc:00 2387 /system/lib64/libneuralnetworks.so | ||
651 | 70621e5000-70621e7000 rw-p 000d0000 fc:00 2387 /system/lib64/libneuralnetworks.so | ||
652 | 70621e7000-7062372000 rw-p 00000000 00:00 0 [anon:.bss] | ||
653 | 7062373000-7062395000 r--s 00000000 fc:00 274 /system/fonts/NotoSerifMyanmar-Bold.otf | ||
654 | 7062395000-7062398000 r-xp 00000000 fc:00 2937 /system/lib64/libjnigraphics.so | ||
655 | 7062398000-70623b4000 ---p 00000000 00:00 0 | ||
656 | 70623b4000-70623b5000 r--p 0000f000 fc:00 2937 /system/lib64/libjnigraphics.so | ||
657 | 70623b5000-70623b6000 rw-p 00010000 fc:00 2937 /system/lib64/libjnigraphics.so | ||
658 | 70623c8000-70623e0000 r-xp 00000000 fc:00 2662 /system/lib64/libGLESv3.so | ||
659 | 70623e0000-70623f7000 ---p 00000000 00:00 0 | ||
660 | 70623f7000-70623f8000 r--p 0001f000 fc:00 2662 /system/lib64/libGLESv3.so | ||
661 | 70623f8000-70623f9000 rw-p 00020000 fc:00 2662 /system/lib64/libGLESv3.so | ||
662 | 70623fc000-706241c000 rw-p 00000000 00:05 10269729 /dev/ashmem/dalvik-CompilerMetadata (deleted) | ||
663 | 706241c000-7062444000 r-xp 00000000 fc:00 2603 /system/lib64/libexif.so | ||
664 | 7062444000-706245f000 ---p 00000000 00:00 0 | ||
665 | 706245f000-7062472000 r--p 0002d000 fc:00 2603 /system/lib64/libexif.so | ||
666 | 7062472000-7062473000 rw-p 00040000 fc:00 2603 /system/lib64/libexif.so | ||
667 | 7062474000-7062490000 r--s 00000000 fc:00 286 /system/fonts/NotoSansMongolian-Regular.ttf | ||
668 | 7062490000-7062491000 r-xp 00000000 fc:00 2357 /system/lib64/libasyncio.so | ||
669 | 7062491000-70624af000 ---p 00000000 00:00 0 | ||
670 | 70624af000-70624b0000 r--p 0000f000 fc:00 2357 /system/lib64/libasyncio.so | ||
671 | 70624b0000-70624b1000 rw-p 00010000 fc:00 2357 /system/lib64/libasyncio.so | ||
672 | 70624b5000-70624cf000 r--s 00000000 fc:00 221 /system/fonts/NotoSansMyanmarUI-Bold.ttf | ||
673 | 70624cf000-7062508000 r-xp 00000000 fc:00 2401 /system/lib64/libmtp.so | ||
674 | 7062508000-7062522000 ---p 00000000 00:00 0 | ||
675 | 7062522000-7062525000 r--p 0003d000 fc:00 2401 /system/lib64/libmtp.so | ||
676 | 7062525000-706252c000 rw-p 00040000 fc:00 2401 /system/lib64/libmtp.so | ||
677 | 7062530000-7062550000 rw-p 00000000 00:05 10269728 /dev/ashmem/dalvik-CompilerMetadata (deleted) | ||
678 | 7062550000-7062572000 r--s 00000000 fc:00 234 /system/fonts/NotoSerifMyanmar-Regular.otf | ||
679 | 7062572000-706259e000 r-xp 00000000 fc:00 2620 /system/lib64/libmediandk.so | ||
680 | 706259e000-70625b9000 ---p 00000000 00:00 0 | ||
681 | 70625b9000-70625bc000 r--p 0002d000 fc:00 2620 /system/lib64/libmediandk.so | ||
682 | 70625bc000-70625c0000 rw-p 00030000 fc:00 2620 /system/lib64/libmediandk.so | ||
683 | 70625c2000-70625d1000 r-xp 00000000 fc:00 2613 /system/lib64/libmidi.so | ||
684 | 70625d1000-70625ef000 ---p 00000000 00:00 0 | ||
685 | 70625ef000-70625f1000 r--p 0000e000 fc:00 2613 /system/lib64/libmidi.so | ||
686 | 70625f1000-70625f2000 rw-p 00010000 fc:00 2613 /system/lib64/libmidi.so | ||
687 | 7062600000-7062621000 r-xp 00000000 fc:00 2366 /system/lib64/libmediadrmmetrics_lite.so | ||
688 | 7062621000-706263d000 ---p 00000000 00:00 0 | ||
689 | 706263d000-706263f000 r--p 0002e000 fc:00 2366 /system/lib64/libmediadrmmetrics_lite.so | ||
690 | 706263f000-7062640000 rw-p 00030000 fc:00 2366 /system/lib64/libmediadrmmetrics_lite.so | ||
691 | 706264b000-706266b000 rw-p 00000000 00:05 10269727 /dev/ashmem/dalvik-CompilerMetadata (deleted) | ||
692 | 706266b000-70626d4000 r-xp 00000000 fc:00 2727 /system/lib64/libmedia_jni.so | ||
693 | 70626d4000-70626eb000 ---p 00000000 00:00 0 | ||
694 | 70626eb000-70626f2000 r--p 00069000 fc:00 2727 /system/lib64/libmedia_jni.so | ||
695 | 70626f2000-70626f3000 rw-p 00070000 fc:00 2727 /system/lib64/libmedia_jni.so | ||
696 | 7062703000-7062732000 r-xp 00000000 fc:00 2399 /system/lib64/libcamera2ndk.so | ||
697 | 7062732000-7062748000 ---p 00000000 00:00 0 | ||
698 | 7062748000-706274b000 r--p 0003d000 fc:00 2399 /system/lib64/libcamera2ndk.so | ||
699 | 706274b000-7062750000 rw-p 00040000 fc:00 2399 /system/lib64/libcamera2ndk.so | ||
700 | 7062768000-7062788000 rw-p 00000000 00:05 10269726 /dev/ashmem/dalvik-CompilerMetadata (deleted) | ||
701 | 7062788000-70627ee000 r-xp 00000000 fc:00 2974 /system/lib64/android.hardware.drm@1.0.so | ||
702 | 70627ee000-7062805000 ---p 00000000 00:00 0 | ||
703 | 7062805000-706280d000 r--p 00068000 fc:00 2974 /system/lib64/android.hardware.drm@1.0.so | ||
704 | 706280d000-706280e000 rw-p 00070000 fc:00 2974 /system/lib64/android.hardware.drm@1.0.so | ||
705 | 706281a000-706281b000 ---p 00000000 00:00 0 [anon:thread signal stack guard] | ||
706 | 706281b000-706281f000 rw-p 00000000 00:00 0 [anon:thread signal stack] | ||
707 | 706281f000-7062843000 r--s 00000000 fc:00 142 /system/fonts/NotoSansKhmer-VF.ttf | ||
708 | 7062843000-7062886000 r-xp 00000000 fc:00 2637 /system/lib64/android.hardware.drm@1.1.so | ||
709 | 7062886000-70628a5000 ---p 00000000 00:00 0 | ||
710 | 70628a5000-70628ab000 r--p 0004a000 fc:00 2637 /system/lib64/android.hardware.drm@1.1.so | ||
711 | 70628ab000-70628ac000 rw-p 00050000 fc:00 2637 /system/lib64/android.hardware.drm@1.1.so | ||
712 | 70628b0000-70628b1000 ---p 00000000 00:00 0 [anon:thread signal stack guard] | ||
713 | 70628b1000-70628b5000 rw-p 00000000 00:00 0 [anon:thread signal stack] | ||
714 | 70628b5000-70628db000 r--s 00000000 fc:00 137 /system/fonts/NotoSansSinhala-Bold.ttf | ||
715 | 70628db000-7062907000 r-xp 00000000 fc:00 2478 /system/lib64/libmediadrm.so | ||
716 | 7062907000-7062918000 ---p 00000000 00:00 0 | ||
717 | 7062918000-7062920000 r--p 00038000 fc:00 2478 /system/lib64/libmediadrm.so | ||
718 | 7062920000-7062921000 rw-p 00040000 fc:00 2478 /system/lib64/libmediadrm.so | ||
719 | 7062922000-7062929000 rw-p 00000000 fc:00 583 /system/etc/event-log-tags | ||
720 | 7062929000-7062951000 r--s 00000000 fc:00 296 /system/fonts/NotoSansSinhala-Regular.ttf | ||
721 | 7062951000-7062997000 r-xp 00000000 fc:00 2448 /system/lib64/libaaudio.so | ||
722 | 7062997000-70629ac000 ---p 00000000 00:00 0 | ||
723 | 70629ac000-70629b2000 r--p 0004a000 fc:00 2448 /system/lib64/libaaudio.so | ||
724 | 70629b2000-70629ba000 rw-p 00050000 fc:00 2448 /system/lib64/libaaudio.so | ||
725 | 70629ba000-70629bb000 ---p 00000000 00:00 0 [anon:thread signal stack guard] | ||
726 | 70629bb000-70629bf000 rw-p 00000000 00:00 0 [anon:thread signal stack] | ||
727 | 70629bf000-70629c0000 ---p 00000000 00:00 0 [anon:bionic TLS guard] | ||
728 | 70629c0000-70629c3000 rw-p 00000000 00:00 0 [anon:bionic TLS] | ||
729 | 70629c3000-70629c4000 ---p 00000000 00:00 0 [anon:bionic TLS guard] | ||
730 | 70629c4000-70629c5000 ---p 00000000 00:00 0 [anon:thread signal stack guard] | ||
731 | 70629c5000-70629c9000 rw-p 00000000 00:00 0 [anon:thread signal stack] | ||
732 | 70629c9000-70629e3000 r-xp 00000000 fc:00 2940 /system/lib64/libandroid.so | ||
733 | 70629e3000-70629f3000 ---p 00000000 00:00 0 | ||
734 | 70629f3000-70629f6000 r--p 0001d000 fc:00 2940 /system/lib64/libandroid.so | ||
735 | 70629f6000-70629f7000 rw-p 00020000 fc:00 2940 /system/lib64/libandroid.so | ||
736 | 70629f8000-70629f9000 ---p 00000000 00:00 0 [anon:bionic TLS guard] | ||
737 | 70629f9000-70629fc000 rw-p 00000000 00:00 0 [anon:bionic TLS] | ||
738 | 70629fc000-70629fd000 ---p 00000000 00:00 0 [anon:bionic TLS guard] | ||
739 | 70629fd000-7062a3e000 r--s 00000000 fc:00 216 /system/fonts/NotoSerif-BoldItalic.ttf | ||
740 | 7062a3e000-7062b06000 rw-p 00000000 00:05 10270984 /dev/ashmem/dalvik-indirect ref table (deleted) | ||
741 | 7062b06000-7062bce000 rw-p 00000000 00:05 10270983 /dev/ashmem/dalvik-indirect ref table (deleted) | ||
742 | 7062bce000-7062dce000 rw-p 00000000 00:05 10270726 /dev/ashmem/dalvik-rb copying gc mark stack (deleted) | ||
743 | 7062dce000-70635ce000 rw-p 00000000 00:05 10270725 /dev/ashmem/dalvik-concurrent copying gc mark stack (deleted) | ||
744 | 70635ce000-7063dcf000 rw-p 00000000 00:05 10270724 /dev/ashmem/dalvik-live stack (deleted) | ||
745 | 7063dcf000-70645d0000 rw-p 00000000 00:05 10270723 /dev/ashmem/dalvik-allocation stack (deleted) | ||
746 | 70645d0000-70649d1000 rw-p 00000000 00:05 10270721 /dev/ashmem/dalvik-card table (deleted) | ||
747 | 70649d1000-7064ad1000 rw-p 00000000 00:05 10267648 /dev/ashmem/dalvik-large object free list space allocation info map (deleted) | ||
748 | 7064ad1000-7065ad1000 rw-p 00000000 00:05 10267644 /dev/ashmem/dalvik-region space live bitmap (deleted) | ||
749 | 7065ad1000-7065bd1000 rw-p 00000000 00:05 10267642 /dev/ashmem/dalvik-allocspace zygote / non moving space mark-bitmap 0 (deleted) | ||
750 | 7065bd1000-7065cd1000 rw-p 00000000 00:05 10267641 /dev/ashmem/dalvik-allocspace zygote / non moving space live-bitmap 0 (deleted) | ||
751 | 7065cd1000-7065cd2000 r-xp 00000000 fc:00 2946 /system/lib64/libsigchain.so | ||
752 | 7065cd2000-7065cf0000 ---p 00000000 00:00 0 | ||
753 | 7065cf0000-7065cf1000 r--p 0000f000 fc:00 2946 /system/lib64/libsigchain.so | ||
754 | 7065cf1000-7065cf2000 rw-p 00010000 fc:00 2946 /system/lib64/libsigchain.so | ||
755 | 7065cf4000-7065d0f000 r--s 00000000 fc:00 190 /system/fonts/NotoSansMyanmar-Bold.ttf | ||
756 | 7065d0f000-7065d22000 r-xp 00000000 fc:00 2405 /system/lib64/liblz4.so | ||
757 | 7065d22000-7065d3e000 ---p 00000000 00:00 0 | ||
758 | 7065d3e000-7065d3f000 r--p 0001f000 fc:00 2405 /system/lib64/liblz4.so | ||
759 | 7065d3f000-7065d40000 rw-p 00020000 fc:00 2405 /system/lib64/liblz4.so | ||
760 | 7065d40000-7065d5a000 r--s 00000000 fc:00 222 /system/fonts/NotoSansMyanmarUI-Regular.ttf | ||
761 | 7065d5a000-7065d5e000 r-xp 00000000 fc:00 2609 /system/lib64/libtombstoned_client.so | ||
762 | 7065d5e000-7065d79000 ---p 00000000 00:00 0 | ||
763 | 7065d79000-7065d7a000 r--p 0000f000 fc:00 2609 /system/lib64/libtombstoned_client.so | ||
764 | 7065d7a000-7065d7b000 rw-p 00010000 fc:00 2609 /system/lib64/libtombstoned_client.so | ||
765 | 7065d7f000-7065d80000 ---p 00000000 00:00 0 [anon:thread signal stack guard] | ||
766 | 7065d80000-7065d84000 rw-p 00000000 00:00 0 [anon:thread signal stack] | ||
767 | 7065d84000-706636e000 r-xp 00000000 fc:00 2671 /system/lib64/libart.so | ||
768 | 706636e000-706638d000 ---p 00000000 00:00 0 | ||
769 | 706638d000-706639e000 r--p 005ef000 fc:00 2671 /system/lib64/libart.so | ||
770 | 706639e000-70663a1000 rw-p 00600000 fc:00 2671 /system/lib64/libart.so | ||
771 | 70663a1000-70663a4000 rw-p 00000000 00:00 0 [anon:.bss] | ||
772 | 70663a6000-70663c6000 rw-p 00000000 00:05 10269725 /dev/ashmem/dalvik-CompilerMetadata (deleted) | ||
773 | 70663c6000-70663c8000 r-xp 00000000 fc:00 2673 /system/lib64/libmetricslogger.so | ||
774 | 70663c8000-70663e5000 ---p 00000000 00:00 0 | ||
775 | 70663e5000-70663e6000 r--p 0000f000 fc:00 2673 /system/lib64/libmetricslogger.so | ||
776 | 70663e6000-70663e7000 rw-p 00010000 fc:00 2673 /system/lib64/libmetricslogger.so | ||
777 | 70663e7000-7066400000 r--s 00000000 fc:00 110 /system/fonts/NotoSansLepcha-Regular.ttf | ||
778 | 7066400000-7066800000 rw-p 00000000 00:00 0 [anon:libc_malloc] | ||
779 | 7066803000-706681e000 r--s 00000000 fc:00 297 /system/fonts/NotoSansMyanmar-Regular.ttf | ||
780 | 706681e000-7066821000 r--p 00000000 00:00 0 [anon:cfi shadow] | ||
781 | 7066821000-7066822000 r--p 00000000 00:00 0 [anon:cfi shadow] | ||
782 | 7066822000-7066b1d000 r--p 00000000 00:00 0 [anon:cfi shadow] | ||
783 | 7066b1d000-7066b1e000 r--p 00000000 00:00 0 [anon:cfi shadow] | ||
784 | 7066b1e000-7066ba0000 r--p 00000000 00:00 0 [anon:cfi shadow] | ||
785 | 7066ba0000-7066ba1000 r--p 00000000 00:00 0 [anon:cfi shadow] | ||
786 | 7066ba1000-7066ba2000 r--p 00000000 00:00 0 [anon:cfi shadow] | ||
787 | 7066ba2000-7066ba5000 r--p 00000000 00:00 0 [anon:cfi shadow] | ||
788 | 7066ba5000-7066ba6000 r--p 00000000 00:00 0 [anon:cfi shadow] | ||
789 | 7066ba6000-70e681e000 r--p 00000000 00:00 0 [anon:cfi shadow] | ||
790 | 70e681e000-70e6854000 r-xp 00000000 fc:00 2431 /system/lib64/libstagefright_foundation.so | ||
791 | 70e6854000-70e6865000 ---p 00000000 00:00 0 | ||
792 | 70e6865000-70e6867000 r--p 0003e000 fc:00 2431 /system/lib64/libstagefright_foundation.so | ||
793 | 70e6867000-70e686c000 rw-p 00040000 fc:00 2431 /system/lib64/libstagefright_foundation.so | ||
794 | 70e686d000-70e686e000 ---p 00000000 00:00 0 [anon:bionic TLS guard] | ||
795 | 70e686e000-70e6871000 rw-p 00000000 00:00 0 [anon:bionic TLS] | ||
796 | 70e6871000-70e6873000 ---p 00000000 00:00 0 [anon:bionic TLS guard] | ||
797 | 70e6873000-70e6876000 rw-p 00000000 00:00 0 [anon:bionic TLS] | ||
798 | 70e6876000-70e6877000 ---p 00000000 00:00 0 [anon:bionic TLS guard] | ||
799 | 70e6877000-70e688c000 r--s 00000000 fc:00 301 /system/fonts/NotoSansSinhalaUI-Bold.otf | ||
800 | 70e688c000-70e688e000 r-xp 00000000 fc:00 2943 /system/lib64/libion.so | ||
801 | 70e688e000-70e68ab000 ---p 00000000 00:00 0 | ||
802 | 70e68ab000-70e68ac000 r--p 0000f000 fc:00 2943 /system/lib64/libion.so | ||
803 | 70e68ac000-70e68ad000 rw-p 00010000 fc:00 2943 /system/lib64/libion.so | ||
804 | 70e68ad000-70e68af000 rw-p 00000000 00:05 10282496 /dev/ashmem/dalvik-indirect ref table (deleted) | ||
805 | 70e68af000-70e68b1000 rw-p 00000000 00:05 10282493 /dev/ashmem/dalvik-indirect ref table (deleted) | ||
806 | 70e68b1000-70e68ee000 r--s 00000000 fc:00 256 /system/fonts/NotoSerif-Italic.ttf | ||
807 | 70e68ee000-70e6910000 r-xp 00000000 fc:00 2502 /system/lib64/libhidlbase.so | ||
808 | 70e6910000-70e692c000 ---p 00000000 00:00 0 | ||
809 | 70e692c000-70e692e000 r--p 0002e000 fc:00 2502 /system/lib64/libhidlbase.so | ||
810 | 70e692e000-70e692f000 rw-p 00030000 fc:00 2502 /system/lib64/libhidlbase.so | ||
811 | 70e6930000-70e693f000 r--s 00000000 fc:00 1082 /system/usr/hyphen-data/hyph-en-us.hyb | ||
812 | 70e693f000-70e6954000 r--s 00000000 fc:00 138 /system/fonts/NotoSansSinhalaUI-Regular.otf | ||
813 | 70e6954000-70e6978000 r-xp 00000000 fc:00 2482 /system/lib64/libui.so | ||
814 | 70e6978000-70e6992000 ---p 00000000 00:00 0 | ||
815 | 70e6992000-70e6994000 r--p 0002e000 fc:00 2482 /system/lib64/libui.so | ||
816 | 70e6994000-70e6995000 rw-p 00030000 fc:00 2482 /system/lib64/libui.so | ||
817 | 70e6996000-70e69a2000 r--s 00000000 fc:00 1117 /system/usr/hyphen-data/hyph-en-gb.hyb | ||
818 | 70e69a2000-70e69b7000 r--s 00000000 fc:00 202 /system/fonts/NotoSerifSinhala-Bold.otf | ||
819 | 70e69b7000-70e69cb000 r--s 00000000 fc:00 124 /system/fonts/NotoSansOriyaUI-Bold.ttf | ||
820 | 70e69cb000-70e69e1000 r-xp 00000000 fc:00 2537 /system/lib64/liblog.so | ||
821 | 70e69e1000-70e69fa000 ---p 00000000 00:00 0 | ||
822 | 70e69fa000-70e69fb000 r--p 0001f000 fc:00 2537 /system/lib64/liblog.so | ||
823 | 70e69fb000-70e69fc000 rw-p 00020000 fc:00 2537 /system/lib64/liblog.so | ||
824 | 70e69fc000-70e69fe000 rw-p 00000000 00:05 10266158 /dev/ashmem/dalvik-indirect ref table (deleted) | ||
825 | 70e69fe000-70e69ff000 ---p 00000000 00:00 0 [anon:bionic TLS guard] | ||
826 | 70e69ff000-70e6a02000 rw-p 00000000 00:00 0 [anon:bionic TLS] | ||
827 | 70e6a02000-70e6a03000 ---p 00000000 00:00 0 [anon:bionic TLS guard] | ||
828 | 70e6a03000-70e6a05000 r-xp 00000000 fc:00 2489 /system/lib64/android.hidl.token@1.0-utils.so | ||
829 | 70e6a05000-70e6a22000 ---p 00000000 00:00 0 | ||
830 | 70e6a22000-70e6a23000 r--p 0000f000 fc:00 2489 /system/lib64/android.hidl.token@1.0-utils.so | ||
831 | 70e6a23000-70e6a24000 rw-p 00010000 fc:00 2489 /system/lib64/android.hidl.token@1.0-utils.so | ||
832 | 70e6a25000-70e6a2e000 r--s 00000000 fc:00 1120 /system/usr/hyphen-data/hyph-ga.hyb | ||
833 | 70e6a2e000-70e6a42000 r--s 00000000 fc:00 109 /system/fonts/NotoSansOriyaUI-Regular.ttf | ||
834 | 70e6a42000-70e6a59000 r-xp 00000000 fc:00 2446 /system/lib64/android.hardware.graphics.mapper@2.0.so | ||
835 | 70e6a59000-70e6a6e000 ---p 00000000 00:00 0 | ||
836 | 70e6a6e000-70e6a70000 r--p 0001e000 fc:00 2446 /system/lib64/android.hardware.graphics.mapper@2.0.so | ||
837 | 70e6a70000-70e6a71000 rw-p 00020000 fc:00 2446 /system/lib64/android.hardware.graphics.mapper@2.0.so | ||
838 | 70e6a72000-70e6a78000 r--s 00000000 fc:00 1084 /system/usr/hyphen-data/hyph-et.hyb | ||
839 | 70e6a78000-70e6a9d000 r--s 00000000 fc:00 207 /system/fonts/NotoSerifTelugu-Bold.ttf | ||
840 | 70e6a9d000-70e6a9f000 r-xp 00000000 fc:00 2330 /system/lib64/android.hardware.configstore-utils.so | ||
841 | 70e6a9f000-70e6abc000 ---p 00000000 00:00 0 | ||
842 | 70e6abc000-70e6abd000 r--p 0000f000 fc:00 2330 /system/lib64/android.hardware.configstore-utils.so | ||
843 | 70e6abd000-70e6abe000 rw-p 00010000 fc:00 2330 /system/lib64/android.hardware.configstore-utils.so | ||
844 | 70e6abe000-70e6ac0000 r--s f8042000 00:10 20630 /dev/kgsl-3d0 | ||
845 | 70e6ac0000-70e6adc000 r--s 00000000 fc:00 172 /system/fonts/NotoSansTeluguUI-Bold.ttf | ||
846 | 70e6adc000-70e6ae0000 r-xp 00000000 fc:00 2555 /system/lib64/libstagefright_omx_utils.so | ||
847 | 70e6ae0000-70e6afb000 ---p 00000000 00:00 0 | ||
848 | 70e6afb000-70e6afc000 r--p 0000f000 fc:00 2555 /system/lib64/libstagefright_omx_utils.so | ||
849 | 70e6afc000-70e6afd000 rw-p 00010000 fc:00 2555 /system/lib64/libstagefright_omx_utils.so | ||
850 | 70e6afd000-70e6afe000 ---p 00000000 00:00 0 [anon:thread signal stack guard] | ||
851 | 70e6afe000-70e6b02000 rw-p 00000000 00:00 0 [anon:thread signal stack] | ||
852 | 70e6b02000-70e6b27000 r--s 00000000 fc:00 271 /system/fonts/NotoSerifTelugu-Regular.ttf | ||
853 | 70e6b27000-70e6b61000 r-xp 00000000 fc:00 2695 /system/lib64/libdexfile.so | ||
854 | 70e6b61000-70e6b73000 ---p 00000000 00:00 0 | ||
855 | 70e6b73000-70e6b75000 r--p 0003e000 fc:00 2695 /system/lib64/libdexfile.so | ||
856 | 70e6b75000-70e6b76000 rw-p 00040000 fc:00 2695 /system/lib64/libdexfile.so | ||
857 | 70e6b76000-70e6b78000 rw-p 00000000 00:05 10253452 /dev/ashmem/dalvik-indirect ref table (deleted) | ||
858 | 70e6b78000-70e6b85000 r--s 00000000 fc:00 1080 /system/usr/hyphen-data/hyph-cu.hyb | ||
859 | 70e6b85000-70e6b96000 r-xp 00000000 fc:00 2957 /system/lib64/libaudioutils.so | ||
860 | 70e6b96000-70e6bb4000 ---p 00000000 00:00 0 | ||
861 | 70e6bb4000-70e6bb5000 r--p 0001f000 fc:00 2957 /system/lib64/libaudioutils.so | ||
862 | 70e6bb5000-70e6bb6000 rw-p 00020000 fc:00 2957 /system/lib64/libaudioutils.so | ||
863 | 70e6bb6000-70e6bb7000 ---p 00000000 00:00 0 [anon:bionic TLS guard] | ||
864 | 70e6bb7000-70e6bba000 rw-p 00000000 00:00 0 [anon:bionic TLS] | ||
865 | 70e6bba000-70e6bbb000 ---p 00000000 00:00 0 [anon:bionic TLS guard] | ||
866 | 70e6bbb000-70e6bd7000 r--s 00000000 fc:00 132 /system/fonts/NotoSansTeluguUI-Regular.ttf | ||
867 | 70e6bd7000-70e6bdc000 r-xp 00000000 fc:00 2409 /system/lib64/libprocessgroup.so | ||
868 | 70e6bdc000-70e6bf6000 ---p 00000000 00:00 0 | ||
869 | 70e6bf6000-70e6bf7000 r--p 0000f000 fc:00 2409 /system/lib64/libprocessgroup.so | ||
870 | 70e6bf7000-70e6bf8000 rw-p 00010000 fc:00 2409 /system/lib64/libprocessgroup.so | ||
871 | 70e6bf8000-70e6c09000 r--s 00000000 fc:00 79 /system/fonts/NotoSansNewa-Regular.otf | ||
872 | 70e6c09000-70e6c1c000 r-xp 00000000 fc:00 2329 /system/lib64/android.hidl.memory.token@1.0.so | ||
873 | 70e6c1c000-70e6c36000 ---p 00000000 00:00 0 | ||
874 | 70e6c36000-70e6c38000 r--p 0001e000 fc:00 2329 /system/lib64/android.hidl.memory.token@1.0.so | ||
875 | 70e6c38000-70e6c39000 rw-p 00020000 fc:00 2329 /system/lib64/android.hidl.memory.token@1.0.so | ||
876 | 70e6c3a000-70e6c4f000 r--s 00000000 fc:00 253 /system/fonts/NotoSansOriya-Bold.ttf | ||
877 | 70e6c4f000-70e6c6b000 r-xp 00000000 fc:00 2407 /system/lib64/libutils.so | ||
878 | 70e6c6b000-70e6c7e000 ---p 00000000 00:00 0 | ||
879 | 70e6c7e000-70e6c7f000 r--p 0001f000 fc:00 2407 /system/lib64/libutils.so | ||
880 | 70e6c7f000-70e6c80000 rw-p 00020000 fc:00 2407 /system/lib64/libutils.so | ||
881 | 70e6c80000-70e6c9d000 r-xp 00000000 fc:00 2934 /system/lib64/libtinyxml2.so | ||
882 | 70e6c9d000-70e6cba000 ---p 00000000 00:00 0 | ||
883 | 70e6cba000-70e6cbc000 r--p 0001e000 fc:00 2934 /system/lib64/libtinyxml2.so | ||
884 | 70e6cbc000-70e6cbf000 rw-p 00020000 fc:00 2934 /system/lib64/libtinyxml2.so | ||
885 | 70e6cbf000-70e6ccf000 r--s 00000000 fc:00 80 /system/fonts/NotoSansMarchen-Regular.otf | ||
886 | 70e6ccf000-70e6ce0000 r-xp 00000000 fc:00 2655 /system/lib64/libbase.so | ||
887 | 70e6ce0000-70e6cfe000 ---p 00000000 00:00 0 | ||
888 | 70e6cfe000-70e6cff000 r--p 0001f000 fc:00 2655 /system/lib64/libbase.so | ||
889 | 70e6cff000-70e6d00000 rw-p 00020000 fc:00 2655 /system/lib64/libbase.so | ||
890 | 70e6d00000-70e6d09000 r--s 00000000 fc:00 1113 /system/usr/hyphen-data/hyph-cy.hyb | ||
891 | 70e6d09000-70e6d50000 r-xp 00000000 fc:00 2495 /system/lib64/libRScpp.so | ||
892 | 70e6d50000-70e6d68000 ---p 00000000 00:00 0 | ||
893 | 70e6d68000-70e6d69000 r--p 0004f000 fc:00 2495 /system/lib64/libRScpp.so | ||
894 | 70e6d69000-70e6d6a000 rw-p 00050000 fc:00 2495 /system/lib64/libRScpp.so | ||
895 | 70e6d6b000-70e6d6d000 r--s 00088000 103:1d 1736830 /data/app/com.google.sample.tunnel-HGGRU03Gu1Mwkf_-RnFmvw==/base.apk | ||
896 | 70e6d6d000-70e6d7d000 r--s 00000000 fc:00 238 /system/fonts/NotoSansVai-Regular.ttf | ||
897 | 70e6d7d000-70e6d98000 r--s 00000000 fc:00 276 /system/fonts/NotoSansTelugu-Bold.ttf | ||
898 | 70e6d98000-70e6f2b000 r-xp 00000000 fc:00 2961 /system/lib64/libicuuc.so | ||
899 | 70e6f2b000-70e6f47000 ---p 00000000 00:00 0 | ||
900 | 70e6f47000-70e6f5c000 r--p 0019b000 fc:00 2961 /system/lib64/libicuuc.so | ||
901 | 70e6f5c000-70e6f5d000 rw-p 001b0000 fc:00 2961 /system/lib64/libicuuc.so | ||
902 | 70e6f5d000-70e6f5e000 rw-p 00000000 00:00 0 [anon:.bss] | ||
903 | 70e6f5f000-70e6f68000 r--s 00000000 fc:00 159 /system/fonts/NotoSansLinearA-Regular.otf | ||
904 | 70e6f68000-70e6f84000 r--s 00000000 fc:00 170 /system/fonts/NotoSansTelugu-Regular.ttf | ||
905 | 70e6f84000-70e7058000 r-xp 00000000 fc:00 2356 /system/lib64/libc.so | ||
906 | 70e7058000-70e706e000 ---p 00000000 00:00 0 | ||
907 | 70e706e000-70e7074000 r--p 000da000 fc:00 2356 /system/lib64/libc.so | ||
908 | 70e7074000-70e7076000 rw-p 000e0000 fc:00 2356 /system/lib64/libc.so | ||
909 | 70e7076000-70e7077000 rw-p 00000000 00:00 0 [anon:.bss] | ||
910 | 70e7077000-70e7078000 r--p 00000000 00:00 0 [anon:.bss] | ||
911 | 70e7078000-70e7080000 rw-p 00000000 00:00 0 [anon:.bss] | ||
912 | 70e7080000-70e7087000 r--s 00000000 fc:00 102 /system/fonts/NotoSansSharada-Regular.otf | ||
913 | 70e7087000-70e708e000 r-xp 00000000 fc:00 2378 /system/lib64/libheif.so | ||
914 | 70e708e000-70e70a4000 ---p 00000000 00:00 0 | ||
915 | 70e70a4000-70e70a6000 r--p 0000e000 fc:00 2378 /system/lib64/libheif.so | ||
916 | 70e70a6000-70e70a7000 rw-p 00010000 fc:00 2378 /system/lib64/libheif.so | ||
917 | 70e70a7000-70e70a9000 r--s 00000000 fc:00 1116 /system/usr/hyphen-data/hyph-sl.hyb | ||
918 | 70e70a9000-70e70ab000 r--s 00000000 fc:00 1147 /system/usr/hyphen-data/hyph-mn-cyrl.hyb | ||
919 | 70e70ab000-70e70c5000 r--s 00000000 fc:00 291 /system/fonts/NotoSansBengaliUI-Bold.ttf | ||
920 | 70e70c5000-70e70ea000 r-xp 00000000 fc:00 2545 /system/lib64/libEGL.so | ||
921 | 70e70ea000-70e7109000 ---p 00000000 00:00 0 | ||
922 | 70e7109000-70e710d000 r--p 0002c000 fc:00 2545 /system/lib64/libEGL.so | ||
923 | 70e710d000-70e710e000 rw-p 00030000 fc:00 2545 /system/lib64/libEGL.so | ||
924 | 70e710e000-70e7115000 rw-p 00000000 00:00 0 [anon:.bss] | ||
925 | 70e7115000-70e7119000 r--s 00000000 fc:00 1143 /system/usr/hyphen-data/hyph-es.hyb | ||
926 | 70e7119000-70e712e000 r--s 00000000 fc:00 71 /system/fonts/NotoSansOriya-Regular.ttf | ||
927 | 70e712e000-70e717a000 r--s 00000000 fc:00 272 /system/fonts/Roboto-Thin.ttf | ||
928 | 70e717a000-70e71db000 r-xp 00000000 fc:00 2393 /system/lib64/libpdx_default_transport.so | ||
929 | 70e71db000-70e71f7000 ---p 00000000 00:00 0 | ||
930 | 70e71f7000-70e71f9000 r--p 0006e000 fc:00 2393 /system/lib64/libpdx_default_transport.so | ||
931 | 70e71f9000-70e71fa000 rw-p 00070000 fc:00 2393 /system/lib64/libpdx_default_transport.so | ||
932 | 70e71fa000-70e71fb000 rw-p 00000000 00:00 0 [anon:.bss] | ||
933 | 70e71fc000-70e71fe000 r--s 00000000 fc:00 1107 /system/usr/hyphen-data/hyph-fr.hyb | ||
934 | 70e71fe000-70e7200000 r--s 00000000 fc:00 1097 /system/usr/hyphen-data/hyph-da.hyb | ||
935 | 70e7200000-70e7223000 r-xp 00000000 fc:00 2380 /system/lib64/libminikin.so | ||
936 | 70e7223000-70e723e000 ---p 00000000 00:00 0 | ||
937 | 70e723e000-70e723f000 r--p 0002f000 fc:00 2380 /system/lib64/libminikin.so | ||
938 | 70e723f000-70e7240000 rw-p 00030000 fc:00 2380 /system/lib64/libminikin.so | ||
939 | 70e7241000-70e724d000 r--s 00000000 fc:00 179 /system/fonts/NotoSansTaiTham-Regular.ttf | ||
940 | 70e724d000-70e725c000 r-xp 00000000 fc:00 2527 /system/lib64/libmediautils.so | ||
941 | 70e725c000-70e7279000 ---p 00000000 00:00 0 | ||
942 | 70e7279000-70e727b000 r--p 0001e000 fc:00 2527 /system/lib64/libmediautils.so | ||
943 | 70e727b000-70e727c000 rw-p 00020000 fc:00 2527 /system/lib64/libmediautils.so | ||
944 | 70e727d000-70e7283000 r--s 00000000 fc:00 136 /system/fonts/NotoSansMiao-Regular.otf | ||
945 | 70e7283000-70e74d2000 r-xp 00000000 fc:00 2349 /system/lib64/libicui18n.so | ||
946 | 70e74d2000-70e74e6000 ---p 00000000 00:00 0 | ||
947 | 70e74e6000-70e74fa000 r--p 0025c000 fc:00 2349 /system/lib64/libicui18n.so | ||
948 | 70e74fa000-70e74fb000 rw-p 00270000 fc:00 2349 /system/lib64/libicui18n.so | ||
949 | 70e74fc000-70e74ff000 r--s 00000000 103:1d 1474562 /data/resource-cache/vendor@overlay@framework-res__auto_generated_rro.apk@idmap | ||
950 | 70e74ff000-70e750c000 r--s 00000000 fc:00 126 /system/fonts/NotoSansSyriacWestern-Regular.ttf | ||
951 | 70e750c000-70e751b000 r-xp 00000000 fc:00 2466 /system/lib64/libmediaextractor.so | ||
952 | 70e751b000-70e753a000 ---p 00000000 00:00 0 | ||
953 | 70e753a000-70e753b000 r--p 0000f000 fc:00 2466 /system/lib64/libmediaextractor.so | ||
954 | 70e753b000-70e753c000 rw-p 00010000 fc:00 2466 /system/lib64/libmediaextractor.so | ||
955 | 70e753d000-70e7540000 r--s 00000000 fc:00 107 /system/fonts/NotoSansPauCinHau-Regular.otf | ||
956 | 70e7540000-70e7593000 r-xp 00000000 fc:00 2363 /system/lib64/libandroidfw.so | ||
957 | 70e7593000-70e75ac000 ---p 00000000 00:00 0 | ||
958 | 70e75ac000-70e75af000 r--p 0005d000 fc:00 2363 /system/lib64/libandroidfw.so | ||
959 | 70e75af000-70e75b0000 rw-p 00060000 fc:00 2363 /system/lib64/libandroidfw.so | ||
960 | 70e75b0000-70e75b2000 r--s 00000000 fc:00 1083 /system/usr/hyphen-data/hyph-be.hyb | ||
961 | 70e75b2000-70e75cd000 r--s 00000000 fc:00 270 /system/fonts/NotoSansBengaliUI-Regular.ttf | ||
962 | 70e75cd000-70e75cf000 r-xp 00000000 fc:00 2701 /system/lib64/libmemtrack.so | ||
963 | 70e75cf000-70e75ec000 ---p 00000000 00:00 0 | ||
964 | 70e75ec000-70e75ed000 r--p 0000f000 fc:00 2701 /system/lib64/libmemtrack.so | ||
965 | 70e75ed000-70e75ee000 rw-p 00010000 fc:00 2701 /system/lib64/libmemtrack.so | ||
966 | 70e75ee000-70e75f0000 r--s 00000000 fc:00 209 /system/fonts/NotoSansSoraSompeng-Regular.otf | ||
967 | 70e75f0000-70e760d000 r--s 00000000 fc:00 243 /system/fonts/NotoSerifBengali-Bold.ttf | ||
968 | 70e760d000-70e7613000 r-xp 00000000 fc:00 2667 /system/lib64/libutilscallstack.so | ||
969 | 70e7613000-70e762c000 ---p 00000000 00:00 0 | ||
970 | 70e762c000-70e762d000 r--p 0000f000 fc:00 2667 /system/lib64/libutilscallstack.so | ||
971 | 70e762d000-70e762e000 rw-p 00010000 fc:00 2667 /system/lib64/libutilscallstack.so | ||
972 | 70e762e000-70e7632000 r--s 00000000 fc:00 99 /system/fonts/NotoSansPahawhHmong-Regular.otf | ||
973 | 70e7632000-70e764f000 r--s 00000000 fc:00 205 /system/fonts/NotoSerifBengali-Regular.ttf | ||
974 | 70e764f000-70e7661000 r-xp 00000000 fc:00 2710 /system/lib64/libcutils.so | ||
975 | 70e7661000-70e767d000 ---p 00000000 00:00 0 | ||
976 | 70e767d000-70e767f000 r--p 0001e000 fc:00 2710 /system/lib64/libcutils.so | ||
977 | 70e767f000-70e7680000 rw-p 00020000 fc:00 2710 /system/lib64/libcutils.so | ||
978 | 70e7680000-70e7683000 r--s 00000000 fc:00 257 /system/fonts/NotoSansPalmyrene-Regular.otf | ||
979 | 70e7683000-70e7697000 r--s 00000000 fc:00 78 /system/fonts/NotoSansKannadaUI-Bold.ttf | ||
980 | 70e7697000-70e769a000 r-xp 00000000 fc:00 2362 /system/lib64/libstagefright_http_support.so | ||
981 | 70e769a000-70e76b6000 ---p 00000000 00:00 0 | ||
982 | 70e76b6000-70e76b7000 r--p 0000f000 fc:00 2362 /system/lib64/libstagefright_http_support.so | ||
983 | 70e76b7000-70e76b8000 rw-p 00010000 fc:00 2362 /system/lib64/libstagefright_http_support.so | ||
984 | 70e76b8000-70e76b9000 rw-p 00000000 00:00 0 [anon:linker_alloc_lob] | ||
985 | 70e76b9000-70e76be000 r--s 00000000 fc:00 165 /system/fonts/NotoSansMeroitic-Regular.otf | ||
986 | 70e76be000-70e76cb000 r--s 00000000 fc:00 112 /system/fonts/NotoSansSyriacEastern-Regular.ttf | ||
987 | 70e76cb000-70e76de000 r-xp 00000000 fc:00 2343 /system/lib64/libsensor.so | ||
988 | 70e76de000-70e76f5000 ---p 00000000 00:00 0 | ||
989 | 70e76f5000-70e76f8000 r--p 0001d000 fc:00 2343 /system/lib64/libsensor.so | ||
990 | 70e76f8000-70e76f9000 rw-p 00020000 fc:00 2343 /system/lib64/libsensor.so | ||
991 | 70e76f9000-70e76fc000 r--s 00000000 fc:00 157 /system/fonts/NotoSansOldPermic-Regular.otf | ||
992 | 70e76fc000-70e7708000 r--s 00000000 fc:00 189 /system/fonts/NotoSansSyriacEstrangela-Regular.ttf | ||
993 | 70e7708000-70e771d000 r-xp 00000000 fc:00 2339 /system/lib64/android.hidl.token@1.0.so | ||
994 | 70e771d000-70e7735000 ---p 00000000 00:00 0 | ||
995 | 70e7735000-70e7737000 r--p 0001e000 fc:00 2339 /system/lib64/android.hidl.token@1.0.so | ||
996 | 70e7737000-70e7738000 rw-p 00020000 fc:00 2339 /system/lib64/android.hidl.token@1.0.so | ||
997 | 70e7738000-70e7739000 r--p 00000000 00:00 0 [anon:linker_alloc] | ||
998 | 70e7739000-70e773b000 r--s 00000000 fc:00 267 /system/fonts/NotoSansOldNorthArabian-Regular.otf | ||
999 | 70e773b000-70e7740000 r--s 00000000 fc:00 208 /system/fonts/NotoSansManichaean-Regular.otf | ||
1000 | 70e7740000-70e775c000 r--s 00000000 fc:00 118 /system/fonts/NotoSansGujaratiUI-Bold.ttf | ||
1001 | 70e775c000-70e7767000 r-xp 00000000 fc:00 2525 /system/lib64/libappfuse.so | ||
1002 | 70e7767000-70e777b000 ---p 00000000 00:00 0 | ||
1003 | 70e777b000-70e777c000 r--p 0000f000 fc:00 2525 /system/lib64/libappfuse.so | ||
1004 | 70e777c000-70e777d000 rw-p 00010000 fc:00 2525 /system/lib64/libappfuse.so | ||
1005 | 70e777e000-70e7795000 r--s 00000000 fc:00 250 /system/fonts/NotoSerifKannada-Bold.ttf | ||
1006 | 70e7795000-70e7798000 r-xp 00000000 fc:00 2413 /system/lib64/libpackagelistparser.so | ||
1007 | 70e7798000-70e77b4000 ---p 00000000 00:00 0 | ||
1008 | 70e77b4000-70e77b5000 r--p 0000f000 fc:00 2413 /system/lib64/libpackagelistparser.so | ||
1009 | 70e77b5000-70e77b6000 rw-p 00010000 fc:00 2413 /system/lib64/libpackagelistparser.so | ||
1010 | 70e77b6000-70e77b8000 r--s 00000000 fc:00 147 /system/fonts/NotoSansNabataean-Regular.otf | ||
1011 | 70e77b8000-70e77ba000 r--s 00000000 fc:00 146 /system/fonts/NotoSansMultani-Regular.otf | ||
1012 | 70e77ba000-70e77c1000 r--s 00000000 fc:00 214 /system/fonts/NotoSansPhagsPa-Regular.ttf | ||
1013 | 70e77c1000-70e77de000 r--s 00000000 fc:00 90 /system/fonts/NotoSansGujaratiUI-Regular.ttf | ||
1014 | 70e77de000-70e77e0000 r-xp 00000000 fc:00 2430 /system/lib64/libdl.so | ||
1015 | 70e77e0000-70e77fd000 ---p 00000000 00:00 0 | ||
1016 | 70e77fd000-70e77fe000 r--p 0000f000 fc:00 2430 /system/lib64/libdl.so | ||
1017 | 70e77fe000-70e77ff000 r--p 00000000 00:00 0 [anon:.bss] | ||
1018 | 70e7800000-70e7809000 r--s 00000000 fc:00 258 /system/fonts/NotoSansSymbols-Regular-Subsetted2.ttf | ||
1019 | 70e7809000-70e7857000 r-xp 00000000 fc:00 2560 /system/lib64/libjpeg.so | ||
1020 | 70e7857000-70e7868000 ---p 00000000 00:00 0 | ||
1021 | 70e7868000-70e7869000 r--p 0004f000 fc:00 2560 /system/lib64/libjpeg.so | ||
1022 | 70e7869000-70e786a000 rw-p 00050000 fc:00 2560 /system/lib64/libjpeg.so | ||
1023 | 70e786a000-70e7887000 r--s 00000000 fc:00 237 /system/fonts/NotoSansGujarati-Bold.ttf | ||
1024 | 70e7887000-70e788a000 r-xp 00000000 fc:00 2608 /system/lib64/libnetd_client.so | ||
1025 | 70e788a000-70e78a6000 ---p 00000000 00:00 0 | ||
1026 | 70e78a6000-70e78a7000 r--p 0000f000 fc:00 2608 /system/lib64/libnetd_client.so | ||
1027 | 70e78a7000-70e78a8000 rw-p 00010000 fc:00 2608 /system/lib64/libnetd_client.so | ||
1028 | 70e78a8000-70e78aa000 r--s 00000000 fc:00 290 /system/fonts/NotoSansMro-Regular.otf | ||
1029 | 70e78aa000-70e78b9000 r--s 00000000 fc:00 84 /system/fonts/NotoSansLinearB-Regular.ttf | ||
1030 | 70e78b9000-70e78d7000 r--s 00000000 fc:00 287 /system/fonts/NotoSansGujarati-Regular.ttf | ||
1031 | 70e78d7000-70e78d8000 r-xp 00000000 fc:00 2651 /system/lib64/libvndksupport.so | ||
1032 | 70e78d8000-70e78f6000 ---p 00000000 00:00 0 | ||
1033 | 70e78f6000-70e78f7000 r--p 0000f000 fc:00 2651 /system/lib64/libvndksupport.so | ||
1034 | 70e78f7000-70e78f8000 rw-p 00010000 fc:00 2651 /system/lib64/libvndksupport.so | ||
1035 | 70e78f9000-70e78fc000 r--s 00000000 fc:00 178 /system/fonts/NotoSansTaiLe-Regular.ttf | ||
1036 | 70e78fc000-70e7900000 r--s 00000000 fc:00 163 /system/fonts/NotoSansTifinagh-Regular.ttf | ||
1037 | 70e7900000-70e7906000 r-xp 00000000 fc:00 2659 /system/lib64/libnativeloader.so | ||
1038 | 70e7906000-70e791f000 ---p 00000000 00:00 0 | ||
1039 | 70e791f000-70e7920000 r--p 0000f000 fc:00 2659 /system/lib64/libnativeloader.so | ||
1040 | 70e7920000-70e7921000 rw-p 00010000 fc:00 2659 /system/lib64/libnativeloader.so | ||
1041 | 70e7921000-70e7923000 r--s 00000000 fc:00 268 /system/fonts/NotoSansHatran-Regular.otf | ||
1042 | 70e7923000-70e7927000 r--s 00000000 fc:00 195 /system/fonts/NotoSansTaiViet-Regular.ttf | ||
1043 | 70e7927000-70e7945000 r--s 00000000 fc:00 139 /system/fonts/NotoSansDevanagariUI-Bold.ttf | ||
1044 | 70e7945000-70e79a3000 r-xp 00000000 fc:00 2450 /system/lib64/libharfbuzz_ng.so | ||
1045 | 70e79a3000-70e79b3000 ---p 00000000 00:00 0 | ||
1046 | 70e79b3000-70e79b5000 r--p 0005e000 fc:00 2450 /system/lib64/libharfbuzz_ng.so | ||
1047 | 70e79b5000-70e79b6000 rw-p 00060000 fc:00 2450 /system/lib64/libharfbuzz_ng.so | ||
1048 | 70e79b6000-70e79c5000 r--s 00000000 fc:00 111 /system/fonts/NotoSansKaithi-Regular.ttf | ||
1049 | 70e79c5000-70e7a92000 r-xp 00000000 fc:00 2332 /system/lib64/libc++.so | ||
1050 | 70e7a92000-70e7aae000 ---p 00000000 00:00 0 | ||
1051 | 70e7aae000-70e7ab8000 r--p 000d6000 fc:00 2332 /system/lib64/libc++.so | ||
1052 | 70e7ab8000-70e7ab9000 rw-p 000e0000 fc:00 2332 /system/lib64/libc++.so | ||
1053 | 70e7ab9000-70e7abc000 rw-p 00000000 00:00 0 [anon:.bss] | ||
1054 | 70e7abc000-70e7abe000 r--s 00000000 fc:00 73 /system/fonts/NotoSansBassaVah-Regular.otf | ||
1055 | 70e7abe000-70e7ac8000 r--s 00000000 fc:00 254 /system/fonts/NotoSansJavanese-Regular.ttf | ||
1056 | 70e7ac8000-70e7acb000 r-xp 00000000 fc:00 2660 /system/lib64/libnativebridge.so | ||
1057 | 70e7acb000-70e7ae7000 ---p 00000000 00:00 0 | ||
1058 | 70e7ae7000-70e7ae8000 r--p 0000f000 fc:00 2660 /system/lib64/libnativebridge.so | ||
1059 | 70e7ae8000-70e7ae9000 rw-p 00010000 fc:00 2660 /system/lib64/libnativebridge.so | ||
1060 | 70e7ae9000-70e7aee000 r--s 00000000 fc:00 158 /system/fonts/NotoSansSaurashtra-Regular.ttf | ||
1061 | 70e7aee000-70e7b0f000 r--s 00000000 fc:00 82 /system/fonts/NotoSansDevanagari-Bold.ttf | ||
1062 | 70e7b0f000-70e7b2e000 r-xp 00000000 fc:00 2612 /system/lib64/libpcre2.so | ||
1063 | 70e7b2e000-70e7b3e000 ---p 00000000 00:00 0 | ||
1064 | 70e7b3e000-70e7b3f000 r--p 0001f000 fc:00 2612 /system/lib64/libpcre2.so | ||
1065 | 70e7b3f000-70e7b40000 rw-p 00020000 fc:00 2612 /system/lib64/libpcre2.so | ||
1066 | 70e7b40000-70e7bcc000 r-xp 00000000 fc:00 2975 /system/lib64/libgui.so | ||
1067 | 70e7bcc000-70e7be2000 ---p 00000000 00:00 0 | ||
1068 | 70e7be2000-70e7bf5000 r--p 0008d000 fc:00 2975 /system/lib64/libgui.so | ||
1069 | 70e7bf5000-70e7bf6000 rw-p 000a0000 fc:00 2975 /system/lib64/libgui.so | ||
1070 | 70e7bf6000-70e7bf7000 r--p 00000000 00:00 0 [anon:linker_alloc] | ||
1071 | 70e7bf7000-70e7bf9000 r--s 00000000 fc:00 228 /system/fonts/NotoSansUgaritic-Regular.ttf | ||
1072 | 70e7bf9000-70e7c08000 r--s 00000000 fc:00 89 /system/fonts/NotoSansCherokee-Regular.ttf | ||
1073 | 70e7c08000-70e7dea000 r-xp 00000000 fc:00 2441 /system/lib64/libandroid_runtime.so | ||
1074 | 70e7dea000-70e7e04000 ---p 00000000 00:00 0 | ||
1075 | 70e7e04000-70e7e23000 r--p 001e1000 fc:00 2441 /system/lib64/libandroid_runtime.so | ||
1076 | 70e7e23000-70e7e24000 rw-p 00200000 fc:00 2441 /system/lib64/libandroid_runtime.so | ||
1077 | 70e7e24000-70e7e28000 rw-p 00000000 00:00 0 [anon:.bss] | ||
1078 | 70e7e29000-70e7e66000 r--s 00000000 fc:00 74 /system/fonts/NotoSerif-Bold.ttf | ||
1079 | 70e7e66000-70e7ed0000 r-xp 00000000 fc:00 2547 /system/lib64/libclang_rt.ubsan_standalone-aarch64-android.so | ||
1080 | 70e7ed0000-70e7edf000 ---p 00000000 00:00 0 | ||
1081 | 70e7edf000-70e7ee1000 r--p 00069000 fc:00 2547 /system/lib64/libclang_rt.ubsan_standalone-aarch64-android.so | ||
1082 | 70e7ee1000-70e7ee4000 rw-p 0006b000 fc:00 2547 /system/lib64/libclang_rt.ubsan_standalone-aarch64-android.so | ||
1083 | 70e7ee4000-70e89f6000 rw-p 00000000 00:00 0 [anon:.bss] | ||
1084 | 70e89f6000-70e89fa000 r--s 00000000 fc:00 127 /system/fonts/NotoSansSylotiNagri-Regular.ttf | ||
1085 | 70e89fa000-70e8a06000 r--s 00000000 fc:00 93 /system/fonts/NotoSansCanadianAboriginal-Regular.ttf | ||
1086 | 70e8a06000-70e8a1b000 r-xp 00000000 fc:00 2460 /system/lib64/android.hardware.graphics.allocator@2.0.so | ||
1087 | 70e8a1b000-70e8a33000 ---p 00000000 00:00 0 | ||
1088 | 70e8a33000-70e8a35000 r--p 0001e000 fc:00 2460 /system/lib64/android.hardware.graphics.allocator@2.0.so | ||
1089 | 70e8a35000-70e8a36000 rw-p 00020000 fc:00 2460 /system/lib64/android.hardware.graphics.allocator@2.0.so | ||
1090 | 70e8a36000-70e8a55000 r--s 00000000 fc:00 145 /system/fonts/NotoSansDevanagariUI-Regular.ttf | ||
1091 | 70e8a55000-70e8a61000 r-xp 00000000 fc:00 2540 /system/lib64/libstagefright_xmlparser.so | ||
1092 | 70e8a61000-70e8a74000 ---p 00000000 00:00 0 | ||
1093 | 70e8a74000-70e8a75000 r--p 0000f000 fc:00 2540 /system/lib64/libstagefright_xmlparser.so | ||
1094 | 70e8a75000-70e8a76000 rw-p 00010000 fc:00 2540 /system/lib64/libstagefright_xmlparser.so | ||
1095 | 70e8a76000-70e8a78000 r--s 00000000 fc:00 293 /system/fonts/NotoSansTagbanwa-Regular.ttf | ||
1096 | 70e8a78000-70e8a8f000 r--s 00000000 fc:00 161 /system/fonts/NotoSerifKannada-Regular.ttf | ||
1097 | 70e8a8f000-70e8b23000 r-xp 00000000 fc:00 2633 /system/lib64/libaudioclient.so | ||
1098 | 70e8b23000-70e8b37000 ---p 00000000 00:00 0 | ||
1099 | 70e8b37000-70e8b49000 r--p 0009e000 fc:00 2633 /system/lib64/libaudioclient.so | ||
1100 | 70e8b49000-70e8b55000 rw-p 000b0000 fc:00 2633 /system/lib64/libaudioclient.so | ||
1101 | 70e8b55000-70e8b9f000 r--s 00000000 fc:00 83 /system/fonts/RobotoCondensed-Light.ttf | ||
1102 | 70e8b9f000-70e8ba1000 r-xp 00000000 fc:00 2520 /system/lib64/libhardware_legacy.so | ||
1103 | 70e8ba1000-70e8bbe000 ---p 00000000 00:00 0 | ||
1104 | 70e8bbe000-70e8bbf000 r--p 0000f000 fc:00 2520 /system/lib64/libhardware_legacy.so | ||
1105 | 70e8bbf000-70e8bc0000 rw-p 00010000 fc:00 2520 /system/lib64/libhardware_legacy.so | ||
1106 | 70e8bc0000-70e8be0000 r-xp 00000000 fc:00 2410 /system/lib64/android.hidl.memory@1.0.so | ||
1107 | 70e8be0000-70e8bfa000 ---p 00000000 00:00 0 | ||
1108 | 70e8bfa000-70e8bfd000 r--p 0002d000 fc:00 2410 /system/lib64/android.hidl.memory@1.0.so | ||
1109 | 70e8bfd000-70e8bfe000 rw-p 00030000 fc:00 2410 /system/lib64/android.hidl.memory@1.0.so | ||
1110 | 70e8bfe000-70e8bff000 r--p 00000000 00:00 0 [anon:linker_alloc] | ||
1111 | 70e8bff000-70e8c02000 r--s 00000000 fc:00 273 /system/fonts/NotoSansSundanese-Regular.ttf | ||
1112 | 70e8c02000-70e8c0f000 r--s 00000000 fc:00 115 /system/fonts/NotoSansAdlam-Regular.ttf | ||
1113 | 70e8c0f000-70e8c18000 r-xp 00000000 fc:00 2350 /system/lib64/libnetdutils.so | ||
1114 | 70e8c18000-70e8c2e000 ---p 00000000 00:00 0 | ||
1115 | 70e8c2e000-70e8c2f000 r--p 0000f000 fc:00 2350 /system/lib64/libnetdutils.so | ||
1116 | 70e8c2f000-70e8c30000 rw-p 00010000 fc:00 2350 /system/lib64/libnetdutils.so | ||
1117 | 70e8c30000-70e8c44000 r--s 00000000 fc:00 283 /system/fonts/NotoSansKannadaUI-Regular.ttf | ||
1118 | 70e8c44000-70e8c45000 r-xp 00000000 fc:00 2926 /system/lib64/libhidlallocatorutils.so | ||
1119 | 70e8c45000-70e8c63000 ---p 00000000 00:00 0 | ||
1120 | 70e8c63000-70e8c64000 r--p 0000f000 fc:00 2926 /system/lib64/libhidlallocatorutils.so | ||
1121 | 70e8c64000-70e8c65000 rw-p 00010000 fc:00 2926 /system/lib64/libhidlallocatorutils.so | ||
1122 | 70e8c65000-70e8c67000 r--s 00000000 fc:00 65 /system/fonts/NotoSansTagalog-Regular.ttf | ||
1123 | 70e8c67000-70e8c70000 r--s 00000000 fc:00 294 /system/fonts/NotoSansChakma-Regular.ttf | ||
1124 | 70e8c70000-70e8c92000 r--s 00000000 fc:00 116 /system/fonts/NotoSansDevanagari-Regular.ttf | ||
1125 | 70e8c92000-70e8c94000 r-xp 00000000 fc:00 2501 /system/lib64/libsync.so | ||
1126 | 70e8c94000-70e8cb1000 ---p 00000000 00:00 0 | ||
1127 | 70e8cb1000-70e8cb2000 r--p 0000f000 fc:00 2501 /system/lib64/libsync.so | ||
1128 | 70e8cb2000-70e8cb3000 rw-p 00010000 fc:00 2501 /system/lib64/libsync.so | ||
1129 | 70e8cb3000-70e8cc6000 r--s 00000000 fc:00 196 /system/fonts/NotoSerifSinhala-Regular.otf | ||
1130 | 70e8cc6000-70e8d5c000 r-xp 00000000 fc:00 2403 /system/lib64/libmedia.so | ||
1131 | 70e8d5c000-70e8d70000 ---p 00000000 00:00 0 | ||
1132 | 70e8d70000-70e8d88000 r--p 00098000 fc:00 2403 /system/lib64/libmedia.so | ||
1133 | 70e8d88000-70e8d95000 rw-p 000b0000 fc:00 2403 /system/lib64/libmedia.so | ||
1134 | 70e8d95000-70e8d96000 r--p 00000000 00:00 0 [anon:atexit handlers] | ||
1135 | 70e8d96000-70e8d99000 r--s 00000000 fc:00 247 /system/fonts/NotoSansSamaritan-Regular.ttf | ||
1136 | 70e8d99000-70e8dad000 r--s 00000000 fc:00 108 /system/fonts/NotoSansKannada-Bold.ttf | ||
1137 | 70e8dad000-70e8dcd000 r--s 00000000 fc:00 303 /system/fonts/NotoSerifEthiopic-Bold.otf | ||
1138 | 70e8dcd000-70e8de5000 r-xp 00000000 fc:00 2954 /system/lib64/libGLESv2.so | ||
1139 | 70e8de5000-70e8dfc000 ---p 00000000 00:00 0 | ||
1140 | 70e8dfc000-70e8dfd000 r--p 0001f000 fc:00 2954 /system/lib64/libGLESv2.so | ||
1141 | 70e8dfd000-70e8dfe000 rw-p 00020000 fc:00 2954 /system/lib64/libGLESv2.so | ||
1142 | 70e8dfe000-70e8e06000 r--s 00000000 fc:00 265 /system/fonts/NotoSansBalinese-Regular.ttf | ||
1143 | 70e8e06000-70e8e0e000 r--s 00000000 fc:00 219 /system/fonts/NotoSansLaoUI-Bold.ttf | ||
1144 | 70e8e0e000-70e8e12000 r-xp 00000000 fc:00 2617 /system/lib64/libdebuggerd_client.so | ||
1145 | 70e8e12000-70e8e2d000 ---p 00000000 00:00 0 | ||
1146 | 70e8e2d000-70e8e2e000 r--p 0000f000 fc:00 2617 /system/lib64/libdebuggerd_client.so | ||
1147 | 70e8e2e000-70e8e2f000 rw-p 00010000 fc:00 2617 /system/lib64/libdebuggerd_client.so | ||
1148 | 70e8e2f000-70e8e4b000 r--s 00000000 fc:00 211 /system/fonts/NotoSerifEthiopic-Regular.otf | ||
1149 | 70e8e4b000-70e8e5e000 r-xp 00000000 fc:00 2484 /system/lib64/android.hardware.memtrack@1.0.so | ||
1150 | 70e8e5e000-70e8e78000 ---p 00000000 00:00 0 | ||
1151 | 70e8e78000-70e8e7a000 r--p 0001e000 fc:00 2484 /system/lib64/android.hardware.memtrack@1.0.so | ||
1152 | 70e8e7a000-70e8e7b000 rw-p 00020000 fc:00 2484 /system/lib64/android.hardware.memtrack@1.0.so | ||
1153 | 70e8e7b000-70e8e7d000 r--s 00000000 fc:00 261 /system/fonts/NotoSansShavian-Regular.ttf | ||
1154 | 70e8e7d000-70e8e80000 r--s 00000000 fc:00 204 /system/fonts/NotoSansRunic-Regular.ttf | ||
1155 | 70e8e80000-70e8ea1000 r-xp 00000000 fc:00 2512 /system/lib64/android.hardware.configstore@1.0.so | ||
1156 | 70e8ea1000-70e8ebb000 ---p 00000000 00:00 0 | ||
1157 | 70e8ebb000-70e8ebe000 r--p 0002d000 fc:00 2512 /system/lib64/android.hardware.configstore@1.0.so | ||
1158 | 70e8ebe000-70e8ebf000 rw-p 00030000 fc:00 2512 /system/lib64/android.hardware.configstore@1.0.so | ||
1159 | 70e8ebf000-70e8ee3000 r--s 00000000 fc:00 226 /system/fonts/NotoSansEthiopic-Bold.ttf | ||
1160 | 70e8ee3000-70e8f1a000 r-xp 00000000 fc:00 2337 /system/lib64/libm.so | ||
1161 | 70e8f1a000-70e8f32000 ---p 00000000 00:00 0 | ||
1162 | 70e8f32000-70e8f33000 r--p 0003f000 fc:00 2337 /system/lib64/libm.so | ||
1163 | 70e8f33000-70e8f34000 rw-p 00040000 fc:00 2337 /system/lib64/libm.so | ||
1164 | 70e8f34000-70e8f36000 r--s 00000000 fc:00 133 /system/fonts/NotoSansRejang-Regular.ttf | ||
1165 | 70e8f36000-70e8f38000 r--s 00000000 fc:00 69 /system/fonts/NotoSansPhoenician-Regular.ttf | ||
1166 | 70e8f38000-70e8f40000 r--s 00000000 fc:00 245 /system/fonts/NotoSansLaoUI-Regular.ttf | ||
1167 | 70e8f40000-70e8f45000 r-xp 00000000 fc:00 2341 /system/lib64/libstagefright_codecbase.so | ||
1168 | 70e8f45000-70e8f5f000 ---p 00000000 00:00 0 | ||
1169 | 70e8f5f000-70e8f60000 r--p 0000f000 fc:00 2341 /system/lib64/libstagefright_codecbase.so | ||
1170 | 70e8f60000-70e8f61000 rw-p 00010000 fc:00 2341 /system/lib64/libstagefright_codecbase.so | ||
1171 | 70e8f61000-70e8f62000 r--p 00000000 00:00 0 [anon:atexit handlers] | ||
1172 | 70e8f62000-70e8f66000 r--s 00000000 fc:00 225 /system/fonts/NotoSansOldPersian-Regular.ttf | ||
1173 | 70e8f66000-70e8f89000 r--s 00000000 fc:00 167 /system/fonts/NotoSansEthiopic-Regular.ttf | ||
1174 | 70e8f89000-70e8f92000 r-xp 00000000 fc:00 2515 /system/lib64/libGLESv1_CM.so | ||
1175 | 70e8f92000-70e8fa8000 ---p 00000000 00:00 0 | ||
1176 | 70e8fa8000-70e8fa9000 r--p 0000f000 fc:00 2515 /system/lib64/libGLESv1_CM.so | ||
1177 | 70e8fa9000-70e8faa000 rw-p 00010000 fc:00 2515 /system/lib64/libGLESv1_CM.so | ||
1178 | 70e8faa000-70e8fad000 r--s 00000000 fc:00 206 /system/fonts/NotoSansOsage-Regular.ttf | ||
1179 | 70e8fad000-70e8fb5000 r--s 00000000 fc:00 121 /system/fonts/NotoSerifLao-Bold.ttf | ||
1180 | 70e8fb5000-70e8fd3000 r--s 00000000 fc:00 68 /system/fonts/NotoNaskhArabicUI-Bold.ttf | ||
1181 | 70e8fd3000-70e9010000 r-xp 00000000 fc:00 2600 /system/lib64/android.hardware.cas@1.0.so | ||
1182 | 70e9010000-70e9026000 ---p 00000000 00:00 0 | ||
1183 | 70e9026000-70e902c000 r--p 0004a000 fc:00 2600 /system/lib64/android.hardware.cas@1.0.so | ||
1184 | 70e902c000-70e902d000 rw-p 00050000 fc:00 2600 /system/lib64/android.hardware.cas@1.0.so | ||
1185 | 70e902d000-70e902e000 r--s 00000000 00:05 31475 /dev/ashmem/5c7d41a6-003d-45a5-9e3b-2d34c5829a2d (deleted) | ||
1186 | 70e902e000-70e9043000 r--s 00000000 fc:00 120 /system/fonts/NotoSansKannada-Regular.ttf | ||
1187 | 70e9043000-70e9067000 r-xp 00000000 fc:00 2729 /system/lib64/libexpat.so | ||
1188 | 70e9067000-70e9081000 ---p 00000000 00:00 0 | ||
1189 | 70e9081000-70e9083000 r--p 0002e000 fc:00 2729 /system/lib64/libexpat.so | ||
1190 | 70e9083000-70e9084000 rw-p 00030000 fc:00 2729 /system/lib64/libexpat.so | ||
1191 | 70e9084000-70e9086000 r--s 00000000 fc:00 155 /system/fonts/NotoSansOsmanya-Regular.ttf | ||
1192 | 70e9086000-70e90c3000 r--s 00000000 fc:00 91 /system/fonts/NotoSerif-Regular.ttf | ||
1193 | 70e90c3000-70e91ce000 r-xp 00000000 fc:00 2647 /system/lib64/libcrypto.so | ||
1194 | 70e91ce000-70e91e2000 ---p 00000000 00:00 0 | ||
1195 | 70e91e2000-70e91f3000 r--p 0010f000 fc:00 2647 /system/lib64/libcrypto.so | ||
1196 | 70e91f3000-70e91f4000 rw-p 00120000 fc:00 2647 /system/lib64/libcrypto.so | ||
1197 | 70e91f4000-70e91f5000 rw-p 00000000 00:00 0 [anon:.bss] | ||
1198 | 70e91f5000-70e91fa000 r--s 00000000 fc:00 149 /system/fonts/NotoSansNKo-Regular.ttf | ||
1199 | 70e91fa000-70e9202000 r--s 00000000 fc:00 198 /system/fonts/NotoSerifLao-Regular.ttf | ||
1200 | 70e9202000-70e921b000 r-xp 00000000 fc:00 2682 /system/lib64/libmedia_helper.so | ||
1201 | 70e921b000-70e922d000 ---p 00000000 00:00 0 | ||
1202 | 70e922d000-70e9230000 r--p 0001d000 fc:00 2682 /system/lib64/libmedia_helper.so | ||
1203 | 70e9230000-70e9231000 rw-p 00020000 fc:00 2682 /system/lib64/libmedia_helper.so | ||
1204 | 70e9231000-70e924a000 r--s 00000000 fc:00 232 /system/fonts/NotoSansBengali-Bold.ttf | ||
1205 | 70e924a000-70e9256000 r-xp 00000000 fc:00 2467 /system/lib64/libsoundtrigger.so | ||
1206 | 70e9256000-70e9272000 ---p 00000000 00:00 0 | ||
1207 | 70e9272000-70e9276000 r--p 0000c000 fc:00 2467 /system/lib64/libsoundtrigger.so | ||
1208 | 70e9276000-70e9277000 rw-p 00010000 fc:00 2467 /system/lib64/libsoundtrigger.so | ||
1209 | 70e9277000-70e9278000 r--s 00000000 fc:01 1177 /vendor/overlay/Pixel/PixelThemeOverlay.apk | ||
1210 | 70e9278000-70e927c000 r--s 00000000 fc:00 215 /system/fonts/NotoSansNewTaiLue-Regular.ttf | ||
1211 | 70e927c000-70e929a000 r--s 00000000 fc:00 235 /system/fonts/NotoNaskhArabicUI-Regular.ttf | ||
1212 | 70e929a000-70e929b000 r-xp 00000000 fc:00 2375 /system/lib64/android.hardware.graphics.common@1.1.so | ||
1213 | 70e929b000-70e92b9000 ---p 00000000 00:00 0 | ||
1214 | 70e92b9000-70e92ba000 r--p 0000f000 fc:00 2375 /system/lib64/android.hardware.graphics.common@1.1.so | ||
1215 | 70e92ba000-70e92bb000 rw-p 00010000 fc:00 2375 /system/lib64/android.hardware.graphics.common@1.1.so | ||
1216 | 70e92bb000-70e92da000 r--s 00000000 fc:00 281 /system/fonts/GoogleSans-BoldItalic.ttf | ||
1217 | 70e92da000-70e9302000 r-xp 00000000 fc:00 2529 /system/lib64/libinput.so | ||
1218 | 70e9302000-70e931b000 ---p 00000000 00:00 0 | ||
1219 | 70e931b000-70e9322000 r--p 00029000 fc:00 2529 /system/lib64/libinput.so | ||
1220 | 70e9322000-70e9323000 rw-p 00030000 fc:00 2529 /system/lib64/libinput.so | ||
1221 | 70e9323000-70e9340000 r--s 00000000 fc:00 130 /system/fonts/NotoNaskhArabic-Bold.ttf | ||
1222 | 70e9340000-70e934b000 r-xp 00000000 fc:00 2451 /system/lib64/libbpf.so | ||
1223 | 70e934b000-70e935f000 ---p 00000000 00:00 0 | ||
1224 | 70e935f000-70e9360000 r--p 0000f000 fc:00 2451 /system/lib64/libbpf.so | ||
1225 | 70e9360000-70e9361000 rw-p 00010000 fc:00 2451 /system/lib64/libbpf.so | ||
1226 | 70e9361000-70e9367000 r--s 00000000 fc:00 96 /system/fonts/NotoSansKharoshthi-Regular.ttf | ||
1227 | 70e9367000-70e9385000 r--s 00000000 fc:00 151 /system/fonts/GoogleSans-Bold.ttf | ||
1228 | 70e9385000-70e93b8000 r-xp 00000000 fc:00 2494 /system/lib64/libpng.so | ||
1229 | 70e93b8000-70e93d4000 ---p 00000000 00:00 0 | ||
1230 | 70e93d4000-70e93d5000 r--p 0003f000 fc:00 2494 /system/lib64/libpng.so | ||
1231 | 70e93d5000-70e93d6000 rw-p 00040000 fc:00 2494 /system/lib64/libpng.so | ||
1232 | 70e93d6000-70e93d7000 r--s 00004000 fc:01 1177 /vendor/overlay/Pixel/PixelThemeOverlay.apk | ||
1233 | 70e93d7000-70e93d9000 r--s 00000000 fc:00 295 /system/fonts/NotoSansOldTurkic-Regular.ttf | ||
1234 | 70e93d9000-70e93e5000 r--s 00000000 fc:00 86 /system/fonts/NotoSerifKhmer-Bold.otf | ||
1235 | 70e93e5000-70e9404000 r--s 00000000 fc:00 240 /system/fonts/GoogleSans-MediumItalic.ttf | ||
1236 | 70e9404000-70e9409000 r-xp 00000000 fc:00 2404 /system/lib64/libhidlmemory.so | ||
1237 | 70e9409000-70e9423000 ---p 00000000 00:00 0 | ||
1238 | 70e9423000-70e9424000 r--p 0000f000 fc:00 2404 /system/lib64/libhidlmemory.so | ||
1239 | 70e9424000-70e9425000 rw-p 00010000 fc:00 2404 /system/lib64/libhidlmemory.so | ||
1240 | 70e9425000-70e943e000 r--s 00000000 fc:00 185 /system/fonts/NotoSansBengali-Regular.ttf | ||
1241 | 70e943e000-70e945c000 r--s 00000000 fc:00 129 /system/fonts/GoogleSans-Medium.ttf | ||
1242 | 70e945c000-70e960c000 r-xp 00000000 fc:00 2398 /system/lib64/libstagefright.so | ||
1243 | 70e960c000-70e9625000 ---p 00000000 00:00 0 | ||
1244 | 70e9625000-70e9638000 r--p 001bd000 fc:00 2398 /system/lib64/libstagefright.so | ||
1245 | 70e9638000-70e966c000 rw-p 001d0000 fc:00 2398 /system/lib64/libstagefright.so | ||
1246 | 70e966c000-70e966d000 rw-p 00000000 00:00 0 [anon:.bss] | ||
1247 | 70e966d000-70e966e000 r--s 00000000 103:1d 1474566 /data/resource-cache/vendor@overlay@Pixel@PixelThemeOverlay.apk@idmap | ||
1248 | 70e966e000-70e9672000 r--s 00000000 fc:00 241 /system/fonts/NotoSansMeeteiMayek-Regular.ttf | ||
1249 | 70e9672000-70e9680000 r--s 00000000 fc:00 150 /system/fonts/NotoSansMalayalamUI-Bold.ttf | ||
1250 | 70e9680000-70e96a7000 r-xp 00000000 fc:00 2365 /system/lib64/libhwbinder.so | ||
1251 | 70e96a7000-70e96bd000 ---p 00000000 00:00 0 | ||
1252 | 70e96bd000-70e96bf000 r--p 0002e000 fc:00 2365 /system/lib64/libhwbinder.so | ||
1253 | 70e96bf000-70e96c0000 rw-p 00030000 fc:00 2365 /system/lib64/libhwbinder.so | ||
1254 | 70e96c0000-70e96c1000 r--s 00088000 103:1d 1736830 /data/app/com.google.sample.tunnel-HGGRU03Gu1Mwkf_-RnFmvw==/base.apk | ||
1255 | 70e96c1000-70e96cb000 r--s 00000000 fc:00 94 /system/fonts/NotoSansKhmerUI-Regular.ttf | ||
1256 | 70e96cb000-70e96d9000 r--s 00000000 fc:00 275 /system/fonts/NotoSansMalayalamUI-Regular.ttf | ||
1257 | 70e96d9000-70e96dd000 r-xp 00000000 fc:00 2386 /system/lib64/libusbhost.so | ||
1258 | 70e96dd000-70e96f8000 ---p 00000000 00:00 0 | ||
1259 | 70e96f8000-70e96f9000 r--p 0000f000 fc:00 2386 /system/lib64/libusbhost.so | ||
1260 | 70e96f9000-70e96fa000 rw-p 00010000 fc:00 2386 /system/lib64/libusbhost.so | ||
1261 | 70e96fa000-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) | ||
1262 | 70e96fb000-70e9701000 r--s 00000000 fc:00 280 /system/fonts/NotoSansCoptic-Regular.ttf | ||
1263 | 70e9701000-70e9720000 r-xp 00000000 fc:00 2490 /system/lib64/libstagefright_bufferqueue_helper.so | ||
1264 | 70e9720000-70e973b000 ---p 00000000 00:00 0 | ||
1265 | 70e973b000-70e973e000 r--p 0002d000 fc:00 2490 /system/lib64/libstagefright_bufferqueue_helper.so | ||
1266 | 70e973e000-70e9740000 rw-p 00030000 fc:00 2490 /system/lib64/libstagefright_bufferqueue_helper.so | ||
1267 | 70e9740000-70e9742000 r--s 00000000 fc:00 141 /system/fonts/NotoSansOldSouthArabian-Regular.ttf | ||
1268 | 70e9742000-70e974c000 r--s 00000000 fc:00 229 /system/fonts/NotoSerifKhmer-Regular.otf | ||
1269 | 70e974c000-70e9759000 r--s 00000000 fc:00 260 /system/fonts/NotoSerifMalayalam-Bold.ttf | ||
1270 | 70e9759000-70e97c7000 r-xp 00000000 fc:00 2428 /system/lib64/libstagefright_omx.so | ||
1271 | 70e97c7000-70e97dc000 ---p 00000000 00:00 0 | ||
1272 | 70e97dc000-70e97e6000 r--p 00076000 fc:00 2428 /system/lib64/libstagefright_omx.so | ||
1273 | 70e97e6000-70e97ed000 rw-p 00080000 fc:00 2428 /system/lib64/libstagefright_omx.so | ||
1274 | 70e97ed000-70e97fa000 r--s 00000000 fc:00 66 /system/fonts/NotoSerifMalayalam-Regular.ttf | ||
1275 | 70e97fa000-70e9819000 r--s 00000000 fc:00 183 /system/fonts/GoogleSans-Italic.ttf | ||
1276 | 70e9819000-70e9856000 r-xp 00000000 fc:00 2434 /system/lib64/libprotobuf-cpp-lite.so | ||
1277 | 70e9856000-70e9867000 ---p 00000000 00:00 0 | ||
1278 | 70e9867000-70e9869000 r--p 0003e000 fc:00 2434 /system/lib64/libprotobuf-cpp-lite.so | ||
1279 | 70e9869000-70e986a000 rw-p 00040000 fc:00 2434 /system/lib64/libprotobuf-cpp-lite.so | ||
1280 | 70e986a000-70e9873000 r--s 00000000 fc:00 134 /system/fonts/NotoSansKhmerUI-Bold.ttf | ||
1281 | 70e9873000-70e9891000 r--s 00000000 fc:00 81 /system/fonts/GoogleSans-Regular.ttf | ||
1282 | 70e9891000-70e989e000 r-xp 00000000 fc:00 2377 /system/lib64/libmediametrics.so | ||
1283 | 70e989e000-70e98ae000 ---p 00000000 00:00 0 | ||
1284 | 70e98ae000-70e98b0000 r--p 0000e000 fc:00 2377 /system/lib64/libmediametrics.so | ||
1285 | 70e98b0000-70e98b1000 rw-p 00010000 fc:00 2377 /system/lib64/libmediametrics.so | ||
1286 | 70e98b1000-70e98b9000 r--s 00000000 fc:00 152 /system/fonts/NotoSansLao-Bold.ttf | ||
1287 | 70e98b9000-70e98c7000 r--s 00000000 fc:00 279 /system/fonts/NotoSansMalayalam-Bold.ttf | ||
1288 | 70e98c7000-70e98ca000 r-xp 00000000 fc:00 2952 /system/lib64/libETC1.so | ||
1289 | 70e98ca000-70e98e6000 ---p 00000000 00:00 0 | ||
1290 | 70e98e6000-70e98e7000 r--p 0000f000 fc:00 2952 /system/lib64/libETC1.so | ||
1291 | 70e98e7000-70e98e8000 rw-p 00010000 fc:00 2952 /system/lib64/libETC1.so | ||
1292 | 70e98e8000-70e98e9000 r--s 00000000 fc:00 1121 /system/usr/hyphen-data/hyph-und-ethi.hyb | ||
1293 | 70e98e9000-70e98ef000 r--s 00000000 fc:00 64 /system/fonts/NotoSansBrahmi-Regular.ttf | ||
1294 | 70e98ef000-70e990f000 rw-p 00000000 00:05 10271012 /dev/ashmem/dalvik-CompilerMetadata (deleted) | ||
1295 | 70e990f000-70e9926000 r-xp 00000000 fc:00 2526 /system/lib64/libbacktrace.so | ||
1296 | 70e9926000-70e993e000 ---p 00000000 00:00 0 | ||
1297 | 70e993e000-70e993f000 r--p 0001f000 fc:00 2526 /system/lib64/libbacktrace.so | ||
1298 | 70e993f000-70e9940000 rw-p 00020000 fc:00 2526 /system/lib64/libbacktrace.so | ||
1299 | 70e9940000-70e9941000 r--s 00000000 fc:00 1129 /system/usr/hyphen-data/hyph-tk.hyb | ||
1300 | 70e9941000-70e99a4000 r-xp 00000000 fc:00 2528 /system/lib64/libcamera_client.so | ||
1301 | 70e99a4000-70e99bc000 ---p 00000000 00:00 0 | ||
1302 | 70e99bc000-70e99c9000 r--p 00063000 fc:00 2528 /system/lib64/libcamera_client.so | ||
1303 | 70e99c9000-70e99d0000 rw-p 00070000 fc:00 2528 /system/lib64/libcamera_client.so | ||
1304 | 70e99d0000-70e99d1000 r--p 00000000 00:00 0 [anon:linker_alloc] | ||
1305 | 70e99d1000-70e99d3000 r--s 00000000 fc:00 200 /system/fonts/NotoSansOldItalic-Regular.ttf | ||
1306 | 70e99d3000-70e99e1000 r--s 00000000 fc:00 153 /system/fonts/NotoSansMalayalam-Regular.ttf | ||
1307 | 70e99e1000-70e9a01000 rw-p 00000000 00:05 10271011 /dev/ashmem/dalvik-CompilerMetadata (deleted) | ||
1308 | 70e9a01000-70e9a1e000 r-xp 00000000 fc:00 2542 /system/lib64/libimg_utils.so | ||
1309 | 70e9a1e000-70e9a39000 ---p 00000000 00:00 0 | ||
1310 | 70e9a39000-70e9a3c000 r--p 0001d000 fc:00 2542 /system/lib64/libimg_utils.so | ||
1311 | 70e9a3c000-70e9a3f000 rw-p 00020000 fc:00 2542 /system/lib64/libimg_utils.so | ||
1312 | 70e9a3f000-70e9a5c000 r--s 00000000 fc:00 262 /system/fonts/NotoNaskhArabic-Regular.ttf | ||
1313 | 70e9a5c000-70e9a69000 r-xp 00000000 fc:00 2706 /system/lib64/libziparchive.so | ||
1314 | 70e9a69000-70e9a7b000 ---p 00000000 00:00 0 | ||
1315 | 70e9a7b000-70e9a7c000 r--p 0000f000 fc:00 2706 /system/lib64/libziparchive.so | ||
1316 | 70e9a7c000-70e9a7d000 rw-p 00010000 fc:00 2706 /system/lib64/libziparchive.so | ||
1317 | 70e9a7d000-70e9a85000 r--s 00000000 fc:00 119 /system/fonts/NotoSansLao-Regular.ttf | ||
1318 | 70e9a85000-70e9a8e000 r--s 00000000 fc:00 77 /system/fonts/NotoSansTamilUI-Bold.ttf | ||
1319 | 70e9a8e000-70e9a97000 r--s 00000000 fc:00 160 /system/fonts/NotoSansTamilUI-Regular.ttf | ||
1320 | 70e9a97000-70e9a9d000 r-xp 00000000 fc:00 2536 /system/lib64/libnativehelper.so | ||
1321 | 70e9a9d000-70e9ab6000 ---p 00000000 00:00 0 | ||
1322 | 70e9ab6000-70e9ab7000 r--p 0000f000 fc:00 2536 /system/lib64/libnativehelper.so | ||
1323 | 70e9ab7000-70e9ab8000 rw-p 00010000 fc:00 2536 /system/lib64/libnativehelper.so | ||
1324 | 70e9ab8000-70e9ab9000 r--s 00000000 fc:00 1134 /system/usr/hyphen-data/hyph-te.hyb | ||
1325 | 70e9ab9000-70e9ac2000 r--s 00000000 fc:00 246 /system/fonts/NotoSerifTamil-Bold.ttf | ||
1326 | 70e9ac2000-70e9acb000 r--s 00000000 fc:00 302 /system/fonts/NotoSerifTamil-Regular.ttf | ||
1327 | 70e9acb000-70e9af4000 r-xp 00000000 fc:00 2950 /system/lib64/libmemunreachable.so | ||
1328 | 70e9af4000-70e9b09000 ---p 00000000 00:00 0 | ||
1329 | 70e9b09000-70e9b0b000 r--p 0002e000 fc:00 2950 /system/lib64/libmemunreachable.so | ||
1330 | 70e9b0b000-70e9b0c000 rw-p 00030000 fc:00 2950 /system/lib64/libmemunreachable.so | ||
1331 | 70e9b0c000-70e9b0d000 r--s 00000000 fc:00 1088 /system/usr/hyphen-data/hyph-ta.hyb | ||
1332 | 70e9b0d000-70e9b0f000 r--s 00000000 fc:00 72 /system/fonts/NotoSansOlChiki-Regular.ttf | ||
1333 | 70e9b0f000-70e9b2f000 rw-p 00000000 00:05 10271010 /dev/ashmem/dalvik-CompilerMetadata (deleted) | ||
1334 | 70e9b2f000-70e9b4f000 r--s 00000000 00:10 16633 /dev/__properties__/u:object_r:persist_debug_prop:s0 | ||
1335 | 70e9b4f000-70e9b65000 r-xp 00000000 fc:00 2920 /system/lib64/android.hardware.cas.native@1.0.so | ||
1336 | 70e9b65000-70e9b7b000 ---p 00000000 00:00 0 | ||
1337 | 70e9b7b000-70e9b7d000 r--p 0001e000 fc:00 2920 /system/lib64/android.hardware.cas.native@1.0.so | ||
1338 | 70e9b7d000-70e9b7e000 rw-p 00020000 fc:00 2920 /system/lib64/android.hardware.cas.native@1.0.so | ||
1339 | 70e9b7e000-70e9b7f000 r--s 00000000 fc:00 1145 /system/usr/hyphen-data/hyph-pt.hyb | ||
1340 | 70e9b7f000-70e9b83000 r--s 00000000 fc:00 277 /system/fonts/NotoSansMandaic-Regular.ttf | ||
1341 | 70e9b83000-70e9bdb000 r-xp 00000000 fc:00 2334 /system/lib64/libsonivox.so | ||
1342 | 70e9bdb000-70e9bf2000 ---p 00000000 00:00 0 | ||
1343 | 70e9bf2000-70e9bf3000 r--p 0005f000 fc:00 2334 /system/lib64/libsonivox.so | ||
1344 | 70e9bf3000-70e9bf4000 rw-p 00060000 fc:00 2334 /system/lib64/libsonivox.so | ||
1345 | 70e9bf4000-70e9bfb000 rw-p 00000000 00:00 0 [anon:.bss] | ||
1346 | 70e9bfb000-70e9c01000 r--s 00000000 fc:00 123 /system/fonts/NotoSansCham-Bold.ttf | ||
1347 | 70e9c01000-70e9c0a000 r--s 00000000 fc:00 255 /system/fonts/NotoSansTamil-Bold.ttf | ||
1348 | 70e9c0a000-70e9c13000 r--s 00000000 fc:00 135 /system/fonts/NotoSansTamil-Regular.ttf | ||
1349 | 70e9c13000-70e9c15000 r-xp 00000000 fc:00 2519 /system/lib64/libgraphicsenv.so | ||
1350 | 70e9c15000-70e9c32000 ---p 00000000 00:00 0 | ||
1351 | 70e9c32000-70e9c33000 r--p 0000f000 fc:00 2519 /system/lib64/libgraphicsenv.so | ||
1352 | 70e9c33000-70e9c34000 rw-p 00010000 fc:00 2519 /system/lib64/libgraphicsenv.so | ||
1353 | 70e9c34000-70e9c3a000 r--s 00000000 fc:00 259 /system/fonts/NotoSansCham-Regular.ttf | ||
1354 | 70e9c3a000-70e9c42000 r--s 00000000 fc:00 114 /system/fonts/NotoSansGurmukhiUI-Bold.ttf | ||
1355 | 70e9c42000-70e9c4a000 r--s 00000000 fc:00 122 /system/fonts/NotoSansGurmukhiUI-Regular.ttf | ||
1356 | 70e9c4a000-70e9c5f000 r-xp 00000000 fc:00 2348 /system/lib64/android.hidl.allocator@1.0.so | ||
1357 | 70e9c5f000-70e9c77000 ---p 00000000 00:00 0 | ||
1358 | 70e9c77000-70e9c79000 r--p 0001e000 fc:00 2348 /system/lib64/android.hidl.allocator@1.0.so | ||
1359 | 70e9c79000-70e9c7a000 rw-p 00020000 fc:00 2348 /system/lib64/android.hidl.allocator@1.0.so | ||
1360 | 70e9c7a000-70e9c7b000 r--s 00000000 fc:00 1095 /system/usr/hyphen-data/hyph-pa.hyb | ||
1361 | 70e9c7b000-70e9c83000 r--s 00000000 fc:00 298 /system/fonts/NotoSerifGurmukhi-Bold.otf | ||
1362 | 70e9c83000-70e9d01000 r-xp 00000000 fc:00 2665 /system/lib64/libbinder.so | ||
1363 | 70e9d01000-70e9d1e000 ---p 00000000 00:00 0 | ||
1364 | 70e9d1e000-70e9d2e000 r--p 00080000 fc:00 2665 /system/lib64/libbinder.so | ||
1365 | 70e9d2e000-70e9d2f000 rw-p 00090000 fc:00 2665 /system/lib64/libbinder.so | ||
1366 | 70e9d2f000-70e9d4f000 rw-p 00000000 00:05 10271009 /dev/ashmem/dalvik-CompilerMetadata (deleted) | ||
1367 | 70e9d4f000-70e9d53000 r-xp 00000000 fc:00 2454 /system/lib64/libaudiomanager.so | ||
1368 | 70e9d53000-70e9d6e000 ---p 00000000 00:00 0 | ||
1369 | 70e9d6e000-70e9d6f000 r--p 0000f000 fc:00 2454 /system/lib64/libaudiomanager.so | ||
1370 | 70e9d6f000-70e9d70000 rw-p 00010000 fc:00 2454 /system/lib64/libaudiomanager.so | ||
1371 | 70e9d70000-70e9d71000 r--s 00000000 fc:00 1087 /system/usr/hyphen-data/hyph-or.hyb | ||
1372 | 70e9d71000-70e9d91000 rw-p 00000000 00:05 10271008 /dev/ashmem/dalvik-CompilerMetadata (deleted) | ||
1373 | 70e9d91000-70e9e21000 r-xp 00000000 fc:00 2627 /system/lib64/libft2.so | ||
1374 | 70e9e21000-70e9e37000 ---p 00000000 00:00 0 | ||
1375 | 70e9e37000-70e9e3c000 r--p 0009b000 fc:00 2627 /system/lib64/libft2.so | ||
1376 | 70e9e3c000-70e9e3d000 rw-p 000a0000 fc:00 2627 /system/lib64/libft2.so | ||
1377 | 70e9e3d000-70e9e3e000 r--s 00000000 fc:00 1142 /system/usr/hyphen-data/hyph-mr.hyb | ||
1378 | 70e9e3e000-70e9e45000 r--s 00000000 fc:00 88 /system/fonts/NotoSerifGurmukhi-Regular.otf | ||
1379 | 70e9e45000-70e9e65000 r--s 00000000 00:10 16594 /dev/__properties__/u:object_r:exported3_default_prop:s0 | ||
1380 | 70e9e65000-70e9e7f000 r-xp 00000000 fc:00 2643 /system/lib64/libunwind.so | ||
1381 | 70e9e7f000-70e9e94000 ---p 00000000 00:00 0 | ||
1382 | 70e9e94000-70e9e95000 r--p 0001f000 fc:00 2643 /system/lib64/libunwind.so | ||
1383 | 70e9e95000-70e9e96000 rw-p 00020000 fc:00 2643 /system/lib64/libunwind.so | ||
1384 | 70e9e96000-70e9eff000 rw-p 00000000 00:00 0 [anon:.bss] | ||
1385 | 70e9eff000-70e9f00000 r--s 00000000 fc:00 1130 /system/usr/hyphen-data/hyph-ml.hyb | ||
1386 | 70e9f00000-70e9f02000 r--s 00000000 fc:00 75 /system/fonts/NotoSansOgham-Regular.ttf | ||
1387 | 70e9f02000-70e9f0a000 r--s 00000000 fc:00 193 /system/fonts/NotoSansGurmukhi-Bold.ttf | ||
1388 | 70e9f0a000-70ea022000 r-xp 00000000 fc:00 2328 /system/lib64/libsqlite.so | ||
1389 | 70ea022000-70ea033000 ---p 00000000 00:00 0 | ||
1390 | 70ea033000-70ea036000 r--p 0011d000 fc:00 2328 /system/lib64/libsqlite.so | ||
1391 | 70ea036000-70ea038000 rw-p 00120000 fc:00 2328 /system/lib64/libsqlite.so | ||
1392 | 70ea038000-70ea03c000 r--s 00000000 fc:00 285 /system/fonts/NotoSansGlagolitic-Regular.ttf | ||
1393 | 70ea03c000-70ea04c000 r--s 00000000 fc:00 184 /system/fonts/NotoSerifGujarati-Bold.ttf | ||
1394 | 70ea04c000-70ea060000 r-xp 00000000 fc:00 2731 /system/lib64/libstatslog.so | ||
1395 | 70ea060000-70ea07b000 ---p 00000000 00:00 0 | ||
1396 | 70ea07b000-70ea07c000 r--p 0001f000 fc:00 2731 /system/lib64/libstatslog.so | ||
1397 | 70ea07c000-70ea07d000 rw-p 00020000 fc:00 2731 /system/lib64/libstatslog.so | ||
1398 | 70ea07d000-70ea081000 r--s 00000000 fc:00 182 /system/fonts/NotoSansBatak-Regular.ttf | ||
1399 | 70ea081000-70ea091000 r--s 00000000 fc:00 264 /system/fonts/NotoSerifGujarati-Regular.ttf | ||
1400 | 70ea091000-70ea160000 r-xp 00000000 fc:00 2728 /system/lib64/libdng_sdk.so | ||
1401 | 70ea160000-70ea173000 ---p 00000000 00:00 0 | ||
1402 | 70ea173000-70ea17a000 r--p 000d9000 fc:00 2728 /system/lib64/libdng_sdk.so | ||
1403 | 70ea17a000-70ea17b000 rw-p 000e0000 fc:00 2728 /system/lib64/libdng_sdk.so | ||
1404 | 70ea17b000-70ea198000 r--s 00000000 fc:00 223 /system/fonts/DancingScript-Bold.ttf | ||
1405 | 70ea198000-70ea19c000 r-xp 00000000 fc:00 2344 /system/lib64/libnativewindow.so | ||
1406 | 70ea19c000-70ea1b7000 ---p 00000000 00:00 0 | ||
1407 | 70ea1b7000-70ea1b8000 r--p 0000f000 fc:00 2344 /system/lib64/libnativewindow.so | ||
1408 | 70ea1b8000-70ea1b9000 rw-p 00010000 fc:00 2344 /system/lib64/libnativewindow.so | ||
1409 | 70ea1b9000-70ea1bd000 r--s 00000000 fc:00 98 /system/fonts/NotoSansAhom-Regular.otf | ||
1410 | 70ea1bd000-70ea1d1000 r--s 00000000 fc:00 104 /system/fonts/NotoSerifDevanagari-Bold.ttf | ||
1411 | 70ea1d1000-70ea1d4000 r-xp 00000000 fc:00 2923 /system/lib64/libstdc++.so | ||
1412 | 70ea1d4000-70ea1f0000 ---p 00000000 00:00 0 | ||
1413 | 70ea1f0000-70ea1f1000 r--p 0000f000 fc:00 2923 /system/lib64/libstdc++.so | ||
1414 | 70ea1f1000-70ea1f2000 rw-p 00010000 fc:00 2923 /system/lib64/libstdc++.so | ||
1415 | 70ea1f2000-70ea1f4000 r--s 00000000 fc:00 117 /system/fonts/NotoSansLydian-Regular.ttf | ||
1416 | 70ea1f4000-70ea211000 r--s 00000000 fc:00 239 /system/fonts/DancingScript-Regular.ttf | ||
1417 | 70ea211000-70ea24a000 r-xp 00000000 fc:00 2933 /system/lib64/android.hardware.graphics.bufferqueue@1.0.so | ||
1418 | 70ea24a000-70ea268000 ---p 00000000 00:00 0 | ||
1419 | 70ea268000-70ea26c000 r--p 0003c000 fc:00 2933 /system/lib64/android.hardware.graphics.bufferqueue@1.0.so | ||
1420 | 70ea26c000-70ea26d000 rw-p 00040000 fc:00 2933 /system/lib64/android.hardware.graphics.bufferqueue@1.0.so | ||
1421 | 70ea26d000-70ea26f000 r--s 00000000 fc:00 244 /system/fonts/NotoSansLycian-Regular.ttf | ||
1422 | 70ea26f000-70ea273000 r--s 00000000 fc:00 173 /system/fonts/NotoSansThaana-Bold.ttf | ||
1423 | 70ea273000-70ea287000 r--s 00000000 fc:00 106 /system/fonts/NotoSerifDevanagari-Regular.ttf | ||
1424 | 70ea287000-70ea29e000 r-xp 00000000 fc:00 2938 /system/lib64/libpiex.so | ||
1425 | 70ea29e000-70ea2b6000 ---p 00000000 00:00 0 | ||
1426 | 70ea2b6000-70ea2b7000 r--p 0001f000 fc:00 2938 /system/lib64/libpiex.so | ||
1427 | 70ea2b7000-70ea2b8000 rw-p 00020000 fc:00 2938 /system/lib64/libpiex.so | ||
1428 | 70ea2b8000-70ea2c0000 r--s 00000000 fc:00 113 /system/fonts/NotoSansGurmukhi-Regular.ttf | ||
1429 | 70ea2c0000-70ea2c6000 r--s 00000000 fc:00 263 /system/fonts/NotoSerifGeorgian-Bold.ttf | ||
1430 | 70ea2c6000-70ea2cc000 r--s 00000000 fc:00 249 /system/fonts/NotoSerifGeorgian-Regular.ttf | ||
1431 | 70ea2cc000-70ea9b4000 r-xp 00000000 fc:00 2532 /system/lib64/libhwui.so | ||
1432 | 70ea9b4000-70ea9d3000 ---p 00000000 00:00 0 | ||
1433 | 70ea9d3000-70eaa0b000 r--p 006e8000 fc:00 2532 /system/lib64/libhwui.so | ||
1434 | 70eaa0b000-70eaa0c000 rw-p 00720000 fc:00 2532 /system/lib64/libhwui.so | ||
1435 | 70eaa0c000-70eaa11000 rw-p 00000000 00:00 0 [anon:.bss] | ||
1436 | 70eaa11000-70eaa12000 r--s 00000000 fc:00 1110 /system/usr/hyphen-data/hyph-la.hyb | ||
1437 | 70eaa12000-70eaa16000 r--s 00000000 fc:00 87 /system/fonts/NotoSansThaana-Regular.ttf | ||
1438 | 70eaa16000-70eaa1b000 r--s 00000000 fc:00 218 /system/fonts/NotoSansGeorgian-Bold.ttf | ||
1439 | 70eaa1b000-70eaa20000 r--s 00000000 fc:00 125 /system/fonts/NotoSansGeorgian-Regular.ttf | ||
1440 | 70eaa20000-70eaa40000 rw-p 00000000 00:05 10271007 /dev/ashmem/dalvik-CompilerMetadata (deleted) | ||
1441 | 70eaa40000-70eaaa0000 r-xp 00000000 fc:00 2384 /system/lib64/libhidltransport.so | ||
1442 | 70eaaa0000-70eaabe000 ---p 00000000 00:00 0 | ||
1443 | 70eaabe000-70eaac6000 r--p 00068000 fc:00 2384 /system/lib64/libhidltransport.so | ||
1444 | 70eaac6000-70eaac7000 rw-p 00070000 fc:00 2384 /system/lib64/libhidltransport.so | ||
1445 | 70eaac7000-70eaacb000 r--s 00000000 fc:00 192 /system/fonts/NotoSerifArmenian-Bold.ttf | ||
1446 | 70eaacb000-70eaad0000 r--s 00000000 fc:00 210 /system/fonts/NotoSansThaiUI-Bold.ttf | ||
1447 | 70eaad0000-70eaaf0000 rw-p 00000000 00:05 10271006 /dev/ashmem/dalvik-CompilerMetadata (deleted) | ||
1448 | 70eaaf0000-70eab10000 rw-p 00000000 00:05 10271005 /dev/ashmem/dalvik-CompilerMetadata (deleted) | ||
1449 | 70eab10000-70eab57000 r-xp 00000000 fc:00 2546 /system/lib64/libmedia_omx.so | ||
1450 | 70eab57000-70eab6d000 ---p 00000000 00:00 0 | ||
1451 | 70eab6d000-70eab7a000 r--p 00053000 fc:00 2546 /system/lib64/libmedia_omx.so | ||
1452 | 70eab7a000-70eab7f000 rw-p 00060000 fc:00 2546 /system/lib64/libmedia_omx.so | ||
1453 | 70eab7f000-70eab80000 r--s 00000000 fc:00 1119 /system/usr/hyphen-data/hyph-kn.hyb | ||
1454 | 70eab80000-70eab86000 r--s 00000000 fc:00 224 /system/fonts/NotoSansThaiUI-Regular.ttf | ||
1455 | 70eab86000-70eab8b000 r--s 00000000 fc:00 300 /system/fonts/NotoSerifThai-Bold.ttf | ||
1456 | 70eab8b000-70eabab000 rw-p 00000000 00:05 10271004 /dev/ashmem/dalvik-CompilerMetadata (deleted) | ||
1457 | 70eabab000-70eac21000 r-xp 00000000 fc:00 2385 /system/lib64/libvintf.so | ||
1458 | 70eac21000-70eac31000 ---p 00000000 00:00 0 | ||
1459 | 70eac31000-70eac36000 r--p 0007b000 fc:00 2385 /system/lib64/libvintf.so | ||
1460 | 70eac36000-70eac37000 rw-p 00080000 fc:00 2385 /system/lib64/libvintf.so | ||
1461 | 70eac37000-70eac39000 rw-p 00000000 00:00 0 [anon:.bss] | ||
1462 | 70eac39000-70eac3a000 r--s 00000000 fc:00 1104 /system/usr/hyphen-data/hyph-hy.hyb | ||
1463 | 70eac3a000-70eac3f000 r--s 00000000 fc:00 212 /system/fonts/NotoSerifThai-Regular.ttf | ||
1464 | 70eac3f000-70eac44000 r--s 00000000 fc:00 220 /system/fonts/NotoSansThai-Bold.ttf | ||
1465 | 70eac44000-70eacb2000 r-xp 00000000 fc:00 2606 /system/lib64/android.hardware.media.omx@1.0.so | ||
1466 | 70eacb2000-70eaccf000 ---p 00000000 00:00 0 | ||
1467 | 70eaccf000-70eacd8000 r--p 00077000 fc:00 2606 /system/lib64/android.hardware.media.omx@1.0.so | ||
1468 | 70eacd8000-70eacd9000 rw-p 00080000 fc:00 2606 /system/lib64/android.hardware.media.omx@1.0.so | ||
1469 | 70eacd9000-70eacdf000 r--s 00000000 fc:00 169 /system/fonts/NotoSansThai-Regular.ttf | ||
1470 | 70eacdf000-70eace9000 r--s 00000000 fc:00 140 /system/fonts/CarroisGothicSC-Regular.ttf | ||
1471 | 70eace9000-70ead09000 rw-p 00000000 00:05 10271003 /dev/ashmem/dalvik-CompilerMetadata (deleted) | ||
1472 | 70ead09000-70ead22000 r-xp 00000000 fc:00 2539 /system/lib64/android.hardware.graphics.mapper@2.1.so | ||
1473 | 70ead22000-70ead34000 ---p 00000000 00:00 0 | ||
1474 | 70ead34000-70ead37000 r--p 0001d000 fc:00 2539 /system/lib64/android.hardware.graphics.mapper@2.1.so | ||
1475 | 70ead37000-70ead38000 rw-p 00020000 fc:00 2539 /system/lib64/android.hardware.graphics.mapper@2.1.so | ||
1476 | 70ead38000-70ead47000 r--s 00000000 fc:00 188 /system/fonts/ComingSoon.ttf | ||
1477 | 70ead47000-70ead5d000 r-xp 00000000 fc:00 2379 /system/lib64/libselinux.so | ||
1478 | 70ead5d000-70ead76000 ---p 00000000 00:00 0 | ||
1479 | 70ead76000-70ead77000 r--p 0001f000 fc:00 2379 /system/lib64/libselinux.so | ||
1480 | 70ead77000-70ead78000 rw-p 00020000 fc:00 2379 /system/lib64/libselinux.so | ||
1481 | 70ead78000-70ead79000 rw-p 00000000 00:00 0 [anon:.bss] | ||
1482 | 70ead79000-70ead7d000 r--s 00000000 fc:00 282 /system/fonts/NotoSerifArmenian-Regular.ttf | ||
1483 | 70ead7d000-70ead82000 r--s 00000000 fc:00 288 /system/fonts/NotoSerifHebrew-Bold.ttf | ||
1484 | 70ead82000-70ead83000 r-xp 00000000 fc:00 2680 /system/lib64/android.hardware.media@1.0.so | ||
1485 | 70ead83000-70eada1000 ---p 00000000 00:00 0 | ||
1486 | 70eada1000-70eada2000 r--p 0000f000 fc:00 2680 /system/lib64/android.hardware.media@1.0.so | ||
1487 | 70eada2000-70eada3000 rw-p 00010000 fc:00 2680 /system/lib64/android.hardware.media@1.0.so | ||
1488 | 70eada3000-70eada8000 r--s 00000000 fc:00 248 /system/fonts/NotoSerifHebrew-Regular.ttf | ||
1489 | 70eada8000-70eadb9000 r--s 00000000 fc:00 252 /system/fonts/CutiveMono.ttf | ||
1490 | 70eadb9000-70eadd9000 r--s 00000000 00:10 16641 /dev/__properties__/u:object_r:radio_prop:s0 | ||
1491 | 70eadd9000-70eadda000 r-xp 00000000 fc:00 2533 /system/lib64/android.hardware.graphics.common@1.0.so | ||
1492 | 70eadda000-70eadf8000 ---p 00000000 00:00 0 | ||
1493 | 70eadf8000-70eadf9000 r--p 0000f000 fc:00 2533 /system/lib64/android.hardware.graphics.common@1.0.so | ||
1494 | 70eadf9000-70eadfa000 rw-p 00010000 fc:00 2533 /system/lib64/android.hardware.graphics.common@1.0.so | ||
1495 | 70eadfa000-70eadfb000 r--s 00000000 fc:00 1126 /system/usr/hyphen-data/hyph-hr.hyb | ||
1496 | 70eadfb000-70eadfd000 r--s 00000000 fc:00 194 /system/fonts/NotoSansLisu-Regular.ttf | ||
1497 | 70eadfd000-70eae18000 r--s 00000000 fc:00 201 /system/fonts/DroidSansMono.ttf | ||
1498 | 70eae18000-70eae3b000 r-xp 00000000 fc:00 2925 /system/lib64/liblzma.so | ||
1499 | 70eae3b000-70eae57000 ---p 00000000 00:00 0 | ||
1500 | 70eae57000-70eae58000 r--p 0002f000 fc:00 2925 /system/lib64/liblzma.so | ||
1501 | 70eae58000-70eae59000 rw-p 00030000 fc:00 2925 /system/lib64/liblzma.so | ||
1502 | 70eae59000-70eae5f000 rw-p 00000000 00:00 0 [anon:.bss] | ||
1503 | 70eae5f000-70eae62000 r--s 00000000 fc:00 103 /system/fonts/NotoSansLimbu-Regular.ttf | ||
1504 | 70eae62000-70eae67000 r--s 00000000 fc:00 236 /system/fonts/NotoSansHebrew-Bold.ttf | ||
1505 | 70eae67000-70eae84000 r--s 001c2000 fc:00 990 /system/framework/ext.jar | ||
1506 | 70eae84000-70eaea4000 rw-p 00000000 00:05 10269720 /dev/ashmem/dalvik-LinearAlloc (deleted) | ||
1507 | 70eaea4000-70eaede000 r-xp 00000000 fc:00 2924 /system/lib64/libwilhelm.so | ||
1508 | 70eaede000-70eaefa000 ---p 00000000 00:00 0 | ||
1509 | 70eaefa000-70eaeff000 r--p 0003b000 fc:00 2924 /system/lib64/libwilhelm.so | ||
1510 | 70eaeff000-70eaf00000 rw-p 00040000 fc:00 2924 /system/lib64/libwilhelm.so | ||
1511 | 70eaf00000-70eaf03000 r--s 00000000 fc:00 242 /system/fonts/NotoSansElbasan-Regular.otf | ||
1512 | 70eaf03000-70eaf21000 r-xp 00000000 fc:00 2415 /system/lib64/libdrmframework.so | ||
1513 | 70eaf21000-70eaf38000 ---p 00000000 00:00 0 | ||
1514 | 70eaf38000-70eaf3d000 r--p 0002b000 fc:00 2415 /system/lib64/libdrmframework.so | ||
1515 | 70eaf3d000-70eaf3e000 rw-p 00030000 fc:00 2415 /system/lib64/libdrmframework.so | ||
1516 | 70eaf3e000-70eaf43000 r--s 00000000 fc:00 70 /system/fonts/NotoSansHebrew-Regular.ttf | ||
1517 | 70eaf43000-70eaf44000 ---p 00000000 00:00 0 [anon:thread signal stack guard] | ||
1518 | 70eaf44000-70eaf48000 rw-p 00000000 00:00 0 [anon:thread signal stack] | ||
1519 | 70eaf48000-70eaf49000 ---p 00000000 00:00 0 [anon:bionic TLS guard] | ||
1520 | 70eaf49000-70eaf4c000 rw-p 00000000 00:00 0 [anon:bionic TLS] | ||
1521 | 70eaf4c000-70eaf4d000 ---p 00000000 00:00 0 [anon:bionic TLS guard] | ||
1522 | 70eaf4d000-70eaf4e000 ---p 00000000 00:00 0 [anon:thread signal stack guard] | ||
1523 | 70eaf4e000-70eaf52000 rw-p 00000000 00:00 0 [anon:thread signal stack] | ||
1524 | 70eaf52000-70eaf98000 r-xp 00000000 fc:00 2426 /system/lib64/libunwindstack.so | ||
1525 | 70eaf98000-70eafb6000 ---p 00000000 00:00 0 | ||
1526 | 70eafb6000-70eafbd000 r--p 00049000 fc:00 2426 /system/lib64/libunwindstack.so | ||
1527 | 70eafbd000-70eafbe000 rw-p 00050000 fc:00 2426 /system/lib64/libunwindstack.so | ||
1528 | 70eafbe000-70eafc0000 r--s 00000000 fc:00 162 /system/fonts/NotoSansKayahLi-Regular.ttf | ||
1529 | 70eafc0000-70eafe4000 r-xp 00000000 fc:00 2944 /system/lib64/libvulkan.so | ||
1530 | 70eafe4000-70eaffc000 ---p 00000000 00:00 0 | ||
1531 | 70eaffc000-70eaffe000 r--p 0002e000 fc:00 2944 /system/lib64/libvulkan.so | ||
1532 | 70eaffe000-70eafff000 rw-p 00030000 fc:00 2944 /system/lib64/libvulkan.so | ||
1533 | 70eafff000-70eb001000 r--s 00000000 fc:00 180 /system/fonts/NotoSansInscriptionalParthian-Regular.ttf | ||
1534 | 70eb001000-70eb01d000 r-xp 00000000 fc:00 2400 /system/lib64/libbufferhubqueue.so | ||
1535 | 70eb01d000-70eb030000 ---p 00000000 00:00 0 | ||
1536 | 70eb030000-70eb031000 r--p 0001f000 fc:00 2400 /system/lib64/libbufferhubqueue.so | ||
1537 | 70eb031000-70eb032000 rw-p 00020000 fc:00 2400 /system/lib64/libbufferhubqueue.so | ||
1538 | 70eb032000-70eb036000 r--s 00000000 fc:00 269 /system/fonts/NotoSansArmenian-Bold.ttf | ||
1539 | 70eb036000-70eb037000 ---p 00000000 00:00 0 [anon:bionic TLS guard] | ||
1540 | 70eb037000-70eb03a000 rw-p 00000000 00:00 0 [anon:bionic TLS] | ||
1541 | 70eb03a000-70eb03b000 ---p 00000000 00:00 0 [anon:bionic TLS guard] | ||
1542 | 70eb03b000-70eb03c000 ---p 00000000 00:00 0 [anon:thread signal stack guard] | ||
1543 | 70eb03c000-70eb040000 rw-p 00000000 00:00 0 [anon:thread signal stack] | ||
1544 | 70eb040000-70eb042000 r-xp 00000000 fc:00 2935 /system/lib64/libhardware.so | ||
1545 | 70eb042000-70eb05f000 ---p 00000000 00:00 0 | ||
1546 | 70eb05f000-70eb060000 r--p 0000f000 fc:00 2935 /system/lib64/libhardware.so | ||
1547 | 70eb060000-70eb061000 rw-p 00010000 fc:00 2935 /system/lib64/libhardware.so | ||
1548 | 70eb061000-70eb063000 r--s 00000000 fc:00 171 /system/fonts/NotoSansInscriptionalPahlavi-Regular.ttf | ||
1549 | 70eb063000-70eb064000 ---p 00000000 00:00 0 [anon:bionic TLS guard] | ||
1550 | 70eb064000-70eb067000 rw-p 00000000 00:00 0 [anon:bionic TLS] | ||
1551 | 70eb067000-70eb068000 ---p 00000000 00:00 0 [anon:bionic TLS guard] | ||
1552 | 70eb068000-70eb069000 ---p 00000000 00:00 0 [anon:thread signal stack guard] | ||
1553 | 70eb069000-70eb06d000 rw-p 00000000 00:00 0 [anon:thread signal stack] | ||
1554 | 70eb06d000-70eb06e000 ---p 00000000 00:00 0 [anon:bionic TLS guard] | ||
1555 | 70eb06e000-70eb071000 rw-p 00000000 00:00 0 [anon:bionic TLS] | ||
1556 | 70eb071000-70eb072000 ---p 00000000 00:00 0 [anon:bionic TLS guard] | ||
1557 | 70eb072000-70eb073000 ---p 00000000 00:00 0 [anon:thread signal stack guard] | ||
1558 | 70eb073000-70eb077000 rw-p 00000000 00:00 0 [anon:thread signal stack] | ||
1559 | 70eb077000-70eb078000 ---p 00000000 00:00 0 [anon:bionic TLS guard] | ||
1560 | 70eb078000-70eb07b000 rw-p 00000000 00:00 0 [anon:bionic TLS] | ||
1561 | 70eb07b000-70eb07c000 ---p 00000000 00:00 0 [anon:bionic TLS guard] | ||
1562 | 70eb07c000-70eb07d000 ---p 00000000 00:00 0 [anon:thread signal stack guard] | ||
1563 | 70eb07d000-70eb081000 rw-p 00000000 00:00 0 [anon:thread signal stack] | ||
1564 | 70eb081000-70eb082000 ---p 00000000 00:00 0 [anon:bionic TLS guard] | ||
1565 | 70eb082000-70eb085000 rw-p 00000000 00:00 0 [anon:bionic TLS] | ||
1566 | 70eb085000-70eb086000 ---p 00000000 00:00 0 [anon:bionic TLS guard] | ||
1567 | 70eb086000-70eb09d000 r-xp 00000000 fc:00 2604 /system/lib64/libz.so | ||
1568 | 70eb09d000-70eb0b5000 ---p 00000000 00:00 0 | ||
1569 | 70eb0b5000-70eb0b6000 r--p 0001f000 fc:00 2604 /system/lib64/libz.so | ||
1570 | 70eb0b6000-70eb0b7000 rw-p 00020000 fc:00 2604 /system/lib64/libz.so | ||
1571 | 70eb0b7000-70eb0bb000 r--s 00000000 fc:00 289 /system/fonts/NotoSansArmenian-Regular.ttf | ||
1572 | 70eb0bb000-70eb0bc000 ---p 00000000 00:00 0 [anon:thread signal stack guard] | ||
1573 | 70eb0bc000-70eb0c0000 rw-p 00000000 00:00 0 [anon:thread signal stack] | ||
1574 | 70eb0c0000-70eb0c1000 ---p 00000000 00:00 0 [anon:bionic TLS guard] | ||
1575 | 70eb0c1000-70eb0c4000 rw-p 00000000 00:00 0 [anon:bionic TLS] | ||
1576 | 70eb0c4000-70eb0c5000 ---p 00000000 00:00 0 [anon:bionic TLS guard] | ||
1577 | 70eb0c5000-70eb0c6000 ---p 00000000 00:00 0 [anon:thread signal stack guard] | ||
1578 | 70eb0c6000-70eb0ca000 rw-p 00000000 00:00 0 [anon:thread signal stack] | ||
1579 | 70eb0ca000-70eb0cb000 ---p 00000000 00:00 0 [anon:bionic TLS guard] | ||
1580 | 70eb0cb000-70eb0ce000 rw-p 00000000 00:00 0 [anon:bionic TLS] | ||
1581 | 70eb0ce000-70eb0cf000 ---p 00000000 00:00 0 [anon:bionic TLS guard] | ||
1582 | 70eb0cf000-70eb0ef000 rw-p 00000000 00:05 10270988 /dev/ashmem/dalvik-LinearAlloc (deleted) | ||
1583 | 70eb0ef000-70eb5bb000 r-xp 00000000 fc:00 2374 /system/lib64/libpdfium.so | ||
1584 | 70eb5bb000-70eb5cf000 ---p 00000000 00:00 0 | ||
1585 | 70eb5cf000-70eb5e6000 r--p 004d9000 fc:00 2374 /system/lib64/libpdfium.so | ||
1586 | 70eb5e6000-70eb5ea000 rw-p 004f0000 fc:00 2374 /system/lib64/libpdfium.so | ||
1587 | 70eb5ea000-70eb5f1000 rw-p 00000000 00:00 0 [anon:.bss] | ||
1588 | 70eb5f1000-70eb5f2000 r--s 00000000 fc:00 1094 /system/usr/hyphen-data/hyph-hi.hyb | ||
1589 | 70eb5f2000-70eb5f6000 rw-p 00000000 00:05 10270982 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1590 | 70eb5f6000-70eb5fa000 rw-p 00000000 00:05 10270981 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1591 | 70eb5fa000-70eb5fe000 rw-p 00000000 00:05 10270980 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1592 | 70eb5fe000-70eb602000 rw-p 00000000 00:05 10270979 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1593 | 70eb602000-70eb606000 rw-p 00000000 00:05 10270978 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1594 | 70eb606000-70eb60a000 rw-p 00000000 00:05 10270977 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1595 | 70eb60a000-70eb60e000 rw-p 00000000 00:05 10270976 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1596 | 70eb60e000-70eb612000 rw-p 00000000 00:05 10270975 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1597 | 70eb612000-70eb616000 rw-p 00000000 00:05 10270974 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1598 | 70eb616000-70eb61a000 r-xp 00000000 fc:00 2479 /system/lib64/libspeexresampler.so | ||
1599 | 70eb61a000-70eb635000 ---p 00000000 00:00 0 | ||
1600 | 70eb635000-70eb636000 r--p 0000f000 fc:00 2479 /system/lib64/libspeexresampler.so | ||
1601 | 70eb636000-70eb637000 rw-p 00010000 fc:00 2479 /system/lib64/libspeexresampler.so | ||
1602 | 70eb637000-70eb639000 r--s 00000000 fc:00 299 /system/fonts/NotoSansImperialAramaic-Regular.ttf | ||
1603 | 70eb639000-70eb63d000 rw-p 00000000 00:05 10270973 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1604 | 70eb63d000-70eb641000 rw-p 00000000 00:05 10270972 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1605 | 70eb641000-70eb645000 rw-p 00000000 00:05 10270971 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1606 | 70eb645000-70eb649000 rw-p 00000000 00:05 10270970 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1607 | 70eb649000-70eb64d000 rw-p 00000000 00:05 10270969 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1608 | 70eb64d000-70eb651000 rw-p 00000000 00:05 10270968 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1609 | 70eb651000-70eb655000 rw-p 00000000 00:05 10270967 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1610 | 70eb655000-70eb659000 rw-p 00000000 00:05 10270966 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1611 | 70eb659000-70eb65d000 rw-p 00000000 00:05 10270965 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1612 | 70eb65d000-70eb661000 rw-p 00000000 00:05 10270964 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1613 | 70eb661000-70eb6c5000 r-xp 00000000 fc:00 2461 /system/lib64/libhidl-gen-utils.so | ||
1614 | 70eb6c5000-70eb6df000 ---p 00000000 00:00 0 | ||
1615 | 70eb6df000-70eb6e1000 r--p 0006e000 fc:00 2461 /system/lib64/libhidl-gen-utils.so | ||
1616 | 70eb6e1000-70eb6e2000 rw-p 00070000 fc:00 2461 /system/lib64/libhidl-gen-utils.so | ||
1617 | 70eb6e2000-70eb6e6000 rw-p 00000000 00:05 10270963 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1618 | 70eb6e6000-70eb6ea000 rw-p 00000000 00:05 10270962 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1619 | 70eb6ea000-70eb6ee000 rw-p 00000000 00:05 10270961 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1620 | 70eb6ee000-70eb6f2000 rw-p 00000000 00:05 10270960 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1621 | 70eb6f2000-70eb6f6000 rw-p 00000000 00:05 10270959 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1622 | 70eb6f6000-70eb6fa000 rw-p 00000000 00:05 10270958 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1623 | 70eb6fa000-70eb6fe000 rw-p 00000000 00:05 10270957 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1624 | 70eb6fe000-70eb702000 rw-p 00000000 00:05 10270956 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1625 | 70eb702000-70eb706000 rw-p 00000000 00:05 10270955 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1626 | 70eb706000-70eb70a000 rw-p 00000000 00:05 10270954 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1627 | 70eb70a000-70eb70e000 rw-p 00000000 00:05 10270953 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1628 | 70eb70e000-70eb712000 rw-p 00000000 00:05 10270952 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1629 | 70eb712000-70eb71a000 r-xp 00000000 fc:00 2652 /system/lib64/libcamera_metadata.so | ||
1630 | 70eb71a000-70eb72f000 ---p 00000000 00:00 0 | ||
1631 | 70eb72f000-70eb730000 r--p 0000f000 fc:00 2652 /system/lib64/libcamera_metadata.so | ||
1632 | 70eb730000-70eb732000 rw-p 00010000 fc:00 2652 /system/lib64/libcamera_metadata.so | ||
1633 | 70eb732000-70eb734000 r--s 00000000 fc:00 131 /system/fonts/NotoSansHanunoo-Regular.ttf | ||
1634 | 70eb734000-70eb738000 rw-p 00000000 00:05 10270951 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1635 | 70eb738000-70eb73c000 rw-p 00000000 00:05 10270950 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1636 | 70eb73c000-70eb740000 rw-p 00000000 00:05 10270949 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1637 | 70eb740000-70eb744000 rw-p 00000000 00:05 10270948 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1638 | 70eb744000-70eb748000 rw-p 00000000 00:05 10270947 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1639 | 70eb748000-70eb74c000 rw-p 00000000 00:05 10270946 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1640 | 70eb74c000-70eb750000 rw-p 00000000 00:05 10270945 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1641 | 70eb750000-70eb754000 rw-p 00000000 00:05 10270944 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1642 | 70eb754000-70eb758000 rw-p 00000000 00:05 10270943 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1643 | 70eb758000-70eb75c000 rw-p 00000000 00:05 10270942 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1644 | 70eb75c000-70eb760000 rw-p 00000000 00:05 10270941 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1645 | 70eb760000-70eb764000 rw-p 00000000 00:05 10270940 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1646 | 70eb764000-70eb767000 rw-p 00000000 00:00 0 [anon:linker_alloc] | ||
1647 | 70eb767000-70eb768000 r--p 00000000 00:00 0 [anon:linker_alloc] | ||
1648 | 70eb768000-70eb76c000 rw-p 00000000 00:05 10270939 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1649 | 70eb76c000-70eb770000 rw-p 00000000 00:05 10270938 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1650 | 70eb770000-70eb771000 rw-p 00000000 00:00 0 [anon:linker_alloc] | ||
1651 | 70eb771000-70eb774000 r--s 00000000 fc:00 231 /system/fonts/NotoSansDeseret-Regular.ttf | ||
1652 | 70eb774000-70eb778000 rw-p 00000000 00:05 10270937 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1653 | 70eb778000-70eb77c000 rw-p 00000000 00:05 10270936 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1654 | 70eb77c000-70eb780000 rw-p 00000000 00:05 10270935 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1655 | 70eb780000-70eb784000 rw-p 00000000 00:05 10270934 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1656 | 70eb784000-70eb788000 rw-p 00000000 00:05 10270933 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1657 | 70eb788000-70eb78c000 rw-p 00000000 00:05 10270932 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1658 | 70eb78c000-70eb790000 rw-p 00000000 00:05 10270931 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1659 | 70eb790000-70eb794000 rw-p 00000000 00:05 10270930 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1660 | 70eb794000-70eb798000 rw-p 00000000 00:05 10270929 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1661 | 70eb798000-70eb79c000 rw-p 00000000 00:05 10270928 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1662 | 70eb79c000-70eb7a0000 rw-p 00000000 00:05 10270927 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1663 | 70eb7a0000-70eb7a1000 r--p 00000000 00:00 0 [anon:linker_alloc] | ||
1664 | 70eb7a1000-70eb7a3000 r--s 00000000 fc:00 176 /system/fonts/NotoSansGothic-Regular.ttf | ||
1665 | 70eb7a3000-70eb7a7000 rw-p 00000000 00:05 10270926 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1666 | 70eb7a7000-70eb7a8000 r--p 00000000 00:00 0 [anon:linker_alloc] | ||
1667 | 70eb7a8000-70eb7a9000 r--s 00000000 fc:00 1109 /system/usr/hyphen-data/hyph-gu.hyb | ||
1668 | 70eb7a9000-70eb7ad000 rw-p 00000000 00:05 10270925 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1669 | 70eb7ad000-70eb7ae000 r--p 00000000 00:00 0 [anon:linker_alloc] | ||
1670 | 70eb7ae000-70eb7af000 rw-p 00000000 00:00 0 [anon:linker_alloc] | ||
1671 | 70eb7af000-70eb7b0000 r--p 00000000 00:00 0 [anon:linker_alloc] | ||
1672 | 70eb7b0000-70eb7b2000 r--s 00000000 fc:00 191 /system/fonts/NotoSansCypriot-Regular.ttf | ||
1673 | 70eb7b2000-70eb7b6000 rw-p 00000000 00:05 10270924 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1674 | 70eb7b6000-70eb7ba000 rw-p 00000000 00:05 10270923 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1675 | 70eb7ba000-70eb7be000 rw-p 00000000 00:05 10270922 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1676 | 70eb7be000-70eb7c2000 rw-p 00000000 00:05 10270921 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1677 | 70eb7c2000-70eb7c6000 rw-p 00000000 00:05 10270920 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1678 | 70eb7c6000-70eb7ca000 rw-p 00000000 00:05 10270919 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1679 | 70eb7ca000-70eb7ce000 rw-p 00000000 00:05 10270918 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1680 | 70eb7ce000-70eb7d2000 rw-p 00000000 00:05 10270917 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1681 | 70eb7d2000-70eb7d6000 rw-p 00000000 00:05 10270916 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1682 | 70eb7d6000-70eb7d7000 rw-p 00000000 00:00 0 [anon:linker_alloc_small_objects] | ||
1683 | 70eb7d7000-70eb7db000 rw-p 00000000 00:05 10270915 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1684 | 70eb7db000-70eb7df000 rw-p 00000000 00:05 10270914 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1685 | 70eb7df000-70eb7e3000 rw-p 00000000 00:05 10270913 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1686 | 70eb7e3000-70eb7e7000 rw-p 00000000 00:05 10270912 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1687 | 70eb7e7000-70eb7e8000 r--p 00000000 00:00 0 [anon:linker_alloc] | ||
1688 | 70eb7e8000-70eb7ea000 r--s 00000000 fc:00 174 /system/fonts/NotoSansCarian-Regular.ttf | ||
1689 | 70eb7ea000-70eb7ee000 rw-p 00000000 00:05 10270911 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1690 | 70eb7ee000-70eb7f2000 rw-p 00000000 00:05 10270910 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1691 | 70eb7f2000-70eb7f6000 rw-p 00000000 00:05 10270909 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1692 | 70eb7f6000-70eb7f7000 rw-p 00000000 00:00 0 [anon:linker_alloc] | ||
1693 | 70eb7f7000-70eb7f8000 r--s 00000000 fc:00 1096 /system/usr/hyphen-data/hyph-eu.hyb | ||
1694 | 70eb7f8000-70eb7fc000 rw-p 00000000 00:05 10270908 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1695 | 70eb7fc000-70eb800000 rw-p 00000000 00:05 10270907 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1696 | 70eb800000-70eb804000 rw-p 00000000 00:05 10270906 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1697 | 70eb804000-70eb808000 rw-p 00000000 00:05 10270905 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1698 | 70eb808000-70eb80c000 rw-p 00000000 00:05 10270904 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1699 | 70eb80c000-70eb810000 rw-p 00000000 00:05 10270903 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1700 | 70eb810000-70eb814000 rw-p 00000000 00:05 10270902 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1701 | 70eb814000-70eb815000 rw-p 00000000 00:00 0 [anon:linker_alloc_vector] | ||
1702 | 70eb815000-70eb819000 rw-p 00000000 00:05 10270901 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1703 | 70eb819000-70eb81d000 rw-p 00000000 00:05 10270900 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1704 | 70eb81d000-70eb81e000 rw-p 00000000 00:00 0 [anon:linker_alloc] | ||
1705 | 70eb81e000-70eb822000 rw-p 00000000 00:05 10270899 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1706 | 70eb822000-70eb826000 rw-p 00000000 00:05 10270898 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1707 | 70eb826000-70eb82a000 rw-p 00000000 00:05 10270897 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1708 | 70eb82a000-70eb82e000 rw-p 00000000 00:05 10270896 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1709 | 70eb82e000-70eb832000 rw-p 00000000 00:05 10270895 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1710 | 70eb832000-70eb836000 rw-p 00000000 00:05 10270894 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1711 | 70eb836000-70eb837000 r--p 00000000 00:00 0 [anon:linker_alloc] | ||
1712 | 70eb837000-70eb83b000 rw-p 00000000 00:05 10270893 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1713 | 70eb83b000-70eb83f000 rw-p 00000000 00:05 10270892 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1714 | 70eb83f000-70eb843000 rw-p 00000000 00:05 10270891 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1715 | 70eb843000-70eb847000 rw-p 00000000 00:05 10270890 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1716 | 70eb847000-70eb84b000 rw-p 00000000 00:05 10270889 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1717 | 70eb84b000-70eb84f000 rw-p 00000000 00:05 10270888 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1718 | 70eb84f000-70eb850000 rw-p 00000000 00:00 0 [anon:linker_alloc] | ||
1719 | 70eb850000-70eb854000 rw-p 00000000 00:05 10270887 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1720 | 70eb854000-70eb858000 rw-p 00000000 00:05 10270886 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1721 | 70eb858000-70eb85c000 rw-p 00000000 00:05 10270885 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1722 | 70eb85c000-70eb860000 rw-p 00000000 00:05 10270884 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1723 | 70eb860000-70eb864000 rw-p 00000000 00:05 10270883 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1724 | 70eb864000-70eb868000 rw-p 00000000 00:05 10270882 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1725 | 70eb868000-70eb869000 r--p 00000000 00:00 0 [anon:linker_alloc] | ||
1726 | 70eb869000-70eb86d000 rw-p 00000000 00:05 10270881 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1727 | 70eb86d000-70eb871000 rw-p 00000000 00:05 10270880 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1728 | 70eb871000-70eb875000 rw-p 00000000 00:05 10270879 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1729 | 70eb875000-70eb879000 rw-p 00000000 00:05 10270878 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1730 | 70eb879000-70eb87d000 rw-p 00000000 00:05 10270877 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1731 | 70eb87d000-70eb881000 rw-p 00000000 00:05 10270876 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1732 | 70eb881000-70eb885000 rw-p 00000000 00:05 10270875 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1733 | 70eb885000-70eb889000 rw-p 00000000 00:05 10270874 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1734 | 70eb889000-70eb88d000 rw-p 00000000 00:05 10270873 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1735 | 70eb88d000-70eb891000 rw-p 00000000 00:05 10270872 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1736 | 70eb891000-70eb892000 r--p 00000000 00:00 0 [anon:linker_alloc] | ||
1737 | 70eb892000-70eb896000 rw-p 00000000 00:05 10270871 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1738 | 70eb896000-70eb89a000 rw-p 00000000 00:05 10270870 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1739 | 70eb89a000-70eb89b000 rw-p 00000000 00:00 0 [anon:linker_alloc_vector] | ||
1740 | 70eb89b000-70eb89c000 rw-p 00000000 00:00 0 [anon:linker_alloc_small_objects] | ||
1741 | 70eb89c000-70eb8a0000 rw-p 00000000 00:05 10270869 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1742 | 70eb8a0000-70eb8a4000 rw-p 00000000 00:05 10270868 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1743 | 70eb8a4000-70eb8a5000 r--p 00000000 00:00 0 [anon:atexit handlers] | ||
1744 | 70eb8a5000-70eb8a9000 rw-p 00000000 00:05 10270867 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1745 | 70eb8a9000-70eb8ad000 rw-p 00000000 00:05 10270866 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1746 | 70eb8ad000-70eb8b1000 rw-p 00000000 00:05 10270865 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1747 | 70eb8b1000-70eb8b5000 rw-p 00000000 00:05 10270864 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1748 | 70eb8b5000-70eb8b9000 rw-p 00000000 00:05 10270863 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1749 | 70eb8b9000-70eb8bd000 rw-p 00000000 00:05 10270862 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1750 | 70eb8bd000-70eb8be000 rw-p 00000000 00:00 0 [anon:linker_alloc] | ||
1751 | 70eb8be000-70eb8c1000 r--s 00000000 fc:00 168 /system/fonts/NotoSansAvestan-Regular.ttf | ||
1752 | 70eb8c1000-70eb8c5000 rw-p 00000000 00:05 10270861 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1753 | 70eb8c5000-70eb8c9000 rw-p 00000000 00:05 10270860 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1754 | 70eb8c9000-70eb8cd000 rw-p 00000000 00:05 10270859 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1755 | 70eb8cd000-70eb8d1000 rw-p 00000000 00:05 10270858 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1756 | 70eb8d1000-70eb8d5000 rw-p 00000000 00:05 10270857 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1757 | 70eb8d5000-70eb8d7000 r--p 00000000 00:00 0 [anon:linker_alloc] | ||
1758 | 70eb8d7000-70eb8db000 rw-p 00000000 00:05 10270856 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1759 | 70eb8db000-70eb8df000 rw-p 00000000 00:05 10270855 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1760 | 70eb8df000-70eb8e3000 rw-p 00000000 00:05 10270854 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1761 | 70eb8e3000-70eb8e7000 rw-p 00000000 00:05 10270853 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1762 | 70eb8e7000-70eb8eb000 rw-p 00000000 00:05 10270852 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1763 | 70eb8eb000-70eb8ec000 r--p 00000000 00:00 0 [anon:linker_alloc] | ||
1764 | 70eb8ec000-70eb8ed000 r--s 00000000 fc:00 1099 /system/usr/hyphen-data/hyph-bn.hyb | ||
1765 | 70eb8ed000-70eb8f1000 rw-p 00000000 00:05 10270851 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1766 | 70eb8f1000-70eb8f5000 rw-p 00000000 00:05 10270850 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1767 | 70eb8f5000-70eb8f9000 rw-p 00000000 00:05 10270849 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1768 | 70eb8f9000-70eb8fd000 rw-p 00000000 00:05 10270848 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1769 | 70eb8fd000-70eb901000 rw-p 00000000 00:05 10270847 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1770 | 70eb901000-70eb905000 rw-p 00000000 00:05 10270846 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1771 | 70eb905000-70eb909000 rw-p 00000000 00:05 10270845 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1772 | 70eb909000-70eb90d000 rw-p 00000000 00:05 10270844 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1773 | 70eb90d000-70eb911000 rw-p 00000000 00:05 10270843 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1774 | 70eb911000-70eb915000 rw-p 00000000 00:05 10270842 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1775 | 70eb915000-70eb916000 rw-p 00000000 00:00 0 [anon:linker_alloc] | ||
1776 | 70eb916000-70eb917000 r--s 00000000 fc:00 1114 /system/usr/hyphen-data/hyph-bg.hyb | ||
1777 | 70eb917000-70eb91b000 rw-p 00000000 00:05 10270841 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1778 | 70eb91b000-70eb91c000 r--p 00000000 00:00 0 [anon:linker_alloc] | ||
1779 | 70eb91c000-70eb91d000 r--s 00000000 fc:00 1133 /system/usr/hyphen-data/hyph-as.hyb | ||
1780 | 70eb91d000-70eb921000 rw-p 00000000 00:05 10270840 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1781 | 70eb921000-70eb925000 rw-p 00000000 00:05 10270839 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1782 | 70eb925000-70eb926000 rw-p 00000000 00:00 0 [anon:linker_alloc_small_objects] | ||
1783 | 70eb926000-70eb927000 r--p 00000000 00:00 0 [anon:linker_alloc] | ||
1784 | 70eb927000-70eb929000 r--s 00000000 fc:00 203 /system/fonts/NotoSansBuhid-Regular.ttf | ||
1785 | 70eb929000-70eb92d000 rw-p 00000000 00:05 10270838 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1786 | 70eb92d000-70eb931000 rw-p 00000000 00:05 10270837 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1787 | 70eb931000-70eb935000 rw-p 00000000 00:05 10270836 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1788 | 70eb935000-70eb939000 rw-p 00000000 00:05 10270835 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1789 | 70eb939000-70eb93d000 rw-p 00000000 00:05 10270834 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1790 | 70eb93d000-70eb941000 rw-p 00000000 00:05 10270833 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1791 | 70eb941000-70eb945000 rw-p 00000000 00:05 10270832 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1792 | 70eb945000-70eb949000 rw-p 00000000 00:05 10270831 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1793 | 70eb949000-70eb94d000 rw-p 00000000 00:05 10270830 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1794 | 70eb94d000-70eb951000 rw-p 00000000 00:05 10270829 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1795 | 70eb951000-70eb991000 rw-p 00000000 00:05 10270722 /dev/ashmem/dalvik-mark stack (deleted) | ||
1796 | 70eb991000-70eb992000 rw-p 00000000 00:00 0 [anon:linker_alloc] | ||
1797 | 70eb992000-70eb996000 rw-p 00000000 00:05 10270828 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1798 | 70eb996000-70eb99a000 rw-p 00000000 00:05 10270827 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1799 | 70eb99a000-70eb99e000 rw-p 00000000 00:05 10270826 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1800 | 70eb99e000-70eb9a2000 rw-p 00000000 00:05 10270825 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1801 | 70eb9a2000-70eb9a4000 r--p 00000000 00:00 0 [anon:linker_alloc] | ||
1802 | 70eb9a4000-70eb9a8000 rw-p 00000000 00:05 10270824 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1803 | 70eb9a8000-70eb9ac000 rw-p 00000000 00:05 10270823 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1804 | 70eb9ac000-70eb9b0000 rw-p 00000000 00:05 10270822 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1805 | 70eb9b0000-70eb9b1000 r--p 00000000 00:00 0 [anon:linker_alloc] | ||
1806 | 70eb9b1000-70eb9b2000 r--s 00021000 fc:01 1180 /vendor/overlay/framework-res__auto_generated_rro.apk | ||
1807 | 70eb9b2000-70eb9b6000 rw-p 00000000 00:05 10270821 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1808 | 70eb9b6000-70eb9ba000 rw-p 00000000 00:05 10270820 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1809 | 70eb9ba000-70eb9be000 rw-p 00000000 00:05 10270819 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1810 | 70eb9be000-70eb9c2000 rw-p 00000000 00:05 10270818 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1811 | 70eb9c2000-70eb9c6000 rw-p 00000000 00:05 10270817 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1812 | 70eb9c6000-70eb9ca000 rw-p 00000000 00:05 10270816 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1813 | 70eb9ca000-70eb9ce000 rw-p 00000000 00:05 10270815 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1814 | 70eb9ce000-70eb9cf000 rw-p 00000000 00:00 0 [anon:linker_alloc] | ||
1815 | 70eb9cf000-70eb9d1000 r--s 00000000 fc:00 213 /system/fonts/NotoSansBuginese-Regular.ttf | ||
1816 | 70eb9d1000-70eb9d5000 rw-p 00000000 00:05 10270814 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1817 | 70eb9d5000-70eb9d9000 rw-p 00000000 00:05 10270813 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1818 | 70eb9d9000-70eb9dd000 rw-p 00000000 00:05 10270812 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1819 | 70eb9dd000-70eb9e1000 rw-p 00000000 00:05 10270811 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1820 | 70eb9e1000-70eb9e5000 rw-p 00000000 00:05 10270810 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1821 | 70eb9e5000-70eb9e9000 rw-p 00000000 00:05 10270809 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1822 | 70eb9e9000-70eb9ed000 rw-p 00000000 00:05 10270808 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1823 | 70eb9ed000-70eb9f1000 rw-p 00000000 00:05 10270807 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1824 | 70eb9f1000-70eb9f5000 rw-p 00000000 00:05 10270806 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1825 | 70eb9f5000-70eb9f6000 r--p 00000000 00:00 0 [anon:linker_alloc] | ||
1826 | 70eb9f6000-70eb9f8000 rw-p 00000000 00:05 10271002 /dev/ashmem/dalvik-indirect ref table (deleted) | ||
1827 | 70eb9f8000-70eb9fc000 rw-p 00000000 00:05 10270805 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1828 | 70eb9fc000-70eb9fd000 rw-p 00000000 00:00 0 [anon:linker_alloc] | ||
1829 | 70eb9fd000-70eb9ff000 rw-p 00000000 00:05 10270999 /dev/ashmem/dalvik-indirect ref table (deleted) | ||
1830 | 70eb9ff000-70eba00000 r--s 00000000 fc:00 983 /system/framework/com.google.vr.platform.jar | ||
1831 | 70eba00000-70eba04000 rw-p 00000000 00:05 10270804 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1832 | 70eba04000-70eba08000 rw-p 00000000 00:05 10270803 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1833 | 70eba08000-70eba0c000 rw-p 00000000 00:05 10270802 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1834 | 70eba0c000-70eba10000 rw-p 00000000 00:05 10270801 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1835 | 70eba10000-70eba14000 rw-p 00000000 00:05 10270800 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1836 | 70eba14000-70eba18000 rw-p 00000000 00:05 10270799 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1837 | 70eba18000-70eba1c000 rw-p 00000000 00:05 10270798 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1838 | 70eba1c000-70eba20000 rw-p 00000000 00:05 10270797 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1839 | 70eba20000-70eba24000 rw-p 00000000 00:05 10270796 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1840 | 70eba24000-70eba28000 rw-p 00000000 00:05 10270795 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1841 | 70eba28000-70eba2c000 rw-p 00000000 00:05 10270794 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1842 | 70eba2c000-70eba2d000 rw-p 00000000 00:00 0 [anon:linker_alloc] | ||
1843 | 70eba2d000-70eba2e000 r--s 00000000 fc:00 881 /system/framework/android.test.base.jar | ||
1844 | 70eba2e000-70eba2f000 r--s 00000000 fc:00 707 /system/framework/framework-oahl-backward-compatibility.jar | ||
1845 | 70eba2f000-70eba30000 r--s 00000000 fc:00 705 /system/framework/android.hidl.manager-V1.0-java.jar | ||
1846 | 70eba30000-70eba34000 rw-p 00000000 00:05 10270793 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1847 | 70eba34000-70eba38000 rw-p 00000000 00:05 10270792 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1848 | 70eba38000-70eba3c000 rw-p 00000000 00:05 10270791 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1849 | 70eba3c000-70eba40000 rw-p 00000000 00:05 10270790 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1850 | 70eba40000-70eba44000 rw-p 00000000 00:05 10270789 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1851 | 70eba44000-70eba48000 rw-p 00000000 00:05 10270788 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1852 | 70eba48000-70eba4c000 rw-p 00000000 00:05 10270787 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1853 | 70eba4c000-70eba50000 rw-p 00000000 00:05 10270786 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1854 | 70eba50000-70eba52000 r--p 00000000 00:00 0 [anon:linker_alloc] | ||
1855 | 70eba52000-70eba53000 r--s 00000000 fc:00 971 /system/framework/android.hidl.base-V1.0-java.jar | ||
1856 | 70eba53000-70eba57000 rw-p 00000000 00:05 10270785 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1857 | 70eba57000-70eba5b000 rw-p 00000000 00:05 10270784 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1858 | 70eba5b000-70eba5f000 rw-p 00000000 00:05 10270783 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1859 | 70eba5f000-70eba63000 rw-p 00000000 00:05 10270782 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1860 | 70eba63000-70eba64000 rw-p 00000000 00:00 0 [anon:linker_alloc] | ||
1861 | 70eba64000-70eba65000 r--s 00000000 fc:00 889 /system/framework/ims-common.jar | ||
1862 | 70eba65000-70eba69000 rw-p 00000000 00:05 10270781 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1863 | 70eba69000-70eba6d000 rw-p 00000000 00:05 10270780 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1864 | 70eba6d000-70eba71000 rw-p 00000000 00:05 10270779 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1865 | 70eba71000-70eba75000 rw-p 00000000 00:05 10270778 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1866 | 70eba75000-70eba95000 rw-p 00000000 00:05 10267647 /dev/ashmem/dalvik-large marked objects (deleted) | ||
1867 | 70eba95000-70ebab5000 rw-p 00000000 00:05 10267646 /dev/ashmem/dalvik-large live objects (deleted) | ||
1868 | 70ebab5000-70ebab6000 r--p 00000000 00:00 0 [anon:linker_alloc] | ||
1869 | 70ebab6000-70ebab7000 rw-p 00000000 00:00 0 [anon:linker_alloc] | ||
1870 | 70ebab7000-70ebabb000 rw-p 00000000 00:05 10270777 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1871 | 70ebabb000-70ebadb000 r--s 00000000 00:10 16603 /dev/__properties__/u:object_r:exported_fingerprint_prop:s0 | ||
1872 | 70ebadb000-70ebadc000 r--p 00000000 00:00 0 [anon:linker_alloc] | ||
1873 | 70ebadc000-70ebadd000 r--s 00000000 fc:00 878 /system/framework/voip-common.jar | ||
1874 | 70ebadd000-70ebadf000 rw-p 00000000 00:05 10270995 /dev/ashmem/dalvik-indirect ref table (deleted) | ||
1875 | 70ebadf000-70ebae3000 rw-p 00000000 00:05 10270776 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1876 | 70ebae3000-70ebae7000 rw-p 00000000 00:05 10270775 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1877 | 70ebae7000-70ebaeb000 rw-p 00000000 00:05 10270774 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1878 | 70ebaeb000-70ebaef000 rw-p 00000000 00:05 10270773 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1879 | 70ebaef000-70ebb0f000 r--s 00000000 00:10 16582 /dev/__properties__/u:object_r:debug_prop:s0 | ||
1880 | 70ebb0f000-70ebb10000 rw-p 00000000 00:00 0 [anon:linker_alloc] | ||
1881 | 70ebb10000-70ebb11000 r--s 00000000 fc:00 703 /system/framework/telephony-common.jar | ||
1882 | 70ebb11000-70ebb13000 rw-p 00000000 00:05 10270994 /dev/ashmem/dalvik-indirect ref table (deleted) | ||
1883 | 70ebb13000-70ebb17000 rw-p 00000000 00:05 10270772 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1884 | 70ebb17000-70ebb19000 r--p 00000000 00:00 0 [anon:linker_alloc] | ||
1885 | 70ebb19000-70ebb1d000 rw-p 00000000 00:05 10270771 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1886 | 70ebb1d000-70ebb3d000 r--s 00000000 00:10 16600 /dev/__properties__/u:object_r:exported_default_prop:s0 | ||
1887 | 70ebb3d000-70ebb5d000 r--s 00000000 00:10 16650 /dev/__properties__/u:object_r:system_prop:s0 | ||
1888 | 70ebb5d000-70ebb7d000 r--s 00000000 00:10 16610 /dev/__properties__/u:object_r:exported_vold_prop:s0 | ||
1889 | 70ebb7d000-70ebb9d000 r--s 00000000 00:10 16598 /dev/__properties__/u:object_r:exported_config_prop:s0 | ||
1890 | 70ebb9d000-70ebb9e000 rw-p 00000000 00:00 0 [anon:linker_alloc] | ||
1891 | 70ebb9e000-70ebba2000 rw-p 00000000 00:05 10270770 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1892 | 70ebba2000-70ebba6000 rw-p 00000000 00:05 10270769 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1893 | 70ebba6000-70ebba7000 r--p 00000000 00:00 0 [anon:linker_alloc] | ||
1894 | 70ebba7000-70ebba8000 r--s 00000000 fc:00 1004 /system/framework/framework.jar | ||
1895 | 70ebba8000-70ebbac000 rw-p 00000000 00:05 10270768 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1896 | 70ebbac000-70ebbb0000 rw-p 00000000 00:05 10270767 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1897 | 70ebbb0000-70ebbb4000 rw-p 00000000 00:05 10270766 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1898 | 70ebbb4000-70ebbb8000 rw-p 00000000 00:05 10270765 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1899 | 70ebbb8000-70ebbbc000 rw-p 00000000 00:05 10270764 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1900 | 70ebbbc000-70ebbc0000 rw-p 00000000 00:05 10270763 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1901 | 70ebbc0000-70ebbc4000 rw-p 00000000 00:05 10270762 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1902 | 70ebbc4000-70ebbe4000 r--s 00000000 00:10 16581 /dev/__properties__/u:object_r:dalvik_prop:s0 | ||
1903 | 70ebbe4000-70ebbe5000 rw-p 00000000 00:00 0 [anon:linker_alloc] | ||
1904 | 70ebbe5000-70ebbe6000 r--s 00004000 fc:00 877 /system/framework/apache-xml.jar | ||
1905 | 70ebbe6000-70ebbe8000 rw-p 00000000 00:05 10270993 /dev/ashmem/dalvik-indirect ref table (deleted) | ||
1906 | 70ebbe8000-70ebbec000 rw-p 00000000 00:05 10270761 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1907 | 70ebbec000-70ebbf0000 rw-p 00000000 00:05 10270760 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1908 | 70ebbf0000-70ebbf4000 rw-p 00000000 00:05 10270759 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1909 | 70ebbf4000-70ebbf8000 rw-p 00000000 00:05 10270758 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1910 | 70ebbf8000-70ebbf9000 r--p 00000000 00:00 0 [anon:linker_alloc] | ||
1911 | 70ebbf9000-70ebbfa000 r--s 00000000 fc:00 968 /system/framework/bouncycastle.jar | ||
1912 | 70ebbfa000-70ebbfc000 rw-p 00000000 00:05 10270992 /dev/ashmem/dalvik-indirect ref table (deleted) | ||
1913 | 70ebbfc000-70ebc00000 rw-p 00000000 00:05 10270757 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1914 | 70ebc00000-70ebc04000 rw-p 00000000 00:05 10270756 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1915 | 70ebc04000-70ebc08000 rw-p 00000000 00:05 10270755 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1916 | 70ebc08000-70ebc0c000 rw-p 00000000 00:05 10270754 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1917 | 70ebc0c000-70ebc10000 rw-p 00000000 00:05 10270753 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1918 | 70ebc10000-70ebc14000 rw-p 00000000 00:05 10270752 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1919 | 70ebc14000-70ebc15000 rw-p 00000000 00:00 0 [anon:linker_alloc] | ||
1920 | 70ebc15000-70ebc16000 r--s 00000000 fc:00 960 /system/framework/okhttp.jar | ||
1921 | 70ebc16000-70ebc1a000 rw-p 00000000 00:05 10270751 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1922 | 70ebc1a000-70ebc1e000 rw-p 00000000 00:05 10270750 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1923 | 70ebc1e000-70ebc3e000 r--s 00000000 00:10 16584 /dev/__properties__/u:object_r:default_prop:s0 | ||
1924 | 70ebc3e000-70ebc3f000 r--p 00000000 00:00 0 [anon:linker_alloc] | ||
1925 | 70ebc3f000-70ebc40000 r--s 00000000 fc:00 974 /system/framework/conscrypt.jar | ||
1926 | 70ebc40000-70ebc42000 rw-p 00000000 00:05 10269719 /dev/ashmem/dalvik-indirect ref table (deleted) | ||
1927 | 70ebc42000-70ebc46000 rw-p 00000000 00:05 10270749 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1928 | 70ebc46000-70ebc4a000 rw-p 00000000 00:05 10270748 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1929 | 70ebc4a000-70ebc4e000 rw-p 00000000 00:05 10270747 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1930 | 70ebc4e000-70ebc4f000 rw-p 00000000 00:00 0 [anon:linker_alloc] | ||
1931 | 70ebc4f000-70ebc51000 rw-p 00000000 00:05 10269718 /dev/ashmem/dalvik-indirect ref table (deleted) | ||
1932 | 70ebc51000-70ebc55000 rw-p 00000000 00:05 10270746 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1933 | 70ebc55000-70ebc59000 rw-p 00000000 00:05 10270745 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1934 | 70ebc59000-70ebc5d000 rw-p 00000000 00:05 10270744 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1935 | 70ebc5d000-70ebc7d000 r--s 00000000 00:10 16599 /dev/__properties__/u:object_r:exported_dalvik_prop:s0 | ||
1936 | 70ebc7d000-70ebc7e000 rw-p 00000000 00:00 0 [anon:linker_alloc] | ||
1937 | 70ebc7e000-70ebc7f000 r--p 00000000 00:00 0 [anon:linker_alloc] | ||
1938 | 70ebc7f000-70ebc80000 r--s 00004000 fc:00 963 /system/framework/core-libart.jar | ||
1939 | 70ebc80000-70ebc81000 r--p 00000000 00:00 0 [anon:linker_alloc] | ||
1940 | 70ebc81000-70ebc85000 rw-p 00000000 00:05 10270743 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1941 | 70ebc85000-70ebc89000 rw-p 00000000 00:05 10270742 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1942 | 70ebc89000-70ebc8a000 rw-p 00000000 00:00 0 [anon:linker_alloc_small_objects] | ||
1943 | 70ebc8a000-70ebc8c000 r--p 00000000 00:00 0 [anon:linker_alloc] | ||
1944 | 70ebc8c000-70ebc8d000 r--s 0001e000 fc:00 699 /system/framework/core-oj.jar | ||
1945 | 70ebc8d000-70ebc91000 rw-p 00000000 00:05 10270741 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1946 | 70ebc91000-70ebc95000 rw-p 00000000 00:05 10270740 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1947 | 70ebc95000-70ebc99000 rw-p 00000000 00:05 10270739 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1948 | 70ebc99000-70ebc9b000 r--p 00000000 00:00 0 [anon:linker_alloc] | ||
1949 | 70ebc9b000-70ebc9c000 rw-p 00000000 00:00 0 [anon:linker_alloc] | ||
1950 | 70ebc9c000-70ebca0000 rw-p 00000000 00:05 10270738 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1951 | 70ebca0000-70ebca4000 rw-p 00000000 00:05 10270737 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1952 | 70ebca4000-70ebca8000 rw-p 00000000 00:05 10270736 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1953 | 70ebca8000-70ebcac000 rw-p 00000000 00:05 10270735 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1954 | 70ebcac000-70ebcb0000 rw-p 00000000 00:05 10270734 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1955 | 70ebcb0000-70ebcd0000 r--s 00000000 00:10 16592 /dev/__properties__/u:object_r:exported2_system_prop:s0 | ||
1956 | 70ebcd0000-70ebcd1000 rw-p 00000000 00:00 0 [anon:linker_alloc] | ||
1957 | 70ebcd1000-70ebcd5000 rw-p 00000000 00:05 10270733 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1958 | 70ebcd5000-70ebcd9000 rw-p 00000000 00:05 10270732 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1959 | 70ebcd9000-70ebcdd000 rw-p 00000000 00:05 10270731 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1960 | 70ebcdd000-70ebce1000 rw-p 00000000 00:05 10270730 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1961 | 70ebce1000-70ebce5000 rw-p 00000000 00:05 10270729 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1962 | 70ebce5000-70ebce9000 rw-p 00000000 00:05 10270728 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1963 | 70ebce9000-70ebcea000 r--p 00000000 00:00 0 [anon:linker_alloc] | ||
1964 | 70ebcea000-70ebcec000 rw-p 00000000 00:05 10270987 /dev/ashmem/dalvik-indirect ref table (deleted) | ||
1965 | 70ebcec000-70ebcf9000 r--p 00646000 103:1d 639532 /data/dalvik-cache/arm64/system@framework@boot-framework.art | ||
1966 | 70ebcf9000-70ebd19000 r--s 00000000 00:10 16620 /dev/__properties__/u:object_r:log_tag_prop:s0 | ||
1967 | 70ebd19000-70ebd39000 r--s 00000000 00:10 16621 /dev/__properties__/u:object_r:logd_prop:s0 | ||
1968 | 70ebd39000-70ebd3a000 rw-p 00000000 00:00 0 [anon:linker_alloc] | ||
1969 | 70ebd3a000-70ebd3b000 r--p 00000000 00:00 0 [anon:linker_alloc] | ||
1970 | 70ebd3b000-70ebd3f000 rw-p 00000000 00:05 10270727 /dev/ashmem/dalvik-thread local mark stack (deleted) | ||
1971 | 70ebd3f000-70ebd40000 r--p 00002000 103:1d 639556 /data/dalvik-cache/arm64/system@framework@boot-com.google.vr.platform.art | ||
1972 | 70ebd40000-70ebd41000 r--p 00005000 103:1d 639553 /data/dalvik-cache/arm64/system@framework@boot-android.test.base.art | ||
1973 | 70ebd41000-70ebd42000 r--p 00000000 00:00 0 [anon:linker_alloc] | ||
1974 | 70ebd42000-70ebd43000 r--p 00001000 103:1d 639550 /data/dalvik-cache/arm64/system@framework@boot-framework-oahl-backward-compatibility.art | ||
1975 | 70ebd43000-70ebd44000 r--p 00005000 103:1d 639547 /data/dalvik-cache/arm64/system@framework@boot-android.hidl.manager-V1.0-java.art | ||
1976 | 70ebd44000-70ebd45000 r--p 00003000 103:1d 639544 /data/dalvik-cache/arm64/system@framework@boot-android.hidl.base-V1.0-java.art | ||
1977 | 70ebd45000-70ebd46000 r--p 00000000 00:00 0 [anon:linker_alloc] | ||
1978 | 70ebd46000-70ebd47000 r--p 0000f000 103:1d 639541 /data/dalvik-cache/arm64/system@framework@boot-ims-common.art | ||
1979 | 70ebd47000-70ebd48000 r--p 0000d000 103:1d 639538 /data/dalvik-cache/arm64/system@framework@boot-voip-common.art | ||
1980 | 70ebd48000-70ebd4a000 r--p 0005e000 103:1d 639535 /data/dalvik-cache/arm64/system@framework@boot-telephony-common.art | ||
1981 | 70ebd4a000-70ebd4b000 r--p 00040000 103:1d 639529 /data/dalvik-cache/arm64/system@framework@boot-ext.art | ||
1982 | 70ebd4b000-70ebd4c000 r--p 0004a000 103:1d 639526 /data/dalvik-cache/arm64/system@framework@boot-apache-xml.art | ||
1983 | 70ebd4c000-70ebd4d000 r--p 00046000 103:1d 639523 /data/dalvik-cache/arm64/system@framework@boot-bouncycastle.art | ||
1984 | 70ebd4d000-70ebd4e000 r--p 00000000 00:00 0 [anon:linker_alloc] | ||
1985 | 70ebd4e000-70ebd53000 r--p 00225000 103:1d 639511 /data/dalvik-cache/arm64/system@framework@boot.art | ||
1986 | 70ebd53000-70ebd5a000 rw-p 00000000 fc:00 583 /system/etc/event-log-tags | ||
1987 | 70ebd5a000-70ebd5b000 r--p 00000000 00:00 0 [anon:linker_alloc] | ||
1988 | 70ebd5b000-70ebd5c000 r--p 0002e000 103:1d 639520 /data/dalvik-cache/arm64/system@framework@boot-okhttp.art | ||
1989 | 70ebd5c000-70ebd5d000 r--p 00035000 103:1d 639517 /data/dalvik-cache/arm64/system@framework@boot-conscrypt.art | ||
1990 | 70ebd5d000-70ebd5f000 r--p 000d0000 103:1d 639514 /data/dalvik-cache/arm64/system@framework@boot-core-libart.art | ||
1991 | 70ebd5f000-70ebd62000 r--p 00000000 00:00 0 [anon:atexit handlers] | ||
1992 | 70ebd62000-70ebd63000 rw-p 00000000 00:00 0 | ||
1993 | 70ebd63000-70ebd83000 r--s 00000000 00:10 16590 /dev/__properties__/u:object_r:exported2_default_prop:s0 | ||
1994 | 70ebd83000-70ebd84000 rw-p 00000000 00:00 0 [anon:linker_alloc] | ||
1995 | 70ebd84000-70ebd89000 rw-p 00000000 00:00 0 | ||
1996 | 70ebd89000-70ebda9000 r--s 00000000 00:10 16669 /dev/__properties__/properties_serial | ||
1997 | 70ebda9000-70ebdb3000 r--s 00000000 00:10 16560 /dev/__properties__/property_info | ||
1998 | 70ebdb3000-70ebdb4000 rw-p 00000000 00:00 0 [anon:linker_alloc_vector] | ||
1999 | 70ebdb4000-70ebdb5000 rw-p 00000000 00:00 0 [anon:linker_alloc_small_objects] | ||
2000 | 70ebdb5000-70ebdb7000 rw-p 00000000 00:00 0 [anon:System property context nodes] | ||
2001 | 70ebdb7000-70ebdb8000 rw-p 00000000 00:00 0 [anon:linker_alloc_vector] | ||
2002 | 70ebdb8000-70ebdba000 rw-p 00000000 00:00 0 [anon:linker_alloc_small_objects] | ||
2003 | 70ebdba000-70ebdbb000 rw-p 00000000 00:00 0 [anon:linker_alloc] | ||
2004 | 70ebdbb000-70ebdbd000 rw-p 00000000 00:00 0 [anon:linker_alloc_small_objects] | ||
2005 | 70ebdbd000-70ebdbe000 r--p 00000000 00:00 0 [anon:atexit handlers] | ||
2006 | 70ebdbe000-70ebdbf000 r--p 00000000 00:00 0 [anon:linker_alloc] | ||
2007 | 70ebdbf000-70ebdc0000 rw-p 00000000 00:00 0 [anon:linker_alloc_small_objects] | ||
2008 | 70ebdc0000-70ebdc1000 rw-p 00000000 00:00 0 [anon:linker_alloc_vector] | ||
2009 | 70ebdc1000-70ebdc2000 rw-p 00000000 00:00 0 [anon:linker_alloc_small_objects] | ||
2010 | 70ebdc2000-70ebdc3000 rw-p 00000000 00:00 0 [anon:linker_alloc_vector] | ||
2011 | 70ebdc3000-70ebdc5000 rw-p 00000000 00:00 0 [anon:linker_alloc_small_objects] | ||
2012 | 70ebdc5000-70ebde5000 r--s 00000000 00:10 16600 /dev/__properties__/u:object_r:exported_default_prop:s0 | ||
2013 | 70ebde5000-70ebde6000 rw-p 00000000 00:00 0 [anon:linker_alloc_small_objects] | ||
2014 | 70ebde6000-70ebde8000 r--p 00000000 00:00 0 [anon:linker_alloc] | ||
2015 | 70ebde8000-70ebe08000 r--s 00000000 00:10 16582 /dev/__properties__/u:object_r:debug_prop:s0 | ||
2016 | 70ebe08000-70ebe09000 ---p 00000000 00:00 0 | ||
2017 | 70ebe09000-70ebe0a000 rw-p 00000000 00:00 0 | ||
2018 | 70ebe0a000-70ebe0b000 ---p 00000000 00:00 0 | ||
2019 | 70ebe0b000-70ebe2b000 r--s 00000000 00:10 16669 /dev/__properties__/properties_serial | ||
2020 | 70ebe2b000-70ebe2d000 rw-p 00000000 00:00 0 [anon:System property context nodes] | ||
2021 | 70ebe2d000-70ebf55000 r-xp 00000000 fc:00 3184 /system/bin/linker64 | ||
2022 | 70ebf55000-70ebf5f000 r--s 00000000 00:10 16560 /dev/__properties__/property_info | ||
2023 | 70ebf5f000-70ebf60000 r--p 00000000 00:00 0 [anon:linker_alloc] | ||
2024 | 70ebf60000-70ebf61000 rw-p 00000000 00:00 0 [anon:linker_alloc_vector] | ||
2025 | 70ebf61000-70ebf62000 rw-p 00000000 00:00 0 [anon:linker_alloc_small_objects] | ||
2026 | 70ebf62000-70ebf63000 rw-p 00000000 00:00 0 [anon:arc4random data] | ||
2027 | 70ebf63000-70ebf64000 rw-p 00000000 00:00 0 [anon:linker_alloc_small_objects] | ||
2028 | 70ebf64000-70ebf65000 r--p 00000000 00:00 0 [anon:atexit handlers] | ||
2029 | 70ebf65000-70ebf66000 ---p 00000000 00:00 0 [anon:thread signal stack guard] | ||
2030 | 70ebf66000-70ebf6a000 rw-p 00000000 00:00 0 [anon:thread signal stack] | ||
2031 | 70ebf6a000-70ebf6b000 rw-p 00000000 00:00 0 [anon:arc4random data] | ||
2032 | 70ebf6b000-70ebf6c000 ---p 00000000 00:00 0 [anon:bionic TLS guard] | ||
2033 | 70ebf6c000-70ebf6f000 rw-p 00000000 00:00 0 [anon:bionic TLS] | ||
2034 | 70ebf6f000-70ebf70000 ---p 00000000 00:00 0 [anon:bionic TLS guard] | ||
2035 | 70ebf70000-70ebf71000 r--p 00000000 00:00 0 [vvar] | ||
2036 | 70ebf71000-70ebf72000 r-xp 00000000 00:00 0 [vdso] | ||
2037 | 70ebf72000-70ebf7d000 r--p 00135000 fc:00 3184 /system/bin/linker64 | ||
2038 | 70ebf7d000-70ebf7e000 rw-p 00140000 fc:00 3184 /system/bin/linker64 | ||
2039 | 70ebf7e000-70ebf81000 rw-p 00000000 00:00 0 | ||
2040 | 70ebf81000-70ebf82000 r--p 00000000 00:00 0 | ||
2041 | 70ebf82000-70ebf89000 rw-p 00000000 00:00 0 | ||
2042 | 7fc7df1000-7fc7df2000 ---p 00000000 00:00 0 | ||
2043 | 7fc7df2000-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 | // ========================================================== | ||
20 | cc_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 @@ | |||
1 | bookatz@google.com | ||
2 | joeo@google.com | ||
3 | yaochen@google.com | ||
4 | yanglu@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 | ||
23 | extern "C" { | ||
24 | #endif | ||
25 | void reset_log_context(android_log_context ctx); | ||
26 | int 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 | */ | ||
40 | class 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 | |||
24 | typedef 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 | |||
40 | extern struct android_log_transport_write statsdLoggerWrite; | ||
41 | |||
42 | static int __write_to_statsd_init(struct iovec* vec, size_t nr); | ||
43 | static 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. | ||
47 | void 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 | |||
67 | int 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 | |||
102 | int 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 */ | ||
123 | static 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 | |||
133 | static 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 | |||
160 | static 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 | |||
40 | static pthread_mutex_t log_init_lock = PTHREAD_MUTEX_INITIALIZER; | ||
41 | |||
42 | void 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 | |||
50 | int statd_writer_trylock() { | ||
51 | return pthread_mutex_trylock(&log_init_lock); | ||
52 | } | ||
53 | |||
54 | void statsd_writer_init_unlock() { | ||
55 | pthread_mutex_unlock(&log_init_lock); | ||
56 | } | ||
57 | |||
58 | static int statsdAvailable(); | ||
59 | static int statsdOpen(); | ||
60 | static void statsdClose(); | ||
61 | static int statsdWrite(struct timespec* ts, struct iovec* vec, size_t nr); | ||
62 | |||
63 | struct 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 */ | ||
73 | static 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 | |||
113 | static void __statsdClose(int negative_errno) { | ||
114 | int sock = atomic_exchange(&statsdLoggerWrite.sock, negative_errno); | ||
115 | if (sock >= 0) { | ||
116 | close(sock); | ||
117 | } | ||
118 | } | ||
119 | |||
120 | static void statsdClose() { | ||
121 | __statsdClose(-EBADF); | ||
122 | } | ||
123 | |||
124 | static 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 | |||
134 | static 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 | */ | ||
29 | void statsd_writer_init_lock(); | ||
30 | int statsd_writer_init_trylock(); | ||
31 | void statsd_writer_init_unlock(); | ||
32 | |||
33 | struct 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 @@ | |||
1 | cc_library_headers { | 1 | cc_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. |
163 | bool Elf::Step(uint64_t rel_pc, uint64_t adjusted_rel_pc, uint64_t elf_offset, Regs* regs, | 163 | bool 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'. | ||
61 | static 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 | |||
162 | bool Maps::Parse() { | 61 | bool 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 | ||
206 | void Maps::Add(uint64_t start, uint64_t end, uint64_t offset, uint64_t flags, | 73 | void Maps::Add(uint64_t start, uint64_t end, uint64_t offset, uint64_t flags, |
@@ -222,26 +89,16 @@ Maps::~Maps() { | |||
222 | } | 89 | } |
223 | 90 | ||
224 | bool BufferMaps::Parse() { | 91 | bool 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 | ||
247 | const std::string RemoteMaps::GetMapsFile() const { | 104 | const 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; | |||
34 | struct MapInfo { | 34 | struct 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 | ||
139 | TEST_F(ElfTest, elf32_invalid_machine) { | 139 | TEST_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, ®s, &process_memory, &finished)); | 333 | ASSERT_TRUE(elf.Step(0x3000, 0x1000, ®s, &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, ®s, &process_memory, &finished)) | 370 | EXPECT_CALL(*interface, Step(0x1000, 0, ®s, &process_memory, &finished)) |
371 | .WillOnce(::testing::Return(true)); | 371 | .WillOnce(::testing::Return(true)); |
372 | 372 | ||
373 | ASSERT_TRUE(elf.Step(0x1004, 0x1000, 0x2000, ®s, &process_memory, &finished)); | 373 | ASSERT_TRUE(elf.Step(0x1004, 0x1000, ®s, &process_memory, &finished)); |
374 | } | 374 | } |
375 | 375 | ||
376 | TEST_F(ElfTest, step_in_interface_non_zero_load_bias) { | 376 | TEST_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, ®s, &process_memory, &finished)) | 388 | EXPECT_CALL(*interface, Step(0x7300, 0x4000, ®s, &process_memory, &finished)) |
389 | .WillOnce(::testing::Return(true)); | 389 | .WillOnce(::testing::Return(true)); |
390 | 390 | ||
391 | ASSERT_TRUE(elf.Step(0x7304, 0x7300, 0x2000, ®s, &process_memory, &finished)); | 391 | ASSERT_TRUE(elf.Step(0x7304, 0x7300, ®s, &process_memory, &finished)); |
392 | } | 392 | } |
393 | 393 | ||
394 | TEST_F(ElfTest, get_global_invalid_elf) { | 394 | TEST_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 | ||
47 | namespace unwindstack { | 47 | namespace unwindstack { |
48 | 48 | ||
49 | static 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 | |||
49 | class UnwindOfflineTest : public ::testing::Test { | 55 | class 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 | ||
182 | TEST_F(UnwindOfflineTest, pc_straddle_arm) { | 203 | TEST_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 | ||
206 | TEST_F(UnwindOfflineTest, pc_in_gnu_debugdata_arm) { | 227 | TEST_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 | ||
226 | TEST_F(UnwindOfflineTest, pc_straddle_arm64) { | 247 | TEST_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 | ||
258 | static 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 | |||
264 | TEST_F(UnwindOfflineTest, jit_debug_x86) { | 279 | TEST_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 | ||
557 | TEST_F(UnwindOfflineTest, jit_debug_arm) { | 572 | TEST_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. |
875 | TEST_F(UnwindOfflineTest, bad_eh_frame_hdr_arm64) { | 890 | TEST_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. |
904 | TEST_F(UnwindOfflineTest, debug_frame_first_x86) { | 919 | TEST_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. |
932 | TEST_F(UnwindOfflineTest, eh_frame_hdr_begin_x86_64) { | 947 | TEST_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 | ||
959 | TEST_F(UnwindOfflineTest, art_quick_osr_stub_arm) { | 974 | TEST_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 | ||
1074 | TEST_F(UnwindOfflineTest, jit_map_arm) { | 1089 | TEST_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 | ||
1129 | TEST_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 @@ | |||
1 | 2b6c000-2e92000 r-xp 42000 00:00 0 libunwindstack_test | ||
2 | f4135000-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 @@ | |||
1 | r0: 5 | ||
2 | r1: 5 | ||
3 | r2: 4 | ||
4 | r3: 1 | ||
5 | r4: 73804b6b | ||
6 | r5: f3c9c000 | ||
7 | r6: 2ea09ac | ||
8 | r7: 10624dd3 | ||
9 | r8: f41b5d8c | ||
10 | r9: f3c9c000 | ||
11 | r10: 6f17 | ||
12 | r11: f3c94048 | ||
13 | ip: 2ea0807 | ||
14 | sp: f43d2ccc | ||
15 | lr: 2e55fef | ||
16 | pc: 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) { | |||
68 | bool SaveRegs(unwindstack::Regs* regs) { | 69 | bool 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 | ||
81 | bool SaveStack(pid_t pid, uint64_t sp_start, uint64_t sp_end) { | 82 | bool 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) { | |||
110 | bool CreateElfFromMemory(std::shared_ptr<unwindstack::Memory>& memory, map_info_t* info) { | 126 | bool 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_ | |||
144 | bool CopyElfFromFile(map_info_t* info) { | 161 | bool 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 @@ | |||
15 | cc_library_headers { | 15 | cc_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: |
68 | 3030 boot_progress_preload_end (time|2|3) | 68 | 3030 boot_progress_preload_end (time|2|3) |
69 | 69 | ||
70 | # Dalvik VM | 70 | # Dalvik VM / ART |
71 | 20003 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) | 71 | 20003 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) |
72 | 20004 art_hidden_api_access (access_method|1),(flags|1),(class|3),(member|3),(type_signature|3) | ||
72 | 73 | ||
73 | 75000 sqlite_mem_alarm_current (current|1|2) | 74 | 75000 sqlite_mem_alarm_current (current|1|2) |
74 | 75001 sqlite_mem_alarm_max (max|1|2) | 75 | 75001 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) | |||
147 | bcp_md5 := | 147 | bcp_md5 := |
148 | bcp_dep := | 148 | bcp_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. |
151 | define append_vndk_version | 151 | define 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 | ) |
158 | endef | 155 | endef |
159 | 156 | ||
@@ -215,31 +212,46 @@ sanitizer_runtime_libraries := | |||
215 | vndk_version_suffix := | 212 | vndk_version_suffix := |
216 | endef # update_and_install_ld_config | 213 | endef # update_and_install_ld_config |
217 | 214 | ||
215 | |||
216 | ####################################### | ||
217 | # ld.config.txt selection variables | ||
218 | # | ||
219 | _enforce_vndk_at_runtime := false | ||
220 | ifdef BOARD_VNDK_VERSION | ||
221 | ifneq ($(BOARD_VNDK_RUNTIME_DISABLE),true) | ||
222 | _enforce_vndk_at_runtime := true | ||
223 | endif | ||
224 | endif | ||
225 | |||
226 | _enforce_vndk_lite_at_runtime := false | ||
227 | ifeq ($(_enforce_vndk_at_runtime),false) | ||
228 | ifeq ($(PRODUCT_TREBLE_LINKER_NAMESPACES)|$(SANITIZE_TARGET),true|) | ||
229 | _enforce_vndk_lite_at_runtime := true | ||
230 | endif | ||
231 | endif | ||
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 | # | ||
230 | include $(CLEAR_VARS) | 248 | include $(CLEAR_VARS) |
231 | LOCAL_MODULE := ld.config.txt | 249 | LOCAL_MODULE := ld.config.txt |
232 | LOCAL_MODULE_CLASS := ETC | 250 | LOCAL_MODULE_CLASS := ETC |
233 | LOCAL_MODULE_PATH := $(TARGET_OUT_ETC) | 251 | LOCAL_MODULE_PATH := $(TARGET_OUT_ETC) |
234 | 252 | ||
235 | _enforce_vndk_at_runtime := false | ||
236 | ifdef BOARD_VNDK_VERSION | ||
237 | ifneq ($(BOARD_VNDK_RUNTIME_DISABLE),true) | ||
238 | _enforce_vndk_at_runtime := true | ||
239 | endif | ||
240 | endif | ||
241 | |||
242 | ifeq ($(_enforce_vndk_at_runtime),true) | 253 | ifeq ($(_enforce_vndk_at_runtime),true) |
254 | |||
243 | # for VNDK enforced devices | 255 | # for VNDK enforced devices |
244 | LOCAL_MODULE_STEM := $(call append_vndk_version,$(LOCAL_MODULE)) | 256 | LOCAL_MODULE_STEM := $(call append_vndk_version,$(LOCAL_MODULE)) |
245 | include $(BUILD_SYSTEM)/base_rules.mk | 257 | include $(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 | ||
251 | else ifeq ($(PRODUCT_TREBLE_LINKER_NAMESPACES)|$(SANITIZE_TARGET),true|) | 263 | else ifeq ($(_enforce_vndk_lite_at_runtime),true) |
252 | # for treblized but VNDK non-enforced devices | 264 | |
253 | LOCAL_MODULE_STEM := $(call append_vndk_version,$(LOCAL_MODULE)) | 265 | # for treblized but VNDK lightly enforced devices |
266 | LOCAL_MODULE_STEM := ld.config.vndk_lite.txt | ||
254 | include $(BUILD_SYSTEM)/base_rules.mk | 267 | include $(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 | ||
261 | else | 274 | else |
275 | |||
262 | # for legacy non-treblized devices | 276 | # for legacy non-treblized devices |
263 | LOCAL_SRC_FILES := etc/ld.config.legacy.txt | ||
264 | LOCAL_MODULE_STEM := $(LOCAL_MODULE) | 277 | LOCAL_MODULE_STEM := $(LOCAL_MODULE) |
278 | LOCAL_SRC_FILES := etc/ld.config.legacy.txt | ||
265 | include $(BUILD_PREBUILT) | 279 | include $(BUILD_PREBUILT) |
266 | 280 | ||
267 | endif # if _enforce_vndk_at_runtime is true | 281 | endif # 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 | 289 | ifeq ($(_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. | ||
280 | include $(CLEAR_VARS) | 291 | include $(CLEAR_VARS) |
281 | LOCAL_MODULE := ld.config.noenforce.txt | 292 | LOCAL_MODULE := ld.config.vndk_lite.txt |
282 | LOCAL_MODULE_CLASS := ETC | 293 | LOCAL_MODULE_CLASS := ETC |
283 | LOCAL_MODULE_PATH := $(TARGET_OUT_ETC) | 294 | LOCAL_MODULE_PATH := $(TARGET_OUT_ETC) |
284 | LOCAL_MODULE_STEM := $(LOCAL_MODULE) | 295 | LOCAL_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 | ||
303 | endif # 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 |
294 | include $(CLEAR_VARS) | 310 | include $(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 |