Merge "init: trigger shutdown directly from builtins"
diff --git a/debuggerd/client/debuggerd_client.cpp b/debuggerd/client/debuggerd_client.cpp
index 1a5b435..7e35a2f 100644
--- a/debuggerd/client/debuggerd_client.cpp
+++ b/debuggerd/client/debuggerd_client.cpp
@@ -195,7 +195,10 @@
     return false;
   }
 
-  InterceptRequest req = {.pid = pid, .dump_type = dump_type};
+  InterceptRequest req = {
+      .dump_type = dump_type,
+      .pid = pid,
+  };
   if (!set_timeout(sockfd)) {
     PLOG(ERROR) << "libdebugger_client: failed to set timeout";
     return false;
diff --git a/debuggerd/debuggerd_test.cpp b/debuggerd/debuggerd_test.cpp
index c9a193c..99729dc 100644
--- a/debuggerd/debuggerd_test.cpp
+++ b/debuggerd/debuggerd_test.cpp
@@ -101,7 +101,10 @@
     FAIL() << "failed to contact tombstoned: " << strerror(errno);
   }
 
-  InterceptRequest req = {.pid = target_pid, .dump_type = intercept_type};
+  InterceptRequest req = {
+      .dump_type = intercept_type,
+      .pid = target_pid,
+  };
 
   unique_fd output_pipe_write;
   if (!Pipe(output_fd, &output_pipe_write)) {
diff --git a/debuggerd/handler/debuggerd_handler.cpp b/debuggerd/handler/debuggerd_handler.cpp
index 598ea85..b90ca80 100644
--- a/debuggerd/handler/debuggerd_handler.cpp
+++ b/debuggerd/handler/debuggerd_handler.cpp
@@ -525,8 +525,8 @@
   log_signal_summary(info);
 
   debugger_thread_info thread_info = {
-      .pseudothread_tid = -1,
       .crashing_tid = __gettid(),
+      .pseudothread_tid = -1,
       .siginfo = info,
       .ucontext = context,
       .abort_msg = reinterpret_cast<uintptr_t>(abort_message),
diff --git a/debuggerd/libdebuggerd/test/tombstone_test.cpp b/debuggerd/libdebuggerd/test/tombstone_test.cpp
index 88c206f..9dea7ac 100644
--- a/debuggerd/libdebuggerd/test/tombstone_test.cpp
+++ b/debuggerd/libdebuggerd/test/tombstone_test.cpp
@@ -345,9 +345,9 @@
 
 TEST_F(TombstoneTest, dump_thread_info_uid) {
   dump_thread_info(&log_, ThreadInfo{.uid = 1,
-                                     .pid = 2,
                                      .tid = 3,
                                      .thread_name = "some_thread",
+                                     .pid = 2,
                                      .process_name = "some_process"});
   std::string expected = "pid: 2, tid: 3, name: some_thread  >>> some_process <<<\nuid: 1\n";
   ASSERT_STREQ(expected.c_str(), amfd_data_.c_str());
diff --git a/fs_mgr/fs_mgr_fstab.cpp b/fs_mgr/fs_mgr_fstab.cpp
index c1a8dae..2ff5243 100644
--- a/fs_mgr/fs_mgr_fstab.cpp
+++ b/fs_mgr/fs_mgr_fstab.cpp
@@ -686,13 +686,14 @@
         if (entries.empty()) {
             FstabEntry entry = {
                     .blk_device = partition,
+                    // .logical_partition_name is required to look up AVB Hashtree descriptors.
+                    .logical_partition_name = "system",
                     .mount_point = mount_point,
                     .fs_type = "ext4",
                     .flags = MS_RDONLY,
                     .fs_options = "barrier=1",
                     .avb_keys = kGsiKeys,
-                    // .logical_partition_name is required to look up AVB Hashtree descriptors.
-                    .logical_partition_name = "system"};
+            };
             entry.fs_mgr_flags.wait = true;
             entry.fs_mgr_flags.logical = true;
             entry.fs_mgr_flags.first_stage_mount = true;
diff --git a/fs_mgr/libdm/Android.bp b/fs_mgr/libdm/Android.bp
index dd95a5e..3ce909e 100644
--- a/fs_mgr/libdm/Android.bp
+++ b/fs_mgr/libdm/Android.bp
@@ -79,3 +79,19 @@
     require_root: true,
     test_min_api_level: 29,
 }
+
+cc_fuzz {
+  name: "dm_table_fuzzer",
+  defaults: ["fs_mgr_defaults"],
+  srcs: [
+    "dm_linear_fuzzer.cpp",
+    "test_util.cpp",
+  ],
+  static_libs: [
+        "libdm",
+        "libbase",
+        "libext2_uuid",
+        "libfs_mgr",
+        "liblog",
+  ],
+}
diff --git a/fs_mgr/libdm/dm_linear_fuzzer.cpp b/fs_mgr/libdm/dm_linear_fuzzer.cpp
new file mode 100644
index 0000000..b119635
--- /dev/null
+++ b/fs_mgr/libdm/dm_linear_fuzzer.cpp
@@ -0,0 +1,139 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <stddef.h>
+#include <stdint.h>
+#include <string.h>
+
+#include <chrono>
+
+#include <android-base/file.h>
+#include <android-base/unique_fd.h>
+#include <libdm/dm_table.h>
+#include <libdm/loop_control.h>
+
+#include "test_util.h"
+
+using namespace android;
+using namespace android::base;
+using namespace android::dm;
+using namespace std;
+using namespace std::chrono_literals;
+
+/*
+ * This test aims at making the library crash, so these functions are not
+ * really useful.
+ * Keeping them here for future use.
+ */
+template <class T, class C>
+void ASSERT_EQ(const T& /*a*/, const C& /*b*/) {
+    // if (a != b) {}
+}
+
+template <class T>
+void ASSERT_FALSE(const T& /*a*/) {
+    // if (a) {}
+}
+
+template <class T, class C>
+void ASSERT_GE(const T& /*a*/, const C& /*b*/) {
+    // if (a < b) {}
+}
+
+template <class T, class C>
+void ASSERT_NE(const T& /*a*/, const C& /*b*/) {
+    // if (a == b) {}
+}
+
+template <class T>
+void ASSERT_TRUE(const T& /*a*/) {
+    // if (!a) {}
+}
+
+template <class T, class C>
+void EXPECT_EQ(const T& a, const C& b) {
+    ASSERT_EQ(a, b);
+}
+
+template <class T>
+void EXPECT_TRUE(const T& a) {
+    ASSERT_TRUE(a);
+}
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+    uint64_t val[6];
+
+    if (size != sizeof(*val)) {
+        return 0;
+    }
+
+    memcpy(&val, &data[0], sizeof(*val));
+
+    unique_fd tmp1(CreateTempFile("file_1", 4096));
+    ASSERT_GE(tmp1, 0);
+    unique_fd tmp2(CreateTempFile("file_2", 4096));
+    ASSERT_GE(tmp2, 0);
+
+    LoopDevice loop_a(tmp1, 10s);
+    ASSERT_TRUE(loop_a.valid());
+    LoopDevice loop_b(tmp2, 10s);
+    ASSERT_TRUE(loop_b.valid());
+
+    // Define a 2-sector device, with each sector mapping to the first sector
+    // of one of our loop devices.
+    DmTable table;
+    ASSERT_TRUE(table.Emplace<DmTargetLinear>(val[0], val[1], loop_a.device(), val[2]));
+    ASSERT_TRUE(table.Emplace<DmTargetLinear>(val[3], val[4], loop_b.device(), val[5]));
+    ASSERT_TRUE(table.valid());
+    ASSERT_EQ(2u, table.num_sectors());
+
+    TempDevice dev("libdm-test-dm-linear", table);
+    ASSERT_TRUE(dev.valid());
+    ASSERT_FALSE(dev.path().empty());
+
+    auto& dm = DeviceMapper::Instance();
+
+    dev_t dev_number;
+    ASSERT_TRUE(dm.GetDeviceNumber(dev.name(), &dev_number));
+    ASSERT_NE(dev_number, 0);
+
+    std::string dev_string;
+    ASSERT_TRUE(dm.GetDeviceString(dev.name(), &dev_string));
+    ASSERT_FALSE(dev_string.empty());
+
+    // Test GetTableStatus.
+    vector<DeviceMapper::TargetInfo> targets;
+    ASSERT_TRUE(dm.GetTableStatus(dev.name(), &targets));
+    ASSERT_EQ(targets.size(), 2);
+    EXPECT_EQ(strcmp(targets[0].spec.target_type, "linear"), 0);
+    EXPECT_TRUE(targets[0].data.empty());
+    EXPECT_EQ(targets[0].spec.sector_start, 0);
+    EXPECT_EQ(targets[0].spec.length, 1);
+    EXPECT_EQ(strcmp(targets[1].spec.target_type, "linear"), 0);
+    EXPECT_TRUE(targets[1].data.empty());
+    EXPECT_EQ(targets[1].spec.sector_start, 1);
+    EXPECT_EQ(targets[1].spec.length, 1);
+
+    // Test GetTargetType().
+    EXPECT_EQ(DeviceMapper::GetTargetType(targets[0].spec), std::string{"linear"});
+    EXPECT_EQ(DeviceMapper::GetTargetType(targets[1].spec), std::string{"linear"});
+
+    // Normally the TestDevice destructor would delete this, but at least one
+    // test should ensure that device deletion works.
+    ASSERT_TRUE(dev.Destroy());
+
+    return 0;
+}
diff --git a/fs_mgr/libfs_avb/tests/avb_util_test.cpp b/fs_mgr/libfs_avb/tests/avb_util_test.cpp
index 0d342d3..784eb9c 100644
--- a/fs_mgr/libfs_avb/tests/avb_util_test.cpp
+++ b/fs_mgr/libfs_avb/tests/avb_util_test.cpp
@@ -101,10 +101,10 @@
 TEST_F(AvbUtilTest, DeriveAvbPartitionName) {
     // The fstab_entry to test.
     FstabEntry fstab_entry = {
-        .blk_device = "/dev/block/dm-1",  // a dm-linear device (logical)
-        .mount_point = "/system",
-        .fs_type = "ext4",
-        .logical_partition_name = "system",
+            .blk_device = "/dev/block/dm-1",  // a dm-linear device (logical)
+            .logical_partition_name = "system",
+            .mount_point = "/system",
+            .fs_type = "ext4",
     };
 
     // Logical partitions.
diff --git a/fs_mgr/libsnapshot/snapshot_test.cpp b/fs_mgr/libsnapshot/snapshot_test.cpp
index fd7754e..aea12be 100644
--- a/fs_mgr/libsnapshot/snapshot_test.cpp
+++ b/fs_mgr/libsnapshot/snapshot_test.cpp
@@ -203,9 +203,9 @@
                     .block_device = fake_super,
                     .metadata = metadata.get(),
                     .partition = &partition,
-                    .device_name = GetPartitionName(partition) + "-base",
                     .force_writable = true,
                     .timeout_ms = 10s,
+                    .device_name = GetPartitionName(partition) + "-base",
             };
             std::string ignore_path;
             if (!CreateLogicalPartition(params, &ignore_path)) {
diff --git a/init/action_parser.cpp b/init/action_parser.cpp
index 9736824..a8e1e09 100644
--- a/init/action_parser.cpp
+++ b/init/action_parser.cpp
@@ -16,11 +16,14 @@
 
 #include "action_parser.h"
 
+#include <ctype.h>
+
 #include <android-base/properties.h>
 #include <android-base/strings.h>
 
 #if defined(__ANDROID__)
 #include "property_service.h"
+#include "selinux.h"
 #else
 #include "host_init_stubs.h"
 #endif
@@ -77,6 +80,17 @@
     return {};
 }
 
+Result<void> ValidateEventTrigger(const std::string& event_trigger) {
+    if (SelinuxGetVendorAndroidVersion() >= __ANDROID_API_R__) {
+        for (const char& c : event_trigger) {
+            if (c != '_' && c != '-' && !std::isalnum(c)) {
+                return Error() << "Illegal character '" << c << "' in '" << event_trigger << "'";
+            }
+        }
+    }
+    return {};
+}
+
 Result<void> ParseTriggers(const std::vector<std::string>& args, Subcontext* subcontext,
                            std::string* event_trigger,
                            std::map<std::string, std::string>* property_triggers) {
@@ -103,6 +117,9 @@
             if (!event_trigger->empty()) {
                 return Error() << "multiple event triggers are not allowed";
             }
+            if (auto result = ValidateEventTrigger(args[i]); !result) {
+                return result;
+            }
 
             *event_trigger = args[i];
         }
diff --git a/init/init_test.cpp b/init/init_test.cpp
index 315d584..9f63e4f 100644
--- a/init/init_test.cpp
+++ b/init/init_test.cpp
@@ -93,6 +93,26 @@
     EXPECT_TRUE(expect_true);
 }
 
