Merge "Fixing a bug introduced due to refactoring var names"
diff --git a/debuggerd/tombstoned/tombstoned.cpp b/debuggerd/tombstoned/tombstoned.cpp
index 5dffa5b..15ae406 100644
--- a/debuggerd/tombstoned/tombstoned.cpp
+++ b/debuggerd/tombstoned/tombstoned.cpp
@@ -61,6 +61,7 @@
 struct Crash {
   ~Crash() { event_free(crash_event); }
 
+  std::string crash_tombstone_path;
   unique_fd crash_tombstone_fd;
   unique_fd crash_socket_fd;
   pid_t crash_pid;
@@ -109,20 +110,22 @@
     return &queue;
   }
 
-  unique_fd get_output() {
+  std::pair<std::string, unique_fd> get_output() {
+    std::string path;
     unique_fd result(openat(dir_fd_, ".", O_WRONLY | O_APPEND | O_TMPFILE | O_CLOEXEC, 0640));
     if (result == -1) {
-      // We might not have O_TMPFILE. Try creating and unlinking instead.
-      result.reset(
-          openat(dir_fd_, ".temporary", O_WRONLY | O_APPEND | O_CREAT | O_TRUNC | O_CLOEXEC, 0640));
+      // We might not have O_TMPFILE. Try creating with an arbitrary filename instead.
+      static size_t counter = 0;
+      std::string tmp_filename = StringPrintf(".temporary%zu", counter++);
+      result.reset(openat(dir_fd_, tmp_filename.c_str(),
+                          O_WRONLY | O_APPEND | O_CREAT | O_TRUNC | O_CLOEXEC, 0640));
       if (result == -1) {
         PLOG(FATAL) << "failed to create temporary tombstone in " << dir_path_;
       }
-      if (unlinkat(dir_fd_, ".temporary", 0) != 0) {
-        PLOG(FATAL) << "failed to unlink temporary tombstone";
-      }
+
+      path = StringPrintf("%s/%s", dir_path_.c_str(), tmp_filename.c_str());
     }
-    return result;
+    return std::make_pair(std::move(path), std::move(result));
   }
 
   std::string get_next_artifact_path() {
@@ -209,7 +212,7 @@
   bool intercepted =
       intercept_manager->GetIntercept(crash->crash_pid, crash->crash_type, &output_fd);
   if (!intercepted) {
-    output_fd = CrashQueue::for_crash(crash)->get_output();
+    std::tie(crash->crash_tombstone_path, output_fd) = CrashQueue::for_crash(crash)->get_output();
     crash->crash_tombstone_fd.reset(dup(output_fd.get()));
   }
 
@@ -351,8 +354,10 @@
   if (crash->crash_tombstone_fd != -1) {
     std::string fd_path = StringPrintf("/proc/self/fd/%d", crash->crash_tombstone_fd.get());
     std::string tombstone_path = CrashQueue::for_crash(crash)->get_next_artifact_path();
+
+    // linkat doesn't let us replace a file, so we need to unlink first.
     int rc = unlink(tombstone_path.c_str());
-    if (rc != 0) {
+    if (rc != 0 && errno != ENOENT) {
       PLOG(ERROR) << "failed to unlink tombstone at " << tombstone_path;
       goto fail;
     }
@@ -370,6 +375,14 @@
         LOG(ERROR) << "Tombstone written to: " << tombstone_path;
       }
     }
+
+    // If we don't have O_TMPFILE, we need to clean up after ourselves.
+    if (!crash->crash_tombstone_path.empty()) {
+      rc = unlink(crash->crash_tombstone_path.c_str());
+      if (rc != 0) {
+        PLOG(ERROR) << "failed to unlink temporary tombstone at " << crash->crash_tombstone_path;
+      }
+    }
   }
 
 fail:
diff --git a/fs_mgr/fs_mgr.cpp b/fs_mgr/fs_mgr.cpp
index 9aab0ba..6769fda 100644
--- a/fs_mgr/fs_mgr.cpp
+++ b/fs_mgr/fs_mgr.cpp
@@ -1383,7 +1383,7 @@
             mount_point = basename(fstab->recs[i].mount_point);
         }
 
