summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--CleanSpec.mk10
-rw-r--r--adb/set_verity_enable_state_service.cpp14
-rw-r--r--adf/libadf/Android.bp6
-rw-r--r--base/include/android-base/test_utils.h1
-rw-r--r--base/test_utils.cpp4
-rw-r--r--bootstat/bootstat.cpp8
-rw-r--r--debuggerd/libdebuggerd/tombstone.cpp29
-rw-r--r--fastboot/Android.mk2
-rw-r--r--fastboot/fs.cpp34
-rw-r--r--fs_mgr/Android.mk37
-rw-r--r--fs_mgr/fs_mgr_format.cpp8
-rw-r--r--fs_mgr/fs_mgr_main.cpp118
-rw-r--r--fs_mgr/fs_mgr_slotselect.cpp13
-rw-r--r--gatekeeperd/Android.mk3
-rw-r--r--gatekeeperd/IUserManager.cpp57
-rw-r--r--gatekeeperd/IUserManager.h46
-rw-r--r--gatekeeperd/gatekeeperd.cpp19
-rw-r--r--healthd/Android.bp7
-rw-r--r--init/firmware_handler.cpp4
-rw-r--r--init/selinux.cpp15
-rw-r--r--libappfuse/FuseBridgeLoop.cc6
-rw-r--r--libappfuse/tests/FuseBridgeLoopTest.cc1
-rw-r--r--libbacktrace/BacktraceMap.cpp7
-rw-r--r--libbacktrace/BacktraceOffline.cpp2
-rw-r--r--libbacktrace/UnwindStack.cpp6
-rw-r--r--libbacktrace/UnwindStackMap.cpp15
-rw-r--r--libbacktrace/UnwindStackMap.h2
-rw-r--r--libbacktrace/backtrace_offline_test.cpp61
-rw-r--r--libbacktrace/backtrace_test.cpp48
-rw-r--r--libbacktrace/include/backtrace/BacktraceMap.h54
-rw-r--r--libbacktrace/testdata/arm/libandroid_runtime.sobin0 -> 1421884 bytes
-rw-r--r--libbacktrace/testdata/arm/offline_testdata_for_libandroid_runtime6
-rw-r--r--libcutils/android_reboot.cpp2
-rw-r--r--libcutils/ashmem-host.cpp16
-rw-r--r--libcutils/sched_policy.cpp8
-rw-r--r--libcutils/socket_local_client_unix.cpp6
-rw-r--r--libcutils/str_parms.cpp5
-rw-r--r--libcutils/trace-host.cpp18
-rw-r--r--liblog/event_tag_map.cpp9
-rw-r--r--liblog/logger_write.c2
-rw-r--r--liblog/tests/Android.mk11
-rw-r--r--liblog/tests/liblog_test.cpp31
-rw-r--r--libnativeloader/include/nativeloader/native_loader.h1
-rw-r--r--libnativeloader/native_loader.cpp78
-rw-r--r--libsystem/include/system/thread_defs.h3
-rw-r--r--libunwindstack/Android.bp5
-rw-r--r--libunwindstack/ArmExidx.cpp4
-rw-r--r--libunwindstack/DwarfMemory.cpp2
-rw-r--r--libunwindstack/DwarfOp.cpp4
-rw-r--r--libunwindstack/DwarfSection.cpp7
-rw-r--r--libunwindstack/Elf.cpp47
-rw-r--r--libunwindstack/ElfInterface.cpp33
-rw-r--r--libunwindstack/ElfInterfaceArm.cpp4
-rw-r--r--libunwindstack/Machine.h141
-rw-r--r--libunwindstack/MachineArm.h50
-rw-r--r--libunwindstack/MachineArm64.h66
-rw-r--r--libunwindstack/MachineX86.h51
-rw-r--r--libunwindstack/MachineX86_64.h52
-rw-r--r--libunwindstack/MapInfo.cpp21
-rw-r--r--libunwindstack/Memory.cpp210
-rw-r--r--libunwindstack/Regs.cpp610
-rw-r--r--libunwindstack/RegsArm.cpp186
-rw-r--r--libunwindstack/RegsArm64.cpp148
-rw-r--r--libunwindstack/RegsX86.cpp179
-rw-r--r--libunwindstack/RegsX86_64.cpp169
-rw-r--r--libunwindstack/Symbols.cpp2
-rw-r--r--libunwindstack/Ucontext.h184
-rw-r--r--libunwindstack/UcontextArm.h63
-rw-r--r--libunwindstack/UcontextArm64.h69
-rw-r--r--libunwindstack/UcontextX86.h77
-rw-r--r--libunwindstack/UcontextX86_64.h81
-rw-r--r--libunwindstack/Unwinder.cpp3
-rw-r--r--libunwindstack/UserArm.h40
-rw-r--r--libunwindstack/UserArm64.h43
-rw-r--r--libunwindstack/UserX86.h56
-rw-r--r--libunwindstack/UserX86_64.h (renamed from libunwindstack/User.h)40
-rw-r--r--libunwindstack/include/unwindstack/Elf.h13
-rw-r--r--libunwindstack/include/unwindstack/ElfInterface.h3
-rw-r--r--libunwindstack/include/unwindstack/MapInfo.h2
-rw-r--r--libunwindstack/include/unwindstack/Memory.h62
-rw-r--r--libunwindstack/include/unwindstack/Regs.h86
-rw-r--r--libunwindstack/include/unwindstack/RegsArm.h56
-rw-r--r--libunwindstack/include/unwindstack/RegsArm64.h56
-rw-r--r--libunwindstack/include/unwindstack/RegsX86.h59
-rw-r--r--libunwindstack/include/unwindstack/RegsX86_64.h59
-rw-r--r--libunwindstack/tests/ArmExidxDecodeTest.cpp2
-rw-r--r--libunwindstack/tests/ElfInterfaceArmTest.cpp4
-rw-r--r--libunwindstack/tests/ElfTest.cpp1
-rw-r--r--libunwindstack/tests/MapInfoCreateMemoryTest.cpp20
-rw-r--r--libunwindstack/tests/MapInfoGetElfTest.cpp16
-rw-r--r--libunwindstack/tests/MapInfoGetLoadBiasTest.cpp150
-rw-r--r--libunwindstack/tests/MemoryBufferTest.cpp36
-rw-r--r--libunwindstack/tests/MemoryFake.cpp6
-rw-r--r--libunwindstack/tests/MemoryFake.h18
-rw-r--r--libunwindstack/tests/MemoryFileTest.cpp45
-rw-r--r--libunwindstack/tests/MemoryLocalTest.cpp51
-rw-r--r--libunwindstack/tests/MemoryRangeTest.cpp35
-rw-r--r--libunwindstack/tests/MemoryRemoteTest.cpp144
-rw-r--r--libunwindstack/tests/RegsFake.h9
-rw-r--r--libunwindstack/tests/RegsIterateTest.cpp12
-rw-r--r--libunwindstack/tests/RegsStepIfSignalHandlerTest.cpp12
-rw-r--r--libunwindstack/tests/RegsTest.cpp19
-rw-r--r--libunwindstack/tests/UnwindOfflineTest.cpp10
-rw-r--r--libunwindstack/tests/UnwindTest.cpp4
-rw-r--r--libunwindstack/tests/UnwinderTest.cpp10
-rw-r--r--libunwindstack/tools/unwind.cpp10
-rw-r--r--libusbhost/usbhost.c44
-rw-r--r--libutils/Unicode.cpp23
-rw-r--r--libziparchive/zip_archive.cc16
-rw-r--r--lmkd/lmkd.c228
-rwxr-xr-x[-rw-r--r--]logd/FlushCommand.cpp16
-rwxr-xr-x[-rw-r--r--]logd/FlushCommand.h30
-rwxr-xr-x[-rw-r--r--]logd/LogAudit.cpp8
-rw-r--r--logd/LogBuffer.cpp2
-rwxr-xr-x[-rw-r--r--]logd/LogKlog.cpp2
-rwxr-xr-x[-rw-r--r--]logd/LogListener.cpp12
-rwxr-xr-x[-rw-r--r--]logd/LogReader.cpp6
-rwxr-xr-x[-rw-r--r--]logd/LogReader.h4
-rw-r--r--logd/LogStatistics.h21
-rwxr-xr-x[-rw-r--r--]logd/LogTimes.cpp5
-rwxr-xr-x[-rw-r--r--]logd/LogTimes.h13
-rw-r--r--logd/logd.rc1
-rw-r--r--logd/tests/Android.mk2
-rw-r--r--rootdir/Android.mk23
-rw-r--r--rootdir/etc/ld.config.legacy.txt5
-rw-r--r--rootdir/etc/ld.config.txt13
-rw-r--r--rootdir/etc/ld.config.txt.in13
-rw-r--r--rootdir/etc/public.libraries.android.txt1
-rw-r--r--rootdir/etc/public.libraries.wear.txt1
-rw-r--r--rootdir/init.rc7
-rw-r--r--sdcard/sdcard.cpp60
-rw-r--r--shell_and_utilities/Android.bp2
-rw-r--r--shell_and_utilities/README.md29
-rw-r--r--storaged/Android.mk1
-rw-r--r--storaged/include/storaged.h3
-rw-r--r--storaged/include/storaged_info.h37
-rw-r--r--storaged/main.cpp2
-rw-r--r--storaged/storaged.cpp7
-rw-r--r--storaged/storaged_info.cpp56
-rw-r--r--storaged/storaged_uid_monitor.cpp74
-rw-r--r--toolbox/Android.bp4
-rw-r--r--trusty/Android.bp1
-rw-r--r--trusty/gatekeeper/Android.bp2
-rw-r--r--trusty/keymaster/Android.bp3
-rw-r--r--trusty/libtrusty/Android.bp1
-rw-r--r--trusty/libtrusty/tipc-test/Android.bp6
-rw-r--r--trusty/nvram/Android.bp61
-rw-r--r--trusty/nvram/module.c39
-rw-r--r--trusty/nvram/nvram_wipe.cpp66
-rw-r--r--trusty/nvram/trusty_nvram_device.cpp34
-rw-r--r--trusty/nvram/trusty_nvram_implementation.cpp113
-rw-r--r--trusty/nvram/trusty_nvram_implementation.h59
-rw-r--r--trusty/storage/interface/Android.bp1
-rw-r--r--trusty/storage/lib/Android.bp5
-rw-r--r--trusty/storage/proxy/Android.bp2
-rw-r--r--trusty/storage/proxy/proxy.c2
-rw-r--r--trusty/storage/tests/Android.bp3
157 files changed, 3314 insertions, 2345 deletions
diff --git a/CleanSpec.mk b/CleanSpec.mk
index 304ce4ec0..e2e95778a 100644
--- a/CleanSpec.mk
+++ b/CleanSpec.mk
@@ -60,4 +60,14 @@ $(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/lib/hw/gatekeeper.$(TARGET_D
60$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/lib64/hw/gatekeeper.$(TARGET_DEVICE).so) 60$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/lib64/hw/gatekeeper.$(TARGET_DEVICE).so)
61$(call add-clean-step, rm -rf $(PRODUCT_OUT)/root/vendor) 61$(call add-clean-step, rm -rf $(PRODUCT_OUT)/root/vendor)
62$(call add-clean-step, rm -rf $(PRODUCT_OUT)/root/init.rc) 62$(call add-clean-step, rm -rf $(PRODUCT_OUT)/root/init.rc)
63$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/lib/libtrusty.so)
64$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/lib64/libtrusty.so)
65$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/lib/hw/keystore.trusty.so)
66$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/lib64/hw/keystore.trusty.so)
67$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/lib/hw/gatekeeper.trusty.so)
68$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/lib64/hw/gatekeeper.trusty.so)
69$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/bin/secure-storage-unit-test)
70$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/bin/storageproxyd)
71$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/bin/tipc-test)
72$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/bin/trusty_keymaster_tipc)
63$(call add-clean-step, rm -rf $(PRODUCT_OUT)/root/root) 73$(call add-clean-step, rm -rf $(PRODUCT_OUT)/root/root)
diff --git a/adb/set_verity_enable_state_service.cpp b/adb/set_verity_enable_state_service.cpp
index 253d14a0e..49e0363a1 100644
--- a/adb/set_verity_enable_state_service.cpp
+++ b/adb/set_verity_enable_state_service.cpp
@@ -93,21 +93,9 @@ static bool set_verity_enabled_state(int fd, const char* block_device, const cha
93/* Helper function to get A/B suffix, if any. If the device isn't 93/* Helper function to get A/B suffix, if any. If the device isn't
94 * using A/B the empty string is returned. Otherwise either "_a", 94 * using A/B the empty string is returned. Otherwise either "_a",
95 * "_b", ... is returned. 95 * "_b", ... is returned.
96 *
97 * Note that since sometime in O androidboot.slot_suffix is deprecated
98 * and androidboot.slot should be used instead. Since bootloaders may
99 * be out of sync with the OS, we check both and for extra safety
100 * prepend a leading underscore if there isn't one already.
101 */ 96 */
102static std::string get_ab_suffix() { 97static std::string get_ab_suffix() {
103 std::string ab_suffix = android::base::GetProperty("ro.boot.slot_suffix", ""); 98 return android::base::GetProperty("ro.boot.slot_suffix", "");
104 if (ab_suffix == "") {
105 ab_suffix = android::base::GetProperty("ro.boot.slot", "");
106 }
107 if (ab_suffix.size() > 0 && ab_suffix[0] != '_') {
108 ab_suffix = std::string("_") + ab_suffix;
109 }
110 return ab_suffix;
111} 99}
112 100
113/* Use AVB to turn verity on/off */ 101/* Use AVB to turn verity on/off */
diff --git a/adf/libadf/Android.bp b/adf/libadf/Android.bp
index c276c5331..8eef2eab9 100644
--- a/adf/libadf/Android.bp
+++ b/adf/libadf/Android.bp
@@ -12,8 +12,12 @@
12// See the License for the specific language governing permissions and 12// See the License for the specific language governing permissions and
13// limitations under the License. 13// limitations under the License.
14 14
15cc_library_static { 15cc_library {
16 name: "libadf", 16 name: "libadf",
17 vendor_available: true,
18 vndk: {
19 enabled: true,
20 },
17 srcs: ["adf.cpp"], 21 srcs: ["adf.cpp"],
18 cflags: ["-Werror"], 22 cflags: ["-Werror"],
19 local_include_dirs: ["include"], 23 local_include_dirs: ["include"],
diff --git a/base/include/android-base/test_utils.h b/base/include/android-base/test_utils.h
index 07a5edda0..4cfa06ba5 100644
--- a/base/include/android-base/test_utils.h
+++ b/base/include/android-base/test_utils.h
@@ -24,6 +24,7 @@
24class TemporaryFile { 24class TemporaryFile {
25 public: 25 public:
26 TemporaryFile(); 26 TemporaryFile();
27 explicit TemporaryFile(const std::string& tmp_dir);
27 ~TemporaryFile(); 28 ~TemporaryFile();
28 29
29 // Release the ownership of fd, caller is reponsible for closing the 30 // Release the ownership of fd, caller is reponsible for closing the
diff --git a/base/test_utils.cpp b/base/test_utils.cpp
index 1cfa9e66f..9d8dfb2fd 100644
--- a/base/test_utils.cpp
+++ b/base/test_utils.cpp
@@ -84,6 +84,10 @@ TemporaryFile::TemporaryFile() {
84 init(GetSystemTempDir()); 84 init(GetSystemTempDir());
85} 85}
86 86
87TemporaryFile::TemporaryFile(const std::string& tmp_dir) {
88 init(tmp_dir);
89}
90
87TemporaryFile::~TemporaryFile() { 91TemporaryFile::~TemporaryFile() {
88 if (fd != -1) { 92 if (fd != -1) {
89 close(fd); 93 close(fd);
diff --git a/bootstat/bootstat.cpp b/bootstat/bootstat.cpp
index 63b36f40c..40ebde027 100644
--- a/bootstat/bootstat.cpp
+++ b/bootstat/bootstat.cpp
@@ -238,6 +238,14 @@ const std::map<std::string, int32_t> kBootReasonMap = {
238 {"watchdog_apps_bite", 98}, 238 {"watchdog_apps_bite", 98},
239 {"xpu_err", 99}, 239 {"xpu_err", 99},
240 {"power_on_usb", 100}, 240 {"power_on_usb", 100},
241 {"watchdog_rpm", 101},
242 {"watchdog_nonsec", 102},
243 {"watchdog_apps_bark", 103},
244 {"reboot_dmverity_corrupted", 104},
245 {"reboot_smpl", 105},
246 {"watchdog_sdi_apps_reset", 106},
247 {"smpl", 107},
248 {"oem_modem_failed_to_powerup", 108},
241}; 249};
242 250
243// Converts a string value representing the reason the system booted to an 251// Converts a string value representing the reason the system booted to an
diff --git a/debuggerd/libdebuggerd/tombstone.cpp b/debuggerd/libdebuggerd/tombstone.cpp
index 725c42cad..a0ba81b68 100644
--- a/debuggerd/libdebuggerd/tombstone.cpp
+++ b/debuggerd/libdebuggerd/tombstone.cpp
@@ -417,7 +417,7 @@ static void dump_all_maps(Backtrace* backtrace, BacktraceMap* map, log_t* log, p
417 "memory map (%zu entr%s):", 417 "memory map (%zu entr%s):",
418 map->size(), map->size() == 1 ? "y" : "ies"); 418 map->size(), map->size() == 1 ? "y" : "ies");
419 if (print_fault_address_marker) { 419 if (print_fault_address_marker) {
420 if (map->begin() != map->end() && addr < map->begin()->start) { 420 if (map->begin() != map->end() && addr < (*map->begin())->start) {
421 _LOG(log, logtype::MAPS, "\n--->Fault address falls at %s before any mapped regions\n", 421 _LOG(log, logtype::MAPS, "\n--->Fault address falls at %s before any mapped regions\n",
422 get_addr_string(addr).c_str()); 422 get_addr_string(addr).c_str());
423 print_fault_address_marker = false; 423 print_fault_address_marker = false;
@@ -429,49 +429,50 @@ static void dump_all_maps(Backtrace* backtrace, BacktraceMap* map, log_t* log, p
429 } 429 }
430 430
431 std::string line; 431 std::string line;
432 for (BacktraceMap::const_iterator it = map->begin(); it != map->end(); ++it) { 432 for (auto it = map->begin(); it != map->end(); ++it) {
433 const backtrace_map_t* entry = *it;
433 line = " "; 434 line = " ";
434 if (print_fault_address_marker) { 435 if (print_fault_address_marker) {
435 if (addr < it->start) { 436 if (addr < entry->start) {
436 _LOG(log, logtype::MAPS, "--->Fault address falls at %s between mapped regions\n", 437 _LOG(log, logtype::MAPS, "--->Fault address falls at %s between mapped regions\n",
437 get_addr_string(addr).c_str()); 438 get_addr_string(addr).c_str());
438 print_fault_address_marker = false; 439 print_fault_address_marker = false;
439 } else if (addr >= it->start && addr < it->end) { 440 } else if (addr >= entry->start && addr < entry->end) {
440 line = "--->"; 441 line = "--->";
441 print_fault_address_marker = false; 442 print_fault_address_marker = false;
442 } 443 }
443 } 444 }
444 line += get_addr_string(it->start) + '-' + get_addr_string(it->end - 1) + ' '; 445 line += get_addr_string(entry->start) + '-' + get_addr_string(entry->end - 1) + ' ';
445 if (it->flags & PROT_READ) { 446 if (entry->flags & PROT_READ) {
446 line += 'r'; 447 line += 'r';
447 } else { 448 } else {
448 line += '-'; 449 line += '-';
449 } 450 }
450 if (it->flags & PROT_WRITE) { 451 if (entry->flags & PROT_WRITE) {
451 line += 'w'; 452 line += 'w';
452 } else { 453 } else {
453 line += '-'; 454 line += '-';
454 } 455 }
455 if (it->flags & PROT_EXEC) { 456 if (entry->flags & PROT_EXEC) {
456 line += 'x'; 457 line += 'x';
457 } else { 458 } else {
458 line += '-'; 459 line += '-';
459 } 460 }
460 line += StringPrintf(" %8" PRIxPTR " %8" PRIxPTR, it->offset, it->end - it->start); 461 line += StringPrintf(" %8" PRIxPTR " %8" PRIxPTR, entry->offset, entry->end - entry->start);
461 bool space_needed = true; 462 bool space_needed = true;
462 if (it->name.length() > 0) { 463 if (entry->name.length() > 0) {
463 space_needed = false; 464 space_needed = false;
464 line += " " + it->name; 465 line += " " + entry->name;
465 std::string build_id; 466 std::string build_id;
466 if ((it->flags & PROT_READ) && elf_get_build_id(backtrace, it->start, &build_id)) { 467 if ((entry->flags & PROT_READ) && elf_get_build_id(backtrace, entry->start, &build_id)) {
467 line += " (BuildId: " + build_id + ")"; 468 line += " (BuildId: " + build_id + ")";
468 } 469 }
469 } 470 }
470 if (it->load_bias != 0) { 471 if (entry->load_bias != 0) {
471 if (space_needed) { 472 if (space_needed) {
472 line += ' '; 473 line += ' ';
473 } 474 }
474 line += StringPrintf(" (load bias 0x%" PRIxPTR ")", it->load_bias); 475 line += StringPrintf(" (load bias 0x%" PRIxPTR ")", entry->load_bias);
475 } 476 }
476 _LOG(log, logtype::MAPS, "%s\n", line.c_str()); 477 _LOG(log, logtype::MAPS, "%s\n", line.c_str());
477 } 478 }
diff --git a/fastboot/Android.mk b/fastboot/Android.mk
index b0b23379a..e0f702d11 100644
--- a/fastboot/Android.mk
+++ b/fastboot/Android.mk
@@ -39,7 +39,7 @@ LOCAL_MODULE := fastboot
39LOCAL_MODULE_TAGS := debug 39LOCAL_MODULE_TAGS := debug
40LOCAL_MODULE_HOST_OS := darwin linux windows 40LOCAL_MODULE_HOST_OS := darwin linux windows
41LOCAL_CFLAGS += -Wall -Wextra -Werror -Wunreachable-code 41LOCAL_CFLAGS += -Wall -Wextra -Werror -Wunreachable-code
42LOCAL_REQUIRED_MODULES := mke2fs e2fsdroid make_f2fs 42LOCAL_REQUIRED_MODULES := mke2fs e2fsdroid mke2fs.conf make_f2fs
43 43
44LOCAL_SRC_FILES_linux := usb_linux.cpp 44LOCAL_SRC_FILES_linux := usb_linux.cpp
45LOCAL_STATIC_LIBRARIES_linux := libselinux 45LOCAL_STATIC_LIBRARIES_linux := libselinux
diff --git a/fastboot/fs.cpp b/fastboot/fs.cpp
index 320cf7f83..9949eae41 100644
--- a/fastboot/fs.cpp
+++ b/fastboot/fs.cpp
@@ -23,11 +23,12 @@
23#include <android-base/stringprintf.h> 23#include <android-base/stringprintf.h>
24#include <android-base/unique_fd.h> 24#include <android-base/unique_fd.h>
25 25
26using android::base::GetExecutableDirectory;
26using android::base::StringPrintf; 27using android::base::StringPrintf;
27using android::base::unique_fd; 28using android::base::unique_fd;
28 29
29#ifdef WIN32 30#ifdef WIN32
30static int exec_e2fs_cmd(const char* /*path*/, char* const argv[]) { 31static int exec_e2fs_cmd(const char* /*path*/, const char** argv, const char** envp) {
31 std::string cmd; 32 std::string cmd;
32 int i = 0; 33 int i = 0;
33 while (argv[i] != nullptr) { 34 while (argv[i] != nullptr) {
@@ -44,7 +45,13 @@ static int exec_e2fs_cmd(const char* /*path*/, char* const argv[]) {
44 si.cb = sizeof(si); 45 si.cb = sizeof(si);
45 ZeroMemory(&pi, sizeof(pi)); 46 ZeroMemory(&pi, sizeof(pi));
46 47
47 SetEnvironmentVariableA("MKE2FS_CONFIG", ""); 48 std::string env_str;
49 if (envp != nullptr) {
50 while (*envp != nullptr) {
51 env_str += std::string(*envp) + std::string("\0", 1);
52 envp++;
53 }
54 }
48 55
49 if (!CreateProcessA(nullptr, // No module name (use command line) 56 if (!CreateProcessA(nullptr, // No module name (use command line)
50 const_cast<char*>(cmd.c_str()), // Command line 57 const_cast<char*>(cmd.c_str()), // Command line
@@ -52,10 +59,10 @@ static int exec_e2fs_cmd(const char* /*path*/, char* const argv[]) {
52 nullptr, // Thread handle not inheritable 59 nullptr, // Thread handle not inheritable
53 FALSE, // Set handle inheritance to FALSE 60 FALSE, // Set handle inheritance to FALSE
54 0, // No creation flags 61 0, // No creation flags
55 nullptr, // Use parent's environment block 62 env_str.empty() ? nullptr : LPSTR(env_str.c_str()),
56 nullptr, // Use parent's starting directory 63 nullptr, // Use parent's starting directory
57 &si, // Pointer to STARTUPINFO structure 64 &si, // Pointer to STARTUPINFO structure
58 &pi) // Pointer to PROCESS_INFORMATION structure 65 &pi) // Pointer to PROCESS_INFORMATION structure
59 ) { 66 ) {
60 fprintf(stderr, "CreateProcess failed: %s\n", 67 fprintf(stderr, "CreateProcess failed: %s\n",
61 android::base::SystemErrorCodeToString(GetLastError()).c_str()); 68 android::base::SystemErrorCodeToString(GetLastError()).c_str());
@@ -72,12 +79,11 @@ static int exec_e2fs_cmd(const char* /*path*/, char* const argv[]) {
72 return exit_code != 0; 79 return exit_code != 0;
73} 80}
74#else 81#else
75static int exec_e2fs_cmd(const char* path, char* const argv[]) { 82static int exec_e2fs_cmd(const char* path, const char** argv, const char** envp) {
76 int status; 83 int status;
77 pid_t child; 84 pid_t child;
78 if ((child = fork()) == 0) { 85 if ((child = fork()) == 0) {
79 setenv("MKE2FS_CONFIG", "", 1); 86 execve(path, const_cast<char**>(argv), const_cast<char**>(envp));
80 execvp(path, argv);
81 _exit(EXIT_FAILURE); 87 _exit(EXIT_FAILURE);
82 } 88 }
83 if (child < 0) { 89 if (child < 0) {
@@ -131,7 +137,10 @@ static int generate_ext4_image(const char* fileName, long long partSize,
131 mke2fs_args.push_back(size_str.c_str()); 137 mke2fs_args.push_back(size_str.c_str());
132 mke2fs_args.push_back(nullptr); 138 mke2fs_args.push_back(nullptr);
133 139
134 int ret = exec_e2fs_cmd(mke2fs_args[0], const_cast<char**>(mke2fs_args.data())); 140 const std::string mke2fs_env = "MKE2FS_CONFIG=" + GetExecutableDirectory() + "/mke2fs.conf";
141 std::vector<const char*> mke2fs_envp = {mke2fs_env.c_str(), nullptr};
142
143 int ret = exec_e2fs_cmd(mke2fs_args[0], mke2fs_args.data(), mke2fs_envp.data());
135 if (ret != 0) { 144 if (ret != 0) {
136 fprintf(stderr, "mke2fs failed: %d\n", ret); 145 fprintf(stderr, "mke2fs failed: %d\n", ret);
137 return -1; 146 return -1;
@@ -145,7 +154,7 @@ static int generate_ext4_image(const char* fileName, long long partSize,
145 std::vector<const char*> e2fsdroid_args = {e2fsdroid_path.c_str(), "-f", initial_dir.c_str(), 154 std::vector<const char*> e2fsdroid_args = {e2fsdroid_path.c_str(), "-f", initial_dir.c_str(),
146 fileName, nullptr}; 155 fileName, nullptr};
147 156
148 ret = exec_e2fs_cmd(e2fsdroid_args[0], const_cast<char**>(e2fsdroid_args.data())); 157 ret = exec_e2fs_cmd(e2fsdroid_args[0], e2fsdroid_args.data(), nullptr);
149 if (ret != 0) { 158 if (ret != 0) {
150 fprintf(stderr, "e2fsdroid failed: %d\n", ret); 159 fprintf(stderr, "e2fsdroid failed: %d\n", ret);
151 return -1; 160 return -1;
@@ -173,7 +182,7 @@ static int generate_f2fs_image(const char* fileName, long long partSize, const s
173 mkf2fs_args.push_back(fileName); 182 mkf2fs_args.push_back(fileName);
174 mkf2fs_args.push_back(nullptr); 183 mkf2fs_args.push_back(nullptr);
175 184
176 int ret = exec_e2fs_cmd(mkf2fs_args[0], const_cast<char**>(mkf2fs_args.data())); 185 int ret = exec_e2fs_cmd(mkf2fs_args[0], mkf2fs_args.data(), nullptr);
177 if (ret != 0) { 186 if (ret != 0) {
178 fprintf(stderr, "mkf2fs failed: %d\n", ret); 187 fprintf(stderr, "mkf2fs failed: %d\n", ret);
179 return -1; 188 return -1;
@@ -185,6 +194,7 @@ static int generate_f2fs_image(const char* fileName, long long partSize, const s
185 } 194 }
186 return 0; 195 return 0;
187#else 196#else
197 UNUSED(fileName, partSize, initial_dir);
188 fprintf(stderr, "make_f2fs not supported on Windows\n"); 198 fprintf(stderr, "make_f2fs not supported on Windows\n");
189 return -1; 199 return -1;
190#endif 200#endif
diff --git a/fs_mgr/Android.mk b/fs_mgr/Android.mk
deleted file mode 100644
index 007189db1..000000000
--- a/fs_mgr/Android.mk
+++ /dev/null
@@ -1,37 +0,0 @@
1# Copyright 2011 The Android Open Source Project
2
3LOCAL_PATH:= $(call my-dir)
4
5common_static_libraries := \
6 liblogwrap \
7 libfec \
8 libfec_rs \
9 libbase \
10 libcrypto_utils \
11 libcrypto \
12 libext4_utils \
13 libsquashfs_utils \
14 libselinux \
15 libavb
16
17include $(CLEAR_VARS)
18LOCAL_SANITIZE := integer
19LOCAL_SRC_FILES:= fs_mgr_main.cpp
20LOCAL_C_INCLUDES := $(LOCAL_PATH)/include
21LOCAL_MODULE:= fs_mgr
22LOCAL_MODULE_TAGS := optional
23LOCAL_REQUIRED_MODULES := mke2fs mke2fs.conf e2fsdroid
24LOCAL_FORCE_STATIC_EXECUTABLE := true
25LOCAL_MODULE_PATH := $(TARGET_ROOT_OUT)/sbin
26LOCAL_UNSTRIPPED_PATH := $(TARGET_ROOT_OUT_UNSTRIPPED)
27LOCAL_STATIC_LIBRARIES := libfs_mgr \
28 $(common_static_libraries) \
29 libcutils \
30 liblog \
31 libc \
32 libsparse \
33 libz \
34 libselinux
35LOCAL_CXX_STL := libc++_static
36LOCAL_CFLAGS := -Werror
37include $(BUILD_EXECUTABLE)
diff --git a/fs_mgr/fs_mgr_format.cpp b/fs_mgr/fs_mgr_format.cpp
index 75feee798..fc88217ce 100644
--- a/fs_mgr/fs_mgr_format.cpp
+++ b/fs_mgr/fs_mgr_format.cpp
@@ -38,7 +38,6 @@ static int format_ext4(char *fs_blkdev, char *fs_mnt_point, bool crypt_footer)
38{ 38{
39 uint64_t dev_sz; 39 uint64_t dev_sz;
40 int fd, rc = 0; 40 int fd, rc = 0;
41 int status;
42 41
43 if ((fd = open(fs_blkdev, O_WRONLY)) < 0) { 42 if ((fd = open(fs_blkdev, O_WRONLY)) < 0) {
44 PERROR << "Cannot open block device"; 43 PERROR << "Cannot open block device";
@@ -62,7 +61,7 @@ static int format_ext4(char *fs_blkdev, char *fs_mnt_point, bool crypt_footer)
62 const char* const mke2fs_args[] = { 61 const char* const mke2fs_args[] = {
63 "/system/bin/mke2fs", "-t", "ext4", "-b", "4096", fs_blkdev, size_str.c_str(), nullptr}; 62 "/system/bin/mke2fs", "-t", "ext4", "-b", "4096", fs_blkdev, size_str.c_str(), nullptr};
64 63
65 rc = android_fork_execvp_ext(arraysize(mke2fs_args), const_cast<char**>(mke2fs_args), &status, 64 rc = android_fork_execvp_ext(arraysize(mke2fs_args), const_cast<char**>(mke2fs_args), NULL,
66 true, LOG_KLOG, true, nullptr, nullptr, 0); 65 true, LOG_KLOG, true, nullptr, nullptr, 0);
67 if (rc) { 66 if (rc) {
68 LERROR << "mke2fs returned " << rc; 67 LERROR << "mke2fs returned " << rc;
@@ -78,7 +77,7 @@ static int format_ext4(char *fs_blkdev, char *fs_mnt_point, bool crypt_footer)
78 nullptr}; 77 nullptr};
79 78
80 rc = android_fork_execvp_ext(arraysize(e2fsdroid_args), const_cast<char**>(e2fsdroid_args), 79 rc = android_fork_execvp_ext(arraysize(e2fsdroid_args), const_cast<char**>(e2fsdroid_args),
81 &status, true, LOG_KLOG, true, nullptr, nullptr, 0); 80 NULL, true, LOG_KLOG, true, nullptr, nullptr, 0);
82 if (rc) { 81 if (rc) {
83 LERROR << "e2fsdroid returned " << rc; 82 LERROR << "e2fsdroid returned " << rc;
84 } 83 }
@@ -88,10 +87,9 @@ static int format_ext4(char *fs_blkdev, char *fs_mnt_point, bool crypt_footer)
88 87
89static int format_f2fs(char *fs_blkdev) 88static int format_f2fs(char *fs_blkdev)
90{ 89{
91 int status;
92 const char* const args[] = {"/system/bin/make_f2fs", "-f", "-O encrypt", fs_blkdev, nullptr}; 90 const char* const args[] = {"/system/bin/make_f2fs", "-f", "-O encrypt", fs_blkdev, nullptr};
93 91
94 return android_fork_execvp_ext(arraysize(args), const_cast<char**>(args), &status, true, 92 return android_fork_execvp_ext(arraysize(args), const_cast<char**>(args), NULL, true,
95 LOG_KLOG, true, nullptr, nullptr, 0); 93 LOG_KLOG, true, nullptr, nullptr, 0);
96} 94}
97 95
diff --git a/fs_mgr/fs_mgr_main.cpp b/fs_mgr/fs_mgr_main.cpp
deleted file mode 100644
index f3919d9d9..000000000
--- a/fs_mgr/fs_mgr_main.cpp
+++ /dev/null
@@ -1,118 +0,0 @@
1/*
2 * Copyright (C) 2012 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 <stdio.h>
18#include <string.h>
19#include <stdlib.h>
20#include "fs_mgr_priv.h"
21
22#ifdef _LIBGEN_H
23#warning "libgen.h must not be included"
24#endif
25
26char *me = nullptr;
27
28static void usage(void)
29{
30 LERROR << me << ": usage: " << me
31 << " <-a | -n mnt_point blk_dev | -u> <fstab_file>";
32 exit(1);
33}
34
35/* Parse the command line. If an error is encountered, print an error message
36 * and exit the program, do not return to the caller.
37 * Return the number of argv[] entries consumed.
38 */
39static void parse_options(int argc, char * const argv[], int *a_flag, int *u_flag, int *n_flag,
40 const char **n_name, const char **n_blk_dev)
41{
42 me = basename(argv[0]);
43
44 if (argc <= 1) {
45 usage();
46 }
47
48 if (!strcmp(argv[1], "-a")) {
49 if (argc != 3) {
50 usage();
51 }
52 *a_flag = 1;
53 }
54 if (!strcmp(argv[1], "-n")) {
55 if (argc != 5) {
56 usage();
57 }
58 *n_flag = 1;
59 *n_name = argv[2];
60 *n_blk_dev = argv[3];
61 }
62 if (!strcmp(argv[1], "-u")) {
63 if (argc != 3) {
64 usage();
65 }
66 *u_flag = 1;
67 }
68
69 /* If no flag is specified, it's an error */
70 if (!(*a_flag | *n_flag | *u_flag)) {
71 usage();
72 }
73
74 /* If more than one flag is specified, it's an error */
75 if ((*a_flag + *n_flag + *u_flag) > 1) {
76 usage();
77 }
78
79 return;
80}
81
82int main(int argc, char * const argv[])
83{
84 int a_flag=0;
85 int u_flag=0;
86 int n_flag=0;
87 const char *n_name=NULL;
88 const char *n_blk_dev=NULL;
89 const char *fstab_file=NULL;
90 struct fstab *fstab=NULL;
91
92 setenv("ANDROID_LOG_TAGS", "*:i", 1); // Set log level to INFO
93 android::base::InitLogging(
94 const_cast<char **>(argv), &android::base::KernelLogger);
95
96 parse_options(argc, argv, &a_flag, &u_flag, &n_flag, &n_name, &n_blk_dev);
97
98 /* The name of the fstab file is last, after the option */
99 fstab_file = argv[argc - 1];
100
101 fstab = fs_mgr_read_fstab(fstab_file);
102
103 if (a_flag) {
104 return fs_mgr_mount_all(fstab, MOUNT_MODE_DEFAULT);
105 } else if (n_flag) {
106 return fs_mgr_do_mount(fstab, n_name, (char *)n_blk_dev, 0);
107 } else if (u_flag) {
108 return fs_mgr_unmount_all(fstab);
109 } else {
110 LERROR << me << ": Internal error, unknown option";
111 exit(1);
112 }
113
114 fs_mgr_free_fstab(fstab);
115
116 /* Should not get here */
117 exit(1);
118}
diff --git a/fs_mgr/fs_mgr_slotselect.cpp b/fs_mgr/fs_mgr_slotselect.cpp
index f604bcfb1..0a113b47e 100644
--- a/fs_mgr/fs_mgr_slotselect.cpp
+++ b/fs_mgr/fs_mgr_slotselect.cpp
@@ -21,19 +21,12 @@
21#include "fs_mgr.h" 21#include "fs_mgr.h"
22#include "fs_mgr_priv.h" 22#include "fs_mgr_priv.h"
23 23
24// Returns "_a" or "_b" based on two possible values in kernel cmdline: 24// Returns "_a" or "_b" based on androidboot.slot_suffix in kernel cmdline, or an empty string
25// - androidboot.slot = a or b OR 25// if that parameter does not exist.
26// - androidboot.slot_suffix = _a or _b
27// TODO: remove slot_suffix once it's deprecated.
28std::string fs_mgr_get_slot_suffix() { 26std::string fs_mgr_get_slot_suffix() {
29 std::string slot;
30 std::string ab_suffix; 27 std::string ab_suffix;
31 28
32 if (fs_mgr_get_boot_config("slot", &slot)) { 29 fs_mgr_get_boot_config("slot_suffix", &ab_suffix);
33 ab_suffix = "_" + slot;
34 } else if (!fs_mgr_get_boot_config("slot_suffix", &ab_suffix)) {
35 ab_suffix = "";
36 }
37 return ab_suffix; 30 return ab_suffix;
38} 31}
39 32
diff --git a/gatekeeperd/Android.mk b/gatekeeperd/Android.mk
index 0dfd9d8a9..28f0b07ab 100644
--- a/gatekeeperd/Android.mk
+++ b/gatekeeperd/Android.mk
@@ -21,8 +21,7 @@ LOCAL_CFLAGS := -Wall -Wextra -Werror -Wunused
21LOCAL_SRC_FILES := \ 21LOCAL_SRC_FILES := \
22 SoftGateKeeperDevice.cpp \ 22 SoftGateKeeperDevice.cpp \
23 IGateKeeperService.cpp \ 23 IGateKeeperService.cpp \
24 gatekeeperd.cpp \ 24 gatekeeperd.cpp
25 IUserManager.cpp
26 25
27LOCAL_MODULE := gatekeeperd 26LOCAL_MODULE := gatekeeperd
28LOCAL_SHARED_LIBRARIES := \ 27LOCAL_SHARED_LIBRARIES := \
diff --git a/gatekeeperd/IUserManager.cpp b/gatekeeperd/IUserManager.cpp
deleted file mode 100644
index 8167d1919..000000000
--- a/gatekeeperd/IUserManager.cpp
+++ /dev/null
@@ -1,57 +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#define LOG_TAG "IUserManager"
18#include <stdint.h>
19#include <sys/types.h>
20#include <utils/Log.h>
21#include <binder/Parcel.h>
22
23#include "IUserManager.h"
24
25namespace android {
26
27class BpUserManager : public BpInterface<IUserManager>
28{
29public:
30 explicit BpUserManager(const sp<IBinder>& impl) :
31 BpInterface<IUserManager>(impl) {
32 }
33 virtual int32_t getCredentialOwnerProfile(int32_t user_id) {
34 Parcel data, reply;
35 data.writeInterfaceToken(IUserManager::getInterfaceDescriptor());
36 data.writeInt32(user_id);
37 status_t rc = remote()->transact(GET_CREDENTIAL_OWNER_PROFILE, data, &reply, 0);
38 if (rc != NO_ERROR) {
39 ALOGE("%s: failed (%d)\n", __func__, rc);
40 return -1;
41 }
42
43 int32_t exception = reply.readExceptionCode();
44 if (exception != 0) {
45 ALOGE("%s: got exception (%d)\n", __func__, exception);
46 return -1;
47 }
48
49 return reply.readInt32();
50 }
51
52};
53
54IMPLEMENT_META_INTERFACE(UserManager, "android.os.IUserManager");
55
56}; // namespace android
57
diff --git a/gatekeeperd/IUserManager.h b/gatekeeperd/IUserManager.h
deleted file mode 100644
index 640e9b511..000000000
--- a/gatekeeperd/IUserManager.h
+++ /dev/null
@@ -1,46 +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 IUSERMANAGER_H_
18#define IUSERMANAGER_H_
19
20#include <inttypes.h>
21#include <utils/Errors.h>
22#include <binder/IInterface.h>
23#include <binder/Parcel.h>
24#include <utils/Vector.h>
25
26namespace android {
27
28/*
29* Communication channel to UserManager
30*/
31class IUserManager : public IInterface {
32 public:
33 // must be kept in sync with IUserManager.aidl
34 enum {
35 GET_CREDENTIAL_OWNER_PROFILE = IBinder::FIRST_CALL_TRANSACTION + 0,
36 };
37
38 virtual int32_t getCredentialOwnerProfile(int32_t user_id) = 0;
39
40 DECLARE_META_INTERFACE(UserManager);
41};
42
43}; // namespace android
44
45#endif // IUSERMANAGER_H_
46
diff --git a/gatekeeperd/gatekeeperd.cpp b/gatekeeperd/gatekeeperd.cpp
index d581736f3..61c880409 100644
--- a/gatekeeperd/gatekeeperd.cpp
+++ b/gatekeeperd/gatekeeperd.cpp
@@ -38,7 +38,6 @@
38#include <utils/String16.h> 38#include <utils/String16.h>
39 39
40#include "SoftGateKeeperDevice.h" 40#include "SoftGateKeeperDevice.h"
41#include "IUserManager.h"
42 41
43#include <hidl/HidlSupport.h> 42#include <hidl/HidlSupport.h>
44#include <android/hardware/gatekeeper/1.0/IGatekeeper.h> 43#include <android/hardware/gatekeeper/1.0/IGatekeeper.h>
@@ -335,23 +334,7 @@ public:
335 return ret; 334 return ret;
336 } 335 }
337 336
338 virtual uint64_t getSecureUserId(uint32_t uid) { 337 virtual uint64_t getSecureUserId(uint32_t uid) { return read_sid(uid); }
339 uint64_t sid = read_sid(uid);
340 if (sid == 0) {
341 // might be a work profile, look up the parent
342 sp<IServiceManager> sm = defaultServiceManager();
343 sp<IBinder> binder = sm->getService(String16("user"));
344 sp<IUserManager> um = interface_cast<IUserManager>(binder);
345 int32_t parent = um->getCredentialOwnerProfile(uid);
346 if (parent < 0) {
347 return 0;
348 } else if (parent != (int32_t) uid) {
349 return read_sid(parent);
350 }
351 }
352 return sid;
353
354 }
355 338
356 virtual void clearSecureUserId(uint32_t uid) { 339 virtual void clearSecureUserId(uint32_t uid) {
357 IPCThreadState* ipc = IPCThreadState::self(); 340 IPCThreadState* ipc = IPCThreadState::self();
diff --git a/healthd/Android.bp b/healthd/Android.bp
new file mode 100644
index 000000000..56f5148ca
--- /dev/null
+++ b/healthd/Android.bp
@@ -0,0 +1,7 @@
1cc_library_headers {
2 name: "libhealthd_headers",
3 vendor_available: true,
4 export_include_dirs: ["include"],
5 header_libs: ["libbatteryservice_headers"],
6 export_header_lib_headers: ["libbatteryservice_headers"],
7}
diff --git a/init/firmware_handler.cpp b/init/firmware_handler.cpp
index b686885fb..8c8d9f2ab 100644
--- a/init/firmware_handler.cpp
+++ b/init/firmware_handler.cpp
@@ -78,8 +78,8 @@ static void ProcessFirmwareEvent(const Uevent& uevent) {
78 return; 78 return;
79 } 79 }
80 80
81 static const char* firmware_dirs[] = {"/etc/firmware/", "/vendor/firmware/", 81 static const char* firmware_dirs[] = {"/etc/firmware/", "/odm/firmware/",
82 "/firmware/image/"}; 82 "/vendor/firmware/", "/firmware/image/"};
83 83
84try_loading_again: 84try_loading_again:
85 for (size_t i = 0; i < arraysize(firmware_dirs); i++) { 85 for (size_t i = 0; i < arraysize(firmware_dirs); i++) {
diff --git a/init/selinux.cpp b/init/selinux.cpp
index 331fad638..21010b094 100644
--- a/init/selinux.cpp
+++ b/init/selinux.cpp
@@ -302,18 +302,18 @@ bool LoadSplitPolicy() {
302 } 302 }
303 std::string mapping_file("/system/etc/selinux/mapping/" + vend_plat_vers + ".cil"); 303 std::string mapping_file("/system/etc/selinux/mapping/" + vend_plat_vers + ".cil");
304 304
305 // vendor_sepolicy.cil and nonplat_declaration.cil are the new design to replace 305 // vendor_sepolicy.cil and plat_pub_versioned.cil are the new design to replace
306 // nonplat_sepolicy.cil. 306 // nonplat_sepolicy.cil.
307 std::string nonplat_declaration_cil_file("/vendor/etc/selinux/nonplat_declaration.cil"); 307 std::string plat_pub_versioned_cil_file("/vendor/etc/selinux/plat_pub_versioned.cil");
308 std::string vendor_policy_cil_file("/vendor/etc/selinux/vendor_sepolicy.cil"); 308 std::string vendor_policy_cil_file("/vendor/etc/selinux/vendor_sepolicy.cil");
309 309
310 if (access(vendor_policy_cil_file.c_str(), F_OK) == -1) { 310 if (access(vendor_policy_cil_file.c_str(), F_OK) == -1) {
311 // For backward compatibility. 311 // For backward compatibility.
312 // TODO: remove this after no device is using nonplat_sepolicy.cil. 312 // TODO: remove this after no device is using nonplat_sepolicy.cil.
313 vendor_policy_cil_file = "/vendor/etc/selinux/nonplat_sepolicy.cil"; 313 vendor_policy_cil_file = "/vendor/etc/selinux/nonplat_sepolicy.cil";
314 nonplat_declaration_cil_file.clear(); 314 plat_pub_versioned_cil_file.clear();
315 } else if (access(nonplat_declaration_cil_file.c_str(), F_OK) == -1) { 315 } else if (access(plat_pub_versioned_cil_file.c_str(), F_OK) == -1) {
316 LOG(ERROR) << "Missing " << nonplat_declaration_cil_file; 316 LOG(ERROR) << "Missing " << plat_pub_versioned_cil_file;
317 return false; 317 return false;
318 } 318 }
319 319
@@ -338,8 +338,8 @@ bool LoadSplitPolicy() {
338 }; 338 };
339 // clang-format on 339 // clang-format on
340 340
341 if (!nonplat_declaration_cil_file.empty()) { 341 if (!plat_pub_versioned_cil_file.empty()) {
342 compile_args.push_back(nonplat_declaration_cil_file.c_str()); 342 compile_args.push_back(plat_pub_versioned_cil_file.c_str());
343 } 343 }
344 if (!vendor_policy_cil_file.empty()) { 344 if (!vendor_policy_cil_file.empty()) {
345 compile_args.push_back(vendor_policy_cil_file.c_str()); 345 compile_args.push_back(vendor_policy_cil_file.c_str());
@@ -418,7 +418,6 @@ void SelinuxRestoreContext() {
418 selinux_android_restorecon("/dev/urandom", 0); 418 selinux_android_restorecon("/dev/urandom", 0);
419 selinux_android_restorecon("/dev/__properties__", 0); 419 selinux_android_restorecon("/dev/__properties__", 0);
420 420
421 selinux_android_restorecon("/file_contexts.bin", 0);
422 selinux_android_restorecon("/plat_file_contexts", 0); 421 selinux_android_restorecon("/plat_file_contexts", 0);
423 selinux_android_restorecon("/nonplat_file_contexts", 0); 422 selinux_android_restorecon("/nonplat_file_contexts", 0);
424 selinux_android_restorecon("/plat_property_contexts", 0); 423 selinux_android_restorecon("/plat_property_contexts", 0);
diff --git a/libappfuse/FuseBridgeLoop.cc b/libappfuse/FuseBridgeLoop.cc
index 07923071b..8b0c53eb2 100644
--- a/libappfuse/FuseBridgeLoop.cc
+++ b/libappfuse/FuseBridgeLoop.cc
@@ -179,7 +179,11 @@ class FuseBridgeEntry {
179 } 179 }
180 180
181 const uint32_t opcode = buffer_.request.header.opcode; 181 const uint32_t opcode = buffer_.request.header.opcode;
182 LOG(VERBOSE) << "Read a fuse packet, opcode=" << opcode; 182 const uint64_t unique = buffer_.request.header.unique;
183 LOG(VERBOSE) << "Read a fuse packet, opcode=" << opcode << " unique=" << unique;
184 if (unique == 0) {
185 return FuseBridgeState::kWaitToReadEither;
186 }
183 switch (opcode) { 187 switch (opcode) {
184 case FUSE_FORGET: 188 case FUSE_FORGET:
185 // Do not reply to FUSE_FORGET. 189 // Do not reply to FUSE_FORGET.
diff --git a/libappfuse/tests/FuseBridgeLoopTest.cc b/libappfuse/tests/FuseBridgeLoopTest.cc
index 51d605136..0a28451bf 100644
--- a/libappfuse/tests/FuseBridgeLoopTest.cc
+++ b/libappfuse/tests/FuseBridgeLoopTest.cc
@@ -67,6 +67,7 @@ class FuseBridgeLoopTest : public ::testing::Test {
67 memset(&request_, 0, sizeof(FuseRequest)); 67 memset(&request_, 0, sizeof(FuseRequest));
68 request_.header.opcode = opcode; 68 request_.header.opcode = opcode;
69 request_.header.len = sizeof(fuse_in_header); 69 request_.header.len = sizeof(fuse_in_header);
70 request_.header.unique = 1;
70 ASSERT_TRUE(request_.Write(dev_sockets_[0])); 71 ASSERT_TRUE(request_.Write(dev_sockets_[0]));
71 72
72 memset(&response_, 0, sizeof(FuseResponse)); 73 memset(&response_, 0, sizeof(FuseResponse));
diff --git a/libbacktrace/BacktraceMap.cpp b/libbacktrace/BacktraceMap.cpp
index 0e314958f..0f1ae11f7 100644
--- a/libbacktrace/BacktraceMap.cpp
+++ b/libbacktrace/BacktraceMap.cpp
@@ -40,9 +40,10 @@ BacktraceMap::~BacktraceMap() {
40 40
41void BacktraceMap::FillIn(uintptr_t addr, backtrace_map_t* map) { 41void BacktraceMap::FillIn(uintptr_t addr, backtrace_map_t* map) {
42 ScopedBacktraceMapIteratorLock lock(this); 42 ScopedBacktraceMapIteratorLock lock(this);
43 for (BacktraceMap::const_iterator it = begin(); it != end(); ++it) { 43 for (auto it = begin(); it != end(); ++it) {
44 if (addr >= it->start && addr < it->end) { 44 const backtrace_map_t* entry = *it;
45 *map = *it; 45 if (addr >= entry->start && addr < entry->end) {
46 *map = *entry;
46 return; 47 return;
47 } 48 }
48 } 49 }
diff --git a/libbacktrace/BacktraceOffline.cpp b/libbacktrace/BacktraceOffline.cpp
index 0a2f5a31f..304149263 100644
--- a/libbacktrace/BacktraceOffline.cpp
+++ b/libbacktrace/BacktraceOffline.cpp
@@ -320,7 +320,7 @@ bool BacktraceOffline::FindProcInfo(unw_addr_space_t addr_space, uint64_t ip,
320 } 320 }
321 if (debug_frame->has_debug_frame || debug_frame->has_gnu_debugdata) { 321 if (debug_frame->has_debug_frame || debug_frame->has_gnu_debugdata) {
322 unw_dyn_info_t di; 322 unw_dyn_info_t di;
323 unw_word_t segbase = map.start - map.offset; 323 unw_word_t segbase = map.start - debug_frame->min_vaddr;
324 // TODO: http://b/32916571 324 // TODO: http://b/32916571
325 // TODO: Do it ourselves is more efficient than calling libunwind functions. 325 // TODO: Do it ourselves is more efficient than calling libunwind functions.
326 int found = dwarf_find_debug_frame(0, &di, ip, segbase, filename.c_str(), map.start, map.end); 326 int found = dwarf_find_debug_frame(0, &di, ip, segbase, filename.c_str(), map.start, map.end);
diff --git a/libbacktrace/UnwindStack.cpp b/libbacktrace/UnwindStack.cpp
index 3a3883902..d61384ef1 100644
--- a/libbacktrace/UnwindStack.cpp
+++ b/libbacktrace/UnwindStack.cpp
@@ -99,8 +99,7 @@ bool UnwindStackCurrent::UnwindFromContext(size_t num_ignore_frames, ucontext_t*
99 // one extra function call appearing in the unwind. 99 // one extra function call appearing in the unwind.
100 unwindstack::RegsGetLocal(regs.get()); 100 unwindstack::RegsGetLocal(regs.get());
101 } else { 101 } else {
102 regs.reset( 102 regs.reset(unwindstack::Regs::CreateFromUcontext(unwindstack::Regs::CurrentArch(), ucontext));
103 unwindstack::Regs::CreateFromUcontext(unwindstack::Regs::CurrentMachineType(), ucontext));
104 } 103 }
105 104
106 error_ = BACKTRACE_UNWIND_NO_ERROR; 105 error_ = BACKTRACE_UNWIND_NO_ERROR;
@@ -120,8 +119,7 @@ bool UnwindStackPtrace::Unwind(size_t num_ignore_frames, ucontext_t* context) {
120 if (context == nullptr) { 119 if (context == nullptr) {
121 regs.reset(unwindstack::Regs::RemoteGet(Tid())); 120 regs.reset(unwindstack::Regs::RemoteGet(Tid()));
122 } else { 121 } else {
123 regs.reset( 122 regs.reset(unwindstack::Regs::CreateFromUcontext(unwindstack::Regs::CurrentArch(), context));
124 unwindstack::Regs::CreateFromUcontext(unwindstack::Regs::CurrentMachineType(), context));
125 } 123 }
126 124
127 error_ = BACKTRACE_UNWIND_NO_ERROR; 125 error_ = BACKTRACE_UNWIND_NO_ERROR;
diff --git a/libbacktrace/UnwindStackMap.cpp b/libbacktrace/UnwindStackMap.cpp
index 9ac0a0b54..836a774b9 100644
--- a/libbacktrace/UnwindStackMap.cpp
+++ b/libbacktrace/UnwindStackMap.cpp
@@ -71,8 +71,19 @@ void UnwindStackMap::FillIn(uintptr_t addr, backtrace_map_t* map) {
71 if (map_info == nullptr) { 71 if (map_info == nullptr) {
72 return; 72 return;
73 } 73 }
74 unwindstack::Elf* elf = map_info->GetElf(process_memory_, true); 74 map->load_bias = map_info->GetLoadBias(process_memory_);
75 map->load_bias = elf->GetLoadBias(); 75}
76
77uint64_t UnwindStackMap::GetLoadBias(size_t index) {
78 if (index >= stack_maps_->Total()) {
79 return 0;
80 }
81
82 unwindstack::MapInfo* map_info = stack_maps_->Get(index);
83 if (map_info == nullptr) {
84 return 0;
85 }
86 return map_info->GetLoadBias(process_memory_);
76} 87}
77 88
78std::string UnwindStackMap::GetFunctionName(uintptr_t pc, uintptr_t* offset) { 89std::string UnwindStackMap::GetFunctionName(uintptr_t pc, uintptr_t* offset) {
diff --git a/libbacktrace/UnwindStackMap.h b/libbacktrace/UnwindStackMap.h
index bc432e745..2f63655fd 100644
--- a/libbacktrace/UnwindStackMap.h
+++ b/libbacktrace/UnwindStackMap.h
@@ -42,6 +42,8 @@ class UnwindStackMap : public BacktraceMap {
42 const std::shared_ptr<unwindstack::Memory>& process_memory() { return process_memory_; } 42 const std::shared_ptr<unwindstack::Memory>& process_memory() { return process_memory_; }
43 43
44 protected: 44 protected:
45 uint64_t GetLoadBias(size_t index) override;
46
45 std::unique_ptr<unwindstack::Maps> stack_maps_; 47 std::unique_ptr<unwindstack::Maps> stack_maps_;
46 std::shared_ptr<unwindstack::Memory> process_memory_; 48 std::shared_ptr<unwindstack::Memory> process_memory_;
47}; 49};
diff --git a/libbacktrace/backtrace_offline_test.cpp b/libbacktrace/backtrace_offline_test.cpp
index 0a1f33dfa..d1b44a117 100644
--- a/libbacktrace/backtrace_offline_test.cpp
+++ b/libbacktrace/backtrace_offline_test.cpp
@@ -27,6 +27,7 @@
27#include <vector> 27#include <vector>
28 28
29#include <android-base/file.h> 29#include <android-base/file.h>
30#include <android-base/logging.h>
30#include <android-base/macros.h> 31#include <android-base/macros.h>
31#include <android-base/stringprintf.h> 32#include <android-base/stringprintf.h>
32#include <android-base/strings.h> 33#include <android-base/strings.h>
@@ -171,10 +172,12 @@ TEST(libbacktrace, DISABLED_generate_offline_testdata) {
171 testdata += android::base::StringPrintf("pid: %d tid: %d\n", getpid(), arg.tid); 172 testdata += android::base::StringPrintf("pid: %d tid: %d\n", getpid(), arg.tid);
172 // 2. Dump maps 173 // 2. Dump maps
173 for (auto it = map->begin(); it != map->end(); ++it) { 174 for (auto it = map->begin(); it != map->end(); ++it) {
174 testdata += android::base::StringPrintf( 175 const backtrace_map_t* entry = *it;
175 "map: start: %" PRIxPTR " end: %" PRIxPTR " offset: %" PRIxPTR " load_bias: %" PRIxPTR 176 testdata +=
176 " flags: %d name: %s\n", 177 android::base::StringPrintf("map: start: %" PRIxPTR " end: %" PRIxPTR " offset: %" PRIxPTR
177 it->start, it->end, it->offset, it->load_bias, it->flags, it->name.c_str()); 178 " load_bias: %" PRIxPTR " flags: %d name: %s\n",
179 entry->start, entry->end, entry->offset, entry->load_bias,
180 entry->flags, entry->name.c_str());
178 } 181 }
179 // 3. Dump registers 182 // 3. Dump registers
180 testdata += android::base::StringPrintf("registers: %zu ", sizeof(arg.unw_context)); 183 testdata += android::base::StringPrintf("registers: %zu ", sizeof(arg.unw_context));
@@ -249,12 +252,21 @@ bool ReadOfflineTestData(const std::string offline_testdata_path, OfflineTestDat
249 return false; 252 return false;
250 } 253 }
251 HexStringToRawData(&line[pos], &testdata->unw_context, size); 254 HexStringToRawData(&line[pos], &testdata->unw_context, size);
255#if defined(__arm__)
256 } else if (android::base::StartsWith(line, "regs:")) {
257 uint64_t pc;
258 uint64_t sp;
259 sscanf(line.c_str(), "regs: pc: %" SCNx64 " sp: %" SCNx64, &pc, &sp);
260 testdata->unw_context.regs[13] = sp;
261 testdata->unw_context.regs[15] = pc;
262#endif
252 } else if (android::base::StartsWith(line, "stack:")) { 263 } else if (android::base::StartsWith(line, "stack:")) {
253 size_t size; 264 size_t size;
254 int pos; 265 int pos;
255 sscanf(line.c_str(), 266 sscanf(line.c_str(),
256 "stack: start: %" SCNx64 " end: %" SCNx64 " size: %zu %n", 267 "stack: start: %" SCNx64 " end: %" SCNx64 " size: %zu %n",
257 &testdata->stack_info.start, &testdata->stack_info.end, &size, &pos); 268 &testdata->stack_info.start, &testdata->stack_info.end, &size, &pos);
269 CHECK_EQ(testdata->stack_info.end - testdata->stack_info.start, size);
258 testdata->stack.resize(size); 270 testdata->stack.resize(size);
259 HexStringToRawData(&line[pos], &testdata->stack[0], size); 271 HexStringToRawData(&line[pos], &testdata->stack[0], size);
260 testdata->stack_info.data = testdata->stack.data(); 272 testdata->stack_info.data = testdata->stack.data();
@@ -389,3 +401,44 @@ TEST(libbacktrace, offline_unwind_mix_eh_frame_and_arm_exidx) {
389 ASSERT_EQ(name, testdata.symbols[i].name); 401 ASSERT_EQ(name, testdata.symbols[i].name);
390 } 402 }
391} 403}
404
405TEST(libbacktrace, offline_debug_frame_with_load_bias) {
406 if (std::string(ABI_STRING) != "arm") {
407 GTEST_LOG_(INFO) << "Skipping test since offline for arm on " << ABI_STRING
408 << " isn't supported.";
409 return;
410 }
411 const std::string testlib_path(GetTestPath("libandroid_runtime.so"));
412 struct stat st;
413 ASSERT_EQ(0, stat(testlib_path.c_str(), &st)) << "can't find testlib " << testlib_path;
414
415 const std::string offline_testdata_path(GetTestPath("offline_testdata_for_libandroid_runtime"));
416 OfflineTestData testdata;
417 ASSERT_TRUE(ReadOfflineTestData(offline_testdata_path, &testdata));
418
419 // Fix path of /system/lib/libandroid_runtime.so.
420 for (auto& map : testdata.maps) {
421 if (map.name.find("libandroid_runtime.so") != std::string::npos) {
422 map.name = testlib_path;
423 }
424 }
425
426 // Do offline backtrace.
427 std::unique_ptr<BacktraceMap> map(BacktraceMap::Create(testdata.pid, testdata.maps));
428 ASSERT_TRUE(map != nullptr);
429
430 std::unique_ptr<Backtrace> backtrace(
431 Backtrace::CreateOffline(testdata.pid, testdata.tid, map.get(), testdata.stack_info));
432 ASSERT_TRUE(backtrace != nullptr);
433
434 ucontext_t ucontext = GetUContextFromUnwContext(testdata.unw_context);
435 ASSERT_TRUE(backtrace->Unwind(0, &ucontext));
436
437 ASSERT_EQ(testdata.symbols.size(), backtrace->NumFrames());
438 for (size_t i = 0; i < backtrace->NumFrames(); ++i) {
439 uintptr_t vaddr_in_file =
440 backtrace->GetFrame(i)->pc - testdata.maps[0].start + testdata.maps[0].load_bias;
441 std::string name = FunctionNameForAddress(vaddr_in_file, testdata.symbols);
442 ASSERT_EQ(name, testdata.symbols[i].name);
443 }
444}
diff --git a/libbacktrace/backtrace_test.cpp b/libbacktrace/backtrace_test.cpp
index 9911e74a6..890ab3f0e 100644
--- a/libbacktrace/backtrace_test.cpp
+++ b/libbacktrace/backtrace_test.cpp
@@ -857,6 +857,34 @@ struct map_test_t {
857 857
858static bool map_sort(map_test_t i, map_test_t j) { return i.start < j.start; } 858static bool map_sort(map_test_t i, map_test_t j) { return i.start < j.start; }
859 859
860static std::string GetTestMapsAsString(const std::vector<map_test_t>& maps) {
861 if (maps.size() == 0) {
862 return "No test map entries\n";
863 }
864 std::string map_txt;
865 for (auto map : maps) {
866 map_txt += android::base::StringPrintf("%" PRIxPTR "-%" PRIxPTR "\n", map.start, map.end);
867 }
868 return map_txt;
869}
870
871static std::string GetMapsAsString(BacktraceMap* maps) {
872 if (maps->size() == 0) {
873 return "No map entries\n";
874 }
875 std::string map_txt;
876 for (const backtrace_map_t* map : *maps) {
877 map_txt += android::base::StringPrintf(
878 "%" PRIxPTR "-%" PRIxPTR " flags: 0x%x offset: 0x%" PRIxPTR " load_bias: 0x%" PRIxPTR,
879 map->start, map->end, map->flags, map->offset, map->load_bias);
880 if (!map->name.empty()) {
881 map_txt += ' ' + map->name;
882 }
883 map_txt += '\n';
884 }
885 return map_txt;
886}
887
860static void VerifyMap(pid_t pid) { 888static void VerifyMap(pid_t pid) {
861 char buffer[4096]; 889 char buffer[4096];
862 snprintf(buffer, sizeof(buffer), "/proc/%d/maps", pid); 890 snprintf(buffer, sizeof(buffer), "/proc/%d/maps", pid);
@@ -875,12 +903,20 @@ static void VerifyMap(pid_t pid) {
875 std::unique_ptr<BacktraceMap> map(BacktraceMap::Create(pid)); 903 std::unique_ptr<BacktraceMap> map(BacktraceMap::Create(pid));
876 904
877 // Basic test that verifies that the map is in the expected order. 905 // Basic test that verifies that the map is in the expected order.
878 ScopedBacktraceMapIteratorLock lock(map.get()); 906 auto test_it = test_maps.begin();
879 std::vector<map_test_t>::const_iterator test_it = test_maps.begin(); 907 for (auto it = map->begin(); it != map->end(); ++it) {
880 for (BacktraceMap::const_iterator it = map->begin(); it != map->end(); ++it) { 908 ASSERT_TRUE(test_it != test_maps.end()) << "Mismatch in number of maps, expected test maps:\n"
881 ASSERT_TRUE(test_it != test_maps.end()); 909 << GetTestMapsAsString(test_maps) << "Actual maps:\n"
882 ASSERT_EQ(test_it->start, it->start); 910 << GetMapsAsString(map.get());
883 ASSERT_EQ(test_it->end, it->end); 911 ASSERT_EQ(test_it->start, (*it)->start) << "Mismatch in map data, expected test maps:\n"
912 << GetTestMapsAsString(test_maps) << "Actual maps:\n"
913 << GetMapsAsString(map.get());
914 ASSERT_EQ(test_it->end, (*it)->end) << "Mismatch maps in map data, expected test maps:\n"
915 << GetTestMapsAsString(test_maps) << "Actual maps:\n"
916 << GetMapsAsString(map.get());
917 // Make sure the load bias get set to a value.
918 ASSERT_NE(static_cast<uint64_t>(-1), (*it)->load_bias) << "Found uninitialized load_bias\n"
919 << GetMapsAsString(map.get());
884 ++test_it; 920 ++test_it;
885 } 921 }
886 ASSERT_TRUE(test_it == test_maps.end()); 922 ASSERT_TRUE(test_it == test_maps.end());
diff --git a/libbacktrace/include/backtrace/BacktraceMap.h b/libbacktrace/include/backtrace/BacktraceMap.h
index d0783929a..4ae68dde0 100644
--- a/libbacktrace/include/backtrace/BacktraceMap.h
+++ b/libbacktrace/include/backtrace/BacktraceMap.h
@@ -30,6 +30,7 @@
30#endif 30#endif
31 31
32#include <deque> 32#include <deque>
33#include <iterator>
33#include <string> 34#include <string>
34#include <vector> 35#include <vector>
35 36
@@ -61,6 +62,49 @@ public:
61 62
62 virtual ~BacktraceMap(); 63 virtual ~BacktraceMap();
63 64
65 class iterator : public std::iterator<std::bidirectional_iterator_tag, backtrace_map_t*> {
66 public:
67 iterator(BacktraceMap* map, size_t index) : map_(map), index_(index) {}
68
69 iterator& operator++() {
70 index_++;
71 return *this;
72 }
73 iterator& operator++(int increment) {
74 index_ += increment;
75 return *this;
76 }
77 iterator& operator--() {
78 index_--;
79 return *this;
80 }
81 iterator& operator--(int decrement) {
82 index_ -= decrement;
83 return *this;
84 }
85
86 bool operator==(const iterator& rhs) { return this->index_ == rhs.index_; }
87 bool operator!=(const iterator& rhs) { return this->index_ != rhs.index_; }
88
89 const backtrace_map_t* operator*() {
90 if (index_ >= map_->size()) {
91 return nullptr;
92 }
93 backtrace_map_t* map = &map_->maps_[index_];
94 if (map->load_bias == static_cast<uintptr_t>(-1)) {
95 map->load_bias = map_->GetLoadBias(index_);
96 }
97 return map;
98 }
99
100 private:
101 BacktraceMap* map_ = nullptr;
102 size_t index_ = 0;
103 };
104
105 iterator begin() { return iterator(this, 0); }
106 iterator end() { return iterator(this, maps_.size()); }
107
64 // Fill in the map data structure for the given address. 108 // Fill in the map data structure for the given address.
65 virtual void FillIn(uintptr_t addr, backtrace_map_t* map); 109 virtual void FillIn(uintptr_t addr, backtrace_map_t* map);
66 110
@@ -89,14 +133,6 @@ public:
89 virtual void LockIterator() {} 133 virtual void LockIterator() {}
90 virtual void UnlockIterator() {} 134 virtual void UnlockIterator() {}
91 135
92 typedef std::deque<backtrace_map_t>::iterator iterator;
93 iterator begin() { return maps_.begin(); }
94 iterator end() { return maps_.end(); }
95
96 typedef std::deque<backtrace_map_t>::const_iterator const_iterator;
97 const_iterator begin() const { return maps_.begin(); }
98 const_iterator end() const { return maps_.end(); }
99
100 size_t size() const { return maps_.size(); } 136 size_t size() const { return maps_.size(); }
101 137
102 virtual bool Build(); 138 virtual bool Build();
@@ -114,6 +150,8 @@ public:
114 protected: 150 protected:
115 BacktraceMap(pid_t pid); 151 BacktraceMap(pid_t pid);
116 152
153 virtual uint64_t GetLoadBias(size_t /* index */) { return 0; }
154
117 virtual bool ParseLine(const char* line, backtrace_map_t* map); 155 virtual bool ParseLine(const char* line, backtrace_map_t* map);
118 156
119 pid_t pid_; 157 pid_t pid_;
diff --git a/libbacktrace/testdata/arm/libandroid_runtime.so b/libbacktrace/testdata/arm/libandroid_runtime.so
new file mode 100644
index 000000000..e4283e63b
--- /dev/null
+++ b/libbacktrace/testdata/arm/libandroid_runtime.so
Binary files differ
diff --git a/libbacktrace/testdata/arm/offline_testdata_for_libandroid_runtime b/libbacktrace/testdata/arm/offline_testdata_for_libandroid_runtime
new file mode 100644
index 000000000..a12bc3c5b
--- /dev/null
+++ b/libbacktrace/testdata/arm/offline_testdata_for_libandroid_runtime
@@ -0,0 +1,6 @@
1pid: 7288 tid: 31656
2regs: pc: f1f6dc49 sp: d8fe6930
3map: start: f1f10000 end: f2049000 offset: 0 load_bias: 10000 flags: 5 name: /system/lib/libandroid_runtime.so
4stack: start: d8fe6954 end: d8fe6958 size: 4 e7dcf6f1
5function: start: 6dbf9 end: 6dce5 name: android::AndroidRuntime::javaThreadShell
6function: start: 6dce5 end: 6dd79 name: android::AndroidRuntime::javaCreateThreadEtc
diff --git a/libcutils/android_reboot.cpp b/libcutils/android_reboot.cpp
index 5e864d442..ce41cd320 100644
--- a/libcutils/android_reboot.cpp
+++ b/libcutils/android_reboot.cpp
@@ -23,7 +23,7 @@
23 23
24#define TAG "android_reboot" 24#define TAG "android_reboot"
25 25
26int android_reboot(int cmd, int flags __unused, const char* arg) { 26int android_reboot(int cmd, int /*flags*/, const char* arg) {
27 int ret; 27 int ret;
28 const char* restart_cmd = NULL; 28 const char* restart_cmd = NULL;
29 char* prop_value; 29 char* prop_value;
diff --git a/libcutils/ashmem-host.cpp b/libcutils/ashmem-host.cpp
index d2c28f393..b2bec9966 100644
--- a/libcutils/ashmem-host.cpp
+++ b/libcutils/ashmem-host.cpp
@@ -35,12 +35,7 @@
35 35
36#include <utils/Compat.h> 36#include <utils/Compat.h>
37 37
38#ifndef __unused 38int ashmem_create_region(const char* /*ignored*/, size_t size) {
39#define __unused __attribute__((__unused__))
40#endif
41
42int ashmem_create_region(const char *ignored __unused, size_t size)
43{
44 char pattern[PATH_MAX]; 39 char pattern[PATH_MAX];
45 snprintf(pattern, sizeof(pattern), "/tmp/android-ashmem-%d-XXXXXXXXX", getpid()); 40 snprintf(pattern, sizeof(pattern), "/tmp/android-ashmem-%d-XXXXXXXXX", getpid());
46 int fd = mkstemp(pattern); 41 int fd = mkstemp(pattern);
@@ -56,18 +51,15 @@ int ashmem_create_region(const char *ignored __unused, size_t size)
56 return fd; 51 return fd;
57} 52}
58 53
59int ashmem_set_prot_region(int fd __unused, int prot __unused) 54int ashmem_set_prot_region(int /*fd*/, int /*prot*/) {
60{
61 return 0; 55 return 0;
62} 56}
63 57
64int ashmem_pin_region(int fd __unused, size_t offset __unused, size_t len __unused) 58int ashmem_pin_region(int /*fd*/, size_t /*offset*/, size_t /*len*/) {
65{
66 return 0 /*ASHMEM_NOT_PURGED*/; 59 return 0 /*ASHMEM_NOT_PURGED*/;
67} 60}
68 61
69int ashmem_unpin_region(int fd __unused, size_t offset __unused, size_t len __unused) 62int ashmem_unpin_region(int /*fd*/, size_t /*offset*/, size_t /*len*/) {
70{
71 return 0 /*ASHMEM_IS_UNPINNED*/; 63 return 0 /*ASHMEM_IS_UNPINNED*/;
72} 64}
73 65
diff --git a/libcutils/sched_policy.cpp b/libcutils/sched_policy.cpp
index 0e6d33333..f5ce82fea 100644
--- a/libcutils/sched_policy.cpp
+++ b/libcutils/sched_policy.cpp
@@ -27,8 +27,6 @@
27 27
28#include <log/log.h> 28#include <log/log.h>
29 29
30#define UNUSED __attribute__((__unused__))
31
32/* Re-map SP_DEFAULT to the system default policy, and leave other values unchanged. 30/* Re-map SP_DEFAULT to the system default policy, and leave other values unchanged.
33 * Call this any place a SchedPolicy is used as an input parameter. 31 * Call this any place a SchedPolicy is used as an input parameter.
34 * Returns the possibly re-mapped policy. 32 * Returns the possibly re-mapped policy.
@@ -445,13 +443,11 @@ int set_sched_policy(int tid, SchedPolicy policy)
445 443
446/* Stubs for non-Android targets. */ 444/* Stubs for non-Android targets. */
447 445
448int set_sched_policy(int tid UNUSED, SchedPolicy policy UNUSED) 446int set_sched_policy(int /*tid*/, SchedPolicy /*policy*/) {
449{
450 return 0; 447 return 0;
451} 448}
452 449
453int get_sched_policy(int tid UNUSED, SchedPolicy *policy) 450int get_sched_policy(int /*tid*/, SchedPolicy* policy) {
454{
455 *policy = SP_SYSTEM_DEFAULT; 451 *policy = SP_SYSTEM_DEFAULT;
456 return 0; 452 return 0;
457} 453}
diff --git a/libcutils/socket_local_client_unix.cpp b/libcutils/socket_local_client_unix.cpp
index 68b2b0ce9..d2b4909d9 100644
--- a/libcutils/socket_local_client_unix.cpp
+++ b/libcutils/socket_local_client_unix.cpp
@@ -39,8 +39,6 @@ int socket_local_client(const char *name, int namespaceId, int type)
39 39
40#include "socket_local_unix.h" 40#include "socket_local_unix.h"
41 41
42#define UNUSED __attribute__((unused))
43
44#define LISTEN_BACKLOG 4 42#define LISTEN_BACKLOG 4
45 43
46/* Documented in header file. */ 44/* Documented in header file. */
@@ -123,9 +121,7 @@ error:
123 * 121 *
124 * Used by AndroidSocketImpl 122 * Used by AndroidSocketImpl
125 */ 123 */
126int socket_local_client_connect(int fd, const char *name, int namespaceId, 124int socket_local_client_connect(int fd, const char* name, int namespaceId, int /*type*/) {
127 int type UNUSED)
128{
129 struct sockaddr_un addr; 125 struct sockaddr_un addr;
130 socklen_t alen; 126 socklen_t alen;
131 int err; 127 int err;
diff --git a/libcutils/str_parms.cpp b/libcutils/str_parms.cpp
index 139d62f6d..f5a52a767 100644
--- a/libcutils/str_parms.cpp
+++ b/libcutils/str_parms.cpp
@@ -30,8 +30,6 @@
30#include <cutils/memory.h> 30#include <cutils/memory.h>
31#include <log/log.h> 31#include <log/log.h>
32 32
33#define UNUSED __attribute__((unused))
34
35/* When an object is allocated but not freed in a function, 33/* When an object is allocated but not freed in a function,
36 * because its ownership is released to other object like a hashmap, 34 * because its ownership is released to other object like a hashmap,
37 * call RELEASE_OWNERSHIP to tell the clang analyzer and avoid 35 * call RELEASE_OWNERSHIP to tell the clang analyzer and avoid
@@ -364,8 +362,7 @@ char *str_parms_to_str(struct str_parms *str_parms)
364 return str; 362 return str;
365} 363}
366 364
367static bool dump_entry(void *key, void *value, void *context UNUSED) 365static bool dump_entry(void* key, void* value, void* /*context*/) {
368{
369 ALOGI("key: '%s' value: '%s'\n", (char *)key, (char *)value); 366 ALOGI("key: '%s' value: '%s'\n", (char *)key, (char *)value);
370 return true; 367 return true;
371} 368}
diff --git a/libcutils/trace-host.cpp b/libcutils/trace-host.cpp
index 05842cd7d..d47cc1861 100644
--- a/libcutils/trace-host.cpp
+++ b/libcutils/trace-host.cpp
@@ -16,21 +16,17 @@
16 16
17#include <cutils/trace.h> 17#include <cutils/trace.h>
18 18
19#ifndef __unused
20#define __unused __attribute__((__unused__))
21#endif
22
23atomic_bool atrace_is_ready = ATOMIC_VAR_INIT(true); 19atomic_bool atrace_is_ready = ATOMIC_VAR_INIT(true);
24int atrace_marker_fd = -1; 20int atrace_marker_fd = -1;
25uint64_t atrace_enabled_tags = 0; 21uint64_t atrace_enabled_tags = 0;
26 22
27void atrace_set_debuggable(bool debuggable __unused) { } 23void atrace_set_debuggable(bool /*debuggable*/) {}
28void atrace_set_tracing_enabled(bool enabled __unused) { } 24void atrace_set_tracing_enabled(bool /*enabled*/) {}
29void atrace_update_tags() { } 25void atrace_update_tags() { }
30void atrace_setup() { } 26void atrace_setup() { }
31void atrace_begin_body(const char* name __unused) { } 27void atrace_begin_body(const char* /*name*/) {}
32void atrace_end_body() { } 28void atrace_end_body() { }
33void atrace_async_begin_body(const char* name __unused, int32_t cookie __unused) { } 29void atrace_async_begin_body(const char* /*name*/, int32_t /*cookie*/) {}
34void atrace_async_end_body(const char* name __unused, int32_t cookie __unused) { } 30void atrace_async_end_body(const char* /*name*/, int32_t /*cookie*/) {}
35void atrace_int_body(const char* name __unused, int32_t value __unused) { } 31void atrace_int_body(const char* /*name*/, int32_t /*value*/) {}
36void atrace_int64_body(const char* name __unused, int64_t value __unused) { } 32void atrace_int64_body(const char* /*name*/, int64_t /*value*/) {}
diff --git a/liblog/event_tag_map.cpp b/liblog/event_tag_map.cpp
index 83064fde3..2e2bf8734 100644
--- a/liblog/event_tag_map.cpp
+++ b/liblog/event_tag_map.cpp
@@ -25,9 +25,9 @@
25#include <string.h> 25#include <string.h>
26#include <sys/mman.h> 26#include <sys/mman.h>
27 27
28#include <experimental/string_view>
29#include <functional> 28#include <functional>
30#include <string> 29#include <string>
30#include <string_view>
31#include <unordered_map> 31#include <unordered_map>
32 32
33#include <log/event_tag_map.h> 33#include <log/event_tag_map.h>
@@ -44,10 +44,10 @@
44class MapString { 44class MapString {
45 private: 45 private:
46 const std::string* alloc; // HAS-AN 46 const std::string* alloc; // HAS-AN
47 const std::experimental::string_view str; // HAS-A 47 const std::string_view str; // HAS-A
48 48
49 public: 49 public:
50 operator const std::experimental::string_view() const { 50 operator const std::string_view() const {
51 return str; 51 return str;
52 } 52 }
53 53
@@ -92,8 +92,7 @@ struct std::hash<MapString>
92 : public std::unary_function<const MapString&, size_t> { 92 : public std::unary_function<const MapString&, size_t> {
93 size_t operator()(const MapString& __t) const noexcept { 93 size_t operator()(const MapString& __t) const noexcept {
94 if (!__t.length()) return 0; 94 if (!__t.length()) return 0;
95 return std::hash<std::experimental::string_view>()( 95 return std::hash<std::string_view>()(std::string_view(__t));
96 std::experimental::string_view(__t));
97 } 96 }
98}; 97};
99 98
diff --git a/liblog/logger_write.c b/liblog/logger_write.c
index 589ce8429..d03a2b674 100644
--- a/liblog/logger_write.c
+++ b/liblog/logger_write.c
@@ -270,7 +270,7 @@ static int __write_to_log_daemon(log_id_t log_id, struct iovec* vec, size_t nr)
270 /* If only we could reset downstream logd counter */ 270 /* If only we could reset downstream logd counter */
271 return -EPERM; 271 return -EPERM;
272 } 272 }
273 } else if (log_id == LOG_ID_EVENTS) { 273 } else if (log_id == LOG_ID_EVENTS || log_id == LOG_ID_STATS) {
274 const char* tag; 274 const char* tag;
275 size_t len; 275 size_t len;
276 EventTagMap *m, *f; 276 EventTagMap *m, *f;
diff --git a/liblog/tests/Android.mk b/liblog/tests/Android.mk
index 275a2d681..39b52ac35 100644
--- a/liblog/tests/Android.mk
+++ b/liblog/tests/Android.mk
@@ -54,7 +54,7 @@ test_c_flags := \
54 -Werror \ 54 -Werror \
55 -fno-builtin \ 55 -fno-builtin \
56 56
57test_src_files := \ 57cts_src_files := \
58 libc_test.cpp \ 58 libc_test.cpp \
59 liblog_test_default.cpp \ 59 liblog_test_default.cpp \
60 liblog_test_local.cpp \ 60 liblog_test_local.cpp \
@@ -67,6 +67,9 @@ test_src_files := \
67 log_time_test.cpp \ 67 log_time_test.cpp \
68 log_wrap_test.cpp 68 log_wrap_test.cpp
69 69
70test_src_files := \
71 $(cts_src_files) \
72
70# Build tests for the device (with .so). Run with: 73# Build tests for the device (with .so). Run with:
71# adb shell /data/nativetest/liblog-unit-tests/liblog-unit-tests 74# adb shell /data/nativetest/liblog-unit-tests/liblog-unit-tests
72include $(CLEAR_VARS) 75include $(CLEAR_VARS)
@@ -82,15 +85,15 @@ cts_executable := CtsLiblogTestCases
82include $(CLEAR_VARS) 85include $(CLEAR_VARS)
83LOCAL_MODULE := $(cts_executable) 86LOCAL_MODULE := $(cts_executable)
84LOCAL_MODULE_TAGS := tests 87LOCAL_MODULE_TAGS := tests
85LOCAL_CFLAGS += $(test_c_flags) 88LOCAL_CFLAGS += $(test_c_flags) -DNO_PSTORE
86LOCAL_SRC_FILES := $(test_src_files) 89LOCAL_SRC_FILES := $(cts_src_files)
87LOCAL_MODULE_PATH := $(TARGET_OUT_DATA)/nativetest 90LOCAL_MODULE_PATH := $(TARGET_OUT_DATA)/nativetest
88LOCAL_MULTILIB := both 91LOCAL_MULTILIB := both
89LOCAL_MODULE_STEM_32 := $(LOCAL_MODULE)32 92LOCAL_MODULE_STEM_32 := $(LOCAL_MODULE)32
90LOCAL_MODULE_STEM_64 := $(LOCAL_MODULE)64 93LOCAL_MODULE_STEM_64 := $(LOCAL_MODULE)64
91LOCAL_SHARED_LIBRARIES := liblog libcutils libbase 94LOCAL_SHARED_LIBRARIES := liblog libcutils libbase
92LOCAL_STATIC_LIBRARIES := libgtest libgtest_main 95LOCAL_STATIC_LIBRARIES := libgtest libgtest_main
93LOCAL_COMPATIBILITY_SUITE := cts 96LOCAL_COMPATIBILITY_SUITE := cts vts
94LOCAL_CTS_TEST_PACKAGE := android.core.liblog 97LOCAL_CTS_TEST_PACKAGE := android.core.liblog
95include $(BUILD_CTS_EXECUTABLE) 98include $(BUILD_CTS_EXECUTABLE)
96 99
diff --git a/liblog/tests/liblog_test.cpp b/liblog/tests/liblog_test.cpp
index e2d5aeb46..597a6bb90 100644
--- a/liblog/tests/liblog_test.cpp
+++ b/liblog/tests/liblog_test.cpp
@@ -116,6 +116,7 @@ static std::string popenToString(const std::string& command) {
116 return ret; 116 return ret;
117} 117}
118 118
119#ifndef NO_PSTORE
119static bool isPmsgActive() { 120static bool isPmsgActive() {
120 pid_t pid = getpid(); 121 pid_t pid = getpid();
121 122
@@ -125,6 +126,7 @@ static bool isPmsgActive() {
125 126
126 return std::string::npos != myPidFds.find(" -> /dev/pmsg0"); 127 return std::string::npos != myPidFds.find(" -> /dev/pmsg0");
127} 128}
129#endif /* NO_PSTORE */
128 130
129static bool isLogdwActive() { 131static bool isLogdwActive() {
130 std::string logdwSignature = 132 std::string logdwSignature =
@@ -189,22 +191,25 @@ TEST(liblog, __android_log_btwrite__android_logger_list_read) {
189 EXPECT_LT(0, __android_log_btwrite(0, EVENT_TYPE_LONG, &ts, sizeof(ts))); 191 EXPECT_LT(0, __android_log_btwrite(0, EVENT_TYPE_LONG, &ts, sizeof(ts)));
190#ifdef USING_LOGGER_DEFAULT 192#ifdef USING_LOGGER_DEFAULT
191 // Check that we can close and reopen the logger 193 // Check that we can close and reopen the logger
192 bool pmsgActiveAfter__android_log_btwrite;
193 bool logdwActiveAfter__android_log_btwrite; 194 bool logdwActiveAfter__android_log_btwrite;
194 if (getuid() == AID_ROOT) { 195 if (getuid() == AID_ROOT) {
195 tested__android_log_close = true; 196 tested__android_log_close = true;
196 pmsgActiveAfter__android_log_btwrite = isPmsgActive(); 197#ifndef NO_PSTORE
197 logdwActiveAfter__android_log_btwrite = isLogdwActive(); 198 bool pmsgActiveAfter__android_log_btwrite = isPmsgActive();
198 EXPECT_TRUE(pmsgActiveAfter__android_log_btwrite); 199 EXPECT_TRUE(pmsgActiveAfter__android_log_btwrite);
200#endif /* NO_PSTORE */
201 logdwActiveAfter__android_log_btwrite = isLogdwActive();
199 EXPECT_TRUE(logdwActiveAfter__android_log_btwrite); 202 EXPECT_TRUE(logdwActiveAfter__android_log_btwrite);
200 } else if (!tested__android_log_close) { 203 } else if (!tested__android_log_close) {
201 fprintf(stderr, "WARNING: can not test __android_log_close()\n"); 204 fprintf(stderr, "WARNING: can not test __android_log_close()\n");
202 } 205 }
203 __android_log_close(); 206 __android_log_close();
204 if (getuid() == AID_ROOT) { 207 if (getuid() == AID_ROOT) {
208#ifndef NO_PSTORE
205 bool pmsgActiveAfter__android_log_close = isPmsgActive(); 209 bool pmsgActiveAfter__android_log_close = isPmsgActive();
206 bool logdwActiveAfter__android_log_close = isLogdwActive();
207 EXPECT_FALSE(pmsgActiveAfter__android_log_close); 210 EXPECT_FALSE(pmsgActiveAfter__android_log_close);
211#endif /* NO_PSTORE */
212 bool logdwActiveAfter__android_log_close = isLogdwActive();
208 EXPECT_FALSE(logdwActiveAfter__android_log_close); 213 EXPECT_FALSE(logdwActiveAfter__android_log_close);
209 } 214 }
210#endif 215#endif
@@ -213,9 +218,11 @@ TEST(liblog, __android_log_btwrite__android_logger_list_read) {
213 EXPECT_LT(0, __android_log_btwrite(0, EVENT_TYPE_LONG, &ts1, sizeof(ts1))); 218 EXPECT_LT(0, __android_log_btwrite(0, EVENT_TYPE_LONG, &ts1, sizeof(ts1)));
214#ifdef USING_LOGGER_DEFAULT 219#ifdef USING_LOGGER_DEFAULT
215 if (getuid() == AID_ROOT) { 220 if (getuid() == AID_ROOT) {
216 pmsgActiveAfter__android_log_btwrite = isPmsgActive(); 221#ifndef NO_PSTORE
217 logdwActiveAfter__android_log_btwrite = isLogdwActive(); 222 bool pmsgActiveAfter__android_log_btwrite = isPmsgActive();
218 EXPECT_TRUE(pmsgActiveAfter__android_log_btwrite); 223 EXPECT_TRUE(pmsgActiveAfter__android_log_btwrite);
224#endif /* NO_PSTORE */
225 logdwActiveAfter__android_log_btwrite = isLogdwActive();
219 EXPECT_TRUE(logdwActiveAfter__android_log_btwrite); 226 EXPECT_TRUE(logdwActiveAfter__android_log_btwrite);
220 } 227 }
221#endif 228#endif
@@ -3036,12 +3043,15 @@ TEST(liblog, android_log_write_list_buffer) {
3036 3043
3037#ifdef USING_LOGGER_DEFAULT // Do not retest pmsg functionality 3044#ifdef USING_LOGGER_DEFAULT // Do not retest pmsg functionality
3038#ifdef __ANDROID__ 3045#ifdef __ANDROID__
3046#ifndef NO_PSTORE
3039static const char __pmsg_file[] = 3047static const char __pmsg_file[] =
3040 "/data/william-shakespeare/MuchAdoAboutNothing.txt"; 3048 "/data/william-shakespeare/MuchAdoAboutNothing.txt";
3049#endif /* NO_PSTORE */
3041#endif 3050#endif
3042 3051
3043TEST(liblog, __android_log_pmsg_file_write) { 3052TEST(liblog, __android_log_pmsg_file_write) {
3044#ifdef __ANDROID__ 3053#ifdef __ANDROID__
3054#ifndef NO_PSTORE
3045 __android_log_close(); 3055 __android_log_close();
3046 if (getuid() == AID_ROOT) { 3056 if (getuid() == AID_ROOT) {
3047 tested__android_log_close = true; 3057 tested__android_log_close = true;
@@ -3092,12 +3102,16 @@ TEST(liblog, __android_log_pmsg_file_write) {
3092 EXPECT_TRUE(pmsgActiveAfter__android_pmsg_file_write); 3102 EXPECT_TRUE(pmsgActiveAfter__android_pmsg_file_write);
3093 EXPECT_TRUE(logdwActiveAfter__android_pmsg_file_write); 3103 EXPECT_TRUE(logdwActiveAfter__android_pmsg_file_write);
3094 } 3104 }
3105#else /* NO_PSTORE */
3106 GTEST_LOG_(INFO) << "This test does nothing because of NO_PSTORE.\n";
3107#endif /* NO_PSTORE */
3095#else 3108#else
3096 GTEST_LOG_(INFO) << "This test does nothing.\n"; 3109 GTEST_LOG_(INFO) << "This test does nothing.\n";
3097#endif 3110#endif
3098} 3111}
3099 3112
3100#ifdef __ANDROID__ 3113#ifdef __ANDROID__
3114#ifndef NO_PSTORE
3101static ssize_t __pmsg_fn(log_id_t logId, char prio, const char* filename, 3115static ssize_t __pmsg_fn(log_id_t logId, char prio, const char* filename,
3102 const char* buf, size_t len, void* arg) { 3116 const char* buf, size_t len, void* arg) {
3103 EXPECT_TRUE(NULL == arg); 3117 EXPECT_TRUE(NULL == arg);
@@ -3118,10 +3132,12 @@ static ssize_t __pmsg_fn(log_id_t logId, char prio, const char* filename,
3118 ? -ENOEXEC 3132 ? -ENOEXEC
3119 : 1; 3133 : 1;
3120} 3134}
3135#endif /* NO_PSTORE */
3121#endif 3136#endif
3122 3137
3123TEST(liblog, __android_log_pmsg_file_read) { 3138TEST(liblog, __android_log_pmsg_file_read) {
3124#ifdef __ANDROID__ 3139#ifdef __ANDROID__
3140#ifndef NO_PSTORE
3125 signaled = 0; 3141 signaled = 0;
3126 3142
3127 __android_log_close(); 3143 __android_log_close();
@@ -3155,6 +3171,9 @@ TEST(liblog, __android_log_pmsg_file_read) {
3155 3171
3156 EXPECT_LT(0, ret); 3172 EXPECT_LT(0, ret);
3157 EXPECT_EQ(1U, signaled); 3173 EXPECT_EQ(1U, signaled);
3174#else /* NO_PSTORE */
3175 GTEST_LOG_(INFO) << "This test does nothing because of NO_PSTORE.\n";
3176#endif /* NO_PSTORE */
3158#else 3177#else
3159 GTEST_LOG_(INFO) << "This test does nothing.\n"; 3178 GTEST_LOG_(INFO) << "This test does nothing.\n";
3160#endif 3179#endif
diff --git a/libnativeloader/include/nativeloader/native_loader.h b/libnativeloader/include/nativeloader/native_loader.h
index 99ae3a759..3563fc149 100644
--- a/libnativeloader/include/nativeloader/native_loader.h
+++ b/libnativeloader/include/nativeloader/native_loader.h
@@ -34,6 +34,7 @@ jstring CreateClassLoaderNamespace(JNIEnv* env,
34 int32_t target_sdk_version, 34 int32_t target_sdk_version,
35 jobject class_loader, 35 jobject class_loader,
36 bool is_shared, 36 bool is_shared,
37 bool is_for_vendor,
37 jstring library_path, 38 jstring library_path,
38 jstring permitted_path); 39 jstring permitted_path);
39 40
diff --git a/libnativeloader/native_loader.cpp b/libnativeloader/native_loader.cpp
index 7ccd7db95..5d160eee7 100644
--- a/libnativeloader/native_loader.cpp
+++ b/libnativeloader/native_loader.cpp
@@ -82,6 +82,11 @@ static constexpr const char* kPublicNativeLibrariesSystemConfigPathFromRoot =
82 "/etc/public.libraries.txt"; 82 "/etc/public.libraries.txt";
83static constexpr const char* kPublicNativeLibrariesVendorConfig = 83static constexpr const char* kPublicNativeLibrariesVendorConfig =
84 "/vendor/etc/public.libraries.txt"; 84 "/vendor/etc/public.libraries.txt";
85static constexpr const char* kLlndkNativeLibrariesSystemConfigPathFromRoot =
86 "/etc/llndk.libraries.txt";
87static constexpr const char* kVndkspNativeLibrariesSystemConfigPathFromRoot =
88 "/etc/vndksp.libraries.txt";
89
85 90
86// The device may be configured to have the vendor libraries loaded to a separate namespace. 91// The device may be configured to have the vendor libraries loaded to a separate namespace.
87// For historical reasons this namespace was named sphal but effectively it is intended 92// For historical reasons this namespace was named sphal but effectively it is intended
@@ -89,6 +94,11 @@ static constexpr const char* kPublicNativeLibrariesVendorConfig =
89// vendor and system namespaces. 94// vendor and system namespaces.
90static constexpr const char* kVendorNamespaceName = "sphal"; 95static constexpr const char* kVendorNamespaceName = "sphal";
91 96
97static constexpr const char* kVndkNamespaceName = "vndk";
98
99static constexpr const char* kClassloaderNamespaceName = "classloader-namespace";
100static constexpr const char* kVendorClassloaderNamespaceName = "vendor-classloader-namespace";
101
92// (http://b/27588281) This is a workaround for apps using custom classloaders and calling 102// (http://b/27588281) This is a workaround for apps using custom classloaders and calling
93// System.load() with an absolute path which is outside of the classloader library search path. 103// System.load() with an absolute path which is outside of the classloader library search path.
94// This list includes all directories app is allowed to access this way. 104// This list includes all directories app is allowed to access this way.
@@ -108,6 +118,7 @@ class LibraryNamespaces {
108 uint32_t target_sdk_version, 118 uint32_t target_sdk_version,
109 jobject class_loader, 119 jobject class_loader,
110 bool is_shared, 120 bool is_shared,
121 bool is_for_vendor,
111 jstring java_library_path, 122 jstring java_library_path,
112 jstring java_permitted_path, 123 jstring java_permitted_path,
113 NativeLoaderNamespace* ns, 124 NativeLoaderNamespace* ns,
@@ -163,9 +174,39 @@ class LibraryNamespaces {
163 is_native_bridge = NativeBridgeIsPathSupported(library_path.c_str()); 174 is_native_bridge = NativeBridgeIsPathSupported(library_path.c_str());
164 } 175 }
165 176
177 std::string system_exposed_libraries = system_public_libraries_;
178 const char* namespace_name = kClassloaderNamespaceName;
179 android_namespace_t* vndk_ns = nullptr;
180 if (is_for_vendor && !is_shared) {
181 LOG_FATAL_IF(is_native_bridge, "Unbundled vendor apk must not use translated architecture");
182
183 // For vendor apks, give access to the vendor lib even though
184 // they are treated as unbundled; the libs and apks are still bundled
185 // together in the vendor partition.
186#if defined(__LP64__)
187 std::string vendor_lib_path = "/vendor/lib64";
188#else
189 std::string vendor_lib_path = "/vendor/lib";
190#endif
191 library_path = library_path + ":" + vendor_lib_path.c_str();
192 permitted_path = permitted_path + ":" + vendor_lib_path.c_str();
193
194 // Also give access to LLNDK libraries since they are available to vendors
195 system_exposed_libraries = system_exposed_libraries + ":" + system_llndk_libraries_.c_str();
196
197 // Give access to VNDK-SP libraries from the 'vndk' namespace.
198 vndk_ns = android_get_exported_namespace(kVndkNamespaceName);
199 LOG_ALWAYS_FATAL_IF(vndk_ns == nullptr,
200 "Cannot find \"%s\" namespace for vendor apks", kVndkNamespaceName);
201
202 // Different name is useful for debugging
203 namespace_name = kVendorClassloaderNamespaceName;
204 ALOGD("classloader namespace configured for unbundled vendor apk. library_path=%s", library_path.c_str());
205 }
206
166 NativeLoaderNamespace native_loader_ns; 207 NativeLoaderNamespace native_loader_ns;
167 if (!is_native_bridge) { 208 if (!is_native_bridge) {
168 android_namespace_t* ns = android_create_namespace("classloader-namespace", 209 android_namespace_t* ns = android_create_namespace(namespace_name,
169 nullptr, 210 nullptr,
170 library_path.c_str(), 211 library_path.c_str(),
171 namespace_type, 212 namespace_type,
@@ -181,11 +222,19 @@ class LibraryNamespaces {
181 // which is expected behavior in this case. 222 // which is expected behavior in this case.
182 android_namespace_t* vendor_ns = android_get_exported_namespace(kVendorNamespaceName); 223 android_namespace_t* vendor_ns = android_get_exported_namespace(kVendorNamespaceName);
183 224
184 if (!android_link_namespaces(ns, nullptr, system_public_libraries_.c_str())) { 225 if (!android_link_namespaces(ns, nullptr, system_exposed_libraries.c_str())) {
185 *error_msg = dlerror(); 226 *error_msg = dlerror();
186 return false; 227 return false;
187 } 228 }
188 229
230 if (vndk_ns != nullptr && !system_vndksp_libraries_.empty()) {
231 // vendor apks are allowed to use VNDK-SP libraries.
232 if (!android_link_namespaces(ns, vndk_ns, system_vndksp_libraries_.c_str())) {
233 *error_msg = dlerror();
234 return false;
235 }
236 }
237
189 if (!vendor_public_libraries_.empty()) { 238 if (!vendor_public_libraries_.empty()) {
190 if (!android_link_namespaces(ns, vendor_ns, vendor_public_libraries_.c_str())) { 239 if (!android_link_namespaces(ns, vendor_ns, vendor_public_libraries_.c_str())) {
191 *error_msg = dlerror(); 240 *error_msg = dlerror();
@@ -195,7 +244,7 @@ class LibraryNamespaces {
195 244
196 native_loader_ns = NativeLoaderNamespace(ns); 245 native_loader_ns = NativeLoaderNamespace(ns);
197 } else { 246 } else {
198 native_bridge_namespace_t* ns = NativeBridgeCreateNamespace("classloader-namespace", 247 native_bridge_namespace_t* ns = NativeBridgeCreateNamespace(namespace_name,
199 nullptr, 248 nullptr,
200 library_path.c_str(), 249 library_path.c_str(),
201 namespace_type, 250 namespace_type,
@@ -209,7 +258,7 @@ class LibraryNamespaces {
209 258
210 native_bridge_namespace_t* vendor_ns = NativeBridgeGetVendorNamespace(); 259 native_bridge_namespace_t* vendor_ns = NativeBridgeGetVendorNamespace();
211 260
212 if (!NativeBridgeLinkNamespaces(ns, nullptr, system_public_libraries_.c_str())) { 261 if (!NativeBridgeLinkNamespaces(ns, nullptr, system_exposed_libraries.c_str())) {
213 *error_msg = NativeBridgeGetError(); 262 *error_msg = NativeBridgeGetError();
214 return false; 263 return false;
215 } 264 }
@@ -259,6 +308,10 @@ class LibraryNamespaces {
259 std::string root_dir = android_root_env != nullptr ? android_root_env : "/system"; 308 std::string root_dir = android_root_env != nullptr ? android_root_env : "/system";
260 std::string public_native_libraries_system_config = 309 std::string public_native_libraries_system_config =
261 root_dir + kPublicNativeLibrariesSystemConfigPathFromRoot; 310 root_dir + kPublicNativeLibrariesSystemConfigPathFromRoot;
311 std::string llndk_native_libraries_system_config =
312 root_dir + kLlndkNativeLibrariesSystemConfigPathFromRoot;
313 std::string vndksp_native_libraries_system_config =
314 root_dir + kVndkspNativeLibrariesSystemConfigPathFromRoot;
262 315
263 std::string error_msg; 316 std::string error_msg;
264 LOG_ALWAYS_FATAL_IF(!ReadConfig(public_native_libraries_system_config, &sonames, &error_msg), 317 LOG_ALWAYS_FATAL_IF(!ReadConfig(public_native_libraries_system_config, &sonames, &error_msg),
@@ -294,6 +347,14 @@ class LibraryNamespaces {
294 system_public_libraries_ = base::Join(sonames, ':'); 347 system_public_libraries_ = base::Join(sonames, ':');
295 348
296 sonames.clear(); 349 sonames.clear();
350 ReadConfig(kLlndkNativeLibrariesSystemConfigPathFromRoot, &sonames);
351 system_llndk_libraries_ = base::Join(sonames, ':');
352
353 sonames.clear();
354 ReadConfig(kVndkspNativeLibrariesSystemConfigPathFromRoot, &sonames);
355 system_vndksp_libraries_ = base::Join(sonames, ':');
356
357 sonames.clear();
297 // This file is optional, quietly ignore if the file does not exist. 358 // This file is optional, quietly ignore if the file does not exist.
298 ReadConfig(kPublicNativeLibrariesVendorConfig, &sonames); 359 ReadConfig(kPublicNativeLibrariesVendorConfig, &sonames);
299 360
@@ -404,6 +465,8 @@ class LibraryNamespaces {
404 std::vector<std::pair<jweak, NativeLoaderNamespace>> namespaces_; 465 std::vector<std::pair<jweak, NativeLoaderNamespace>> namespaces_;
405 std::string system_public_libraries_; 466 std::string system_public_libraries_;
406 std::string vendor_public_libraries_; 467 std::string vendor_public_libraries_;
468 std::string system_llndk_libraries_;
469 std::string system_vndksp_libraries_;
407 470
408 DISALLOW_COPY_AND_ASSIGN(LibraryNamespaces); 471 DISALLOW_COPY_AND_ASSIGN(LibraryNamespaces);
409}; 472};
@@ -430,6 +493,7 @@ jstring CreateClassLoaderNamespace(JNIEnv* env,
430 int32_t target_sdk_version, 493 int32_t target_sdk_version,
431 jobject class_loader, 494 jobject class_loader,
432 bool is_shared, 495 bool is_shared,
496 bool is_for_vendor,
433 jstring library_path, 497 jstring library_path,
434 jstring permitted_path) { 498 jstring permitted_path) {
435#if defined(__ANDROID__) 499#if defined(__ANDROID__)
@@ -441,6 +505,7 @@ jstring CreateClassLoaderNamespace(JNIEnv* env,
441 target_sdk_version, 505 target_sdk_version,
442 class_loader, 506 class_loader,
443 is_shared, 507 is_shared,
508 is_for_vendor,
444 library_path, 509 library_path,
445 permitted_path, 510 permitted_path,
446 &ns, 511 &ns,
@@ -449,7 +514,7 @@ jstring CreateClassLoaderNamespace(JNIEnv* env,
449 return env->NewStringUTF(error_msg.c_str()); 514 return env->NewStringUTF(error_msg.c_str());
450 } 515 }
451#else 516#else
452 UNUSED(env, target_sdk_version, class_loader, is_shared, 517 UNUSED(env, target_sdk_version, class_loader, is_shared, is_for_vendor,
453 library_path, permitted_path); 518 library_path, permitted_path);
454#endif 519#endif
455 return nullptr; 520 return nullptr;
@@ -478,7 +543,8 @@ void* OpenNativeLibrary(JNIEnv* env,
478 if (!g_namespaces->Create(env, 543 if (!g_namespaces->Create(env,
479 target_sdk_version, 544 target_sdk_version,
480 class_loader, 545 class_loader,
481 false, 546 false /* is_shared */,
547 false /* is_for_vendor */,
482 library_path, 548 library_path,
483 nullptr, 549 nullptr,
484 &ns, 550 &ns,
diff --git a/libsystem/include/system/thread_defs.h b/libsystem/include/system/thread_defs.h
index 377a48ce9..80d11608b 100644
--- a/libsystem/include/system/thread_defs.h
+++ b/libsystem/include/system/thread_defs.h
@@ -55,6 +55,9 @@ enum {
55 /* ui service treads might want to run at a urgent display (uncommon) */ 55 /* ui service treads might want to run at a urgent display (uncommon) */
56 ANDROID_PRIORITY_URGENT_DISPLAY = HAL_PRIORITY_URGENT_DISPLAY, 56 ANDROID_PRIORITY_URGENT_DISPLAY = HAL_PRIORITY_URGENT_DISPLAY,
57 57
58 /* all normal video threads */
59 ANDROID_PRIORITY_VIDEO = -10,
60
58 /* all normal audio threads */ 61 /* all normal audio threads */
59 ANDROID_PRIORITY_AUDIO = -16, 62 ANDROID_PRIORITY_AUDIO = -16,
60 63
diff --git a/libunwindstack/Android.bp b/libunwindstack/Android.bp
index 75aa427f5..4125b1204 100644
--- a/libunwindstack/Android.bp
+++ b/libunwindstack/Android.bp
@@ -60,6 +60,10 @@ cc_library {
60 "Maps.cpp", 60 "Maps.cpp",
61 "Memory.cpp", 61 "Memory.cpp",
62 "Regs.cpp", 62 "Regs.cpp",
63 "RegsArm.cpp",
64 "RegsArm64.cpp",
65 "RegsX86.cpp",
66 "RegsX86_64.cpp",
63 "Unwinder.cpp", 67 "Unwinder.cpp",
64 "Symbols.cpp", 68 "Symbols.cpp",
65 ], 69 ],
@@ -118,6 +122,7 @@ cc_test {
118 "tests/ElfTestUtils.cpp", 122 "tests/ElfTestUtils.cpp",
119 "tests/LogFake.cpp", 123 "tests/LogFake.cpp",
120 "tests/MapInfoGetElfTest.cpp", 124 "tests/MapInfoGetElfTest.cpp",
125 "tests/MapInfoGetLoadBiasTest.cpp",
121 "tests/MapsTest.cpp", 126 "tests/MapsTest.cpp",
122 "tests/MemoryBufferTest.cpp", 127 "tests/MemoryBufferTest.cpp",
123 "tests/MemoryFake.cpp", 128 "tests/MemoryFake.cpp",
diff --git a/libunwindstack/ArmExidx.cpp b/libunwindstack/ArmExidx.cpp
index fed3e0e0f..6b0646fbc 100644
--- a/libunwindstack/ArmExidx.cpp
+++ b/libunwindstack/ArmExidx.cpp
@@ -23,11 +23,11 @@
23 23
24#include <unwindstack/Log.h> 24#include <unwindstack/Log.h>
25#include <unwindstack/Memory.h> 25#include <unwindstack/Memory.h>
26#include <unwindstack/Regs.h> 26#include <unwindstack/RegsArm.h>
27 27
28#include "ArmExidx.h" 28#include "ArmExidx.h"
29#include "Check.h" 29#include "Check.h"
30#include "Machine.h" 30#include "MachineArm.h"
31 31
32namespace unwindstack { 32namespace unwindstack {
33 33
diff --git a/libunwindstack/DwarfMemory.cpp b/libunwindstack/DwarfMemory.cpp
index 901f49285..6ffdc0de1 100644
--- a/libunwindstack/DwarfMemory.cpp
+++ b/libunwindstack/DwarfMemory.cpp
@@ -27,7 +27,7 @@
27namespace unwindstack { 27namespace unwindstack {
28 28
29bool DwarfMemory::ReadBytes(void* dst, size_t num_bytes) { 29bool DwarfMemory::ReadBytes(void* dst, size_t num_bytes) {
30 if (!memory_->Read(cur_offset_, dst, num_bytes)) { 30 if (!memory_->ReadFully(cur_offset_, dst, num_bytes)) {
31 return false; 31 return false;
32 } 32 }
33 cur_offset_ += num_bytes; 33 cur_offset_ += num_bytes;
diff --git a/libunwindstack/DwarfOp.cpp b/libunwindstack/DwarfOp.cpp
index b3fd0df91..3b3d340f4 100644
--- a/libunwindstack/DwarfOp.cpp
+++ b/libunwindstack/DwarfOp.cpp
@@ -141,7 +141,7 @@ bool DwarfOp<AddressType>::op_deref() {
141 // Read the address and dereference it. 141 // Read the address and dereference it.
142 AddressType addr = StackPop(); 142 AddressType addr = StackPop();
143 AddressType value; 143 AddressType value;
144 if (!regular_memory()->Read(addr, &value, sizeof(value))) { 144 if (!regular_memory()->ReadFully(addr, &value, sizeof(value))) {
145 last_error_ = DWARF_ERROR_MEMORY_INVALID; 145 last_error_ = DWARF_ERROR_MEMORY_INVALID;
146 return false; 146 return false;
147 } 147 }
@@ -159,7 +159,7 @@ bool DwarfOp<AddressType>::op_deref_size() {
159 // Read the address and dereference it. 159 // Read the address and dereference it.
160 AddressType addr = StackPop(); 160 AddressType addr = StackPop();
161 AddressType value = 0; 161 AddressType value = 0;
162 if (!regular_memory()->Read(addr, &value, bytes_to_read)) { 162 if (!regular_memory()->ReadFully(addr, &value, bytes_to_read)) {
163 last_error_ = DWARF_ERROR_MEMORY_INVALID; 163 last_error_ = DWARF_ERROR_MEMORY_INVALID;
164 return false; 164 return false;
165 } 165 }
diff --git a/libunwindstack/DwarfSection.cpp b/libunwindstack/DwarfSection.cpp
index 805dcd34b..095418726 100644
--- a/libunwindstack/DwarfSection.cpp
+++ b/libunwindstack/DwarfSection.cpp
@@ -142,7 +142,7 @@ bool DwarfSectionImpl<AddressType>::Eval(const DwarfCie* cie, Memory* regular_me
142 return false; 142 return false;
143 } 143 }
144 if (loc->type == DWARF_LOCATION_EXPRESSION) { 144 if (loc->type == DWARF_LOCATION_EXPRESSION) {
145 if (!regular_memory->Read(value, &cfa, sizeof(AddressType))) { 145 if (!regular_memory->ReadFully(value, &cfa, sizeof(AddressType))) {
146 last_error_ = DWARF_ERROR_MEMORY_INVALID; 146 last_error_ = DWARF_ERROR_MEMORY_INVALID;
147 return false; 147 return false;
148 } 148 }
@@ -175,7 +175,8 @@ bool DwarfSectionImpl<AddressType>::Eval(const DwarfCie* cie, Memory* regular_me
175 const DwarfLocation* loc = &entry.second; 175 const DwarfLocation* loc = &entry.second;
176 switch (loc->type) { 176 switch (loc->type) {
177 case DWARF_LOCATION_OFFSET: 177 case DWARF_LOCATION_OFFSET:
178 if (!regular_memory->Read(cfa + loc->values[0], &(*cur_regs)[reg], sizeof(AddressType))) { 178 if (!regular_memory->ReadFully(cfa + loc->values[0], &(*cur_regs)[reg],
179 sizeof(AddressType))) {
179 last_error_ = DWARF_ERROR_MEMORY_INVALID; 180 last_error_ = DWARF_ERROR_MEMORY_INVALID;
180 return false; 181 return false;
181 } 182 }
@@ -210,7 +211,7 @@ bool DwarfSectionImpl<AddressType>::Eval(const DwarfCie* cie, Memory* regular_me
210 return false; 211 return false;
211 } 212 }
212 if (loc->type == DWARF_LOCATION_EXPRESSION) { 213 if (loc->type == DWARF_LOCATION_EXPRESSION) {
213 if (!regular_memory->Read(value, &(*cur_regs)[reg], sizeof(AddressType))) { 214 if (!regular_memory->ReadFully(value, &(*cur_regs)[reg], sizeof(AddressType))) {
214 last_error_ = DWARF_ERROR_MEMORY_INVALID; 215 last_error_ = DWARF_ERROR_MEMORY_INVALID;
215 return false; 216 return false;
216 } 217 }
diff --git a/libunwindstack/Elf.cpp b/libunwindstack/Elf.cpp
index 48e33ee2b..025429f52 100644
--- a/libunwindstack/Elf.cpp
+++ b/libunwindstack/Elf.cpp
@@ -31,7 +31,6 @@
31#include <unwindstack/Regs.h> 31#include <unwindstack/Regs.h>
32 32
33#include "ElfInterfaceArm.h" 33#include "ElfInterfaceArm.h"
34#include "Machine.h"
35#include "Symbols.h" 34#include "Symbols.h"
36 35
37namespace unwindstack { 36namespace unwindstack {
@@ -136,7 +135,7 @@ bool Elf::IsValidElf(Memory* memory) {
136 135
137 // Verify that this is a valid elf file. 136 // Verify that this is a valid elf file.
138 uint8_t e_ident[SELFMAG + 1]; 137 uint8_t e_ident[SELFMAG + 1];
139 if (!memory->Read(0, e_ident, SELFMAG)) { 138 if (!memory->ReadFully(0, e_ident, SELFMAG)) {
140 return false; 139 return false;
141 } 140 }
142 141
@@ -156,7 +155,7 @@ void Elf::GetInfo(Memory* memory, bool* valid, uint64_t* size) {
156 155
157 // Now read the section header information. 156 // Now read the section header information.
158 uint8_t class_type; 157 uint8_t class_type;
159 if (!memory->Read(EI_CLASS, &class_type, 1)) { 158 if (!memory->ReadFully(EI_CLASS, &class_type, 1)) {
160 return; 159 return;
161 } 160 }
162 if (class_type == ELFCLASS32) { 161 if (class_type == ELFCLASS32) {
@@ -174,45 +173,65 @@ ElfInterface* Elf::CreateInterfaceFromMemory(Memory* memory) {
174 } 173 }
175 174
176 std::unique_ptr<ElfInterface> interface; 175 std::unique_ptr<ElfInterface> interface;
177 if (!memory->Read(EI_CLASS, &class_type_, 1)) { 176 if (!memory->ReadFully(EI_CLASS, &class_type_, 1)) {
178 return nullptr; 177 return nullptr;
179 } 178 }
180 if (class_type_ == ELFCLASS32) { 179 if (class_type_ == ELFCLASS32) {
181 Elf32_Half e_machine; 180 Elf32_Half e_machine;
182 if (!memory->Read(EI_NIDENT + sizeof(Elf32_Half), &e_machine, sizeof(e_machine))) { 181 if (!memory->ReadFully(EI_NIDENT + sizeof(Elf32_Half), &e_machine, sizeof(e_machine))) {
183 return nullptr;
184 }
185
186 if (e_machine != EM_ARM && e_machine != EM_386) {
187 // Unsupported.
188 ALOGI("32 bit elf that is neither arm nor x86: e_machine = %d\n", e_machine);
189 return nullptr; 182 return nullptr;
190 } 183 }
191 184
192 machine_type_ = e_machine; 185 machine_type_ = e_machine;
193 if (e_machine == EM_ARM) { 186 if (e_machine == EM_ARM) {
187 arch_ = ARCH_ARM;
194 interface.reset(new ElfInterfaceArm(memory)); 188 interface.reset(new ElfInterfaceArm(memory));
195 } else if (e_machine == EM_386) { 189 } else if (e_machine == EM_386) {
190 arch_ = ARCH_X86;
196 interface.reset(new ElfInterface32(memory)); 191 interface.reset(new ElfInterface32(memory));
197 } else { 192 } else {
193 // Unsupported.
198 ALOGI("32 bit elf that is neither arm nor x86: e_machine = %d\n", e_machine); 194 ALOGI("32 bit elf that is neither arm nor x86: e_machine = %d\n", e_machine);
199 return nullptr; 195 return nullptr;
200 } 196 }
201 } else if (class_type_ == ELFCLASS64) { 197 } else if (class_type_ == ELFCLASS64) {
202 Elf64_Half e_machine; 198 Elf64_Half e_machine;
203 if (!memory->Read(EI_NIDENT + sizeof(Elf64_Half), &e_machine, sizeof(e_machine))) { 199 if (!memory->ReadFully(EI_NIDENT + sizeof(Elf64_Half), &e_machine, sizeof(e_machine))) {
204 return nullptr; 200 return nullptr;
205 } 201 }
206 if (e_machine != EM_AARCH64 && e_machine != EM_X86_64) { 202
203 machine_type_ = e_machine;
204 if (e_machine == EM_AARCH64) {
205 arch_ = ARCH_ARM64;
206 } else if (e_machine == EM_X86_64) {
207 arch_ = ARCH_X86_64;
208 } else {
207 // Unsupported. 209 // Unsupported.
208 ALOGI("64 bit elf that is neither aarch64 nor x86_64: e_machine = %d\n", e_machine); 210 ALOGI("64 bit elf that is neither aarch64 nor x86_64: e_machine = %d\n", e_machine);
209 return nullptr; 211 return nullptr;
210 } 212 }
211 machine_type_ = e_machine;
212 interface.reset(new ElfInterface64(memory)); 213 interface.reset(new ElfInterface64(memory));
213 } 214 }
214 215
215 return interface.release(); 216 return interface.release();
216} 217}
217 218
219uint64_t Elf::GetLoadBias(Memory* memory) {
220 if (!IsValidElf(memory)) {
221 return 0;
222 }
223
224 uint8_t class_type;
225 if (!memory->Read(EI_CLASS, &class_type, 1)) {
226 return 0;
227 }
228
229 if (class_type == ELFCLASS32) {
230 return ElfInterface::GetLoadBias<Elf32_Ehdr, Elf32_Phdr>(memory);
231 } else if (class_type == ELFCLASS64) {
232 return ElfInterface::GetLoadBias<Elf64_Ehdr, Elf64_Phdr>(memory);
233 }
234 return 0;
235}
236
218} // namespace unwindstack 237} // namespace unwindstack
diff --git a/libunwindstack/ElfInterface.cpp b/libunwindstack/ElfInterface.cpp
index d5d158f82..334cf76f6 100644
--- a/libunwindstack/ElfInterface.cpp
+++ b/libunwindstack/ElfInterface.cpp
@@ -53,7 +53,7 @@ Memory* ElfInterface::CreateGnuDebugdataMemory() {
53 Crc64GenerateTable(); 53 Crc64GenerateTable();
54 54
55 std::vector<uint8_t> src(gnu_debugdata_size_); 55 std::vector<uint8_t> src(gnu_debugdata_size_);
56 if (!memory_->Read(gnu_debugdata_offset_, src.data(), gnu_debugdata_size_)) { 56 if (!memory_->ReadFully(gnu_debugdata_offset_, src.data(), gnu_debugdata_size_)) {
57 gnu_debugdata_offset_ = 0; 57 gnu_debugdata_offset_ = 0;
58 gnu_debugdata_size_ = static_cast<uint64_t>(-1); 58 gnu_debugdata_size_ = static_cast<uint64_t>(-1);
59 return nullptr; 59 return nullptr;
@@ -131,7 +131,7 @@ void ElfInterface::InitHeadersWithTemplate() {
131template <typename EhdrType, typename PhdrType, typename ShdrType> 131template <typename EhdrType, typename PhdrType, typename ShdrType>
132bool ElfInterface::ReadAllHeaders(uint64_t* load_bias) { 132bool ElfInterface::ReadAllHeaders(uint64_t* load_bias) {
133 EhdrType ehdr; 133 EhdrType ehdr;
134 if (!memory_->Read(0, &ehdr, sizeof(ehdr))) { 134 if (!memory_->ReadFully(0, &ehdr, sizeof(ehdr))) {
135 return false; 135 return false;
136 } 136 }
137 137
@@ -148,6 +148,26 @@ bool ElfInterface::ReadAllHeaders(uint64_t* load_bias) {
148} 148}
149 149
150template <typename EhdrType, typename PhdrType> 150template <typename EhdrType, typename PhdrType>
151uint64_t ElfInterface::GetLoadBias(Memory* memory) {
152 EhdrType ehdr;
153 if (!memory->Read(0, &ehdr, sizeof(ehdr))) {
154 return false;
155 }
156
157 uint64_t offset = ehdr.e_phoff;
158 for (size_t i = 0; i < ehdr.e_phnum; i++, offset += ehdr.e_phentsize) {
159 PhdrType phdr;
160 if (!memory->Read(offset, &phdr, sizeof(phdr))) {
161 return 0;
162 }
163 if (phdr.p_type == PT_LOAD && phdr.p_offset == 0) {
164 return phdr.p_vaddr;
165 }
166 }
167 return 0;
168}
169
170template <typename EhdrType, typename PhdrType>
151bool ElfInterface::ReadProgramHeaders(const EhdrType& ehdr, uint64_t* load_bias) { 171bool ElfInterface::ReadProgramHeaders(const EhdrType& ehdr, uint64_t* load_bias) {
152 uint64_t offset = ehdr.e_phoff; 172 uint64_t offset = ehdr.e_phoff;
153 for (size_t i = 0; i < ehdr.e_phnum; i++, offset += ehdr.e_phentsize) { 173 for (size_t i = 0; i < ehdr.e_phnum; i++, offset += ehdr.e_phentsize) {
@@ -242,7 +262,7 @@ bool ElfInterface::ReadSectionHeaders(const EhdrType& ehdr) {
242 } 262 }
243 263
244 if (shdr.sh_type == SHT_SYMTAB || shdr.sh_type == SHT_DYNSYM) { 264 if (shdr.sh_type == SHT_SYMTAB || shdr.sh_type == SHT_DYNSYM) {
245 if (!memory_->Read(offset, &shdr, sizeof(shdr))) { 265 if (!memory_->ReadFully(offset, &shdr, sizeof(shdr))) {
246 return false; 266 return false;
247 } 267 }
248 // Need to go get the information about the section that contains 268 // Need to go get the information about the section that contains
@@ -324,7 +344,7 @@ bool ElfInterface::GetSonameWithTemplate(std::string* soname) {
324 uint64_t offset = dynamic_offset_; 344 uint64_t offset = dynamic_offset_;
325 uint64_t max_offset = offset + dynamic_size_; 345 uint64_t max_offset = offset + dynamic_size_;
326 for (uint64_t offset = dynamic_offset_; offset < max_offset; offset += sizeof(DynType)) { 346 for (uint64_t offset = dynamic_offset_; offset < max_offset; offset += sizeof(DynType)) {
327 if (!memory_->Read(offset, &dyn, sizeof(dyn))) { 347 if (!memory_->ReadFully(offset, &dyn, sizeof(dyn))) {
328 return false; 348 return false;
329 } 349 }
330 350
@@ -388,7 +408,7 @@ bool ElfInterface::Step(uint64_t pc, Regs* regs, Memory* process_memory, bool* f
388template <typename EhdrType> 408template <typename EhdrType>
389void ElfInterface::GetMaxSizeWithTemplate(Memory* memory, uint64_t* size) { 409void ElfInterface::GetMaxSizeWithTemplate(Memory* memory, uint64_t* size) {
390 EhdrType ehdr; 410 EhdrType ehdr;
391 if (!memory->Read(0, &ehdr, sizeof(ehdr))) { 411 if (!memory->ReadFully(0, &ehdr, sizeof(ehdr))) {
392 return; 412 return;
393 } 413 }
394 if (ehdr.e_shnum == 0) { 414 if (ehdr.e_shnum == 0) {
@@ -421,4 +441,7 @@ template bool ElfInterface::GetFunctionNameWithTemplate<Elf64_Sym>(uint64_t, uin
421template void ElfInterface::GetMaxSizeWithTemplate<Elf32_Ehdr>(Memory*, uint64_t*); 441template void ElfInterface::GetMaxSizeWithTemplate<Elf32_Ehdr>(Memory*, uint64_t*);
422template void ElfInterface::GetMaxSizeWithTemplate<Elf64_Ehdr>(Memory*, uint64_t*); 442template void ElfInterface::GetMaxSizeWithTemplate<Elf64_Ehdr>(Memory*, uint64_t*);
423 443
444template uint64_t ElfInterface::GetLoadBias<Elf32_Ehdr, Elf32_Phdr>(Memory*);
445template uint64_t ElfInterface::GetLoadBias<Elf64_Ehdr, Elf64_Phdr>(Memory*);
446
424} // namespace unwindstack 447} // namespace unwindstack
diff --git a/libunwindstack/ElfInterfaceArm.cpp b/libunwindstack/ElfInterfaceArm.cpp
index 170a5cdf7..9841e2474 100644
--- a/libunwindstack/ElfInterfaceArm.cpp
+++ b/libunwindstack/ElfInterfaceArm.cpp
@@ -18,11 +18,11 @@
18#include <stdint.h> 18#include <stdint.h>
19 19
20#include <unwindstack/Memory.h> 20#include <unwindstack/Memory.h>
21#include <unwindstack/Regs.h> 21#include <unwindstack/RegsArm.h>
22 22
23#include "ArmExidx.h" 23#include "ArmExidx.h"
24#include "ElfInterfaceArm.h" 24#include "ElfInterfaceArm.h"
25#include "Machine.h" 25#include "MachineArm.h"
26 26
27namespace unwindstack { 27namespace unwindstack {
28 28
diff --git a/libunwindstack/Machine.h b/libunwindstack/Machine.h
deleted file mode 100644
index 1fb930905..000000000
--- a/libunwindstack/Machine.h
+++ /dev/null
@@ -1,141 +0,0 @@
1/*
2 * Copyright (C) 2016 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 _LIBUNWINDSTACK_MACHINE_H
18#define _LIBUNWINDSTACK_MACHINE_H
19
20#include <stdint.h>
21
22namespace unwindstack {
23
24enum ArmReg : uint16_t {
25 ARM_REG_R0 = 0,
26 ARM_REG_R1,
27 ARM_REG_R2,
28 ARM_REG_R3,
29 ARM_REG_R4,
30 ARM_REG_R5,
31 ARM_REG_R6,
32 ARM_REG_R7,
33 ARM_REG_R8,
34 ARM_REG_R9,
35 ARM_REG_R10,
36 ARM_REG_R11,
37 ARM_REG_R12,
38 ARM_REG_R13,
39 ARM_REG_R14,
40 ARM_REG_R15,
41 ARM_REG_LAST,
42
43 ARM_REG_SP = ARM_REG_R13,
44 ARM_REG_LR = ARM_REG_R14,
45 ARM_REG_PC = ARM_REG_R15,
46};
47
48enum Arm64Reg : uint16_t {
49 ARM64_REG_R0 = 0,
50 ARM64_REG_R1,
51 ARM64_REG_R2,
52 ARM64_REG_R3,
53 ARM64_REG_R4,
54 ARM64_REG_R5,
55 ARM64_REG_R6,
56 ARM64_REG_R7,
57 ARM64_REG_R8,
58 ARM64_REG_R9,
59 ARM64_REG_R10,
60 ARM64_REG_R11,
61 ARM64_REG_R12,
62 ARM64_REG_R13,
63 ARM64_REG_R14,
64 ARM64_REG_R15,
65 ARM64_REG_R16,
66 ARM64_REG_R17,
67 ARM64_REG_R18,
68 ARM64_REG_R19,
69 ARM64_REG_R20,
70 ARM64_REG_R21,
71 ARM64_REG_R22,
72 ARM64_REG_R23,
73 ARM64_REG_R24,
74 ARM64_REG_R25,
75 ARM64_REG_R26,
76 ARM64_REG_R27,
77 ARM64_REG_R28,
78 ARM64_REG_R29,
79 ARM64_REG_R30,
80 ARM64_REG_R31,
81 ARM64_REG_PC,
82 ARM64_REG_LAST,
83
84 ARM64_REG_SP = ARM64_REG_R31,
85 ARM64_REG_LR = ARM64_REG_R30,
86};
87
88// Matches the numbers for the registers as generated by compilers.
89// If this is changed, then unwinding will fail.
90enum X86Reg : uint16_t {
91 X86_REG_EAX = 0,
92 X86_REG_ECX = 1,
93 X86_REG_EDX = 2,
94 X86_REG_EBX = 3,
95 X86_REG_ESP = 4,
96 X86_REG_EBP = 5,
97 X86_REG_ESI = 6,
98 X86_REG_EDI = 7,
99 X86_REG_EIP = 8,
100 X86_REG_EFL = 9,
101 X86_REG_CS = 10,
102 X86_REG_SS = 11,
103 X86_REG_DS = 12,
104 X86_REG_ES = 13,
105 X86_REG_FS = 14,
106 X86_REG_GS = 15,
107 X86_REG_LAST,
108
109 X86_REG_SP = X86_REG_ESP,
110 X86_REG_PC = X86_REG_EIP,
111};
112
113// Matches the numbers for the registers as generated by compilers.
114// If this is changed, then unwinding will fail.
115enum X86_64Reg : uint16_t {
116 X86_64_REG_RAX = 0,
117 X86_64_REG_RDX = 1,
118 X86_64_REG_RCX = 2,
119 X86_64_REG_RBX = 3,
120 X86_64_REG_RSI = 4,
121 X86_64_REG_RDI = 5,
122 X86_64_REG_RBP = 6,
123 X86_64_REG_RSP = 7,
124 X86_64_REG_R8 = 8,
125 X86_64_REG_R9 = 9,
126 X86_64_REG_R10 = 10,
127 X86_64_REG_R11 = 11,
128 X86_64_REG_R12 = 12,
129 X86_64_REG_R13 = 13,
130 X86_64_REG_R14 = 14,
131 X86_64_REG_R15 = 15,
132 X86_64_REG_RIP = 16,
133 X86_64_REG_LAST,
134
135 X86_64_REG_SP = X86_64_REG_RSP,
136 X86_64_REG_PC = X86_64_REG_RIP,
137};
138
139} // namespace unwindstack
140
141#endif // _LIBUNWINDSTACK_MACHINE_H
diff --git a/libunwindstack/MachineArm.h b/libunwindstack/MachineArm.h
new file mode 100644
index 000000000..3f902b194
--- /dev/null
+++ b/libunwindstack/MachineArm.h
@@ -0,0 +1,50 @@
1/*
2 * Copyright (C) 2017 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 _LIBUNWINDSTACK_MACHINE_ARM_H
18#define _LIBUNWINDSTACK_MACHINE_ARM_H
19
20#include <stdint.h>
21
22namespace unwindstack {
23
24enum ArmReg : uint16_t {
25 ARM_REG_R0 = 0,
26 ARM_REG_R1,
27 ARM_REG_R2,
28 ARM_REG_R3,
29 ARM_REG_R4,
30 ARM_REG_R5,
31 ARM_REG_R6,
32 ARM_REG_R7,
33 ARM_REG_R8,
34 ARM_REG_R9,
35 ARM_REG_R10,
36 ARM_REG_R11,
37 ARM_REG_R12,
38 ARM_REG_R13,
39 ARM_REG_R14,
40 ARM_REG_R15,
41 ARM_REG_LAST,
42
43 ARM_REG_SP = ARM_REG_R13,
44 ARM_REG_LR = ARM_REG_R14,
45 ARM_REG_PC = ARM_REG_R15,
46};
47
48} // namespace unwindstack
49
50#endif // _LIBUNWINDSTACK_MACHINE_ARM_H
diff --git a/libunwindstack/MachineArm64.h b/libunwindstack/MachineArm64.h
new file mode 100644
index 000000000..e8b778b13
--- /dev/null
+++ b/libunwindstack/MachineArm64.h
@@ -0,0 +1,66 @@
1/*
2 * Copyright (C) 2017 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 _LIBUNWINDSTACK_MACHINE_ARM64_H
18#define _LIBUNWINDSTACK_MACHINE_ARM64_H
19
20#include <stdint.h>
21
22namespace unwindstack {
23
24enum Arm64Reg : uint16_t {
25 ARM64_REG_R0 = 0,
26 ARM64_REG_R1,
27 ARM64_REG_R2,
28 ARM64_REG_R3,
29 ARM64_REG_R4,
30 ARM64_REG_R5,
31 ARM64_REG_R6,
32 ARM64_REG_R7,
33 ARM64_REG_R8,
34 ARM64_REG_R9,
35 ARM64_REG_R10,
36 ARM64_REG_R11,
37 ARM64_REG_R12,
38 ARM64_REG_R13,
39 ARM64_REG_R14,
40 ARM64_REG_R15,
41 ARM64_REG_R16,
42 ARM64_REG_R17,
43 ARM64_REG_R18,
44 ARM64_REG_R19,
45 ARM64_REG_R20,
46 ARM64_REG_R21,
47 ARM64_REG_R22,
48 ARM64_REG_R23,
49 ARM64_REG_R24,
50 ARM64_REG_R25,
51 ARM64_REG_R26,
52 ARM64_REG_R27,
53 ARM64_REG_R28,
54 ARM64_REG_R29,
55 ARM64_REG_R30,
56 ARM64_REG_R31,
57 ARM64_REG_PC,
58 ARM64_REG_LAST,
59
60 ARM64_REG_SP = ARM64_REG_R31,
61 ARM64_REG_LR = ARM64_REG_R30,
62};
63
64} // namespace unwindstack
65
66#endif // _LIBUNWINDSTACK_MACHINE_ARM64_H
diff --git a/libunwindstack/MachineX86.h b/libunwindstack/MachineX86.h
new file mode 100644
index 000000000..02adb98c3
--- /dev/null
+++ b/libunwindstack/MachineX86.h
@@ -0,0 +1,51 @@
1/*
2 * Copyright (C) 2017 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 _LIBUNWINDSTACK_MACHINE_X86_H
18#define _LIBUNWINDSTACK_MACHINE_X86_H
19
20#include <stdint.h>
21
22namespace unwindstack {
23
24// Matches the numbers for the registers as generated by compilers.
25// If this is changed, then unwinding will fail.
26enum X86Reg : uint16_t {
27 X86_REG_EAX = 0,
28 X86_REG_ECX = 1,
29 X86_REG_EDX = 2,
30 X86_REG_EBX = 3,
31 X86_REG_ESP = 4,
32 X86_REG_EBP = 5,
33 X86_REG_ESI = 6,
34 X86_REG_EDI = 7,
35 X86_REG_EIP = 8,
36 X86_REG_EFL = 9,
37 X86_REG_CS = 10,
38 X86_REG_SS = 11,
39 X86_REG_DS = 12,
40 X86_REG_ES = 13,
41 X86_REG_FS = 14,
42 X86_REG_GS = 15,
43 X86_REG_LAST,
44
45 X86_REG_SP = X86_REG_ESP,
46 X86_REG_PC = X86_REG_EIP,
47};
48
49} // namespace unwindstack
50
51#endif // _LIBUNWINDSTACK_MACHINE_X86_H
diff --git a/libunwindstack/MachineX86_64.h b/libunwindstack/MachineX86_64.h
new file mode 100644
index 000000000..af33fea80
--- /dev/null
+++ b/libunwindstack/MachineX86_64.h
@@ -0,0 +1,52 @@
1/*
2 * Copyright (C) 2017 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 _LIBUNWINDSTACK_MACHINE_X86_64_H
18#define _LIBUNWINDSTACK_MACHINE_X86_64_H
19
20#include <stdint.h>
21
22namespace unwindstack {
23
24// Matches the numbers for the registers as generated by compilers.
25// If this is changed, then unwinding will fail.
26enum X86_64Reg : uint16_t {
27 X86_64_REG_RAX = 0,
28 X86_64_REG_RDX = 1,
29 X86_64_REG_RCX = 2,
30 X86_64_REG_RBX = 3,
31 X86_64_REG_RSI = 4,
32 X86_64_REG_RDI = 5,
33 X86_64_REG_RBP = 6,
34 X86_64_REG_RSP = 7,
35 X86_64_REG_R8 = 8,
36 X86_64_REG_R9 = 9,
37 X86_64_REG_R10 = 10,
38 X86_64_REG_R11 = 11,
39 X86_64_REG_R12 = 12,
40 X86_64_REG_R13 = 13,
41 X86_64_REG_R14 = 14,
42 X86_64_REG_R15 = 15,
43 X86_64_REG_RIP = 16,
44 X86_64_REG_LAST,
45
46 X86_64_REG_SP = X86_64_REG_RSP,
47 X86_64_REG_PC = X86_64_REG_RIP,
48};
49
50} // namespace unwindstack
51
52#endif // _LIBUNWINDSTACK_MACHINE_X86_64_H
diff --git a/libunwindstack/MapInfo.cpp b/libunwindstack/MapInfo.cpp
index 541765992..51bce8eea 100644
--- a/libunwindstack/MapInfo.cpp
+++ b/libunwindstack/MapInfo.cpp
@@ -102,7 +102,7 @@ Memory* MapInfo::CreateMemory(const std::shared_ptr<Memory>& process_memory) {
102 if (!(flags & PROT_READ)) { 102 if (!(flags & PROT_READ)) {
103 return nullptr; 103 return nullptr;
104 } 104 }
105 return new MemoryRange(process_memory, start, end); 105 return new MemoryRange(process_memory, start, end - start, 0);
106} 106}
107 107
108Elf* MapInfo::GetElf(const std::shared_ptr<Memory>& process_memory, bool init_gnu_debugdata) { 108Elf* MapInfo::GetElf(const std::shared_ptr<Memory>& process_memory, bool init_gnu_debugdata) {
@@ -121,4 +121,23 @@ Elf* MapInfo::GetElf(const std::shared_ptr<Memory>& process_memory, bool init_gn
121 return elf; 121 return elf;
122} 122}
123 123
124uint64_t MapInfo::GetLoadBias(const std::shared_ptr<Memory>& process_memory) {
125 {
126 // Make sure no other thread is trying to add the elf to this map.
127 std::lock_guard<std::mutex> guard(mutex_);
128 if (elf != nullptr) {
129 if (elf->valid()) {
130 return elf->GetLoadBias();
131 } else {
132 return 0;
133 }
134 }
135 }
136
137 // Call lightweight static function that will only read enough of the
138 // elf data to get the load bias.
139 std::unique_ptr<Memory> memory(CreateMemory(process_memory));
140 return Elf::GetLoadBias(memory.get());
141}
142
124} // namespace unwindstack 143} // namespace unwindstack
diff --git a/libunwindstack/Memory.cpp b/libunwindstack/Memory.cpp
index 32753df6f..b1b39a0b3 100644
--- a/libunwindstack/Memory.cpp
+++ b/libunwindstack/Memory.cpp
@@ -32,14 +32,69 @@
32 32
33#include "Check.h" 33#include "Check.h"
34 34
35static size_t ProcessVmRead(pid_t pid, void* dst, uint64_t remote_src, size_t len) {
36 struct iovec dst_iov = {
37 .iov_base = dst,
38 .iov_len = len,
39 };
40
41 // Split up the remote read across page boundaries.
42 // From the manpage:
43 // A partial read/write may result if one of the remote_iov elements points to an invalid
44 // memory region in the remote process.
45 //
46 // Partial transfers apply at the granularity of iovec elements. These system calls won't
47 // perform a partial transfer that splits a single iovec element.
48 constexpr size_t kMaxIovecs = 64;
49 struct iovec src_iovs[kMaxIovecs];
50 size_t iovecs_used = 0;
51
52 uint64_t cur = remote_src;
53 while (len > 0) {
54 if (iovecs_used == kMaxIovecs) {
55 errno = EINVAL;
56 return 0;
57 }
58
59 // struct iovec uses void* for iov_base.
60 if (cur >= UINTPTR_MAX) {
61 errno = EFAULT;
62 return 0;
63 }
64
65 src_iovs[iovecs_used].iov_base = reinterpret_cast<void*>(cur);
66
67 uintptr_t misalignment = cur & (getpagesize() - 1);
68 size_t iov_len = getpagesize() - misalignment;
69 iov_len = std::min(iov_len, len);
70
71 len -= iov_len;
72 if (__builtin_add_overflow(cur, iov_len, &cur)) {
73 errno = EFAULT;
74 return 0;
75 }
76
77 src_iovs[iovecs_used].iov_len = iov_len;
78 ++iovecs_used;
79 }
80
81 ssize_t rc = process_vm_readv(pid, &dst_iov, 1, src_iovs, iovecs_used, 0);
82 return rc == -1 ? 0 : rc;
83}
84
35namespace unwindstack { 85namespace unwindstack {
36 86
87bool Memory::ReadFully(uint64_t addr, void* dst, size_t size) {
88 size_t rc = Read(addr, dst, size);
89 return rc == size;
90}
91
37bool Memory::ReadString(uint64_t addr, std::string* string, uint64_t max_read) { 92bool Memory::ReadString(uint64_t addr, std::string* string, uint64_t max_read) {
38 string->clear(); 93 string->clear();
39 uint64_t bytes_read = 0; 94 uint64_t bytes_read = 0;
40 while (bytes_read < max_read) { 95 while (bytes_read < max_read) {
41 uint8_t value; 96 uint8_t value;
42 if (!Read(addr, &value, sizeof(value))) { 97 if (!ReadFully(addr, &value, sizeof(value))) {
43 return false; 98 return false;
44 } 99 }
45 if (value == '\0') { 100 if (value == '\0') {
@@ -59,16 +114,17 @@ std::shared_ptr<Memory> Memory::CreateProcessMemory(pid_t pid) {
59 return std::shared_ptr<Memory>(new MemoryRemote(pid)); 114 return std::shared_ptr<Memory>(new MemoryRemote(pid));
60} 115}
61 116
62bool MemoryBuffer::Read(uint64_t addr, void* dst, size_t size) { 117size_t MemoryBuffer::Read(uint64_t addr, void* dst, size_t size) {
63 uint64_t last_read_byte; 118 if (addr >= raw_.size()) {
64 if (__builtin_add_overflow(size, addr, &last_read_byte)) { 119 return 0;
65 return false;
66 } 120 }
67 if (last_read_byte > raw_.size()) { 121
68 return false; 122 size_t bytes_left = raw_.size() - static_cast<size_t>(addr);
69 } 123 const unsigned char* actual_base = static_cast<const unsigned char*>(raw_.data()) + addr;
70 memcpy(dst, &raw_[addr], size); 124 size_t actual_len = std::min(bytes_left, size);
71 return true; 125
126 memcpy(dst, actual_base, actual_len);
127 return actual_len;
72} 128}
73 129
74uint8_t* MemoryBuffer::GetPtr(size_t offset) { 130uint8_t* MemoryBuffer::GetPtr(size_t offset) {
@@ -129,45 +185,43 @@ bool MemoryFileAtOffset::Init(const std::string& file, uint64_t offset, uint64_t
129 return true; 185 return true;
130} 186}
131 187
132bool MemoryFileAtOffset::Read(uint64_t addr, void* dst, size_t size) { 188size_t MemoryFileAtOffset::Read(uint64_t addr, void* dst, size_t size) {
133 uint64_t max_size; 189 if (addr >= size_) {
134 if (__builtin_add_overflow(addr, size, &max_size) || max_size > size_) { 190 return 0;
135 return false;
136 } 191 }
137 memcpy(dst, &data_[addr], size); 192
138 return true; 193 size_t bytes_left = size_ - static_cast<size_t>(addr);
194 const unsigned char* actual_base = static_cast<const unsigned char*>(data_) + addr;
195 size_t actual_len = std::min(bytes_left, size);
196
197 memcpy(dst, actual_base, actual_len);
198 return actual_len;
139} 199}
140 200
141bool MemoryRemote::PtraceRead(uint64_t addr, long* value) { 201static bool PtraceReadLong(pid_t pid, uint64_t addr, long* value) {
142#if !defined(__LP64__)
143 // Cannot read an address greater than 32 bits.
144 if (addr > UINT32_MAX) {
145 return false;
146 }
147#endif
148 // ptrace() returns -1 and sets errno when the operation fails. 202 // ptrace() returns -1 and sets errno when the operation fails.
149 // To disambiguate -1 from a valid result, we clear errno beforehand. 203 // To disambiguate -1 from a valid result, we clear errno beforehand.
150 errno = 0; 204 errno = 0;
151 *value = ptrace(PTRACE_PEEKTEXT, pid_, reinterpret_cast<void*>(addr), nullptr); 205 *value = ptrace(PTRACE_PEEKTEXT, pid, reinterpret_cast<void*>(addr), nullptr);
152 if (*value == -1 && errno) { 206 if (*value == -1 && errno) {
153 return false; 207 return false;
154 } 208 }
155 return true; 209 return true;
156} 210}
157 211
158bool MemoryRemote::Read(uint64_t addr, void* dst, size_t bytes) { 212static size_t ReadWithPtrace(pid_t pid, uint64_t addr, void* dst, size_t bytes) {
159 // Make sure that there is no overflow. 213 // Make sure that there is no overflow.
160 uint64_t max_size; 214 uint64_t max_size;
161 if (__builtin_add_overflow(addr, bytes, &max_size)) { 215 if (__builtin_add_overflow(addr, bytes, &max_size)) {
162 return false; 216 return 0;
163 } 217 }
164 218
165 size_t bytes_read = 0; 219 size_t bytes_read = 0;
166 long data; 220 long data;
167 size_t align_bytes = addr & (sizeof(long) - 1); 221 size_t align_bytes = addr & (sizeof(long) - 1);
168 if (align_bytes != 0) { 222 if (align_bytes != 0) {
169 if (!PtraceRead(addr & ~(sizeof(long) - 1), &data)) { 223 if (!PtraceReadLong(pid, addr & ~(sizeof(long) - 1), &data)) {
170 return false; 224 return 0;
171 } 225 }
172 size_t copy_bytes = std::min(sizeof(long) - align_bytes, bytes); 226 size_t copy_bytes = std::min(sizeof(long) - align_bytes, bytes);
173 memcpy(dst, reinterpret_cast<uint8_t*>(&data) + align_bytes, copy_bytes); 227 memcpy(dst, reinterpret_cast<uint8_t*>(&data) + align_bytes, copy_bytes);
@@ -178,8 +232,8 @@ bool MemoryRemote::Read(uint64_t addr, void* dst, size_t bytes) {
178 } 232 }
179 233
180 for (size_t i = 0; i < bytes / sizeof(long); i++) { 234 for (size_t i = 0; i < bytes / sizeof(long); i++) {
181 if (!PtraceRead(addr, &data)) { 235 if (!PtraceReadLong(pid, addr, &data)) {
182 return false; 236 return bytes_read;
183 } 237 }
184 memcpy(dst, &data, sizeof(long)); 238 memcpy(dst, &data, sizeof(long));
185 dst = reinterpret_cast<void*>(reinterpret_cast<uintptr_t>(dst) + sizeof(long)); 239 dst = reinterpret_cast<void*>(reinterpret_cast<uintptr_t>(dst) + sizeof(long));
@@ -189,85 +243,79 @@ bool MemoryRemote::Read(uint64_t addr, void* dst, size_t bytes) {
189 243
190 size_t left_over = bytes & (sizeof(long) - 1); 244 size_t left_over = bytes & (sizeof(long) - 1);
191 if (left_over) { 245 if (left_over) {
192 if (!PtraceRead(addr, &data)) { 246 if (!PtraceReadLong(pid, addr, &data)) {
193 return false; 247 return bytes_read;
194 } 248 }
195 memcpy(dst, &data, left_over); 249 memcpy(dst, &data, left_over);
196 bytes_read += left_over; 250 bytes_read += left_over;
197 } 251 }
198 return true; 252 return bytes_read;
199} 253}
200 254
201bool MemoryLocal::Read(uint64_t addr, void* dst, size_t size) { 255size_t MemoryRemote::Read(uint64_t addr, void* dst, size_t size) {
202 // Make sure that there is no overflow. 256#if !defined(__LP64__)
203 uint64_t max_size; 257 // Cannot read an address greater than 32 bits.
204 if (__builtin_add_overflow(addr, size, &max_size)) { 258 if (addr > UINT32_MAX) {
205 return false; 259 return 0;
206 } 260 }
261#endif
262 return ReadWithPtrace(pid_, addr, dst, size);
263}
207 264
208 // The process_vm_readv call will not always work on remote 265size_t MemoryLocal::Read(uint64_t addr, void* dst, size_t size) {
209 // processes, so only use it for reads from the current pid. 266 return ProcessVmRead(getpid(), dst, addr, size);
210 // Use this method to avoid crashes if an address is invalid since 267}
211 // unwind data could try to access any part of the address space.
212 struct iovec local_io;
213 local_io.iov_base = dst;
214 local_io.iov_len = size;
215 268
216 struct iovec remote_io; 269MemoryRange::MemoryRange(const std::shared_ptr<Memory>& memory, uint64_t begin, uint64_t length,
217 remote_io.iov_base = reinterpret_cast<void*>(static_cast<uintptr_t>(addr)); 270 uint64_t offset)
218 remote_io.iov_len = size; 271 : memory_(memory), begin_(begin), length_(length), offset_(offset) {}
219 272
220 ssize_t bytes_read = process_vm_readv(getpid(), &local_io, 1, &remote_io, 1, 0); 273size_t MemoryRange::Read(uint64_t addr, void* dst, size_t size) {
221 if (bytes_read == -1) { 274 if (addr < offset_) {
222 return false; 275 return 0;
223 } 276 }
224 return static_cast<size_t>(bytes_read) == size;
225}
226 277
227bool MemoryOffline::Init(const std::string& file, uint64_t offset) { 278 uint64_t read_offset = addr - offset_;
228 if (!MemoryFileAtOffset::Init(file, offset)) { 279 if (read_offset >= length_) {
229 return false; 280 return 0;
230 } 281 }
231 // The first uint64_t value is the start of memory. 282
232 if (!MemoryFileAtOffset::Read(0, &start_, sizeof(start_))) { 283 uint64_t read_length = std::min(static_cast<uint64_t>(size), length_ - read_offset);
233 return false; 284 uint64_t read_addr;
285 if (__builtin_add_overflow(read_offset, begin_, &read_addr)) {
286 return 0;
234 } 287 }
235 // Subtract the first 64 bit value from the total size. 288
236 size_ -= sizeof(start_); 289 return memory_->Read(read_addr, dst, read_length);
237 return true;
238} 290}
239 291
240bool MemoryOffline::Read(uint64_t addr, void* dst, size_t size) { 292bool MemoryOffline::Init(const std::string& file, uint64_t offset) {
241 uint64_t max_size; 293 auto memory_file = std::make_shared<MemoryFileAtOffset>();
242 if (__builtin_add_overflow(addr, size, &max_size)) { 294 if (!memory_file->Init(file, offset)) {
243 return false; 295 return false;
244 } 296 }
245 297
246 uint64_t real_size; 298 // The first uint64_t value is the start of memory.
247 if (__builtin_add_overflow(start_, offset_, &real_size) || 299 uint64_t start;
248 __builtin_add_overflow(real_size, size_, &real_size)) { 300 if (!memory_file->ReadFully(0, &start, sizeof(start))) {
249 return false; 301 return false;
250 } 302 }
251 303
252 if (addr < start_ || max_size > real_size) { 304 uint64_t size = memory_file->Size();
305 if (__builtin_sub_overflow(size, sizeof(start), &size)) {
253 return false; 306 return false;
254 } 307 }
255 memcpy(dst, &data_[addr + offset_ - start_ + sizeof(start_)], size);
256 return true;
257}
258 308
259MemoryRange::MemoryRange(const std::shared_ptr<Memory>& memory, uint64_t begin, uint64_t end) 309 memory_ = std::make_unique<MemoryRange>(memory_file, sizeof(start), size, start);
260 : memory_(memory), begin_(begin), length_(end - begin) { 310 return true;
261 CHECK(end > begin);
262} 311}
263 312
264bool MemoryRange::Read(uint64_t addr, void* dst, size_t size) { 313size_t MemoryOffline::Read(uint64_t addr, void* dst, size_t size) {
265 uint64_t max_read; 314 if (!memory_) {
266 if (__builtin_add_overflow(addr, size, &max_read) || max_read > length_) { 315 return 0;
267 return false;
268 } 316 }
269 // The check above guarantees that addr + begin_ will not overflow. 317
270 return memory_->Read(addr + begin_, dst, size); 318 return memory_->Read(addr, dst, size);
271} 319}
272 320
273} // namespace unwindstack 321} // namespace unwindstack
diff --git a/libunwindstack/Regs.cpp b/libunwindstack/Regs.cpp
index 36b8e25f5..29dbf9d15 100644
--- a/libunwindstack/Regs.cpp
+++ b/libunwindstack/Regs.cpp
@@ -14,7 +14,6 @@
14 * limitations under the License. 14 * limitations under the License.
15 */ 15 */
16 16
17#include <elf.h>
18#include <stdint.h> 17#include <stdint.h>
19#include <sys/ptrace.h> 18#include <sys/ptrace.h>
20#include <sys/uio.h> 19#include <sys/uio.h>
@@ -23,315 +22,21 @@
23 22
24#include <unwindstack/Elf.h> 23#include <unwindstack/Elf.h>
25#include <unwindstack/MapInfo.h> 24#include <unwindstack/MapInfo.h>
26#include <unwindstack/Memory.h>
27#include <unwindstack/Regs.h> 25#include <unwindstack/Regs.h>
26#include <unwindstack/RegsArm.h>
27#include <unwindstack/RegsArm64.h>
28#include <unwindstack/RegsX86.h>
29#include <unwindstack/RegsX86_64.h>
28 30
29#include "Check.h" 31#include "UserArm.h"
30#include "Machine.h" 32#include "UserArm64.h"
31#include "Ucontext.h" 33#include "UserX86.h"
32#include "User.h" 34#include "UserX86_64.h"
33 35
34namespace unwindstack { 36namespace unwindstack {
35 37
36RegsArm::RegsArm() 38// The largest user structure.
37 : RegsImpl<uint32_t>(ARM_REG_LAST, ARM_REG_SP, Location(LOCATION_REGISTER, ARM_REG_LR)) {} 39constexpr size_t MAX_USER_REGS_SIZE = sizeof(arm64_user_regs) + 10;
38
39uint32_t RegsArm::MachineType() {
40 return EM_ARM;
41}
42
43uint64_t RegsArm::GetAdjustedPc(uint64_t rel_pc, Elf* elf) {
44 if (!elf->valid()) {
45 return rel_pc;
46 }
47
48 uint64_t load_bias = elf->GetLoadBias();
49 if (rel_pc < load_bias) {
50 return rel_pc;
51 }
52 uint64_t adjusted_rel_pc = rel_pc - load_bias;
53
54 if (adjusted_rel_pc < 5) {
55 return rel_pc;
56 }
57
58 if (adjusted_rel_pc & 1) {
59 // This is a thumb instruction, it could be 2 or 4 bytes.
60 uint32_t value;
61 if (rel_pc < 5 || !elf->memory()->Read(adjusted_rel_pc - 5, &value, sizeof(value)) ||
62 (value & 0xe000f000) != 0xe000f000) {
63 return rel_pc - 2;
64 }
65 }
66 return rel_pc - 4;
67}
68
69void RegsArm::SetFromRaw() {
70 set_pc(regs_[ARM_REG_PC]);
71 set_sp(regs_[ARM_REG_SP]);
72}
73
74bool RegsArm::SetPcFromReturnAddress(Memory*) {
75 if (pc() == regs_[ARM_REG_LR]) {
76 return false;
77 }
78
79 set_pc(regs_[ARM_REG_LR]);
80 return true;
81}
82
83void RegsArm::IterateRegisters(std::function<void(const char*, uint64_t)> fn) {
84 fn("r0", regs_[ARM_REG_R0]);
85 fn("r1", regs_[ARM_REG_R1]);
86 fn("r2", regs_[ARM_REG_R2]);
87 fn("r3", regs_[ARM_REG_R3]);
88 fn("r4", regs_[ARM_REG_R4]);
89 fn("r5", regs_[ARM_REG_R5]);
90 fn("r6", regs_[ARM_REG_R6]);
91 fn("r7", regs_[ARM_REG_R7]);
92 fn("r8", regs_[ARM_REG_R8]);
93 fn("r9", regs_[ARM_REG_R9]);
94 fn("r10", regs_[ARM_REG_R10]);
95 fn("r11", regs_[ARM_REG_R11]);
96 fn("ip", regs_[ARM_REG_R12]);
97 fn("sp", regs_[ARM_REG_SP]);
98 fn("lr", regs_[ARM_REG_LR]);
99 fn("pc", regs_[ARM_REG_PC]);
100}
101
102RegsArm64::RegsArm64()
103 : RegsImpl<uint64_t>(ARM64_REG_LAST, ARM64_REG_SP, Location(LOCATION_REGISTER, ARM64_REG_LR)) {}
104
105uint32_t RegsArm64::MachineType() {
106 return EM_AARCH64;
107}
108
109uint64_t RegsArm64::GetAdjustedPc(uint64_t rel_pc, Elf* elf) {
110 if (!elf->valid()) {
111 return rel_pc;
112 }
113
114 if (rel_pc < 4) {
115 return rel_pc;
116 }
117 return rel_pc - 4;
118}
119
120void RegsArm64::SetFromRaw() {
121 set_pc(regs_[ARM64_REG_PC]);
122 set_sp(regs_[ARM64_REG_SP]);
123}
124
125bool RegsArm64::SetPcFromReturnAddress(Memory*) {
126 if (pc() == regs_[ARM64_REG_LR]) {
127 return false;
128 }
129
130 set_pc(regs_[ARM64_REG_LR]);
131 return true;
132}
133
134void RegsArm64::IterateRegisters(std::function<void(const char*, uint64_t)> fn) {
135 fn("x0", regs_[ARM64_REG_R0]);
136 fn("x1", regs_[ARM64_REG_R1]);
137 fn("x2", regs_[ARM64_REG_R2]);
138 fn("x3", regs_[ARM64_REG_R3]);
139 fn("x4", regs_[ARM64_REG_R4]);
140 fn("x5", regs_[ARM64_REG_R5]);
141 fn("x6", regs_[ARM64_REG_R6]);
142 fn("x7", regs_[ARM64_REG_R7]);
143 fn("x8", regs_[ARM64_REG_R8]);
144 fn("x9", regs_[ARM64_REG_R9]);
145 fn("x10", regs_[ARM64_REG_R10]);
146 fn("x11", regs_[ARM64_REG_R11]);
147 fn("x12", regs_[ARM64_REG_R12]);
148 fn("x13", regs_[ARM64_REG_R13]);
149 fn("x14", regs_[ARM64_REG_R14]);
150 fn("x15", regs_[ARM64_REG_R15]);
151 fn("x16", regs_[ARM64_REG_R16]);
152 fn("x17", regs_[ARM64_REG_R17]);
153 fn("x18", regs_[ARM64_REG_R18]);
154 fn("x19", regs_[ARM64_REG_R19]);
155 fn("x20", regs_[ARM64_REG_R20]);
156 fn("x21", regs_[ARM64_REG_R21]);
157 fn("x22", regs_[ARM64_REG_R22]);
158 fn("x23", regs_[ARM64_REG_R23]);
159 fn("x24", regs_[ARM64_REG_R24]);
160 fn("x25", regs_[ARM64_REG_R25]);
161 fn("x26", regs_[ARM64_REG_R26]);
162 fn("x27", regs_[ARM64_REG_R27]);
163 fn("x28", regs_[ARM64_REG_R28]);
164 fn("x29", regs_[ARM64_REG_R29]);
165 fn("sp", regs_[ARM64_REG_SP]);
166 fn("lr", regs_[ARM64_REG_LR]);
167 fn("pc", regs_[ARM64_REG_PC]);
168}
169
170RegsX86::RegsX86()
171 : RegsImpl<uint32_t>(X86_REG_LAST, X86_REG_SP, Location(LOCATION_SP_OFFSET, -4)) {}
172
173uint32_t RegsX86::MachineType() {
174 return EM_386;
175}
176
177uint64_t RegsX86::GetAdjustedPc(uint64_t rel_pc, Elf* elf) {
178 if (!elf->valid()) {
179 return rel_pc;
180 }
181
182 if (rel_pc == 0) {
183 return 0;
184 }
185 return rel_pc - 1;
186}
187
188void RegsX86::SetFromRaw() {
189 set_pc(regs_[X86_REG_PC]);
190 set_sp(regs_[X86_REG_SP]);
191}
192
193bool RegsX86::SetPcFromReturnAddress(Memory* process_memory) {
194 // Attempt to get the return address from the top of the stack.
195 uint32_t new_pc;
196 if (!process_memory->Read(sp_, &new_pc, sizeof(new_pc)) || new_pc == pc()) {
197 return false;
198 }
199
200 set_pc(new_pc);
201 return true;
202}
203
204void RegsX86::IterateRegisters(std::function<void(const char*, uint64_t)> fn) {
205 fn("eax", regs_[X86_REG_EAX]);
206 fn("ebx", regs_[X86_REG_EBX]);
207 fn("ecx", regs_[X86_REG_ECX]);
208 fn("edx", regs_[X86_REG_EDX]);
209 fn("ebp", regs_[X86_REG_EBP]);
210 fn("edi", regs_[X86_REG_EDI]);
211 fn("esi", regs_[X86_REG_ESI]);
212 fn("esp", regs_[X86_REG_ESP]);
213 fn("eip", regs_[X86_REG_EIP]);
214}
215
216RegsX86_64::RegsX86_64()
217 : RegsImpl<uint64_t>(X86_64_REG_LAST, X86_64_REG_SP, Location(LOCATION_SP_OFFSET, -8)) {}
218
219uint32_t RegsX86_64::MachineType() {
220 return EM_X86_64;
221}
222
223uint64_t RegsX86_64::GetAdjustedPc(uint64_t rel_pc, Elf* elf) {
224 if (!elf->valid()) {
225 return rel_pc;
226 }
227
228 if (rel_pc == 0) {
229 return 0;
230 }
231
232 return rel_pc - 1;
233}
234
235void RegsX86_64::SetFromRaw() {
236 set_pc(regs_[X86_64_REG_PC]);
237 set_sp(regs_[X86_64_REG_SP]);
238}
239
240bool RegsX86_64::SetPcFromReturnAddress(Memory* process_memory) {
241 // Attempt to get the return address from the top of the stack.
242 uint64_t new_pc;
243 if (!process_memory->Read(sp_, &new_pc, sizeof(new_pc)) || new_pc == pc()) {
244 return false;
245 }
246
247 set_pc(new_pc);
248 return true;
249}
250
251void RegsX86_64::IterateRegisters(std::function<void(const char*, uint64_t)> fn) {
252 fn("rax", regs_[X86_64_REG_RAX]);
253 fn("rbx", regs_[X86_64_REG_RBX]);
254 fn("rcx", regs_[X86_64_REG_RCX]);
255 fn("rdx", regs_[X86_64_REG_RDX]);
256 fn("r8", regs_[X86_64_REG_R8]);
257 fn("r9", regs_[X86_64_REG_R9]);
258 fn("r10", regs_[X86_64_REG_R10]);
259 fn("r11", regs_[X86_64_REG_R11]);
260 fn("r12", regs_[X86_64_REG_R12]);
261 fn("r13", regs_[X86_64_REG_R13]);
262 fn("r14", regs_[X86_64_REG_R14]);
263 fn("r15", regs_[X86_64_REG_R15]);
264 fn("rdi", regs_[X86_64_REG_RDI]);
265 fn("rsi", regs_[X86_64_REG_RSI]);
266 fn("rbp", regs_[X86_64_REG_RBP]);
267 fn("rsp", regs_[X86_64_REG_RSP]);
268 fn("rip", regs_[X86_64_REG_RIP]);
269}
270
271static Regs* ReadArm(void* remote_data) {
272 arm_user_regs* user = reinterpret_cast<arm_user_regs*>(remote_data);
273
274 RegsArm* regs = new RegsArm();
275 memcpy(regs->RawData(), &user->regs[0], ARM_REG_LAST * sizeof(uint32_t));
276 regs->SetFromRaw();
277 return regs;
278}
279
280static Regs* ReadArm64(void* remote_data) {
281 arm64_user_regs* user = reinterpret_cast<arm64_user_regs*>(remote_data);
282
283 RegsArm64* regs = new RegsArm64();
284 memcpy(regs->RawData(), &user->regs[0], (ARM64_REG_R31 + 1) * sizeof(uint64_t));
285 uint64_t* reg_data = reinterpret_cast<uint64_t*>(regs->RawData());
286 reg_data[ARM64_REG_PC] = user->pc;
287 reg_data[ARM64_REG_SP] = user->sp;
288 regs->SetFromRaw();
289 return regs;
290}
291
292static Regs* ReadX86(void* remote_data) {
293 x86_user_regs* user = reinterpret_cast<x86_user_regs*>(remote_data);
294
295 RegsX86* regs = new RegsX86();
296 (*regs)[X86_REG_EAX] = user->eax;
297 (*regs)[X86_REG_EBX] = user->ebx;
298 (*regs)[X86_REG_ECX] = user->ecx;
299 (*regs)[X86_REG_EDX] = user->edx;
300 (*regs)[X86_REG_EBP] = user->ebp;
301 (*regs)[X86_REG_EDI] = user->edi;
302 (*regs)[X86_REG_ESI] = user->esi;
303 (*regs)[X86_REG_ESP] = user->esp;
304 (*regs)[X86_REG_EIP] = user->eip;
305
306 regs->SetFromRaw();
307 return regs;
308}
309
310static Regs* ReadX86_64(void* remote_data) {
311 x86_64_user_regs* user = reinterpret_cast<x86_64_user_regs*>(remote_data);
312
313 RegsX86_64* regs = new RegsX86_64();
314 (*regs)[X86_64_REG_RAX] = user->rax;
315 (*regs)[X86_64_REG_RBX] = user->rbx;
316 (*regs)[X86_64_REG_RCX] = user->rcx;
317 (*regs)[X86_64_REG_RDX] = user->rdx;
318 (*regs)[X86_64_REG_R8] = user->r8;
319 (*regs)[X86_64_REG_R9] = user->r9;
320 (*regs)[X86_64_REG_R10] = user->r10;
321 (*regs)[X86_64_REG_R11] = user->r11;
322 (*regs)[X86_64_REG_R12] = user->r12;
323 (*regs)[X86_64_REG_R13] = user->r13;
324 (*regs)[X86_64_REG_R14] = user->r14;
325 (*regs)[X86_64_REG_R15] = user->r15;
326 (*regs)[X86_64_REG_RDI] = user->rdi;
327 (*regs)[X86_64_REG_RSI] = user->rsi;
328 (*regs)[X86_64_REG_RBP] = user->rbp;
329 (*regs)[X86_64_REG_RSP] = user->rsp;
330 (*regs)[X86_64_REG_RIP] = user->rip;
331
332 regs->SetFromRaw();
333 return regs;
334}
335 40
336// This function assumes that reg_data is already aligned to a 64 bit value. 41// This function assumes that reg_data is already aligned to a 64 bit value.
337// If not this could crash with an unaligned access. 42// If not this could crash with an unaligned access.
@@ -348,106 +53,42 @@ Regs* Regs::RemoteGet(pid_t pid) {
348 53
349 switch (io.iov_len) { 54 switch (io.iov_len) {
350 case sizeof(x86_user_regs): 55 case sizeof(x86_user_regs):
351 return ReadX86(buffer.data()); 56 return RegsX86::Read(buffer.data());
352 case sizeof(x86_64_user_regs): 57 case sizeof(x86_64_user_regs):
353 return ReadX86_64(buffer.data()); 58 return RegsX86_64::Read(buffer.data());
354 case sizeof(arm_user_regs): 59 case sizeof(arm_user_regs):
355 return ReadArm(buffer.data()); 60 return RegsArm::Read(buffer.data());
356 case sizeof(arm64_user_regs): 61 case sizeof(arm64_user_regs):
357 return ReadArm64(buffer.data()); 62 return RegsArm64::Read(buffer.data());
358 } 63 }
359 return nullptr; 64 return nullptr;
360} 65}
361 66
362static Regs* CreateFromArmUcontext(void* ucontext) { 67Regs* Regs::CreateFromUcontext(ArchEnum arch, void* ucontext) {
363 arm_ucontext_t* arm_ucontext = reinterpret_cast<arm_ucontext_t*>(ucontext); 68 switch (arch) {
364 69 case ARCH_X86:
365 RegsArm* regs = new RegsArm(); 70 return RegsX86::CreateFromUcontext(ucontext);
366 memcpy(regs->RawData(), &arm_ucontext->uc_mcontext.regs[0], ARM_REG_LAST * sizeof(uint32_t)); 71 case ARCH_X86_64:
367 regs->SetFromRaw(); 72 return RegsX86_64::CreateFromUcontext(ucontext);
368 return regs; 73 case ARCH_ARM:
369} 74 return RegsArm::CreateFromUcontext(ucontext);
370 75 case ARCH_ARM64:
371static Regs* CreateFromArm64Ucontext(void* ucontext) { 76 return RegsArm64::CreateFromUcontext(ucontext);
372 arm64_ucontext_t* arm64_ucontext = reinterpret_cast<arm64_ucontext_t*>(ucontext); 77 case ARCH_UNKNOWN:
373 78 default:
374 RegsArm64* regs = new RegsArm64(); 79 return nullptr;
375 memcpy(regs->RawData(), &arm64_ucontext->uc_mcontext.regs[0], ARM64_REG_LAST * sizeof(uint64_t));
376 regs->SetFromRaw();
377 return regs;
378}
379
380void RegsX86::SetFromUcontext(x86_ucontext_t* ucontext) {
381 // Put the registers in the expected order.
382 regs_[X86_REG_EDI] = ucontext->uc_mcontext.edi;
383 regs_[X86_REG_ESI] = ucontext->uc_mcontext.esi;
384 regs_[X86_REG_EBP] = ucontext->uc_mcontext.ebp;
385 regs_[X86_REG_ESP] = ucontext->uc_mcontext.esp;
386 regs_[X86_REG_EBX] = ucontext->uc_mcontext.ebx;
387 regs_[X86_REG_EDX] = ucontext->uc_mcontext.edx;
388 regs_[X86_REG_ECX] = ucontext->uc_mcontext.ecx;
389 regs_[X86_REG_EAX] = ucontext->uc_mcontext.eax;
390 regs_[X86_REG_EIP] = ucontext->uc_mcontext.eip;
391 SetFromRaw();
392}
393
394static Regs* CreateFromX86Ucontext(void* ucontext) {
395 x86_ucontext_t* x86_ucontext = reinterpret_cast<x86_ucontext_t*>(ucontext);
396
397 RegsX86* regs = new RegsX86();
398 regs->SetFromUcontext(x86_ucontext);
399 return regs;
400}
401
402void RegsX86_64::SetFromUcontext(x86_64_ucontext_t* ucontext) {
403 // R8-R15
404 memcpy(&regs_[X86_64_REG_R8], &ucontext->uc_mcontext.r8, 8 * sizeof(uint64_t));
405
406 // Rest of the registers.
407 regs_[X86_64_REG_RDI] = ucontext->uc_mcontext.rdi;
408 regs_[X86_64_REG_RSI] = ucontext->uc_mcontext.rsi;
409 regs_[X86_64_REG_RBP] = ucontext->uc_mcontext.rbp;
410 regs_[X86_64_REG_RBX] = ucontext->uc_mcontext.rbx;
411 regs_[X86_64_REG_RDX] = ucontext->uc_mcontext.rdx;
412 regs_[X86_64_REG_RAX] = ucontext->uc_mcontext.rax;
413 regs_[X86_64_REG_RCX] = ucontext->uc_mcontext.rcx;
414 regs_[X86_64_REG_RSP] = ucontext->uc_mcontext.rsp;
415 regs_[X86_64_REG_RIP] = ucontext->uc_mcontext.rip;
416
417 SetFromRaw();
418}
419
420static Regs* CreateFromX86_64Ucontext(void* ucontext) {
421 x86_64_ucontext_t* x86_64_ucontext = reinterpret_cast<x86_64_ucontext_t*>(ucontext);
422
423 RegsX86_64* regs = new RegsX86_64();
424 regs->SetFromUcontext(x86_64_ucontext);
425 return regs;
426}
427
428Regs* Regs::CreateFromUcontext(uint32_t machine_type, void* ucontext) {
429 switch (machine_type) {