Merge "debuggerd_handler: print pid and process name."
diff --git a/init/README.md b/init/README.md
index f3b57bc..0ea00fb 100644
--- a/init/README.md
+++ b/init/README.md
@@ -447,6 +447,9 @@
`rmdir <path>`
> Calls rmdir(2) on the given path.
+`readahead <file|dir>`
+> Calls readahead(2) on the file or files within given directory.
+
`setprop <name> <value>`
> Set system property _name_ to _value_. Properties are expanded
within _value_.
diff --git a/init/builtins.cpp b/init/builtins.cpp
index 5335608..eea78fd 100644
--- a/init/builtins.cpp
+++ b/init/builtins.cpp
@@ -19,6 +19,7 @@
#include <dirent.h>
#include <errno.h>
#include <fcntl.h>
+#include <fts.h>
#include <linux/loop.h>
#include <linux/module.h>
#include <mntent.h>
@@ -627,7 +628,7 @@
static int do_sysclktz(const std::vector<std::string>& args) {
struct timezone tz = {};
- if (android::base::ParseInt(args[1], &tz.tz_minuteswest) && settimeofday(NULL, &tz) != -1) {
+ if (android::base::ParseInt(args[1], &tz.tz_minuteswest) && settimeofday(nullptr, &tz) != -1) {
return 0;
}
return -1;
@@ -660,6 +661,66 @@
return 0;
}
+static int do_readahead(const std::vector<std::string>& args) {
+ struct stat sb;
+
+ if (stat(args[1].c_str(), &sb)) {
+ PLOG(ERROR) << "Error opening " << args[1];
+ return -1;
+ }
+
+ // We will do readahead in a forked process in order not to block init
+ // since it may block while it reads the
+ // filesystem metadata needed to locate the requested blocks. This
+ // occurs frequently with ext[234] on large files using indirect blocks
+ // instead of extents, giving the appearance that the call blocks until
+ // the requested data has been read.
+ pid_t pid = fork();
+ if (pid == 0) {
+ android::base::Timer t;
+ if (S_ISREG(sb.st_mode)) {
+ android::base::unique_fd fd(TEMP_FAILURE_RETRY(open(args[1].c_str(), O_RDONLY)));
+ if (fd == -1) {
+ PLOG(ERROR) << "Error opening file: " << args[1];
+ _exit(EXIT_FAILURE);
+ }
+ if (readahead(fd, 0, std::numeric_limits<size_t>::max())) {
+ PLOG(ERROR) << "Error readahead file: " << args[1];
+ _exit(EXIT_FAILURE);
+ }
+ } else if (S_ISDIR(sb.st_mode)) {
+ char* paths[] = {const_cast<char*>(args[1].data()), nullptr};
+ std::unique_ptr<FTS, decltype(&fts_close)> fts(
+ fts_open(paths, FTS_PHYSICAL | FTS_NOCHDIR | FTS_XDEV, nullptr), fts_close);
+ if (!fts) {
+ PLOG(ERROR) << "Error opening directory: " << args[1];
+ _exit(EXIT_FAILURE);
+ }
+ // Traverse the entire hierarchy and do readahead
+ for (FTSENT* ftsent = fts_read(fts.get()); ftsent != nullptr;
+ ftsent = fts_read(fts.get())) {
+ if (ftsent->fts_info & FTS_F) {
+ android::base::unique_fd fd(
+ TEMP_FAILURE_RETRY(open(ftsent->fts_accpath, O_RDONLY)));
+ if (fd == -1) {
+ PLOG(ERROR) << "Error opening file: " << args[1];
+ continue;
+ }
+ if (readahead(fd, 0, std::numeric_limits<size_t>::max())) {
+ PLOG(ERROR) << "Unable to readahead on file: " << ftsent->fts_accpath;
+ }
+ }
+ }
+ }
+ LOG(INFO) << "Readahead " << args[1] << " took " << t;
+ _exit(0);
+ } else if (pid < 0) {
+ PLOG(ERROR) << "Fork failed";
+ return -1;
+ }
+ return 0;
+}
+
static int do_copy(const std::vector<std::string>& args) {
std::string data;
std::string err;
@@ -898,6 +959,7 @@
{"mount_all", {1, kMax, do_mount_all}},
{"mount", {3, kMax, do_mount}},
{"umount", {1, 1, do_umount}},
+ {"readahead", {1, 1, do_readahead}},
{"restart", {1, 1, do_restart}},
{"restorecon", {1, kMax, do_restorecon}},
{"restorecon_recursive", {1, kMax, do_restorecon_recursive}},
diff --git a/init/init.cpp b/init/init.cpp
index 69d1564..63a993f 100644
--- a/init/init.cpp
+++ b/init/init.cpp
@@ -1013,7 +1013,7 @@
mknod("/dev/kmsg", S_IFCHR | 0600, makedev(1, 11));
if constexpr (WORLD_WRITABLE_KMSG) {
- mknod("/dev/kmsg_debug", S_IFCHR | 0622, makedev(1, 11));
+ mknod("/dev/kmsg_debug", S_IFCHR | 0622, makedev(1, 11));
}
mknod("/dev/random", S_IFCHR | 0666, makedev(1, 8));
diff --git a/libcutils/include/private/android_filesystem_config.h b/libcutils/include/private/android_filesystem_config.h
index e80bf36..55ece54 100644
--- a/libcutils/include/private/android_filesystem_config.h
+++ b/libcutils/include/private/android_filesystem_config.h
@@ -121,6 +121,7 @@
#define AID_OTA_UPDATE 1061 /* resource tracking UID for OTA updates */
#define AID_AUTOMOTIVE_EVS 1062 /* Automotive rear and surround view system */
#define AID_LOWPAN 1063 /* LoWPAN subsystem */
+#define AID_HSM 1064 /* hardware security module subsystem */
/* Changes to this file must be made in AOSP, *not* in internal branches. */
#define AID_SHELL 2000 /* adb and debug shell user */
diff --git a/libunwindstack/DwarfEhFrame.cpp b/libunwindstack/DwarfEhFrame.cpp
index d0b35c3..db8f558 100644
--- a/libunwindstack/DwarfEhFrame.cpp
+++ b/libunwindstack/DwarfEhFrame.cpp
@@ -100,7 +100,7 @@
fde_info_.erase(index);
return nullptr;
}
- info->pc = value;
+ info->pc = value + 4;
return info;
}
@@ -175,7 +175,7 @@
last_error_ = DWARF_ERROR_MEMORY_INVALID;
return false;
}
- info->pc = value;
+ info->pc = value + 4;
if (pc < info->pc) {
if (prev_info == nullptr) {
diff --git a/libunwindstack/DwarfMemory.cpp b/libunwindstack/DwarfMemory.cpp
index b6e0412..901f492 100644
--- a/libunwindstack/DwarfMemory.cpp
+++ b/libunwindstack/DwarfMemory.cpp
@@ -235,7 +235,7 @@
return false;
}
- return AdjustEncodedValue(encoding & 0xf0, value);
+ return AdjustEncodedValue(encoding & 0x70, value);
}
// Instantiate all of the needed template functions.
diff --git a/libunwindstack/tests/DwarfEhFrameTest.cpp b/libunwindstack/tests/DwarfEhFrameTest.cpp
index e9501e3..07159b0 100644
--- a/libunwindstack/tests/DwarfEhFrameTest.cpp
+++ b/libunwindstack/tests/DwarfEhFrameTest.cpp
@@ -124,7 +124,7 @@
auto info = this->eh_frame_->GetFdeInfoFromIndex(2);
ASSERT_TRUE(info != nullptr);
- EXPECT_EQ(0x1380U, info->pc);
+ EXPECT_EQ(0x1384U, info->pc);
EXPECT_EQ(0x1540U, info->offset);
}
@@ -139,7 +139,7 @@
auto info = this->eh_frame_->GetFdeInfoFromIndex(2);
ASSERT_TRUE(info != nullptr);
- EXPECT_EQ(0x3340U, info->pc);
+ EXPECT_EQ(0x3344U, info->pc);
EXPECT_EQ(0x3500U, info->offset);
}
@@ -153,7 +153,7 @@
auto info = this->eh_frame_->GetFdeInfoFromIndex(2);
ASSERT_TRUE(info != nullptr);
- EXPECT_EQ(0x340U, info->pc);
+ EXPECT_EQ(0x344U, info->pc);
EXPECT_EQ(0x500U, info->offset);
// Clear the memory so that this will fail if it doesn't read cached data.
@@ -161,7 +161,7 @@
info = this->eh_frame_->GetFdeInfoFromIndex(2);
ASSERT_TRUE(info != nullptr);
- EXPECT_EQ(0x340U, info->pc);
+ EXPECT_EQ(0x344U, info->pc);
EXPECT_EQ(0x500U, info->offset);
}
@@ -220,18 +220,18 @@
// Verify that if entries is zero, that it fails.
uint64_t fde_offset;
- ASSERT_FALSE(this->eh_frame_->GetFdeOffsetSequential(0x340, &fde_offset));
+ ASSERT_FALSE(this->eh_frame_->GetFdeOffsetSequential(0x344, &fde_offset));
this->eh_frame_->TestSetCurEntriesOffset(0x1040);
- ASSERT_TRUE(this->eh_frame_->GetFdeOffsetSequential(0x340, &fde_offset));
+ ASSERT_TRUE(this->eh_frame_->GetFdeOffsetSequential(0x344, &fde_offset));
EXPECT_EQ(0x500U, fde_offset);
- ASSERT_TRUE(this->eh_frame_->GetFdeOffsetSequential(0x440, &fde_offset));
+ ASSERT_TRUE(this->eh_frame_->GetFdeOffsetSequential(0x444, &fde_offset));
EXPECT_EQ(0x600U, fde_offset);
// Expect that the data is cached so no more memory reads will occur.
this->memory_.Clear();
- ASSERT_TRUE(this->eh_frame_->GetFdeOffsetSequential(0x440, &fde_offset));
+ ASSERT_TRUE(this->eh_frame_->GetFdeOffsetSequential(0x444, &fde_offset));
EXPECT_EQ(0x600U, fde_offset);
}
diff --git a/libunwindstack/tests/DwarfMemoryTest.cpp b/libunwindstack/tests/DwarfMemoryTest.cpp
index 08fe7cf..f12d2fe 100644
--- a/libunwindstack/tests/DwarfMemoryTest.cpp
+++ b/libunwindstack/tests/DwarfMemoryTest.cpp
@@ -52,6 +52,8 @@
void ReadEncodedValue_non_zero_adjust();
template <typename AddressType>
void ReadEncodedValue_overflow();
+ template <typename AddressType>
+ void ReadEncodedValue_high_bit_set();
MemoryFake memory_;
std::unique_ptr<DwarfMemory> dwarf_mem_;
@@ -435,6 +437,26 @@
ReadEncodedValue_overflow<uint64_t>();
}
+template <typename AddressType>
+void DwarfMemoryTest::ReadEncodedValue_high_bit_set() {
+ uint64_t value;
+ memory_.SetData32(0, 0x15234);
+ ASSERT_FALSE(dwarf_mem_->ReadEncodedValue<AddressType>(0xc3, &value));
+
+ dwarf_mem_->set_func_offset(0x60000);
+ dwarf_mem_->set_cur_offset(0);
+ ASSERT_TRUE(dwarf_mem_->ReadEncodedValue<AddressType>(0xc3, &value));
+ ASSERT_EQ(0x75234U, value);
+}
+
+TEST_F(DwarfMemoryTest, ReadEncodedValue_high_bit_set_uint32_t) {
+ ReadEncodedValue_high_bit_set<uint32_t>();
+}
+
+TEST_F(DwarfMemoryTest, ReadEncodedValue_high_bit_set_uint64_t) {
+ ReadEncodedValue_high_bit_set<uint64_t>();
+}
+
TEST_F(DwarfMemoryTest, AdjustEncodedValue_absptr) {
uint64_t value = 0x1234;
ASSERT_TRUE(dwarf_mem_->AdjustEncodedValue(0x00, &value));