Merge "Test is-logical command for vendor and boot partitions." into qt-dev
diff --git a/fs_mgr/fs_mgr_fstab.cpp b/fs_mgr/fs_mgr_fstab.cpp
index f6f6f50..4043fc6 100644
--- a/fs_mgr/fs_mgr_fstab.cpp
+++ b/fs_mgr/fs_mgr_fstab.cpp
@@ -754,14 +754,15 @@
FstabEntry BuildGsiSystemFstabEntry() {
// .logical_partition_name is required to look up AVB Hashtree descriptors.
- FstabEntry system = {.blk_device = "system_gsi",
- .mount_point = "/system",
- .fs_type = "ext4",
- .flags = MS_RDONLY,
- .fs_options = "barrier=1",
- // could add more keys separated by ':'.
- .avb_keys = "/avb/gsi.avbpubkey:",
- .logical_partition_name = "system"};
+ FstabEntry system = {
+ .blk_device = "system_gsi",
+ .mount_point = "/system",
+ .fs_type = "ext4",
+ .flags = MS_RDONLY,
+ .fs_options = "barrier=1",
+ // could add more keys separated by ':'.
+ .avb_keys = "/avb/q-gsi.avbpubkey:/avb/r-gsi.avbpubkey:/avb/s-gsi.avbpubkey",
+ .logical_partition_name = "system"};
system.fs_mgr_flags.wait = true;
system.fs_mgr_flags.logical = true;
system.fs_mgr_flags.first_stage_mount = true;
diff --git a/fs_mgr/liblp/images.cpp b/fs_mgr/liblp/images.cpp
index 56b5353..db27022 100644
--- a/fs_mgr/liblp/images.cpp
+++ b/fs_mgr/liblp/images.cpp
@@ -98,11 +98,12 @@
return WriteToImageFile(fd, input);
}
-SparseBuilder::SparseBuilder(const LpMetadata& metadata, uint32_t block_size,
- const std::map<std::string, std::string>& images)
+ImageBuilder::ImageBuilder(const LpMetadata& metadata, uint32_t block_size,
+ const std::map<std::string, std::string>& images, bool sparsify)
: metadata_(metadata),
geometry_(metadata.geometry),
block_size_(block_size),
+ sparsify_(sparsify),
images_(images) {
uint64_t total_size = GetTotalSuperPartitionSize(metadata);
if (block_size % LP_SECTOR_SIZE != 0) {
@@ -144,11 +145,11 @@
}
}
-bool SparseBuilder::IsValid() const {
+bool ImageBuilder::IsValid() const {
return device_images_.size() == metadata_.block_devices.size();
}
-bool SparseBuilder::Export(const char* file) {
+bool ImageBuilder::Export(const char* file) {
unique_fd fd(open(file, O_CREAT | O_RDWR | O_TRUNC | O_CLOEXEC, 0644));
if (fd < 0) {
PERROR << "open failed: " << file;
@@ -158,8 +159,8 @@
LERROR << "Cannot export to a single image on retrofit builds.";
return false;
}
- // No gzip compression; sparseify; no checksum.
- int ret = sparse_file_write(device_images_[0].get(), fd, false, true, false);
+ // No gzip compression; no checksum.
+ int ret = sparse_file_write(device_images_[0].get(), fd, false, sparsify_, false);
if (ret != 0) {
LERROR << "sparse_file_write failed (error code " << ret << ")";
return false;
@@ -167,7 +168,7 @@
return true;
}
-bool SparseBuilder::ExportFiles(const std::string& output_dir) {
+bool ImageBuilder::ExportFiles(const std::string& output_dir) {
for (size_t i = 0; i < device_images_.size(); i++) {
std::string name = GetBlockDevicePartitionName(metadata_.block_devices[i]);
std::string file_name = "super_" + name + ".img";
@@ -179,8 +180,8 @@
PERROR << "open failed: " << file_path;
return false;
}
- // No gzip compression; sparseify; no checksum.
- int ret = sparse_file_write(device_images_[i].get(), fd, false, true, false);
+ // No gzip compression; no checksum.
+ int ret = sparse_file_write(device_images_[i].get(), fd, false, sparsify_, false);
if (ret != 0) {
LERROR << "sparse_file_write failed (error code " << ret << ")";
return false;
@@ -189,7 +190,7 @@
return true;
}
-bool SparseBuilder::AddData(sparse_file* file, const std::string& blob, uint64_t sector) {
+bool ImageBuilder::AddData(sparse_file* file, const std::string& blob, uint64_t sector) {
uint32_t block;
if (!SectorToBlock(sector, &block)) {
return false;
@@ -203,7 +204,7 @@
return true;
}
-bool SparseBuilder::SectorToBlock(uint64_t sector, uint32_t* block) {
+bool ImageBuilder::SectorToBlock(uint64_t sector, uint32_t* block) {
// The caller must ensure that the metadata has an alignment that is a
// multiple of the block size. liblp will take care of the rest, ensuring
// that all partitions are on an aligned boundary. Therefore all writes
@@ -218,11 +219,11 @@
return true;
}
-uint64_t SparseBuilder::BlockToSector(uint64_t block) const {
+uint64_t ImageBuilder::BlockToSector(uint64_t block) const {
return (block * block_size_) / LP_SECTOR_SIZE;
}
-bool SparseBuilder::Build() {
+bool ImageBuilder::Build() {
if (sparse_file_add_fill(device_images_[0].get(), 0, LP_PARTITION_RESERVED_BYTES, 0) < 0) {
LERROR << "Could not add initial sparse block for reserved zeroes";
return false;
@@ -275,8 +276,8 @@
return true;
}
-bool SparseBuilder::AddPartitionImage(const LpMetadataPartition& partition,
- const std::string& file) {
+bool ImageBuilder::AddPartitionImage(const LpMetadataPartition& partition,
+ const std::string& file) {
// Track which extent we're processing.
uint32_t extent_index = partition.first_extent_index;
@@ -371,7 +372,7 @@
return true;
}
-uint64_t SparseBuilder::ComputePartitionSize(const LpMetadataPartition& partition) const {
+uint64_t ImageBuilder::ComputePartitionSize(const LpMetadataPartition& partition) const {
uint64_t sectors = 0;
for (size_t i = 0; i < partition.num_extents; i++) {
sectors += metadata_.extents[partition.first_extent_index + i].num_sectors;
@@ -386,7 +387,7 @@
//
// Without this, it would be more difficult to find the appropriate extent for
// an output block. With this guarantee it is a linear walk.
-bool SparseBuilder::CheckExtentOrdering() {
+bool ImageBuilder::CheckExtentOrdering() {
std::vector<uint64_t> last_sectors(metadata_.block_devices.size());
for (const auto& extent : metadata_.extents) {
@@ -407,7 +408,7 @@
return true;
}
-int SparseBuilder::OpenImageFile(const std::string& file) {
+int ImageBuilder::OpenImageFile(const std::string& file) {
android::base::unique_fd source_fd = GetControlFileOrOpen(file.c_str(), O_RDONLY | O_CLOEXEC);
if (source_fd < 0) {
PERROR << "open image file failed: " << file;
@@ -437,15 +438,16 @@
return temp_fds_.back().get();
}
-bool WriteToSparseFile(const char* file, const LpMetadata& metadata, uint32_t block_size,
- const std::map<std::string, std::string>& images) {
- SparseBuilder builder(metadata, block_size, images);
+bool WriteToImageFile(const char* file, const LpMetadata& metadata, uint32_t block_size,
+ const std::map<std::string, std::string>& images, bool sparsify) {
+ ImageBuilder builder(metadata, block_size, images, sparsify);
return builder.IsValid() && builder.Build() && builder.Export(file);
}
-bool WriteSplitSparseFiles(const std::string& output_dir, const LpMetadata& metadata,
- uint32_t block_size, const std::map<std::string, std::string>& images) {
- SparseBuilder builder(metadata, block_size, images);
+bool WriteSplitImageFiles(const std::string& output_dir, const LpMetadata& metadata,
+ uint32_t block_size, const std::map<std::string, std::string>& images,
+ bool sparsify) {
+ ImageBuilder builder(metadata, block_size, images, sparsify);
return builder.IsValid() && builder.Build() && builder.ExportFiles(output_dir);
}
diff --git a/fs_mgr/liblp/images.h b/fs_mgr/liblp/images.h
index 44217a0..75060f9 100644
--- a/fs_mgr/liblp/images.h
+++ b/fs_mgr/liblp/images.h
@@ -32,13 +32,13 @@
bool WriteToImageFile(const char* file, const LpMetadata& metadata);
bool WriteToImageFile(int fd, const LpMetadata& metadata);
-// We use an object to build the sparse file since it requires that data
+// We use an object to build the image file since it requires that data
// pointers be held alive until the sparse file is destroyed. It's easier
// to do this when the data pointers are all in one place.
-class SparseBuilder {
+class ImageBuilder {
public:
- SparseBuilder(const LpMetadata& metadata, uint32_t block_size,
- const std::map<std::string, std::string>& images);
+ ImageBuilder(const LpMetadata& metadata, uint32_t block_size,
+ const std::map<std::string, std::string>& images, bool sparsify);
bool Build();
bool Export(const char* file);
@@ -60,6 +60,7 @@
const LpMetadata& metadata_;
const LpMetadataGeometry& geometry_;
uint32_t block_size_;
+ bool sparsify_;
std::vector<SparsePtr> device_images_;
std::string all_metadata_;
diff --git a/fs_mgr/liblp/include/liblp/liblp.h b/fs_mgr/liblp/include/liblp/liblp.h
index 6348f55..5f782b0 100644
--- a/fs_mgr/liblp/include/liblp/liblp.h
+++ b/fs_mgr/liblp/include/liblp/liblp.h
@@ -72,8 +72,8 @@
// Read/Write logical partition metadata to an image file, for diagnostics or
// flashing.
-bool WriteToSparseFile(const char* file, const LpMetadata& metadata, uint32_t block_size,
- const std::map<std::string, std::string>& images);
+bool WriteToImageFile(const char* file, const LpMetadata& metadata, uint32_t block_size,
+ const std::map<std::string, std::string>& images, bool sparsify);
bool WriteToImageFile(const char* file, const LpMetadata& metadata);
std::unique_ptr<LpMetadata> ReadFromImageFile(const std::string& image_file);
std::unique_ptr<LpMetadata> ReadFromImageBlob(const void* data, size_t bytes);
@@ -83,8 +83,9 @@
// is intended for retrofit devices, and will generate one sparse file per
// block device (each named super_<name>.img) and placed in the specified
// output folder.
-bool WriteSplitSparseFiles(const std::string& output_dir, const LpMetadata& metadata,
- uint32_t block_size, const std::map<std::string, std::string>& images);
+bool WriteSplitImageFiles(const std::string& output_dir, const LpMetadata& metadata,
+ uint32_t block_size, const std::map<std::string, std::string>& images,
+ bool sparsify);
// Helper to extract safe C++ strings from partition info.
std::string GetPartitionName(const LpMetadataPartition& partition);
diff --git a/fs_mgr/liblp/io_test.cpp b/fs_mgr/liblp/io_test.cpp
index 9f3314d..8fc02cb 100644
--- a/fs_mgr/liblp/io_test.cpp
+++ b/fs_mgr/liblp/io_test.cpp
@@ -598,7 +598,7 @@
ASSERT_NE(exported, nullptr);
// Build the sparse file.
- SparseBuilder sparse(*exported.get(), 512, {});
+ ImageBuilder sparse(*exported.get(), 512, {}, true /* sparsify */);
ASSERT_TRUE(sparse.IsValid());
ASSERT_TRUE(sparse.Build());
diff --git a/libcutils/ashmem-dev.cpp b/libcutils/ashmem-dev.cpp
index e35b91a..e67b458 100644
--- a/libcutils/ashmem-dev.cpp
+++ b/libcutils/ashmem-dev.cpp
@@ -73,6 +73,8 @@
#ifndef __ANDROID_VNDK__
using openFdType = int (*)();
+static openFdType openFd;
+
openFdType initOpenAshmemFd() {
openFdType openFd = nullptr;
void* handle = dlopen("libashmemd_client.so", RTLD_NOW);
@@ -221,7 +223,10 @@
int fd = -1;
#ifndef __ANDROID_VNDK__
- static auto openFd = initOpenAshmemFd();
+ if (!openFd) {
+ openFd = initOpenAshmemFd();
+ }
+
if (openFd) {
fd = openFd();
}
@@ -480,3 +485,11 @@
return __ashmem_check_failure(fd, TEMP_FAILURE_RETRY(ioctl(fd, ASHMEM_GET_SIZE, NULL)));
}
+
+void ashmem_init() {
+#ifndef __ANDROID_VNDK__
+ pthread_mutex_lock(&__ashmem_lock);
+ openFd = initOpenAshmemFd();
+ pthread_mutex_unlock(&__ashmem_lock);
+#endif //__ANDROID_VNDK__
+}
diff --git a/libcutils/ashmem-host.cpp b/libcutils/ashmem-host.cpp
index bb990d5..32446d4 100644
--- a/libcutils/ashmem-host.cpp
+++ b/libcutils/ashmem-host.cpp
@@ -82,3 +82,5 @@
return buf.st_size;
}
+
+void ashmem_init() {}
diff --git a/libcutils/include/cutils/ashmem.h b/libcutils/include/cutils/ashmem.h
index d80caa6..abc5068 100644
--- a/libcutils/include/cutils/ashmem.h
+++ b/libcutils/include/cutils/ashmem.h
@@ -26,6 +26,7 @@
int ashmem_pin_region(int fd, size_t offset, size_t len);
int ashmem_unpin_region(int fd, size_t offset, size_t len);
int ashmem_get_size_region(int fd);
+void ashmem_init();
#ifdef __cplusplus
}
diff --git a/libprocessgroup/cgrouprc/Android.bp b/libprocessgroup/cgrouprc/Android.bp
index 774738d..6848620 100644
--- a/libprocessgroup/cgrouprc/Android.bp
+++ b/libprocessgroup/cgrouprc/Android.bp
@@ -45,7 +45,11 @@
symbol_file: "libcgrouprc.map.txt",
versions: ["29"],
},
- version_script: "libcgrouprc.map.txt",
+ target: {
+ linux: {
+ version_script: "libcgrouprc.map.txt",
+ },
+ },
}
llndk_library {
diff --git a/libprocessgroup/setup/cgroup_map_write.cpp b/libprocessgroup/setup/cgroup_map_write.cpp
index 26703ee..da60948 100644
--- a/libprocessgroup/setup/cgroup_map_write.cpp
+++ b/libprocessgroup/setup/cgroup_map_write.cpp
@@ -235,14 +235,9 @@
#endif
-// WARNING: This function should be called only from SetupCgroups and only once.
-// It intentionally leaks an FD, so additional invocation will result in additional leak.
static bool WriteRcFile(const std::map<std::string, CgroupDescriptor>& descriptors) {
- // WARNING: We are intentionally leaking the FD to keep the file open forever.
- // Let init keep the FD open to prevent file mappings from becoming invalid in
- // case the file gets deleted somehow.
- int fd = TEMP_FAILURE_RETRY(open(CGROUPS_RC_PATH, O_CREAT | O_WRONLY | O_TRUNC | O_CLOEXEC,
- S_IRUSR | S_IRGRP | S_IROTH));
+ unique_fd fd(TEMP_FAILURE_RETRY(open(CGROUPS_RC_PATH, O_CREAT | O_WRONLY | O_TRUNC | O_CLOEXEC,
+ S_IRUSR | S_IRGRP | S_IROTH)));
if (fd < 0) {
PLOG(ERROR) << "open() failed for " << CGROUPS_RC_PATH;
return false;
diff --git a/libunwindstack/ElfInterface.cpp b/libunwindstack/ElfInterface.cpp
index e09a2ae..32c637f 100644
--- a/libunwindstack/ElfInterface.cpp
+++ b/libunwindstack/ElfInterface.cpp
@@ -285,7 +285,7 @@
if (gnu_build_id_size_ - offset < hdr.n_descsz || hdr.n_descsz == 0) {
return "";
}
- std::string build_id(hdr.n_descsz - 1, '\0');
+ std::string build_id(hdr.n_descsz, '\0');
if (memory_->ReadFully(gnu_build_id_offset_ + offset, &build_id[0], hdr.n_descsz)) {
return build_id;
}
diff --git a/libunwindstack/tests/ElfInterfaceTest.cpp b/libunwindstack/tests/ElfInterfaceTest.cpp
index d895863..cdc927a 100644
--- a/libunwindstack/tests/ElfInterfaceTest.cpp
+++ b/libunwindstack/tests/ElfInterfaceTest.cpp
@@ -1192,14 +1192,16 @@
char note_section[128];
Nhdr note_header = {};
note_header.n_namesz = 4; // "GNU"
- note_header.n_descsz = 8; // "BUILDID"
+ note_header.n_descsz = 7; // "BUILDID"
note_header.n_type = NT_GNU_BUILD_ID;
memcpy(¬e_section, ¬e_header, sizeof(note_header));
size_t note_offset = sizeof(note_header);
+ // The note information contains the GNU and trailing '\0'.
memcpy(¬e_section[note_offset], "GNU", sizeof("GNU"));
note_offset += sizeof("GNU");
- memcpy(¬e_section[note_offset], "BUILDID", sizeof("BUILDID"));
- note_offset += sizeof("BUILDID");
+ // This part of the note does not contain any trailing '\0'.
+ memcpy(¬e_section[note_offset], "BUILDID", 7);
+ note_offset += 8;
Shdr shdr = {};
shdr.sh_type = SHT_NOTE;
@@ -1244,24 +1246,27 @@
char note_section[128];
Nhdr note_header = {};
note_header.n_namesz = 8; // "WRONG" aligned to 4
- note_header.n_descsz = 8; // "BUILDID"
+ note_header.n_descsz = 7; // "BUILDID"
note_header.n_type = NT_GNU_BUILD_ID;
memcpy(¬e_section, ¬e_header, sizeof(note_header));
size_t note_offset = sizeof(note_header);
memcpy(¬e_section[note_offset], "WRONG", sizeof("WRONG"));
note_offset += 8;
- memcpy(¬e_section[note_offset], "BUILDID", sizeof("BUILDID"));
- note_offset += sizeof("BUILDID");
+ // This part of the note does not contain any trailing '\0'.
+ memcpy(¬e_section[note_offset], "BUILDID", 7);
+ note_offset += 8;
note_header.n_namesz = 4; // "GNU"
- note_header.n_descsz = 8; // "BUILDID"
+ note_header.n_descsz = 7; // "BUILDID"
note_header.n_type = NT_GNU_BUILD_ID;
memcpy(¬e_section[note_offset], ¬e_header, sizeof(note_header));
note_offset += sizeof(note_header);
+ // The note information contains the GNU and trailing '\0'.
memcpy(¬e_section[note_offset], "GNU", sizeof("GNU"));
note_offset += sizeof("GNU");
- memcpy(¬e_section[note_offset], "BUILDID", sizeof("BUILDID"));
- note_offset += sizeof("BUILDID");
+ // This part of the note does not contain any trailing '\0'.
+ memcpy(¬e_section[note_offset], "BUILDID", 7);
+ note_offset += 8;
Shdr shdr = {};
shdr.sh_type = SHT_NOTE;
@@ -1306,14 +1311,16 @@
char note_section[128];
Nhdr note_header = {};
note_header.n_namesz = 4; // "GNU"
- note_header.n_descsz = 8; // "BUILDID"
+ note_header.n_descsz = 7; // "BUILDID"
note_header.n_type = NT_GNU_BUILD_ID;
memcpy(¬e_section, ¬e_header, sizeof(note_header));
size_t note_offset = sizeof(note_header);
+ // The note information contains the GNU and trailing '\0'.
memcpy(¬e_section[note_offset], "GNU", sizeof("GNU"));
note_offset += sizeof("GNU");
- memcpy(¬e_section[note_offset], "BUILDID", sizeof("BUILDID"));
- note_offset += sizeof("BUILDID");
+ // This part of the note does not contain any trailing '\0'.
+ memcpy(¬e_section[note_offset], "BUILDID", 7);
+ note_offset += 8;
Shdr shdr = {};
shdr.sh_type = SHT_NOTE;
@@ -1358,14 +1365,16 @@
char note_section[128];
Nhdr note_header = {};
note_header.n_namesz = 4; // "GNU"
- note_header.n_descsz = 8; // "BUILDID"
+ note_header.n_descsz = 7; // "BUILDID"
note_header.n_type = NT_GNU_BUILD_ID;
memcpy(¬e_section, ¬e_header, sizeof(note_header));
size_t note_offset = sizeof(note_header);
+ // The note information contains the GNU and trailing '\0'.
memcpy(¬e_section[note_offset], "GNU", sizeof("GNU"));
note_offset += sizeof("GNU");
- memcpy(¬e_section[note_offset], "BUILDID", sizeof("BUILDID"));
- note_offset += sizeof("BUILDID");
+ // This part of the note does not contain any trailing '\0'.
+ memcpy(¬e_section[note_offset], "BUILDID", 7);
+ note_offset += 8;
Shdr shdr = {};
shdr.sh_type = SHT_NOTE;
@@ -1410,14 +1419,16 @@
char note_section[128];
Nhdr note_header = {};
note_header.n_namesz = 4; // "GNU"
- note_header.n_descsz = 8; // "BUILDID"
+ note_header.n_descsz = 7; // "BUILDID"
note_header.n_type = NT_GNU_BUILD_ID;
memcpy(¬e_section, ¬e_header, sizeof(note_header));
size_t note_offset = sizeof(note_header);
+ // The note information contains the GNU and trailing '\0'.
memcpy(¬e_section[note_offset], "GNU", sizeof("GNU"));
note_offset += sizeof("GNU");
- memcpy(¬e_section[note_offset], "BUILDID", sizeof("BUILDID"));
- note_offset += sizeof("BUILDID");
+ // This part of the note does not contain any trailing '\0'.
+ memcpy(¬e_section[note_offset], "BUILDID", 7);
+ note_offset += 8;
Shdr shdr = {};
shdr.sh_type = SHT_NOTE;
diff --git a/libunwindstack/tests/UnwindOfflineTest.cpp b/libunwindstack/tests/UnwindOfflineTest.cpp
index 0867561..e3c646a 100644
--- a/libunwindstack/tests/UnwindOfflineTest.cpp
+++ b/libunwindstack/tests/UnwindOfflineTest.cpp
@@ -204,6 +204,7 @@
TEST_F(UnwindOfflineTest, pc_straddle_arm) {
ASSERT_NO_FATAL_FAILURE(Init("straddle_arm/", ARCH_ARM));
+ std::unique_ptr<Regs> regs_copy(regs_->Clone());
Unwinder unwinder(128, maps_.get(), regs_.get(), process_memory_);
unwinder.Unwind();
@@ -223,6 +224,22 @@
EXPECT_EQ(0xe9c86730U, unwinder.frames()[2].sp);
EXPECT_EQ(0xf3367147U, unwinder.frames()[3].pc);
EXPECT_EQ(0xe9c86778U, unwinder.frames()[3].sp);
+
+ // Display build ids now.
+ unwinder.SetRegs(regs_copy.get());
+ unwinder.SetDisplayBuildID(true);
+ unwinder.Unwind();
+
+ frame_info = DumpFrames(unwinder);
+ ASSERT_EQ(4U, unwinder.NumFrames()) << "Unwind:\n" << frame_info;
+ EXPECT_EQ(
+ " #00 pc 0001a9f8 libc.so (abort+64) (BuildId: 2dd0d4ba881322a0edabeed94808048c)\n"
+ " #01 pc 00006a1b libbase.so (android::base::DefaultAborter(char const*)+6) (BuildId: "
+ "ed43842c239cac1a618e600ea91c4cbd)\n"
+ " #02 pc 00007441 libbase.so (android::base::LogMessage::~LogMessage()+748) (BuildId: "
+ "ed43842c239cac1a618e600ea91c4cbd)\n"
+ " #03 pc 00015147 /does/not/exist/libhidlbase.so\n",
+ frame_info);
}
TEST_F(UnwindOfflineTest, pc_in_gnu_debugdata_arm) {