-        fs_mgr_verity_ioctl_init(io, mount_point, 0);
+        fs_mgr_verity_ioctl_init(io, mount_point);
 
         const char* status;
         if (ioctl(fd, DM_TABLE_STATUS, io)) {
diff --git a/fs_mgr/fs_mgr_avb.cpp b/fs_mgr/fs_mgr_avb.cpp
index 7824cfa..6ea3833 100644
--- a/fs_mgr/fs_mgr_avb.cpp
+++ b/fs_mgr/fs_mgr_avb.cpp
@@ -303,13 +303,14 @@
 
 static bool load_verity_table(struct dm_ioctl* io, const std::string& dm_device_name, int fd,
                               uint64_t image_size, const std::string& verity_table) {
-    fs_mgr_verity_ioctl_init(io, dm_device_name, DM_STATUS_TABLE_FLAG);
+    fs_mgr_verity_ioctl_init(io, dm_device_name);
 
     // The buffer consists of [dm_ioctl][dm_target_spec][verity_params].
     char* buffer = (char*)io;
 
     // Builds the dm_target_spec arguments.
     struct dm_target_spec* dm_target = (struct dm_target_spec*)&buffer[sizeof(struct dm_ioctl)];
+    io->flags = DM_READONLY_FLAG;
     io->target_count = 1;
     dm_target->status = 0;
     dm_target->sector_start = 0;
diff --git a/fs_mgr/fs_mgr_dm_ioctl.cpp b/fs_mgr/fs_mgr_dm_ioctl.cpp
index 4cbd5a8..5f9b118 100644
--- a/fs_mgr/fs_mgr_dm_ioctl.cpp
+++ b/fs_mgr/fs_mgr_dm_ioctl.cpp
@@ -23,21 +23,20 @@
 #include "fs_mgr_priv.h"
 #include "fs_mgr_priv_dm_ioctl.h"
 
-void fs_mgr_verity_ioctl_init(struct dm_ioctl* io, const std::string& name, unsigned flags) {
+void fs_mgr_verity_ioctl_init(struct dm_ioctl* io, const std::string& name) {
     memset(io, 0, DM_BUF_SIZE);
     io->data_size = DM_BUF_SIZE;
     io->data_start = sizeof(struct dm_ioctl);
     io->version[0] = 4;
     io->version[1] = 0;
     io->version[2] = 0;
-    io->flags = flags | DM_READONLY_FLAG;
     if (!name.empty()) {
         strlcpy(io->name, name.c_str(), sizeof(io->name));
     }
 }
 
 bool fs_mgr_create_verity_device(struct dm_ioctl* io, const std::string& name, int fd) {
-    fs_mgr_verity_ioctl_init(io, name, 1);
+    fs_mgr_verity_ioctl_init(io, name);
     if (ioctl(fd, DM_DEV_CREATE, io)) {
         PERROR << "Error creating device mapping";
         return false;
@@ -46,7 +45,7 @@
 }
 
 bool fs_mgr_destroy_verity_device(struct dm_ioctl* io, const std::string& name, int fd) {
-    fs_mgr_verity_ioctl_init(io, name, 0);
+    fs_mgr_verity_ioctl_init(io, name);
     if (ioctl(fd, DM_DEV_REMOVE, io)) {
         PERROR << "Error removing device mapping";
         return false;
@@ -58,7 +57,7 @@
                                    std::string* out_dev_name) {
     FS_MGR_CHECK(out_dev_name != nullptr);
 
-    fs_mgr_verity_ioctl_init(io, name, 0);
+    fs_mgr_verity_ioctl_init(io, name);
     if (ioctl(fd, DM_DEV_STATUS, io)) {
         PERROR << "Error fetching verity device number";
         return false;
@@ -71,7 +70,7 @@
 }
 
 bool fs_mgr_resume_verity_table(struct dm_ioctl* io, const std::string& name, int fd) {
-    fs_mgr_verity_ioctl_init(io, name, 0);
+    fs_mgr_verity_ioctl_init(io, name);
     if (ioctl(fd, DM_DEV_SUSPEND, io)) {
         PERROR << "Error activating verity device";
         return false;
diff --git a/fs_mgr/fs_mgr_priv_dm_ioctl.h b/fs_mgr/fs_mgr_priv_dm_ioctl.h
index a00a9c1..792683e 100644
--- a/fs_mgr/fs_mgr_priv_dm_ioctl.h
+++ b/fs_mgr/fs_mgr_priv_dm_ioctl.h
@@ -20,7 +20,7 @@
 #include <linux/dm-ioctl.h>
 #include <string>
 
-void fs_mgr_verity_ioctl_init(struct dm_ioctl* io, const std::string& name, unsigned flags);
+void fs_mgr_verity_ioctl_init(struct dm_ioctl* io, const std::string& name);
 
 bool fs_mgr_create_verity_device(struct dm_ioctl* io, const std::string& name, int fd);
 
diff --git a/fs_mgr/fs_mgr_verity.cpp b/fs_mgr/fs_mgr_verity.cpp
index 896b603..d0bb058 100644
--- a/fs_mgr/fs_mgr_verity.cpp
+++ b/fs_mgr/fs_mgr_verity.cpp
@@ -258,12 +258,13 @@
     char *buffer = (char*) io;
     size_t bufsize;
 
-    fs_mgr_verity_ioctl_init(io, name, DM_STATUS_TABLE_FLAG);
+    fs_mgr_verity_ioctl_init(io, name);
 
     struct dm_target_spec *tgt = (struct dm_target_spec *) &buffer[sizeof(struct dm_ioctl)];
 
     // set tgt arguments
     io->target_count = 1;
+    io->flags = DM_READONLY_FLAG;
     tgt->status = 0;
     tgt->sector_start = 0;
     tgt->length = device_size / 512;
diff --git a/init/init_first_stage.cpp b/init/init_first_stage.cpp
index 45d3d44..1b6e97e 100644
--- a/init/init_first_stage.cpp
+++ b/init/init_first_stage.cpp
@@ -118,14 +118,14 @@
 // -----------------
 FirstStageMount::FirstStageMount()
     : need_dm_verity_(false), device_tree_fstab_(fs_mgr_read_fstab_dt(), fs_mgr_free_fstab) {
-    if (!device_tree_fstab_) {
+    if (device_tree_fstab_) {
+        // Stores device_tree_fstab_->recs[] into mount_fstab_recs_ (vector<fstab_rec*>)
+        // for easier manipulation later, e.g., range-base for loop.
+        for (int i = 0; i < device_tree_fstab_->num_entries; i++) {
+            mount_fstab_recs_.push_back(&device_tree_fstab_->recs[i]);
+        }
+    } else {
         LOG(INFO) << "Failed to read fstab from device tree";
-        return;
-    }
-    // Stores device_tree_fstab_->recs[] into mount_fstab_recs_ (vector<fstab_rec*>)
-    // for easier manipulation later, e.g., range-base for loop.
-    for (int i = 0; i < device_tree_fstab_->num_entries; i++) {
-        mount_fstab_recs_.push_back(&device_tree_fstab_->recs[i]);
     }
 }
 
@@ -138,8 +138,11 @@
 }
 
 bool FirstStageMount::DoFirstStageMount() {
-    // Nothing to mount.
-    if (mount_fstab_recs_.empty()) return true;
+    if (mount_fstab_recs_.empty()) {
+        // Nothing to mount.
+        LOG(INFO) << "First stage mount skipped (missing/incompatible/empty fstab in device tree)";
+        return true;
+    }
 
     if (!InitDevices()) return false;
 
@@ -479,12 +482,6 @@
         return true;
     }
 
-    // Firstly checks if device tree fstab entries are compatible.
-    if (!is_android_dt_value_expected("fstab/compatible", "android,fstab")) {
-        LOG(INFO) << "First stage mount skipped (missing/incompatible fstab in device tree)";
-        return true;
-    }
-
     std::unique_ptr<FirstStageMount> handle = FirstStageMount::Create();
     if (!handle) {
         LOG(ERROR) << "Failed to create FirstStageMount";
diff --git a/libbacktrace/Android.bp b/libbacktrace/Android.bp
index f38b7a2..11b8144 100644
--- a/libbacktrace/Android.bp
+++ b/libbacktrace/Android.bp
@@ -22,11 +22,6 @@
         "-Werror",
     ],
 
-    // The latest clang (r230699) does not allow SP/PC to be declared in inline asm lists.
-    clang_cflags: ["-Wno-inline-asm"],
-
-    include_dirs: ["external/libunwind/include/tdep"],
-
     target: {
         darwin: {
             enabled: false,
@@ -92,7 +87,6 @@
             shared_libs: [
                 "libbase",
                 "liblog",
-                "libunwind",
                 "libunwindstack",
                 "libdexfile",
             ],