Merge changes Ic90fac0b,Id9c12303,I2d9bdcb1,I9d699af1,Ia4d03f9e, ...

* changes:
  adbd: turn on fdsan warnings.
  adb: add error-generating overload of adb_close(unique_fd).
  adb: fix register_socket_transport related double-closes.
  adb: fix double close in local_connect_arbitrary_ports.
  adb: use adb's unique_fd instead of android::base.
  adb: move remount_service.h into daemon.
  adb: split shell_service.h into client/daemon/protocol parts.
  adb: split file_sync_service.h into client and daemon parts.
diff --git a/fastboot/usb.h b/fastboot/usb.h
index 96eb934..7ca44c4 100644
--- a/fastboot/usb.h
+++ b/fastboot/usb.h
@@ -55,6 +55,7 @@
 class UsbTransport : public Transport {
     // Resets the underlying transport.  Returns 0 on success.
     // This effectively simulates unplugging and replugging
+  public:
     virtual int Reset() = 0;
 };
 
diff --git a/fastboot/usb_osx.cpp b/fastboot/usb_osx.cpp
index 442dea5..4d48f6e 100644
--- a/fastboot/usb_osx.cpp
+++ b/fastboot/usb_osx.cpp
@@ -67,7 +67,8 @@
 
 class OsxUsbTransport : public UsbTransport {
   public:
-    OsxUsbTransport(std::unique_ptr<usb_handle> handle, uint32_t ms_timeout)
+    // A timeout of 0 is blocking
+    OsxUsbTransport(std::unique_ptr<usb_handle> handle, uint32_t ms_timeout = 0)
         : handle_(std::move(handle)), ms_timeout_(ms_timeout) {}
     ~OsxUsbTransport() override = default;
 
@@ -475,15 +476,17 @@
     return 0;
 }
 
+/*
+  TODO: this SHOULD be easy to do with ResetDevice() from IOUSBDeviceInterface.
+  However to perform operations that manipulate the state of the device, you must
+  claim ownership of the device with USBDeviceOpenSeize(). However, this operation
+  always fails with kIOReturnExclusiveAccess.
+  It seems that the kext com.apple.driver.usb.AppleUSBHostCompositeDevice
+  always loads and claims ownership of the device and refuses to give it up.
+*/
 int OsxUsbTransport::Reset() {
-    IOReturn result = (*handle_->interface)->ResetDevice(handle_->interface);
-
-    if (result == 0) {
-        return 0;
-    } else {
-        ERR("usb_reset failed with status %x\n", result);
-        return -1;
-    }
+    ERR("USB reset is currently unsupported on osx\n");
+    return -1;
 }
 
 ssize_t OsxUsbTransport::Read(void* data, size_t len) {
@@ -508,9 +511,14 @@
         return -1;
     }
 
-    result = (*handle_->interface)
-                     ->ReadPipeTO(handle_->interface, handle_->bulkIn, data, &numBytes,
-                                  USB_TRANSACTION_TIMEOUT, USB_TRANSACTION_TIMEOUT);
+    if (!ms_timeout_) {
+        result = (*handle_->interface)
+                         ->ReadPipe(handle_->interface, handle_->bulkIn, data, &numBytes);
+    } else {
+        result = (*handle_->interface)
+                         ->ReadPipeTO(handle_->interface, handle_->bulkIn, data, &numBytes,
+                                      ms_timeout_, ms_timeout_);
+    }
 
     if (result == 0) {
         return (int) numBytes;
@@ -557,8 +565,16 @@
         int lenToSend = lenRemaining > maxLenToSend
             ? maxLenToSend : lenRemaining;
 
-        result = (*handle_->interface)->WritePipe(
-                handle_->interface, handle_->bulkOut, (void *)data, lenToSend);
+        if (!ms_timeout_) {  // blocking
+            result = (*handle_->interface)
+                             ->WritePipe(handle_->interface, handle_->bulkOut, (void*)data,
+                                         lenToSend);
+        } else {
+            result = (*handle_->interface)
+                             ->WritePipeTO(handle_->interface, handle_->bulkOut, (void*)data,
+                                           lenToSend, ms_timeout_, ms_timeout_);
+        }
+
         if (result != 0) break;
 
         lenRemaining -= lenToSend;
diff --git a/fs_mgr/Android.bp b/fs_mgr/Android.bp
index a3ce879..bf69096 100644
--- a/fs_mgr/Android.bp
+++ b/fs_mgr/Android.bp
@@ -30,7 +30,7 @@
     ],
 }
 