+TEST(init, WrongEventTrigger) {
+    std::string init_script =
+            R"init(
+on boot:
+pass_test
+)init";
+
+    TemporaryFile tf;
+    ASSERT_TRUE(tf.fd != -1);
+    ASSERT_TRUE(android::base::WriteStringToFd(init_script, tf.fd));
+
+    ActionManager am;
+
+    Parser parser;
+    parser.AddSectionParser("on", std::make_unique<ActionParser>(&am, nullptr));
+
+    ASSERT_TRUE(parser.ParseConfig(tf.path));
+    ASSERT_EQ(1u, parser.parse_error_count());
+}
+
 TEST(init, EventTriggerOrder) {
     std::string init_script =
         R"init(
diff --git a/liblog/tests/liblog_test.cpp b/liblog/tests/liblog_test.cpp
index cfcfd99..fdb18e4 100644
--- a/liblog/tests/liblog_test.cpp
+++ b/liblog/tests/liblog_test.cpp
@@ -27,10 +27,12 @@
 #include <sys/types.h>
 #include <unistd.h>
 
+#include <memory>
 #include <string>
 
 #include <android-base/file.h>
 #include <android-base/macros.h>
+#include <android-base/scopeguard.h>
 #include <android-base/stringprintf.h>
 #ifdef __ANDROID__  // includes sys/properties.h which does not exist outside
 #include <cutils/properties.h>
@@ -42,6 +44,8 @@
 #include <private/android_filesystem_config.h>
 #include <private/android_logger.h>
 
+using android::base::make_scope_guard;
+
 // #define ENABLE_FLAKY_TESTS
 
 // enhanced version of LOG_FAILURE_RETRY to add support for EAGAIN and
@@ -58,6 +62,79 @@
     _rc;                                                                 \
   })
 
