Merge "Rename data/pkg_staging to data/app-staging."
diff --git a/bootstat/bootstat.cpp b/bootstat/bootstat.cpp
index ed955ea..ea49798 100644
--- a/bootstat/bootstat.cpp
+++ b/bootstat/bootstat.cpp
@@ -293,6 +293,8 @@
{"kernel_panic,dsps", 166},
{"kernel_panic,wcnss", 167},
{"kernel_panic,_sde_encoder_phys_cmd_handle_ppdone_timeout", 168},
+ {"recovery,quiescent", 169},
+ {"reboot,quiescent", 170},
};
// Converts a string value representing the reason the system booted to an
diff --git a/fs_mgr/libfiemap_writer/Android.bp b/fs_mgr/libfiemap_writer/Android.bp
index 7463810..32fc3d2 100644
--- a/fs_mgr/libfiemap_writer/Android.bp
+++ b/fs_mgr/libfiemap_writer/Android.bp
@@ -41,6 +41,9 @@
cc_test {
name: "fiemap_writer_test",
+ cflags: [
+ "-D_FILE_OFFSET_BITS=64",
+ ],
static_libs: [
"libbase",
"libdm",
diff --git a/fs_mgr/libfiemap_writer/fiemap_writer.cpp b/fs_mgr/libfiemap_writer/fiemap_writer.cpp
index 99a1a2f..45b997f 100644
--- a/fs_mgr/libfiemap_writer/fiemap_writer.cpp
+++ b/fs_mgr/libfiemap_writer/fiemap_writer.cpp
@@ -51,6 +51,9 @@
FIEMAP_EXTENT_NOT_ALIGNED | FIEMAP_EXTENT_DATA_INLINE | FIEMAP_EXTENT_DATA_TAIL |
FIEMAP_EXTENT_UNWRITTEN | FIEMAP_EXTENT_SHARED | FIEMAP_EXTENT_MERGED;
+// Large file support must be enabled.
+static_assert(sizeof(off_t) == sizeof(uint64_t));
+
static inline void cleanup(const std::string& file_path, bool created) {
if (created) {
unlink(file_path.c_str());
@@ -229,6 +232,42 @@
return true;
}
+static bool FallocateFallback(int file_fd, uint64_t block_size, uint64_t file_size,
+ const std::string& file_path,
+ const std::function<bool(uint64_t, uint64_t)>& on_progress) {
+ // Even though this is much faster than writing zeroes, it is still slow
+ // enough that we need to fire the progress callback periodically. To
+ // easily achieve this, we seek in chunks. We use 1000 chunks since
+ // normally we only fire the callback on 1/1000th increments.
+ uint64_t bytes_per_chunk = std::max(file_size / 1000, block_size);
+
+ // Seek just to the end of each chunk and write a single byte, causing
+ // the filesystem to allocate blocks.
+ off_t cursor = 0;
+ off_t end = static_cast<off_t>(file_size);
+ while (cursor < end) {
+ cursor = std::min(static_cast<off_t>(cursor + bytes_per_chunk), end);
+ auto rv = TEMP_FAILURE_RETRY(lseek(file_fd, cursor - 1, SEEK_SET));
+ if (rv < 0) {
+ PLOG(ERROR) << "Failed to lseek " << file_path;
+ return false;
+ }
+ if (rv != cursor - 1) {
+ LOG(ERROR) << "Seek returned wrong offset " << rv << " for file " << file_path;
+ return false;
+ }
+ char buffer[] = {0};
+ if (!android::base::WriteFully(file_fd, buffer, 1)) {
+ PLOG(ERROR) << "Write failed: " << file_path;
+ return false;
+ }
+ if (on_progress && !on_progress(cursor, file_size)) {
+ return false;
+ }
+ }
+ return true;
+}
+
static bool AllocateFile(int file_fd, const std::string& file_path, uint64_t blocksz,
uint64_t file_size, unsigned int fs_type,
std::function<bool(uint64_t, uint64_t)> on_progress) {
@@ -245,28 +284,10 @@
return false;
}
break;
- case MSDOS_SUPER_MAGIC: {
+ case MSDOS_SUPER_MAGIC:
// fallocate() is not supported, and not needed, since VFAT does not support holes.
// Instead we can perform a much faster allocation.
- auto offset = TEMP_FAILURE_RETRY(lseek(file_fd, file_size - 1, SEEK_SET));
- if (offset < 0) {
- PLOG(ERROR) << "Failed to lseek " << file_path;
- return false;
- }
- if (offset != file_size - 1) {
- LOG(ERROR) << "Seek returned wrong offset " << offset << " for file " << file_path;
- return false;
- }
- char buffer[] = {0};
- if (!android::base::WriteFully(file_fd, buffer, 1)) {
- PLOG(ERROR) << "Write failed: " << file_path;
- return false;
- }
- if (on_progress && !on_progress(file_size, file_size)) {
- return false;
- }
- return true;
- }
+ return FallocateFallback(file_fd, blocksz, file_size, file_path, on_progress);
default:
LOG(ERROR) << "Missing fallocate() support for file system " << fs_type;
return false;
@@ -288,16 +309,19 @@
}
int permille = -1;
- for (; offset < file_size; offset += blocksz) {
+ while (offset < file_size) {
if (!::android::base::WriteFully(file_fd, buffer.get(), blocksz)) {
PLOG(ERROR) << "Failed to write" << blocksz << " bytes at offset" << offset
<< " in file " << file_path;
return false;
}
+
+ offset += blocksz;
+
// Don't invoke the callback every iteration - wait until a significant
// chunk (here, 1/1000th) of the data has been processed.
int new_permille = (static_cast<uint64_t>(offset) * 1000) / file_size;
- if (new_permille != permille) {
+ if (new_permille != permille && static_cast<uint64_t>(offset) != file_size) {
if (on_progress && !on_progress(offset, file_size)) {
return false;
}
@@ -501,12 +525,13 @@
}
if (!extents->empty() && block == last_block + 1) {
- extents->back().fe_length++;
+ extents->back().fe_length += s.st_blksize;
} else {
- extents->push_back(fiemap_extent{.fe_logical = block_number,
- .fe_physical = block,
- .fe_length = 1,
- .fe_flags = 0});
+ extents->push_back(
+ fiemap_extent{.fe_logical = block_number,
+ .fe_physical = static_cast<uint64_t>(block) * s.st_blksize,
+ .fe_length = static_cast<uint64_t>(s.st_blksize),
+ .fe_flags = 0});
}
last_block = block;
}
diff --git a/fs_mgr/libfiemap_writer/fiemap_writer_test.cpp b/fs_mgr/libfiemap_writer/fiemap_writer_test.cpp
index 66eb9ae..4a1a5ab 100644
--- a/fs_mgr/libfiemap_writer/fiemap_writer_test.cpp
+++ b/fs_mgr/libfiemap_writer/fiemap_writer_test.cpp
@@ -108,28 +108,29 @@
EXPECT_EQ(access(testfile.c_str(), F_OK), 0);
}
+TEST_F(FiemapWriterTest, CheckFileSize) {
+ // Create a large-ish file and test that the expected size matches.
+ FiemapUniquePtr fptr = FiemapWriter::Open(testfile, 1024 * 1024 * 16);
+ ASSERT_NE(fptr, nullptr);
+
+ struct stat s;
+ ASSERT_EQ(stat(testfile.c_str(), &s), 0);
+ EXPECT_EQ(static_cast<uint64_t>(s.st_size), fptr->size());
+}
+
TEST_F(FiemapWriterTest, CheckProgress) {
std::vector<uint64_t> expected;
size_t invocations = 0;
auto callback = [&](uint64_t done, uint64_t total) -> bool {
- EXPECT_LT(invocations, expected.size());
+ if (invocations >= expected.size()) {
+ return false;
+ }
EXPECT_EQ(done, expected[invocations]);
EXPECT_EQ(total, gBlockSize);
invocations++;
return true;
};
- uint32_t fs_type;
- {
- auto ptr = FiemapWriter::Open(testfile, gBlockSize, true);
- ASSERT_NE(ptr, nullptr);
- fs_type = ptr->fs_type();
- }
- ASSERT_EQ(unlink(testfile.c_str()), 0);
-
- if (fs_type != MSDOS_SUPER_MAGIC) {
- expected.push_back(0);
- }
expected.push_back(gBlockSize);
auto ptr = FiemapWriter::Open(testfile, gBlockSize, true, std::move(callback));
@@ -163,7 +164,7 @@
struct stat sb;
ASSERT_EQ(stat(testfile.c_str(), &sb), 0);
- EXPECT_EQ(sb.st_size, testfile_size);
+ EXPECT_GE(sb.st_size, testfile_size);
}
TEST_F(FiemapWriterTest, CheckFileExtents) {
@@ -227,7 +228,7 @@
}
TEST_F(SplitFiemapTest, DeleteOnFail) {
- auto ptr = SplitFiemap::Create(testfile, 1024 * 1024 * 10, 1);
+ auto ptr = SplitFiemap::Create(testfile, 1024 * 1024 * 100, 1);
ASSERT_EQ(ptr, nullptr);
std::string first_file = testfile + ".0001";
diff --git a/fs_mgr/libfiemap_writer/include/libfiemap_writer/split_fiemap_writer.h b/fs_mgr/libfiemap_writer/include/libfiemap_writer/split_fiemap_writer.h
index 07f3c10..7b977e1 100644
--- a/fs_mgr/libfiemap_writer/include/libfiemap_writer/split_fiemap_writer.h
+++ b/fs_mgr/libfiemap_writer/include/libfiemap_writer/split_fiemap_writer.h
@@ -69,6 +69,7 @@
const std::vector<struct fiemap_extent>& extents();
uint32_t block_size() const;
uint64_t size() const { return total_size_; }
+ const std::string& bdev_path() const;
// Non-copyable & Non-movable
SplitFiemap(const SplitFiemap&) = delete;
diff --git a/fs_mgr/libfiemap_writer/split_fiemap_writer.cpp b/fs_mgr/libfiemap_writer/split_fiemap_writer.cpp
index dbb67a8..a0ccc10 100644
--- a/fs_mgr/libfiemap_writer/split_fiemap_writer.cpp
+++ b/fs_mgr/libfiemap_writer/split_fiemap_writer.cpp
@@ -289,5 +289,9 @@
return files_[0]->block_size();
}
+const std::string& SplitFiemap::bdev_path() const {
+ return files_[0]->bdev_path();
+}
+
} // namespace fiemap_writer
} // namespace android
diff --git a/init/epoll.cpp b/init/epoll.cpp
index 4bca09e..94dd553 100644
--- a/init/epoll.cpp
+++ b/init/epoll.cpp
@@ -16,6 +16,7 @@
#include "epoll.h"
+#include <stdint.h>
#include <sys/epoll.h>
#include <chrono>
@@ -37,13 +38,16 @@
return Success();
}
-Result<Success> Epoll::RegisterHandler(int fd, std::function<void()> handler) {
+Result<Success> Epoll::RegisterHandler(int fd, std::function<void()> handler, uint32_t events) {
+ if (!events) {
+ return Error() << "Must specify events";
+ }
auto [it, inserted] = epoll_handlers_.emplace(fd, std::move(handler));
if (!inserted) {
return Error() << "Cannot specify two epoll handlers for a given FD";
}
epoll_event ev;
- ev.events = EPOLLIN;
+ ev.events = events;
// std::map's iterators do not get invalidated until erased, so we use the
// pointer to the std::function in the map directly for epoll_ctl.
ev.data.ptr = reinterpret_cast<void*>(&it->second);
diff --git a/init/epoll.h b/init/epoll.h
index 85a791c..9789bef 100644
--- a/init/epoll.h
+++ b/init/epoll.h
@@ -17,6 +17,9 @@
#ifndef _INIT_EPOLL_H
#define _INIT_EPOLL_H
+#include <stdint.h>
+#include <sys/epoll.h>
+
#include <chrono>
#include <functional>
#include <map>
@@ -34,7 +37,8 @@
Epoll();
Result<Success> Open();
- Result<Success> RegisterHandler(int fd, std::function<void()> handler);
+ Result<Success> RegisterHandler(int fd, std::function<void()> handler,
+ uint32_t events = EPOLLIN);
Result<Success> UnregisterHandler(int fd);
Result<Success> Wait(std::optional<std::chrono::milliseconds> timeout);
diff --git a/libasyncio/Android.bp b/libasyncio/Android.bp
index 0fd2a3a..4ab439d 100644
--- a/libasyncio/Android.bp
+++ b/libasyncio/Android.bp
@@ -27,7 +27,6 @@
name: "libasyncio",
defaults: ["libasyncio_defaults"],
vendor_available: true,
- double_loadable: true,
recovery_available: true,
host_supported: true,
srcs: [
diff --git a/libcutils/fs_config.cpp b/libcutils/fs_config.cpp
index f1dcd50..a3df380 100644
--- a/libcutils/fs_config.cpp
+++ b/libcutils/fs_config.cpp
@@ -219,8 +219,6 @@
{ 00755, AID_ROOT, AID_SHELL, 0, "product/bin/*" },
{ 00750, AID_ROOT, AID_SHELL, 0, "sbin/*" },
{ 00755, AID_ROOT, AID_SHELL, 0, "system/bin/*" },
- { 00755, AID_ROOT, AID_ROOT, 0, "system/lib/valgrind/*" },
- { 00755, AID_ROOT, AID_ROOT, 0, "system/lib64/valgrind/*" },
{ 00755, AID_ROOT, AID_SHELL, 0, "system/xbin/*" },
{ 00755, AID_ROOT, AID_SHELL, 0, "system/apex/*/bin/*" },
{ 00755, AID_ROOT, AID_SHELL, 0, "vendor/bin/*" },
diff --git a/libcutils/include/cutils/native_handle.h b/libcutils/include/cutils/native_handle.h
index 10f5bc0..f6cae36 100644
--- a/libcutils/include/cutils/native_handle.h
+++ b/libcutils/include/cutils/native_handle.h
@@ -23,6 +23,9 @@
extern "C" {
#endif
+#define NATIVE_HANDLE_MAX_FDS 1024
+#define NATIVE_HANDLE_MAX_INTS 1024
+
/* Declare a char array for use with native_handle_init */
#define NATIVE_HANDLE_DECLARE_STORAGE(name, maxFds, maxInts) \
alignas(native_handle_t) char (name)[ \
diff --git a/libcutils/native_handle.cpp b/libcutils/native_handle.cpp
index 66f7a3d..b409e5b 100644
--- a/libcutils/native_handle.cpp
+++ b/libcutils/native_handle.cpp
@@ -22,9 +22,6 @@
#include <string.h>
#include <unistd.h>
-static const int kMaxNativeFds = 1024;
-static const int kMaxNativeInts = 1024;
-
native_handle_t* native_handle_init(char* storage, int numFds, int numInts) {
if ((uintptr_t) storage % alignof(native_handle_t)) {
errno = EINVAL;
@@ -39,7 +36,8 @@
}
native_handle_t* native_handle_create(int numFds, int numInts) {
- if (numFds < 0 || numInts < 0 || numFds > kMaxNativeFds || numInts > kMaxNativeInts) {
+ if (numFds < 0 || numInts < 0 || numFds > NATIVE_HANDLE_MAX_FDS ||
+ numInts > NATIVE_HANDLE_MAX_INTS) {
errno = EINVAL;
return NULL;
}
diff --git a/libmemtrack/Android.bp b/libmemtrack/Android.bp
index 320b851..4e4554a 100644
--- a/libmemtrack/Android.bp
+++ b/libmemtrack/Android.bp
@@ -6,7 +6,6 @@
vndk: {
enabled: true,
},
- double_loadable: true,
srcs: ["memtrack.cpp"],
export_include_dirs: ["include"],
local_include_dirs: ["include"],
diff --git a/libprocinfo/Android.bp b/libprocinfo/Android.bp
index 27cda93..15f03d0 100644
--- a/libprocinfo/Android.bp
+++ b/libprocinfo/Android.bp
@@ -31,7 +31,6 @@
vndk: {
enabled: true,
},
- double_loadable: true,
host_supported: true,
srcs: [
"process.cpp",
diff --git a/libunwindstack/Android.bp b/libunwindstack/Android.bp
index a49fd9e..b7650a1 100644
--- a/libunwindstack/Android.bp
+++ b/libunwindstack/Android.bp
@@ -248,6 +248,7 @@
"tests/files/offline/offset_arm/*",
"tests/files/offline/shared_lib_in_apk_arm64/*",
"tests/files/offline/shared_lib_in_apk_memory_only_arm64/*",
+ "tests/files/offline/shared_lib_in_apk_single_map_arm64/*",
"tests/files/offline/straddle_arm/*",
"tests/files/offline/straddle_arm64/*",
],
diff --git a/libunwindstack/MapInfo.cpp b/libunwindstack/MapInfo.cpp
index 89a6a79..a38236c 100644
--- a/libunwindstack/MapInfo.cpp
+++ b/libunwindstack/MapInfo.cpp
@@ -88,6 +88,7 @@
// Check if the start of this map is an embedded elf.
uint64_t max_size = 0;
if (Elf::GetInfo(memory.get(), &max_size)) {
+ elf_start_offset = offset;
if (max_size > map_size) {
if (memory->Init(name, offset, max_size)) {
return memory.release();
@@ -96,6 +97,7 @@
if (memory->Init(name, offset, map_size)) {
return memory.release();
}
+ elf_start_offset = 0;
return nullptr;
}
return memory.release();
diff --git a/libunwindstack/tests/MapInfoCreateMemoryTest.cpp b/libunwindstack/tests/MapInfoCreateMemoryTest.cpp
index a66685a..2ddadef 100644
--- a/libunwindstack/tests/MapInfoCreateMemoryTest.cpp
+++ b/libunwindstack/tests/MapInfoCreateMemoryTest.cpp
@@ -178,7 +178,7 @@
std::unique_ptr<Memory> memory(info.CreateMemory(process_memory_));
ASSERT_TRUE(memory.get() != nullptr);
ASSERT_EQ(0U, info.elf_offset);
- EXPECT_EQ(0U, info.elf_start_offset);
+ EXPECT_EQ(0x1000U, info.elf_start_offset);
// Read the valid part of the file.
std::vector<uint8_t> buffer(0x100);
@@ -202,7 +202,7 @@
std::unique_ptr<Memory> memory(info.CreateMemory(process_memory_));
ASSERT_TRUE(memory.get() != nullptr);
ASSERT_EQ(0U, info.elf_offset);
- EXPECT_EQ(0U, info.elf_start_offset);
+ EXPECT_EQ(0x1000U, info.elf_start_offset);
// Verify the memory is a valid elf.
uint8_t e_ident[SELFMAG + 1];
@@ -219,7 +219,7 @@
std::unique_ptr<Memory> memory(info.CreateMemory(process_memory_));
ASSERT_TRUE(memory.get() != nullptr);
ASSERT_EQ(0U, info.elf_offset);
- EXPECT_EQ(0U, info.elf_start_offset);
+ EXPECT_EQ(0x2000U, info.elf_start_offset);
// Verify the memory is a valid elf.
uint8_t e_ident[SELFMAG + 1];
diff --git a/libunwindstack/tests/UnwindOfflineTest.cpp b/libunwindstack/tests/UnwindOfflineTest.cpp
index b5feb38..86bc465 100644
--- a/libunwindstack/tests/UnwindOfflineTest.cpp
+++ b/libunwindstack/tests/UnwindOfflineTest.cpp
@@ -1372,4 +1372,56 @@
// Ignore top frame since the test code was modified to end in __libc_init.
}
+TEST_F(UnwindOfflineTest, shared_lib_in_apk_single_map_arm64) {
+ ASSERT_NO_FATAL_FAILURE(Init("shared_lib_in_apk_single_map_arm64/", ARCH_ARM64));
+
+ Unwinder unwinder(128, maps_.get(), regs_.get(), process_memory_);
+ unwinder.Unwind();
+
+ std::string frame_info(DumpFrames(unwinder));
+ ASSERT_EQ(13U, unwinder.NumFrames()) << "Unwind:\n" << frame_info;
+ EXPECT_EQ(
+ " #00 pc 00000000000814bc libc.so (syscall+28)\n"
+ " #01 pc 00000000008cdf5c test.apk (offset 0x5000)\n"
+ " #02 pc 00000000008cde9c test.apk (offset 0x5000)\n"
+ " #03 pc 00000000008cdd70 test.apk (offset 0x5000)\n"
+ " #04 pc 00000000008ce408 test.apk (offset 0x5000)\n"
+ " #05 pc 00000000008ce8d8 test.apk (offset 0x5000)\n"
+ " #06 pc 00000000008ce814 test.apk (offset 0x5000)\n"
+ " #07 pc 00000000008bcf60 test.apk (offset 0x5000)\n"
+ " #08 pc 0000000000133024 test.apk (offset 0x5000)\n"
+ " #09 pc 0000000000134ad0 test.apk (offset 0x5000)\n"
+ " #10 pc 0000000000134b64 test.apk (offset 0x5000)\n"
+ " #11 pc 00000000000e406c libc.so (__pthread_start(void*)+36)\n"
+ " #12 pc 0000000000085e18 libc.so (__start_thread+64)\n",
+ frame_info);
+
+ EXPECT_EQ(0x7cbe0b14bcULL, unwinder.frames()[0].pc);
+ EXPECT_EQ(0x7be4f077d0ULL, unwinder.frames()[0].sp);
+ EXPECT_EQ(0x7be6715f5cULL, unwinder.frames()[1].pc);
+ EXPECT_EQ(0x7be4f077d0ULL, unwinder.frames()[1].sp);
+ EXPECT_EQ(0x7be6715e9cULL, unwinder.frames()[2].pc);
+ EXPECT_EQ(0x7be4f07800ULL, unwinder.frames()[2].sp);
+ EXPECT_EQ(0x7be6715d70ULL, unwinder.frames()[3].pc);
+ EXPECT_EQ(0x7be4f07840ULL, unwinder.frames()[3].sp);
+ EXPECT_EQ(0x7be6716408ULL, unwinder.frames()[4].pc);
+ EXPECT_EQ(0x7be4f07860ULL, unwinder.frames()[4].sp);
+ EXPECT_EQ(0x7be67168d8ULL, unwinder.frames()[5].pc);
+ EXPECT_EQ(0x7be4f07880ULL, unwinder.frames()[5].sp);
+ EXPECT_EQ(0x7be6716814ULL, unwinder.frames()[6].pc);
+ EXPECT_EQ(0x7be4f078f0ULL, unwinder.frames()[6].sp);
+ EXPECT_EQ(0x7be6704f60ULL, unwinder.frames()[7].pc);
+ EXPECT_EQ(0x7be4f07910ULL, unwinder.frames()[7].sp);
+ EXPECT_EQ(0x7be5f7b024ULL, unwinder.frames()[8].pc);
+ EXPECT_EQ(0x7be4f07950ULL, unwinder.frames()[8].sp);
+ EXPECT_EQ(0x7be5f7cad0ULL, unwinder.frames()[9].pc);
+ EXPECT_EQ(0x7be4f07aa0ULL, unwinder.frames()[9].sp);
+ EXPECT_EQ(0x7be5f7cb64ULL, unwinder.frames()[10].pc);
+ EXPECT_EQ(0x7be4f07ce0ULL, unwinder.frames()[10].sp);
+ EXPECT_EQ(0x7cbe11406cULL, unwinder.frames()[11].pc);
+ EXPECT_EQ(0x7be4f07d00ULL, unwinder.frames()[11].sp);
+ EXPECT_EQ(0x7cbe0b5e18ULL, unwinder.frames()[12].pc);
+ EXPECT_EQ(0x7be4f07d20ULL, unwinder.frames()[12].sp);
+}
+
} // namespace unwindstack
diff --git a/libunwindstack/tests/files/offline/shared_lib_in_apk_single_map_arm64/libc.so b/libunwindstack/tests/files/offline/shared_lib_in_apk_single_map_arm64/libc.so
new file mode 100644
index 0000000..cac1dd9
--- /dev/null
+++ b/libunwindstack/tests/files/offline/shared_lib_in_apk_single_map_arm64/libc.so
Binary files differ
diff --git a/libunwindstack/tests/files/offline/shared_lib_in_apk_single_map_arm64/maps.txt b/libunwindstack/tests/files/offline/shared_lib_in_apk_single_map_arm64/maps.txt
new file mode 100644
index 0000000..2c5ca62
--- /dev/null
+++ b/libunwindstack/tests/files/offline/shared_lib_in_apk_single_map_arm64/maps.txt
@@ -0,0 +1,3 @@
+7be5e48000-7be6b2b000 r-xp 5000 00:00 0 test.apk
+7cbe030000-7cbe070000 r--p 0 00:00 0 libc.so
+7cbe070000-7cbe11a000 r-xp 40000 00:00 0 libc.so
diff --git a/libunwindstack/tests/files/offline/shared_lib_in_apk_single_map_arm64/regs.txt b/libunwindstack/tests/files/offline/shared_lib_in_apk_single_map_arm64/regs.txt
new file mode 100644
index 0000000..090aeda
--- /dev/null
+++ b/libunwindstack/tests/files/offline/shared_lib_in_apk_single_map_arm64/regs.txt
@@ -0,0 +1,33 @@
+x0: 7c326f6568
+x1: 80
+x2: 0
+x3: 0
+x4: 0
+x5: 0
+x6: 0
+x7: 7f7f7f7f7f7f7f7f
+x8: 62
+x9: 1
+x10: 1
+x11: 0
+x12: ffffffffc4653600
+x13: 17645696f
+x14: 2742ed97ca77a3
+x15: 3ab49084
+x16: 7be6b6bdb8
+x17: 7cbe0b14a0
+x18: 7c2b02a000
+x19: 0
+x20: 7c326f6568
+x21: 7be69c827c
+x22: 7be69c8272
+x23: 1
+x24: 7be74f7100
+x25: 881
+x26: 7be4f07a00
+x27: c479c000
+x28: 7be4f07998
+x29: 7be4f079b4
+sp: 7be4f077d0
+lr: 7be6715f60
+pc: 7cbe0b14bc
diff --git a/libunwindstack/tests/files/offline/shared_lib_in_apk_single_map_arm64/stack.data b/libunwindstack/tests/files/offline/shared_lib_in_apk_single_map_arm64/stack.data
new file mode 100644
index 0000000..27d5bf3
--- /dev/null
+++ b/libunwindstack/tests/files/offline/shared_lib_in_apk_single_map_arm64/stack.data
Binary files differ
diff --git a/libunwindstack/tests/files/offline/shared_lib_in_apk_single_map_arm64/test.apk b/libunwindstack/tests/files/offline/shared_lib_in_apk_single_map_arm64/test.apk
new file mode 100644
index 0000000..70a9c71
--- /dev/null
+++ b/libunwindstack/tests/files/offline/shared_lib_in_apk_single_map_arm64/test.apk
Binary files differ
diff --git a/libusbhost/Android.bp b/libusbhost/Android.bp
index 39bf3a5..fc6f305 100644
--- a/libusbhost/Android.bp
+++ b/libusbhost/Android.bp
@@ -20,7 +20,6 @@
vndk: {
enabled: true,
},
- double_loadable: true,
host_supported: true,
srcs: ["usbhost.c"],
cflags: ["-Werror"],
diff --git a/libvndksupport/linker.c b/libvndksupport/linker.c
index 821940a..84c2132 100644
--- a/libvndksupport/linker.c
+++ b/libvndksupport/linker.c
@@ -20,6 +20,8 @@
#define LOG_TAG "vndksupport"
#include <log/log.h>
+#include <sys/types.h>
+#include <unistd.h>
__attribute__((weak)) extern struct android_namespace_t* android_get_exported_namespace(const char*);
__attribute__((weak)) extern void* android_dlopen_ext(const char*, int, const android_dlextinfo*);
@@ -46,6 +48,11 @@
}
int android_is_in_vendor_process() {
+ // Special case init, since when init runs, ld.config.<ver>.txt hasn't been
+ // loaded (sysprop service isn't up for init to know <ver>).
+ if (getpid() == 1) {
+ return 0;
+ }
if (android_get_exported_namespace == NULL) {
ALOGD("android_get_exported_namespace() not available. Assuming system process.");
return 0;
diff --git a/lmkd/lmkd.c b/lmkd/lmkd.c
index 18421e8..2d3fbfc 100644
--- a/lmkd/lmkd.c
+++ b/lmkd/lmkd.c
@@ -110,7 +110,7 @@
*/
#define PSI_WINDOW_SIZE_MS 1000
/* Polling period after initial PSI signal */
-#define PSI_POLL_PERIOD_MS 200
+#define PSI_POLL_PERIOD_MS 40
/* Poll for the duration of one window after initial PSI signal */
#define PSI_POLL_COUNT (PSI_WINDOW_SIZE_MS / PSI_POLL_PERIOD_MS)
diff --git a/rootdir/init.environ.rc.in b/rootdir/init.environ.rc.in
index 5d6cd2d..455c9a8 100644
--- a/rootdir/init.environ.rc.in
+++ b/rootdir/init.environ.rc.in
@@ -6,6 +6,7 @@
export ANDROID_DATA /data
export ANDROID_STORAGE /storage
export ANDROID_RUNTIME_ROOT /apex/com.android.runtime
+ export ANDROID_TZDATA_ROOT /apex/com.android.tzdata
export EXTERNAL_STORAGE /sdcard
export ASEC_MOUNTPOINT /mnt/asec
export BOOTCLASSPATH %BOOTCLASSPATH%
diff --git a/rootdir/init.rc b/rootdir/init.rc
index 399424b..3854c73 100644
--- a/rootdir/init.rc
+++ b/rootdir/init.rc
@@ -389,6 +389,8 @@
chmod 0700 /metadata/vold
mkdir /metadata/password_slots 0771 root system
+ mkdir /metadata/apex 0700 root system
+ mkdir /metadata/apex/sessions 0700 root system
on late-fs
# Ensure that tracefs has the correct permissions.
# This does not work correctly if it is called in post-fs.
diff --git a/run-as/run-as.cpp b/run-as/run-as.cpp
index 8752eef..432c434 100644
--- a/run-as/run-as.cpp
+++ b/run-as/run-as.cpp
@@ -70,32 +70,40 @@
return true; // Keep searching.
}
-static bool check_directory(const char* path, uid_t uid) {
+static void check_directory(const char* path, uid_t uid) {
struct stat st;
- if (TEMP_FAILURE_RETRY(lstat(path, &st)) == -1) return false;
+ if (TEMP_FAILURE_RETRY(lstat(path, &st)) == -1) {
+ error(1, errno, "couldn't stat %s", path);
+ }
// /data/user/0 is a known safe symlink.
- if (strcmp("/data/user/0", path) == 0) return true;
+ if (strcmp("/data/user/0", path) == 0) return;
// Must be a real directory, not a symlink.
- if (!S_ISDIR(st.st_mode)) return false;
+ if (!S_ISDIR(st.st_mode)) {
+ error(1, 0, "%s not a directory: %o", path, st.st_mode);
+ }
// Must be owned by specific uid/gid.
- if (st.st_uid != uid || st.st_gid != uid) return false;
+ if (st.st_uid != uid || st.st_gid != uid) {
+ error(1, 0, "%s has wrong owner: %d/%d, not %d", path, st.st_uid, st.st_gid, uid);
+ }
// Must not be readable or writable by others.
- if ((st.st_mode & (S_IROTH|S_IWOTH)) != 0) return false;
-
- return true;
+ if ((st.st_mode & (S_IROTH | S_IWOTH)) != 0) {
+ error(1, 0, "%s readable or writable by others: %o", path, st.st_mode);
+ }
}
// This function is used to check the data directory path for safety.
// We check that every sub-directory is owned by the 'system' user
// and exists and is not a symlink. We also check that the full directory
// path is properly owned by the user ID.
-static bool check_data_path(const char* data_path, uid_t uid) {
+static void check_data_path(const char* package_name, const char* data_path, uid_t uid) {
// The path should be absolute.
- if (data_path[0] != '/') return false;
+ if (data_path[0] != '/') {
+ error(1, 0, "%s data path not absolute: %s", package_name, data_path);
+ }
// Look for all sub-paths, we do that by finding
// directory separators in the input path and
@@ -110,26 +118,28 @@
if (data_path[nn+1] == '\0') break;
/* found a separator, check that data_path is not too long. */
- if (nn >= (int)(sizeof subpath)) return false;
+ if (nn >= (int)(sizeof subpath)) {
+ error(1, 0, "%s data path too long: %s", package_name, data_path);
+ }
/* reject any '..' subpath */
if (nn >= 3 &&
data_path[nn-3] == '/' &&
data_path[nn-2] == '.' &&
data_path[nn-1] == '.') {
- return false;
+ error(1, 0, "%s contains '..': %s", package_name, data_path);
}
/* copy to 'subpath', then check ownership */
memcpy(subpath, data_path, nn);
subpath[nn] = '\0';
- if (!check_directory(subpath, AID_SYSTEM)) return false;
+ check_directory(subpath, AID_SYSTEM);
}
// All sub-paths were checked, now verify that the full data
// directory is owned by the application uid.
- return check_directory(data_path, uid);
+ check_directory(data_path, uid);
}
std::vector<gid_t> get_supplementary_gids(uid_t userAppId) {
@@ -222,9 +232,7 @@
}
// Check that the data directory path is valid.
- if (!check_data_path(info.data_dir, userAppId)) {
- error(1, 0, "package has corrupt installation: %s", pkgname);
- }
+ check_data_path(pkgname, info.data_dir, userAppId);
// Ensure that we change all real/effective/saved IDs at the
// same time to avoid nasty surprises.