-cc_library_static {
+cc_library {
     name: "libfs_mgr",
     defaults: ["fs_mgr_defaults"],
     recovery_available: true,
@@ -44,15 +44,20 @@
         "fs_mgr_avb_ops.cpp",
         "fs_mgr_dm_linear.cpp",
     ],
-    static_libs: [
+    shared_libs: [
         "libfec",
         "libfec_rs",
         "libbase",
         "libcrypto_utils",
         "libcrypto",
+        "libcutils",
         "libext4_utils",
+        "libkeyutils",
+        "liblog",
         "libsquashfs_utils",
         "libselinux",
+    ],
+    static_libs: [
         "libavb",
         "libfstab",
         "libdm",
diff --git a/fs_mgr/libdm/dm_target.cpp b/fs_mgr/libdm/dm_target.cpp
index 20b26df..7c18267 100644
--- a/fs_mgr/libdm/dm_target.cpp
+++ b/fs_mgr/libdm/dm_target.cpp
@@ -111,5 +111,9 @@
     return base + " " + std::to_string(optional_args_.size()) + " " + optional;
 }
 
+std::string DmTargetAndroidVerity::GetParameterString() const {
+    return keyid_ + " " + block_device_;
+}
+
 }  // namespace dm
 }  // namespace android
diff --git a/fs_mgr/libdm/include/libdm/dm_target.h b/fs_mgr/libdm/include/libdm/dm_target.h
index d5974f4..31863c8 100644
--- a/fs_mgr/libdm/include/libdm/dm_target.h
+++ b/fs_mgr/libdm/include/libdm/dm_target.h
@@ -128,6 +128,20 @@
     bool valid_;
 };
 
+class DmTargetAndroidVerity final : public DmTarget {
+  public:
+    DmTargetAndroidVerity(uint64_t start, uint64_t length, const std::string& block_device,
+                          const std::string& keyid)
+        : DmTarget(start, length), keyid_(keyid), block_device_(block_device) {}
+
+    std::string name() const override { return "android-verity"; }
+    std::string GetParameterString() const override;
+
+  private:
+    std::string keyid_;
+    std::string block_device_;
+};
+
 // This is the same as DmTargetVerity, but the table may be specified as a raw
 // string. This code exists only for fs_mgr_verity and should be avoided. Use
 // DmTargetVerity for new code instead.
diff --git a/fs_mgr/tools/dmctl.cpp b/fs_mgr/tools/dmctl.cpp
index 5e11c84..45a81af 100644
--- a/fs_mgr/tools/dmctl.cpp
+++ b/fs_mgr/tools/dmctl.cpp
@@ -40,6 +40,7 @@
 using DmTarget = ::android::dm::DmTarget;
 using DmTargetLinear = ::android::dm::DmTargetLinear;
 using DmTargetZero = ::android::dm::DmTargetZero;
+using DmTargetAndroidVerity = ::android::dm::DmTargetAndroidVerity;
 using DmTargetTypeInfo = ::android::dm::DmTargetTypeInfo;
 using DmBlockDevice = ::android::dm::DeviceMapper::DmBlockDevice;
 
@@ -96,6 +97,16 @@
             }
             return std::make_unique<DmTargetLinear>(start_sector, num_sectors, block_device,
                                                     physical_sector);