+// This function is meant to be used for most log tests, it does the following:
+// 1) Open the log_buffer with a blocking reader
+// 2) Write the messages via write_messages
+// 3) Set an alarm for 2 seconds as a timeout
+// 4) Read until check_message returns true, which should be used to indicate the target message
+//    is found
+// 5) Open log_buffer with a non_blocking reader and dump all messages
+// 6) Count the number of times check_messages returns true for these messages and assert it's
+//    only 1.
+template <typename FWrite, typename FCheck>
+static void RunLogTests(log_id_t log_buffer, FWrite write_messages, FCheck check_message) {
+  pid_t pid = getpid();
+
+  // std::unique_ptr doesn't let you provide a pointer to a deleter (android_logger_list_close()) if
+  // the type (struct logger_list) is an incomplete type, so we create ListCloser instead.
+  struct ListCloser {
+    void operator()(struct logger_list* list) { android_logger_list_close(list); }
+  };
+  auto logger_list = std::unique_ptr<struct logger_list, ListCloser>{
+      android_logger_list_open(log_buffer, ANDROID_LOG_RDONLY, 1000, pid)};
+  ASSERT_TRUE(logger_list);
+
+  write_messages();
+
+  alarm(2);
+  auto alarm_guard = android::base::make_scope_guard([] { alarm(0); });
+  bool found = false;
+  while (!found) {
+    log_msg log_msg;
+    ASSERT_GT(android_logger_list_read(logger_list.get(), &log_msg), 0);
+
+    ASSERT_EQ(log_buffer, log_msg.id());
+    ASSERT_EQ(pid, log_msg.entry.pid);
+
+    // TODO: Should this be an assert?
+    if (log_msg.msg() == nullptr) {
+      continue;
+    }
+
+    check_message(log_msg, &found);
+  }
+
+  auto logger_list_non_block = std::unique_ptr<struct logger_list, ListCloser>{
+      android_logger_list_open(log_buffer, ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK, 1000, pid)};
+  ASSERT_TRUE(logger_list_non_block);
+
+  size_t count = 0;
+  while (true) {
+    log_msg log_msg;
+    auto ret = android_logger_list_read(logger_list_non_block.get(), &log_msg);
+    if (ret == -EAGAIN) {
+      break;
+    }
+    ASSERT_GT(ret, 0);
+
+    ASSERT_EQ(log_buffer, log_msg.id());
+    ASSERT_EQ(pid, log_msg.entry.pid);
+
+    // TODO: Should this be an assert?
+    if (log_msg.msg() == nullptr) {
+      continue;
+    }
+
+    found = false;
+    check_message(log_msg, &found);
+    if (found) {
+      ++count;
+    }
+  }
+
+  EXPECT_EQ(1U, count);
+}
+
 TEST(liblog, __android_log_btwrite) {
   int intBuf = 0xDEADBEEF;
   EXPECT_LT(0,
@@ -903,32 +980,17 @@
   memcpy(tag, max_payload_tag, sizeof(tag));
   snprintf(tag + sizeof(tag) - 5, 5, "%04X", pid & 0xFFFF);
 
-  LOG_FAILURE_RETRY(__android_log_buf_write(LOG_ID_SYSTEM, ANDROID_LOG_INFO,
-                                            tag, max_payload_buf));
-  sleep(2);
+  auto write_function = [&] {
+    LOG_FAILURE_RETRY(
+        __android_log_buf_write(LOG_ID_SYSTEM, ANDROID_LOG_INFO, tag, max_payload_buf));
+  };
 
-  struct logger_list* logger_list;
-
-  ASSERT_TRUE(NULL != (logger_list = android_logger_list_open(
-                           LOG_ID_SYSTEM, ANDROID_LOG_RDONLY, 100, 0)));
-
-  bool matches = false;
   ssize_t max_len = 0;
-
-  for (;;) {
-    log_msg log_msg;
-    if (android_logger_list_read(logger_list, &log_msg) <= 0) {
-      break;
-    }
-
-    if ((log_msg.entry.pid != pid) || (log_msg.id() != LOG_ID_SYSTEM)) {
-      continue;
-    }
-
+  auto check_function = [&](log_msg log_msg, bool* found) {
     char* data = log_msg.msg();
 
     if (!data || strcmp(++data, tag)) {
-      continue;
+      return;
     }
 
     data += strlen(data) + 1;
@@ -945,14 +1007,11 @@
     }
 
     if (max_len > 512) {
-      matches = true;
-      break;
+      *found = true;
     }
-  }
+  };
 
-  android_logger_list_close(logger_list);
-
-  EXPECT_EQ(true, matches);
+  RunLogTests(LOG_ID_SYSTEM, write_function, check_function);
 
   EXPECT_LE(SIZEOF_MAX_PAYLOAD_BUF, static_cast<size_t>(max_len));
 #else
@@ -963,39 +1022,17 @@
 
 TEST(liblog, __android_log_buf_print__maxtag) {
 #ifdef __ANDROID__
-  struct logger_list* logger_list;
+  auto write_function = [&] {
+    EXPECT_LT(0, __android_log_buf_print(LOG_ID_MAIN, ANDROID_LOG_INFO, max_payload_buf,
+                                         max_payload_buf));
+  };
 
-  pid_t pid = getpid();
-
-  ASSERT_TRUE(
-      NULL !=
-      (logger_list = android_logger_list_open(
-           LOG_ID_MAIN, ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK, 1000, pid)));
-
-  log_time ts(android_log_clockid());
-
-  EXPECT_LT(0, __android_log_buf_print(LOG_ID_MAIN, ANDROID_LOG_INFO,
-                                       max_payload_buf, max_payload_buf));
-  usleep(1000000);
-
-  int count = 0;
-
-  for (;;) {
-    log_msg log_msg;
-    if (android_logger_list_read(logger_list, &log_msg) <= 0) {
-      break;
+  auto check_function = [&](log_msg log_msg, bool* found) {
+    if ((size_t)log_msg.entry.len < LOGGER_ENTRY_MAX_PAYLOAD) {
+      return;
     }
 
-    ASSERT_EQ(log_msg.entry.pid, pid);
-
-    if ((log_msg.entry.sec < (ts.tv_sec - 1)) ||
-        ((ts.tv_sec + 1) < log_msg.entry.sec) ||
-        ((size_t)log_msg.entry.len < LOGGER_ENTRY_MAX_PAYLOAD) ||
-        (log_msg.id() != LOG_ID_MAIN)) {
-      continue;
-    }
-
-    ++count;
+    *found = true;
 
     AndroidLogFormat* logformat = android_log_format_new();
     EXPECT_TRUE(NULL != logformat);
@@ -1013,16 +1050,18 @@
       EXPECT_GT(LOGGER_ENTRY_MAX_PAYLOAD * 13 / 8, printLogLine);
     }
     android_log_format_free(logformat);
-  }
+  };
 
-  EXPECT_EQ(1, count);
+  RunLogTests(LOG_ID_MAIN, write_function, check_function);
 
-  android_logger_list_close(logger_list);
 #else
   GTEST_LOG_(INFO) << "This test does nothing.\n";
 #endif
 }
 
+// TODO: This test is tautological. android_logger_list_read() calls recv() with
+// LOGGER_ENTRY_MAX_PAYLOAD as its size argument, so it's not possible for this test to read a
+// payload larger than that size.
 TEST(liblog, too_big_payload) {
 #ifdef __ANDROID__
   pid_t pid = getpid();
@@ -1032,32 +1071,18 @@
   snprintf(tag + sizeof(tag) - 5, 5, "%04X", pid & 0xFFFF);
 
   std::string longString(3266519, 'x');
+  ssize_t ret;
 
-  ssize_t ret = LOG_FAILURE_RETRY(__android_log_buf_write(
-      LOG_ID_SYSTEM, ANDROID_LOG_INFO, tag, longString.c_str()));
+  auto write_function = [&] {
+    ret = LOG_FAILURE_RETRY(
+        __android_log_buf_write(LOG_ID_SYSTEM, ANDROID_LOG_INFO, tag, longString.c_str()));
+  };
 
-  struct logger_list* logger_list;
-
-  ASSERT_TRUE(NULL != (logger_list = android_logger_list_open(
-                           LOG_ID_SYSTEM,
-                           ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK, 100, 0)));
-
-  ssize_t max_len = 0;
-
-  for (;;) {
-    log_msg log_msg;
-    if (android_logger_list_read(logger_list, &log_msg) <= 0) {
-      break;
-    }
-
-    if ((log_msg.entry.pid != pid) || (log_msg.id() != LOG_ID_SYSTEM)) {
-      continue;
-    }
-
+  auto check_function = [&](log_msg log_msg, bool* found) {
     char* data = log_msg.msg();
 
     if (!data || strcmp(++data, tag)) {
-      continue;
+      return;
     }
 
     data += strlen(data) + 1;
@@ -1069,23 +1094,19 @@
       ++right;
     }
 
-    if (max_len <= (left - data)) {
-      max_len = left - data + 1;
+    ssize_t len = left - data + 1;
+    // Check that we don't see any entries larger than the max payload.
+    EXPECT_LE(static_cast<size_t>(len), LOGGER_ENTRY_MAX_PAYLOAD - sizeof(big_payload_tag));
+
+    // Once we've found our expected entry, break.
+    if (len == LOGGER_ENTRY_MAX_PAYLOAD - sizeof(big_payload_tag)) {
+      EXPECT_EQ(ret, len + static_cast<ssize_t>(sizeof(big_payload_tag)));
+      *found = true;
     }
-  }
+  };
 
-  android_logger_list_close(logger_list);
+  RunLogTests(LOG_ID_SYSTEM, write_function, check_function);
 
-  EXPECT_LE(LOGGER_ENTRY_MAX_PAYLOAD - sizeof(big_payload_tag),
-            static_cast<size_t>(max_len));
-
-  // SLOP: Allow the underlying interface to optionally place a
-  // terminating nul at the LOGGER_ENTRY_MAX_PAYLOAD's last byte
-  // or not.
-  if (ret == (max_len + static_cast<ssize_t>(sizeof(big_payload_tag)) - 1)) {
-    --max_len;
-  }
-  EXPECT_EQ(ret, max_len + static_cast<ssize_t>(sizeof(big_payload_tag)));
 #else
   GTEST_LOG_(INFO) << "This test does nothing.\n";
 #endif
@@ -1886,101 +1907,71 @@
 #endif  // ENABLE_FLAKY_TESTS
 
 #ifdef __ANDROID__
-static void android_errorWriteWithInfoLog_helper(int TAG, const char* SUBTAG,
-                                                 int UID, const char* payload,
-                                                 int DATA_LEN, int& count) {
-  struct logger_list* logger_list;
+static void android_errorWriteWithInfoLog_helper(int tag, const char* subtag, int uid,
+                                                 const char* payload, int data_len) {
+  auto write_function = [&] {
+    int ret = android_errorWriteWithInfoLog(tag, subtag, uid, payload, data_len);
+    ASSERT_LT(0, ret);
+  };
 
-  pid_t pid = getpid();
-
-  count = 0;
-
-  ASSERT_TRUE(NULL !=
-              (logger_list = android_logger_list_open(
-                   LOG_ID_EVENTS, ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK,
-                   1000, pid)));
-
-  int retval_android_errorWriteWithinInfoLog =
-      android_errorWriteWithInfoLog(TAG, SUBTAG, UID, payload, DATA_LEN);
-  if (payload) {
-    ASSERT_LT(0, retval_android_errorWriteWithinInfoLog);
-  } else {
-    ASSERT_GT(0, retval_android_errorWriteWithinInfoLog);
-  }
-
-  sleep(2);
-
-  for (;;) {
-    log_msg log_msg;
-    if (android_logger_list_read(logger_list, &log_msg) <= 0) {
-      break;
-    }
-
-    char* eventData = log_msg.msg();
-    if (!eventData) {
-      continue;
-    }
-
-    char* original = eventData;
+  auto check_function = [&](log_msg log_msg, bool* found) {
+    char* event_data = log_msg.msg();
+    char* original = event_data;
 
     // Tag
-    auto* event_header = reinterpret_cast<android_event_header_t*>(eventData);
-    eventData += sizeof(android_event_header_t);
-
-    if (event_header->tag != TAG) {
-      continue;
-    }
-
-    if (!payload) {
-      // This tag should not have been written because the data was null
-      ++count;
-      break;
+    auto* event_header = reinterpret_cast<android_event_header_t*>(event_data);
+    event_data += sizeof(android_event_header_t);
+    if (event_header->tag != tag) {
+      return;
     }
 
     // List type
-    auto* event_list = reinterpret_cast<android_event_list_t*>(eventData);
+    auto* event_list = reinterpret_cast<android_event_list_t*>(event_data);
     ASSERT_EQ(EVENT_TYPE_LIST, event_list->type);
     ASSERT_EQ(3, event_list->element_count);
-    eventData += sizeof(android_event_list_t);
+    event_data += sizeof(android_event_list_t);
 
     // Element #1: string type for subtag
-    auto* event_string_subtag = reinterpret_cast<android_event_string_t*>(eventData);
+    auto* event_string_subtag = reinterpret_cast<android_event_string_t*>(event_data);
     ASSERT_EQ(EVENT_TYPE_STRING, event_string_subtag->type);
-    unsigned subtag_len = strlen(SUBTAG);
-    if (subtag_len > 32) subtag_len = 32;
-    ASSERT_EQ(static_cast<int32_t>(subtag_len), event_string_subtag->length);
-    if (memcmp(SUBTAG, &event_string_subtag->data, subtag_len)) {
-      continue;
+    int32_t subtag_len = strlen(subtag);
+    if (subtag_len > 32) {
+      subtag_len = 32;
     }
-    eventData += sizeof(android_event_string_t) + subtag_len;
+    ASSERT_EQ(subtag_len, event_string_subtag->length);
+    if (memcmp(subtag, &event_string_subtag->data, subtag_len)) {
+      return;
+    }
+    event_data += sizeof(android_event_string_t) + subtag_len;
 
     // Element #2: int type for uid
-    auto* event_int_uid = reinterpret_cast<android_event_int_t*>(eventData);
+    auto* event_int_uid = reinterpret_cast<android_event_int_t*>(event_data);
     ASSERT_EQ(EVENT_TYPE_INT, event_int_uid->type);
-    ASSERT_EQ(UID, event_int_uid->data);
-    eventData += sizeof(android_event_int_t);
+    ASSERT_EQ(uid, event_int_uid->data);
+    event_data += sizeof(android_event_int_t);
 
     // Element #3: string type for data
-    auto* event_string_data = reinterpret_cast<android_event_string_t*>(eventData);
+    auto* event_string_data = reinterpret_cast<android_event_string_t*>(event_data);
     ASSERT_EQ(EVENT_TYPE_STRING, event_string_data->type);
-    size_t dataLen = event_string_data->length;
-    if (DATA_LEN < 512) ASSERT_EQ(DATA_LEN, (int)dataLen);
-    if (memcmp(payload, &event_string_data->data, dataLen)) {
-      continue;
+    int32_t message_data_len = event_string_data->length;
+    if (data_len < 512) {
+      ASSERT_EQ(data_len, message_data_len);
     }
-    eventData += sizeof(android_event_string_t);
+    if (memcmp(payload, &event_string_data->data, message_data_len) != 0) {
+      return;
+    }
+    event_data += sizeof(android_event_string_t);
 
-    if (DATA_LEN >= 512) {
-      eventData += dataLen;
+    if (data_len >= 512) {
+      event_data += message_data_len;
       // 4 bytes for the tag, and max_payload_buf should be truncated.
-      ASSERT_LE(4 + 512, eventData - original);       // worst expectations
-      ASSERT_GT(4 + DATA_LEN, eventData - original);  // must be truncated
+      ASSERT_LE(4 + 512, event_data - original);       // worst expectations
+      ASSERT_GT(4 + data_len, event_data - original);  // must be truncated
     }
+    *found = true;
+  };
 
-    ++count;
-  }
-
-  android_logger_list_close(logger_list);
+  RunLogTests(LOG_ID_EVENTS, write_function, check_function);
 }
 #endif
 
@@ -1995,10 +1986,7 @@
 
 TEST(liblog, android_errorWriteWithInfoLog__android_logger_list_read__typical) {
 #ifdef __ANDROID__
-  int count;
-  android_errorWriteWithInfoLog_helper(UNIQUE_TAG(1), "test-subtag", -1,
-                                       max_payload_buf, 200, count);
-  EXPECT_EQ(1, count);
+  android_errorWriteWithInfoLog_helper(UNIQUE_TAG(1), "test-subtag", -1, max_payload_buf, 200);
 #else
   GTEST_LOG_(INFO) << "This test does nothing.\n";
 #endif
@@ -2007,23 +1995,20 @@
 TEST(liblog,
      android_errorWriteWithInfoLog__android_logger_list_read__data_too_large) {
 #ifdef __ANDROID__
-  int count;
-  android_errorWriteWithInfoLog_helper(UNIQUE_TAG(2), "test-subtag", -1,
-                                       max_payload_buf, sizeof(max_payload_buf),
-                                       count);
-  EXPECT_EQ(1, count);
+  android_errorWriteWithInfoLog_helper(UNIQUE_TAG(2), "test-subtag", -1, max_payload_buf,
+                                       sizeof(max_payload_buf));
 #else
   GTEST_LOG_(INFO) << "This test does nothing.\n";
 #endif
 }
 
+// TODO: Do we need to check that we didn't actually write anything if we return a failure here?
 TEST(liblog,
      android_errorWriteWithInfoLog__android_logger_list_read__null_data) {
 #ifdef __ANDROID__
-  int count;
-  android_errorWriteWithInfoLog_helper(UNIQUE_TAG(3), "test-subtag", -1, NULL,
-                                       200, count);
-  EXPECT_EQ(0, count);
+  int retval_android_errorWriteWithinInfoLog =
+      android_errorWriteWithInfoLog(UNIQUE_TAG(3), "test-subtag", -1, nullptr, 200);
+  ASSERT_GT(0, retval_android_errorWriteWithinInfoLog);
 #else
   GTEST_LOG_(INFO) << "This test does nothing.\n";
 #endif
@@ -2032,11 +2017,8 @@
 TEST(liblog,
      android_errorWriteWithInfoLog__android_logger_list_read__subtag_too_long) {
 #ifdef __ANDROID__
-  int count;
   android_errorWriteWithInfoLog_helper(
-      UNIQUE_TAG(4), "abcdefghijklmnopqrstuvwxyz now i know my abc", -1,
-      max_payload_buf, 200, count);
-  EXPECT_EQ(1, count);
+      UNIQUE_TAG(4), "abcdefghijklmnopqrstuvwxyz now i know my abc", -1, max_payload_buf, 200);
 #else
   GTEST_LOG_(INFO) << "This test does nothing.\n";
 #endif
@@ -2050,124 +2032,44 @@
   buf_write_test(max_payload_buf);
 }
 
-#ifdef __ANDROID__
-static void android_errorWriteLog_helper(int TAG, const char* SUBTAG,
-                                         int& count) {
-  struct logger_list* logger_list;
-
-  pid_t pid = getpid();
-
-  count = 0;
-
-  // Do a Before and After on the count to measure the effect. Decrement
-  // what we find in Before to set the stage.
-  ASSERT_TRUE(NULL !=
-              (logger_list = android_logger_list_open(
-                   LOG_ID_EVENTS, ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK,
-                   1000, pid)));
-
-  for (;;) {
-    log_msg log_msg;
-    if (android_logger_list_read(logger_list, &log_msg) <= 0) break;
-
-    char* eventData = log_msg.msg();
-    if (!eventData) continue;
-
-    // Tag
-    auto* event_header = reinterpret_cast<android_event_header_t*>(eventData);
-    eventData += sizeof(android_event_header_t);
-
-    if (event_header->tag != TAG) {
-      continue;
-    }
-
-    if (!SUBTAG) {
-      // This tag should not have been written because the data was null
-      --count;
-      break;
-    }
-
-    // List type
-    eventData++;
-    // Number of elements in list
-    eventData++;
-    // Element #1: string type for subtag
-    eventData++;
-
-    eventData += 4;
-
-    if (memcmp(SUBTAG, eventData, strlen(SUBTAG))) continue;
-    --count;
-  }
-
-  android_logger_list_close(logger_list);
-
-  // Do an After on the count to measure the effect.
-  ASSERT_TRUE(NULL !=
-              (logger_list = android_logger_list_open(
-                   LOG_ID_EVENTS, ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK,
-                   1000, pid)));
-
-  int retval_android_errorWriteLog = android_errorWriteLog(TAG, SUBTAG);
-  if (SUBTAG) {
-    ASSERT_LT(0, retval_android_errorWriteLog);
-  } else {
-    ASSERT_GT(0, retval_android_errorWriteLog);
-  }
-
-  sleep(2);
-
-  for (;;) {
-    log_msg log_msg;
-    if (android_logger_list_read(logger_list, &log_msg) <= 0) {
-      break;
-    }
-
-    char* eventData = log_msg.msg();
-    if (!eventData) {
-      continue;
-    }
-
-    // Tag
-    auto* event_header = reinterpret_cast<android_event_header_t*>(eventData);
-    eventData += sizeof(android_event_header_t);
-
-    if (event_header->tag != TAG) {
-      continue;
-    }
-
-    if (!SUBTAG) {
-      // This tag should not have been written because the data was null
-      ++count;
-      break;
-    }
-
-    // List type
-    auto* event_list = reinterpret_cast<android_event_list_t*>(eventData);
-    ASSERT_EQ(EVENT_TYPE_LIST, event_list->type);
-    ASSERT_EQ(3, event_list->element_count);
-    eventData += sizeof(android_event_list_t);
-
-    // Element #1: string type for subtag
-    auto* event_string = reinterpret_cast<android_event_string_t*>(eventData);
-    ASSERT_EQ(EVENT_TYPE_STRING, event_string->type);
-    ASSERT_EQ(static_cast<int32_t>(strlen(SUBTAG)), event_string->length);
-
-    if (memcmp(SUBTAG, &event_string->data, strlen(SUBTAG))) {
-      continue;
-    }
-    ++count;
-  }
-
-  android_logger_list_close(logger_list);
-}
-#endif
-
 TEST(liblog, android_errorWriteLog__android_logger_list_read__success) {
 #ifdef __ANDROID__
-  int count;
-  android_errorWriteLog_helper(UNIQUE_TAG(5), "test-subtag", count);
-  EXPECT_EQ(1, count);
+  int kTag = UNIQUE_TAG(5);
+  const char* kSubTag = "test-subtag";
+
+  auto write_function = [&] {
+    int retval_android_errorWriteLog = android_errorWriteLog(kTag, kSubTag);
+    ASSERT_LT(0, retval_android_errorWriteLog);
+  };
+
+  auto check_function = [&](log_msg log_msg, bool* found) {
+    char* event_data = log_msg.msg();
+
+    // Tag
+    auto* event_header = reinterpret_cast<android_event_header_t*>(event_data);
+    event_data += sizeof(android_event_header_t);
+    if (event_header->tag != kTag) {
+      return;
+    }
+
+    // List type
+    auto* event_list = reinterpret_cast<android_event_list_t*>(event_data);
+    ASSERT_EQ(EVENT_TYPE_LIST, event_list->type);
+    ASSERT_EQ(3, event_list->element_count);
+    event_data += sizeof(android_event_list_t);
+
+    // Element #1: string type for subtag
+    auto* event_string_subtag = reinterpret_cast<android_event_string_t*>(event_data);
+    ASSERT_EQ(EVENT_TYPE_STRING, event_string_subtag->type);
+    int32_t subtag_len = strlen(kSubTag);
+    ASSERT_EQ(subtag_len, event_string_subtag->length);
+    if (memcmp(kSubTag, &event_string_subtag->data, subtag_len) == 0) {
+      *found = true;
+    }
+  };
+
+  RunLogTests(LOG_ID_EVENTS, write_function, check_function);
+
 #else
   GTEST_LOG_(INFO) << "This test does nothing.\n";
 #endif
@@ -2175,9 +2077,7 @@
 
 TEST(liblog, android_errorWriteLog__android_logger_list_read__null_subtag) {
 #ifdef __ANDROID__
-  int count;
-  android_errorWriteLog_helper(UNIQUE_TAG(6), NULL, count);
-  EXPECT_EQ(0, count);
+  EXPECT_LT(android_errorWriteLog(UNIQUE_TAG(6), nullptr), 0);
 #else
   GTEST_LOG_(INFO) << "This test does nothing.\n";
 #endif
@@ -2595,52 +2495,21 @@
 
 static void create_android_logger(const char* (*fn)(uint32_t tag,
                                                     size_t& expected_len)) {
-  struct logger_list* logger_list;
+  size_t expected_len;
+  const char* expected_string;
+  auto write_function = [&] {
+    expected_string = (*fn)(1005, expected_len);
+    ASSERT_NE(nullptr, expected_string);
+  };
 
   pid_t pid = getpid();
-
-  ASSERT_TRUE(NULL !=
-              (logger_list = android_logger_list_open(
-                   LOG_ID_EVENTS, ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK,
-                   1000, pid)));
-
-#ifdef __ANDROID__
-  log_time ts(android_log_clockid());
-#else
-  log_time ts(CLOCK_REALTIME);
-#endif
-
-  size_t expected_len;
-  const char* expected_string = (*fn)(1005, expected_len);
-
-  if (!expected_string) {
-    android_logger_list_close(logger_list);
-    return;
-  }
-
-  usleep(1000000);
-
-  int count = 0;
-
-  for (;;) {
-    log_msg log_msg;
-    if (android_logger_list_read(logger_list, &log_msg) <= 0) {
-      break;
-    }
-
-    ASSERT_EQ(log_msg.entry.pid, pid);
-
-    if ((log_msg.entry.sec < (ts.tv_sec - 1)) ||
-        ((ts.tv_sec + 1) < log_msg.entry.sec) ||
-        ((size_t)log_msg.entry.len != expected_len) ||
-        (log_msg.id() != LOG_ID_EVENTS)) {
-      continue;
+  auto check_function = [&](log_msg log_msg, bool* found) {
+    if (static_cast<size_t>(log_msg.entry.len) != expected_len) {
+      return;
     }
 
     char* eventData = log_msg.msg();
 
-    ++count;
-
     AndroidLogFormat* logformat = android_log_format_new();
     EXPECT_TRUE(NULL != logformat);
     AndroidLogEntry entry;
@@ -2676,11 +2545,10 @@
     }
     EXPECT_EQ(0, buffer_to_string);
     EXPECT_STREQ(expected_string, msgBuf);
-  }
+    *found = true;
+  };
 
-  EXPECT_EQ(1, count);
-
-  android_logger_list_close(logger_list);
+  RunLogTests(LOG_ID_EVENTS, write_function, check_function);
 }
 #endif
 
diff --git a/libmeminfo/include/meminfo/procmeminfo.h b/libmeminfo/include/meminfo/procmeminfo.h
index f782ec5..8c1280f 100644
--- a/libmeminfo/include/meminfo/procmeminfo.h
+++ b/libmeminfo/include/meminfo/procmeminfo.h
@@ -48,6 +48,10 @@
     // Same as Maps() except, do not read the usage stats for each map.
     const std::vector<Vma>& MapsWithoutUsageStats();
 
+    // If MapsWithoutUsageStats was called, this function will fill in
+    // usage stats for this single vma.
+    bool FillInVmaStats(Vma& vma);
+
     // Collect all 'vma' or 'maps' from /proc/<pid>/smaps and store them in 'maps_'. Returns a
     // constant reference to the vma vector after the collection is done.
     //
diff --git a/libmeminfo/libmeminfo_test.cpp b/libmeminfo/libmeminfo_test.cpp
index cf5341d..378a4cd 100644
--- a/libmeminfo/libmeminfo_test.cpp
+++ b/libmeminfo/libmeminfo_test.cpp
@@ -101,6 +101,33 @@
     }
 }
 
+TEST(ProcMemInfo, MapsUsageFillInLater) {
+    ProcMemInfo proc_mem(pid);
+    const std::vector<Vma>& maps = proc_mem.MapsWithoutUsageStats();
+    EXPECT_FALSE(maps.empty());
+    for (auto& map : maps) {
+        Vma update_map(map);
+        ASSERT_EQ(map.start, update_map.start);
+        ASSERT_EQ(map.end, update_map.end);
+        ASSERT_EQ(map.offset, update_map.offset);
+        ASSERT_EQ(map.flags, update_map.flags);
+        ASSERT_EQ(map.name, update_map.name);
+        ASSERT_EQ(0, update_map.usage.vss);
+        ASSERT_EQ(0, update_map.usage.rss);
+        ASSERT_EQ(0, update_map.usage.pss);
+        ASSERT_EQ(0, update_map.usage.uss);
+        ASSERT_EQ(0, update_map.usage.swap);
+        ASSERT_EQ(0, update_map.usage.swap_pss);
+        ASSERT_EQ(0, update_map.usage.private_clean);
+        ASSERT_EQ(0, update_map.usage.private_dirty);
+        ASSERT_EQ(0, update_map.usage.shared_clean);
+        ASSERT_EQ(0, update_map.usage.shared_dirty);
+        ASSERT_TRUE(proc_mem.FillInVmaStats(update_map));
+        // Check that at least one usage stat was updated.
+        ASSERT_NE(0, update_map.usage.vss);
+    }
+}
+
 TEST(ProcMemInfo, PageMapPresent) {
     static constexpr size_t kNumPages = 20;
     size_t pagesize = getpagesize();
diff --git a/libmeminfo/procmeminfo.cpp b/libmeminfo/procmeminfo.cpp
index 6f68ab4..9e9a705 100644
--- a/libmeminfo/procmeminfo.cpp
+++ b/libmeminfo/procmeminfo.cpp
@@ -244,6 +244,15 @@
     return true;
 }
 
+static int GetPagemapFd(pid_t pid) {
+    std::string pagemap_file = ::android::base::StringPrintf("/proc/%d/pagemap", pid);
+    int fd = TEMP_FAILURE_RETRY(open(pagemap_file.c_str(), O_RDONLY | O_CLOEXEC));
+    if (fd == -1) {
+        PLOG(ERROR) << "Failed to open " << pagemap_file;
+    }
+    return fd;
+}
+
 bool ProcMemInfo::ReadMaps(bool get_wss, bool use_pageidle, bool get_usage_stats) {
     // Each object reads /proc/<pid>/maps only once. This is done to make sure programs that are
     // running for the lifetime of the system can recycle the objects and don't have to
@@ -269,11 +278,8 @@
         return true;
     }
 
-    std::string pagemap_file = ::android::base::StringPrintf("/proc/%d/pagemap", pid_);
-    ::android::base::unique_fd pagemap_fd(
-            TEMP_FAILURE_RETRY(open(pagemap_file.c_str(), O_RDONLY | O_CLOEXEC)));
-    if (pagemap_fd < 0) {
-        PLOG(ERROR) << "Failed to open " << pagemap_file;
+    ::android::base::unique_fd pagemap_fd(GetPagemapFd(pid_));
+    if (pagemap_fd == -1) {
         return false;
     }
 
@@ -290,6 +296,20 @@
     return true;
 }
 
+bool ProcMemInfo::FillInVmaStats(Vma& vma) {
+    ::android::base::unique_fd pagemap_fd(GetPagemapFd(pid_));
+    if (pagemap_fd == -1) {
+        return false;
+    }
+
+    if (!ReadVmaStats(pagemap_fd.get(), vma, get_wss_, false)) {
+        LOG(ERROR) << "Failed to read page map for vma " << vma.name << "[" << vma.start << "-"
+                   << vma.end << "]";
+        return false;
+    }
+    return true;
+}
+
 bool ProcMemInfo::ReadVmaStats(int pagemap_fd, Vma& vma, bool get_wss, bool use_pageidle) {
     PageAcct& pinfo = PageAcct::Instance();
     if (get_wss && use_pageidle && !pinfo.InitPageAcct(true)) {
diff --git a/libunwindstack/tests/DwarfSectionTest.cpp b/libunwindstack/tests/DwarfSectionTest.cpp
index 6df2bae..953dc75 100644
--- a/libunwindstack/tests/DwarfSectionTest.cpp
+++ b/libunwindstack/tests/DwarfSectionTest.cpp
@@ -30,23 +30,24 @@
   MockDwarfSection(Memory* memory) : DwarfSection(memory) {}
   virtual ~MockDwarfSection() = default;
 
-  MOCK_METHOD3(Init, bool(uint64_t, uint64_t, int64_t));
+  MOCK_METHOD(bool, Init, (uint64_t, uint64_t, int64_t), (override));
 
-  MOCK_METHOD5(Eval, bool(const DwarfCie*, Memory*, const dwarf_loc_regs_t&, Regs*, bool*));
+  MOCK_METHOD(bool, Eval, (const DwarfCie*, Memory*, const dwarf_loc_regs_t&, Regs*, bool*),
+              (override));
 
-  MOCK_METHOD3(Log, bool(uint8_t, uint64_t, const DwarfFde*));
+  MOCK_METHOD(bool, Log, (uint8_t, uint64_t, const DwarfFde*), (override));
 
-  MOCK_METHOD1(GetFdes, void(std::vector<const DwarfFde*>*));
+  MOCK_METHOD(void, GetFdes, (std::vector<const DwarfFde*>*), (override));
 
-  MOCK_METHOD1(GetFdeFromPc, const DwarfFde*(uint64_t));
+  MOCK_METHOD(const DwarfFde*, GetFdeFromPc, (uint64_t), (override));
 
-  MOCK_METHOD3(GetCfaLocationInfo, bool(uint64_t, const DwarfFde*, dwarf_loc_regs_t*));
+  MOCK_METHOD(bool, GetCfaLocationInfo, (uint64_t, const DwarfFde*, dwarf_loc_regs_t*), (override));
 
-  MOCK_METHOD1(GetCieOffsetFromFde32, uint64_t(uint32_t));
+  MOCK_METHOD(uint64_t, GetCieOffsetFromFde32, (uint32_t), (override));
 
-  MOCK_METHOD1(GetCieOffsetFromFde64, uint64_t(uint64_t));
+  MOCK_METHOD(uint64_t, GetCieOffsetFromFde64, (uint64_t), (override));
 
-  MOCK_METHOD1(AdjustPcFromFde, uint64_t(uint64_t));
+  MOCK_METHOD(uint64_t, AdjustPcFromFde, (uint64_t), (override));
 };
 
 class DwarfSectionTest : public ::testing::Test {
diff --git a/libunwindstack/tests/ElfTest.cpp b/libunwindstack/tests/ElfTest.cpp
index 8c1eade..e6728a0 100644
--- a/libunwindstack/tests/ElfTest.cpp
+++ b/libunwindstack/tests/ElfTest.cpp
@@ -316,9 +316,9 @@
   bool GetFunctionName(uint64_t, std::string*, uint64_t*) override { return false; }
   std::string GetBuildID() override { return ""; }
 
-  MOCK_METHOD4(Step, bool(uint64_t, Regs*, Memory*, bool*));
-  MOCK_METHOD2(GetGlobalVariable, bool(const std::string&, uint64_t*));
-  MOCK_METHOD1(IsValidPc, bool(uint64_t));
+  MOCK_METHOD(bool, Step, (uint64_t, Regs*, Memory*, bool*), (override));
+  MOCK_METHOD(bool, GetGlobalVariable, (const std::string&, uint64_t*), (override));
+  MOCK_METHOD(bool, IsValidPc, (uint64_t), (override));
 
   void MockSetDynamicOffset(uint64_t offset) { dynamic_offset_ = offset; }
   void MockSetDynamicVaddr(uint64_t vaddr) { dynamic_vaddr_ = vaddr; }