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));