+        } else if (target_type == "android-verity") {
+            if (!HasArgs(2)) {
+                std::cerr << "Expected \"android-verity\" <public-key-id> <block_device>"
+                          << std::endl;
+                return nullptr;
+            }
+            std::string keyid = NextArg();
+            std::string block_device = NextArg();
+            return std::make_unique<DmTargetAndroidVerity>(start_sector, num_sectors, keyid,
+                                                           block_device);
         } else {
             std::cerr << "Unrecognized target type: " << target_type << std::endl;
             return nullptr;
@@ -132,11 +143,11 @@
     while (arg_index < argc && argv[arg_index][0] == '-') {
         if (strcmp(argv[arg_index], "-ro") == 0) {
             table.set_readonly(true);
+            arg_index++;
         } else {
             std::cerr << "Unrecognized option: " << argv[arg_index] << std::endl;
             return -EINVAL;
         }
-        arg_index++;
     }
 
     // Parse everything else as target information.
diff --git a/gatekeeperd/OWNERS b/gatekeeperd/OWNERS
new file mode 100644
index 0000000..9c99c6e
--- /dev/null
+++ b/gatekeeperd/OWNERS
@@ -0,0 +1,2 @@
+swillden@google.com
+jdanis@google.com
diff --git a/init/action_parser.cpp b/init/action_parser.cpp
index 8a4b518..1481162 100644
--- a/init/action_parser.cpp
+++ b/init/action_parser.cpp
@@ -60,7 +60,7 @@
     prop_name.erase(equal_pos);
 
     if (!IsActionableProperty(subcontext, prop_name)) {
-        return Error() << "unexported property tigger found: " << prop_name;
+        return Error() << "unexported property trigger found: " << prop_name;
     }
 
     if (auto [it, inserted] = property_triggers->emplace(prop_name, prop_value); !inserted) {
diff --git a/liblog/include/log/log_main.h b/liblog/include/log/log_main.h
index 9c68ff2..1314330 100644
--- a/liblog/include/log/log_main.h
+++ b/liblog/include/log/log_main.h
@@ -47,7 +47,8 @@
  * so don't link with __clang_analyzer__ defined.
  */
 #ifdef __clang_analyzer__
-extern void __FAKE_USE_VA_ARGS(...);
+extern void __fake_use_va_args(int, ...);
+#define __FAKE_USE_VA_ARGS(...) __fake_use_va_args(0, ##__VA_ARGS__)
 #else
 #define __FAKE_USE_VA_ARGS(...) ((void)(0))
 #endif
diff --git a/libsysutils/src/FrameworkListener.cpp b/libsysutils/src/FrameworkListener.cpp
index 87e2684..835e226 100644
--- a/libsysutils/src/FrameworkListener.cpp
+++ b/libsysutils/src/FrameworkListener.cpp
@@ -42,7 +42,7 @@
 
 FrameworkListener::FrameworkListener(int sock) :
                             SocketListener(sock, true) {
-    init(NULL, false);
+    init(nullptr, false);
 }
 
 void FrameworkListener::init(const char *socketName UNUSED, bool withSeq) {
@@ -154,7 +154,7 @@
             if (!haveCmdNum) {
                 char *endptr;
                 int cmdNum = (int)strtol(tmp, &endptr, 0);
-                if (endptr == NULL || *endptr != '\0') {
+                if (endptr == nullptr || *endptr != '\0') {
                     cli->sendMsg(500, "Invalid sequence number", false);
                     goto out;
                 }
diff --git a/libsysutils/src/NetlinkEvent.cpp b/libsysutils/src/NetlinkEvent.cpp
index f0c66ec..24ea7aa 100644
--- a/libsysutils/src/NetlinkEvent.cpp
+++ b/libsysutils/src/NetlinkEvent.cpp
@@ -45,8 +45,8 @@
 NetlinkEvent::NetlinkEvent() {
     mAction = Action::kUnknown;
     memset(mParams, 0, sizeof(mParams));
-    mPath = NULL;
-    mSubsystem = NULL;
+    mPath = nullptr;
+    mSubsystem = nullptr;
 }
 
 NetlinkEvent::~NetlinkEvent() {
@@ -89,7 +89,7 @@
         NL_EVENT_RTM_NAME(LOCAL_QLOG_NL_EVENT);
         NL_EVENT_RTM_NAME(LOCAL_NFLOG_PACKET);
         default:
-            return NULL;
+            return nullptr;
     }
 #undef NL_EVENT_RTM_NAME
 }
@@ -158,7 +158,7 @@
  */
 bool NetlinkEvent::parseIfAddrMessage(const struct nlmsghdr *nh) {
     struct ifaddrmsg *ifaddr = (struct ifaddrmsg *) NLMSG_DATA(nh);
-    struct ifa_cacheinfo *cacheinfo = NULL;
+    struct ifa_cacheinfo *cacheinfo = nullptr;
     char addrstr[INET6_ADDRSTRLEN] = "";
     char ifname[IFNAMSIZ] = "";
 
@@ -286,7 +286,7 @@
 bool NetlinkEvent::parseNfPacketMessage(struct nlmsghdr *nh) {
     int uid = -1;
     int len = 0;
-    char* raw = NULL;
+    char* raw = nullptr;
 
     struct nlattr* uid_attr = findNlAttr(nh, sizeof(struct genlmsghdr), NFULA_UID);
     if (uid_attr) {
@@ -584,7 +584,7 @@
         (prefixlen == 0 || !memcmp(str, prefix, prefixlen))) {
         return str + prefixlen;
     } else {
-        return NULL;
+        return nullptr;
     }
 }
 
@@ -625,16 +625,16 @@
             first = 0;
         } else {
             const char* a;
-            if ((a = HAS_CONST_PREFIX(s, end, "ACTION=")) != NULL) {
+            if ((a = HAS_CONST_PREFIX(s, end, "ACTION=")) != nullptr) {
                 if (!strcmp(a, "add"))
                     mAction = Action::kAdd;
                 else if (!strcmp(a, "remove"))
                     mAction = Action::kRemove;
                 else if (!strcmp(a, "change"))
                     mAction = Action::kChange;
-            } else if ((a = HAS_CONST_PREFIX(s, end, "SEQNUM=")) != NULL) {
+            } else if ((a = HAS_CONST_PREFIX(s, end, "SEQNUM=")) != nullptr) {
                 mSeq = atoi(a);
-            } else if ((a = HAS_CONST_PREFIX(s, end, "SUBSYSTEM=")) != NULL) {
+            } else if ((a = HAS_CONST_PREFIX(s, end, "SUBSYSTEM=")) != nullptr) {
                 mSubsystem = strdup(a);
             } else if (param_idx < NL_PARAMS_MAX) {
                 mParams[param_idx++] = strdup(s);
@@ -656,14 +656,14 @@
 
 const char *NetlinkEvent::findParam(const char *paramName) {
     size_t len = strlen(paramName);
-    for (int i = 0; i < NL_PARAMS_MAX && mParams[i] != NULL; ++i) {
+    for (int i = 0; i < NL_PARAMS_MAX && mParams[i] != nullptr; ++i) {
         const char *ptr = mParams[i] + len;
         if (!strncmp(mParams[i], paramName, len) && *ptr == '=')
             return ++ptr;
     }
 
     SLOGE("NetlinkEvent::FindParam(): Parameter '%s' not found", paramName);
-    return NULL;
+    return nullptr;
 }
 
 nlattr* NetlinkEvent::findNlAttr(const nlmsghdr* nh, size_t hdrlen, uint16_t attr) {
diff --git a/libsysutils/src/SocketClient.cpp b/libsysutils/src/SocketClient.cpp
index 971f908..0625db7 100644
--- a/libsysutils/src/SocketClient.cpp
+++ b/libsysutils/src/SocketClient.cpp
@@ -42,8 +42,8 @@
     mSocket = socket;
     mSocketOwned = owned;
     mUseCmdNum = useCmdNum;
-    pthread_mutex_init(&mWriteMutex, NULL);
-    pthread_mutex_init(&mRefCountMutex, NULL);
+    pthread_mutex_init(&mWriteMutex, nullptr);
+    pthread_mutex_init(&mRefCountMutex, nullptr);
     mPid = -1;
     mUid = -1;
     mGid = -1;
@@ -135,9 +135,9 @@
     const char *end = arg + len;
     char *oldresult;
 
-    if(result == NULL) {
+    if(result == nullptr) {
         SLOGW("malloc error (%s)", strerror(errno));
-        return NULL;
+        return nullptr;
     }
 
     *(current++) = '"';
diff --git a/libsysutils/src/SocketListener.cpp b/libsysutils/src/SocketListener.cpp
index 3f8f3db..0c8a688 100644
--- a/libsysutils/src/SocketListener.cpp
+++ b/libsysutils/src/SocketListener.cpp
@@ -39,7 +39,7 @@
 }
 
 SocketListener::SocketListener(int socketFd, bool listen) {
-    init(NULL, socketFd, listen, false);
+    init(nullptr, socketFd, listen, false);
 }
 
 SocketListener::SocketListener(const char *socketName, bool listen, bool useCmdNum) {
@@ -51,7 +51,7 @@
     mSocketName = socketName;
     mSock = socketFd;
     mUseCmdNum = useCmdNum;
-    pthread_mutex_init(&mClientsLock, NULL);
+    pthread_mutex_init(&mClientsLock, nullptr);
     mClients = new SocketClientCollection();
 }
 
@@ -102,7 +102,7 @@
         return -1;
     }
 
-    if (pthread_create(&mThread, NULL, SocketListener::threadStart, this)) {
+    if (pthread_create(&mThread, nullptr, SocketListener::threadStart, this)) {
         SLOGE("pthread_create (%s)", strerror(errno));
         return -1;
     }
@@ -147,8 +147,8 @@
     SocketListener *me = reinterpret_cast<SocketListener *>(obj);
 
     me->runListener();
-    pthread_exit(NULL);
-    return NULL;
+    pthread_exit(nullptr);
+    return nullptr;
 }
 
 void SocketListener::runListener() {
@@ -183,7 +183,7 @@
         }
         pthread_mutex_unlock(&mClientsLock);
         SLOGV("mListen=%d, max=%d, mSocketName=%s", mListen, max, mSocketName);
-        if ((rc = select(max + 1, &read_fds, NULL, NULL, NULL)) < 0) {
+        if ((rc = select(max + 1, &read_fds, nullptr, nullptr, nullptr)) < 0) {
             if (errno == EINTR)
                 continue;
             SLOGE("select failed (%s) mListen=%d, max=%d", strerror(errno), mListen, max);
diff --git a/libunwindstack/DexFile.cpp b/libunwindstack/DexFile.cpp
index b18b0ce..3d982f6 100644
--- a/libunwindstack/DexFile.cpp
+++ b/libunwindstack/DexFile.cpp
@@ -68,17 +68,51 @@
     return false;  // The DEX offset is not within the bytecode of this dex file.
   }
 
-  for (uint32_t i = 0; i < dex_file_->NumClassDefs(); ++i) {
-    const art::DexFile::ClassDef& class_def = dex_file_->GetClassDef(i);
+  if (dex_file_->IsCompactDexFile()) {
+    // The data section of compact dex files might be shared.
+    // Check the subrange unique to this compact dex.
+    const auto& cdex_header = dex_file_->AsCompactDexFile()->GetHeader();
+    uint32_t begin = cdex_header.data_off_ + cdex_header.OwnedDataBegin();
+    uint32_t end = cdex_header.data_off_ + cdex_header.OwnedDataEnd();
+    if (dex_offset < begin || dex_offset >= end) {
+      return false;  // The DEX offset is not within the bytecode of this dex file.
+    }
+  }
+
+  // The method data is cached in a std::map indexed by method end offset and
+  // contains the start offset and the method member index.
+  // Only cache the method data as it is searched. Do not read the entire
+  // set of method data into the cache at once.
+  // This is done because many unwinds only find a single frame with dex file
+  // info, so reading the entire method data is wasteful. However, still cache
+  // the data so that anything doing multiple unwinds will have this data
+  // cached for future use.
+
+  // First look in the method cache.
+  auto entry = method_cache_.upper_bound(dex_offset);
+  if (entry != method_cache_.end() && dex_offset >= entry->second.first) {
+    *method_name = dex_file_->PrettyMethod(entry->second.second, false);
+    *method_offset = dex_offset - entry->second.first;
+    return true;
+  }
+
+  // Check the methods we haven't cached.
+  for (; class_def_index_ < dex_file_->NumClassDefs(); class_def_index_++) {
+    const art::DexFile::ClassDef& class_def = dex_file_->GetClassDef(class_def_index_);
     const uint8_t* class_data = dex_file_->GetClassData(class_def);
     if (class_data == nullptr) {
       continue;
     }
-    for (art::ClassDataItemIterator it(*dex_file_.get(), class_data); it.HasNext(); it.Next()) {
-      if (!it.IsAtMethod()) {
+
+    if (class_it_.get() == nullptr || !class_it_->HasNext()) {
+      class_it_.reset(new art::ClassDataItemIterator(*dex_file_.get(), class_data));
+    }
+
+    for (; class_it_->HasNext(); class_it_->Next()) {
+      if (!class_it_->IsAtMethod()) {
         continue;
       }
-      const art::DexFile::CodeItem* code_item = it.GetMethodCodeItem();
+      const art::DexFile::CodeItem* code_item = class_it_->GetMethodCodeItem();
       if (code_item == nullptr) {
         continue;
       }
@@ -87,11 +121,15 @@
         continue;
       }
 
-      uint64_t offset = reinterpret_cast<const uint8_t*>(code.Insns()) - dex_file_->Begin();
-      size_t size = code.InsnsSizeInCodeUnits() * sizeof(uint16_t);
-      if (offset <= dex_offset && dex_offset < offset + size) {
-        *method_name = dex_file_->PrettyMethod(it.GetMemberIndex(), false);
+      uint32_t offset = reinterpret_cast<const uint8_t*>(code.Insns()) - dex_file_->Begin();
+      uint32_t offset_end = offset + code.InsnsSizeInCodeUnits() * sizeof(uint16_t);
+      uint32_t member_index = class_it_->GetMemberIndex();
+      method_cache_[offset_end] = std::make_pair(offset, member_index);
+      if (offset <= dex_offset && dex_offset < offset_end) {
+        *method_name = dex_file_->PrettyMethod(member_index, false);
         *method_offset = dex_offset - offset;
+        // Move past this element.
+        class_it_->Next();
         return true;
       }
     }
diff --git a/libunwindstack/DexFile.h b/libunwindstack/DexFile.h
index 3ce2f1e..508692d 100644
--- a/libunwindstack/DexFile.h
+++ b/libunwindstack/DexFile.h
@@ -19,8 +19,10 @@
 
 #include <stdint.h>
 
+#include <map>
 #include <memory>
 #include <string>
+#include <utility>
 #include <vector>
 
 #include <dex/dex_file-inl.h>
@@ -37,7 +39,13 @@
   static DexFile* Create(uint64_t dex_file_offset_in_memory, Memory* memory, MapInfo* info);
 
  protected:
+  void Init();
+
   std::unique_ptr<const art::DexFile> dex_file_;
+  std::map<uint32_t, std::pair<uint64_t, uint32_t>> method_cache_;  // dex offset to method index.
+
+  uint32_t class_def_index_ = 0;
+  std::unique_ptr<art::ClassDataItemIterator> class_it_;
 };
 
 class DexFileFromFile : public DexFile {
diff --git a/libunwindstack/tests/DexFileTest.cpp b/libunwindstack/tests/DexFileTest.cpp
index 0b02c5b..4dd8cb0 100644
--- a/libunwindstack/tests/DexFileTest.cpp
+++ b/libunwindstack/tests/DexFileTest.cpp
@@ -206,15 +206,42 @@
 
   std::string method;
   uint64_t method_offset;
-  dex_file->GetMethodInformation(0x102, &method, &method_offset);
+  ASSERT_TRUE(dex_file->GetMethodInformation(0x102, &method, &method_offset));
   EXPECT_EQ("Main.<init>", method);
   EXPECT_EQ(2U, method_offset);
 
-  method = "not_in_a_method";
-  method_offset = 0x123;
-  dex_file->GetMethodInformation(0x100000, &method, &method_offset);
-  EXPECT_EQ("not_in_a_method", method);
-  EXPECT_EQ(0x123U, method_offset);
+  ASSERT_TRUE(dex_file->GetMethodInformation(0x118, &method, &method_offset));
+  EXPECT_EQ("Main.main", method);
+  EXPECT_EQ(0U, method_offset);
+
+  // Make sure that any data that is cached is still retrievable.
+  ASSERT_TRUE(dex_file->GetMethodInformation(0x104, &method, &method_offset));
+  EXPECT_EQ("Main.<init>", method);
+  EXPECT_EQ(4U, method_offset);
+
+  ASSERT_TRUE(dex_file->GetMethodInformation(0x119, &method, &method_offset));
+  EXPECT_EQ("Main.main", method);
+  EXPECT_EQ(1U, method_offset);
+}
+
+TEST(DexFileTest, get_method_empty) {
+  MemoryFake memory;
+  memory.SetMemory(0x4000, kDexData, sizeof(kDexData));
+  MapInfo info(0x100, 0x10000, 0x200, 0x5, "");
+  std::unique_ptr<DexFile> dex_file(DexFile::Create(0x4000, &memory, &info));
+  ASSERT_TRUE(dex_file != nullptr);
+
+  std::string method;
+  uint64_t method_offset;
+  EXPECT_FALSE(dex_file->GetMethodInformation(0x100000, &method, &method_offset));
+
+  EXPECT_FALSE(dex_file->GetMethodInformation(0x98, &method, &method_offset));
+
+  // Make sure that once the whole dex file has been cached, no problems occur.
+  EXPECT_FALSE(dex_file->GetMethodInformation(0x98, &method, &method_offset));
+
+  // Choose a value that is in the cached map, but not in a valid method.
+  EXPECT_FALSE(dex_file->GetMethodInformation(0x110, &method, &method_offset));
 }
 
 }  // namespace unwindstack
diff --git a/lmkd/lmkd.c b/lmkd/lmkd.c
index 1cfef34..c2487d6 100644
--- a/lmkd/lmkd.c
+++ b/lmkd/lmkd.c
@@ -332,7 +332,7 @@
         data->fd = -1;
         return -1;
     }
-    ALOG_ASSERT((size_t)size < buf_size - 1, data->filename " too large");
+    ALOG_ASSERT((size_t)size < buf_size - 1, "%s too large", data->filename);
     buf[size] = 0;
 
     return 0;
diff --git a/trusty/OWNERS b/trusty/OWNERS
index 357b4f4..e807d71 100644
--- a/trusty/OWNERS
+++ b/trusty/OWNERS
@@ -1,3 +1,7 @@
-bohr@google.com
-swillden@google.com
+arve@google.com
 dkrahn@google.com
+drewry@google.com
+gmar@google.com
+ncbray@google.com
+rpere@google.com
+swillden@google.com
diff --git a/trusty/libtrusty/tipc-test/tipc_test.c b/trusty/libtrusty/tipc-test/tipc_test.c
index 1fb34c9..d20d4ee 100644
--- a/trusty/libtrusty/tipc-test/tipc_test.c
+++ b/trusty/libtrusty/tipc-test/tipc_test.c
@@ -587,8 +587,15 @@
 
 static int ta2ta_ipc_test(void)
 {
+	enum test_message_header {
+		TEST_PASSED = 0,
+		TEST_FAILED = 1,
+		TEST_MESSAGE = 2,
+	};
+
 	int fd;
-	char rx_buf[64];
+	int ret;
+	unsigned char rx_buf[256];
 
 	if (!opt_silent) {
 		printf("%s:\n", __func__);
@@ -601,12 +608,31 @@
 		return fd;
 	}
 
-	/* wait for test to complete */
-	(void) read(fd, rx_buf, sizeof(rx_buf));
+	/* Wait for tests to complete and read status */
+	while (true) {
+		ret = read(fd, rx_buf, sizeof(rx_buf));
+		if (ret <= 0 || ret >= (int)sizeof(rx_buf)) {
+			fprintf(stderr, "%s: Read failed: %d\n", __func__, ret);
+			tipc_close(fd);
+			return -1;
+		}
+
+		if (rx_buf[0] == TEST_PASSED) {
+			break;
+		} else if (rx_buf[0] == TEST_FAILED) {
+			break;
+		} else if (rx_buf[0] == TEST_MESSAGE) {
+			write(STDOUT_FILENO, rx_buf + 1, ret - 1);
+		} else {
+			fprintf(stderr, "%s: Bad message header: %d\n",
+			        __func__, rx_buf[0]);
+			break;
+		}
+	}
 
 	tipc_close(fd);
 
-	return 0;
+	return rx_buf[0] == TEST_PASSED ? 0 : -1;
 }
 
 typedef struct uuid