Merge "lmkd: set PSI_POLL_PERIOD to 40ms"
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/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/libutils/RefBase_test.cpp b/libutils/RefBase_test.cpp
index b594ca5..2e0cf6e 100644
--- a/libutils/RefBase_test.cpp
+++ b/libutils/RefBase_test.cpp
@@ -45,44 +45,6 @@
bool* mDeleted;
};
-// A version of Foo that ensures that all objects are allocated at the same
-// address. No more than one can be allocated at a time. Thread-hostile.
-class FooFixedAlloc : public RefBase {
-public:
- static void* operator new(size_t size) {
- if (mAllocCount != 0) {
- abort();
- }
- mAllocCount = 1;
- if (theMemory == nullptr) {
- theMemory = malloc(size);
- }
- return theMemory;
- }
-
- static void operator delete(void *p) {
- if (mAllocCount != 1 || p != theMemory) {
- abort();
- }
- mAllocCount = 0;
- }
-
- FooFixedAlloc(bool* deleted_check) : mDeleted(deleted_check) {
- *mDeleted = false;
- }
-
- ~FooFixedAlloc() {
- *mDeleted = true;
- }
-private:
- bool* mDeleted;
- static int mAllocCount;
- static void* theMemory;
-};
-
-int FooFixedAlloc::mAllocCount(0);
-void* FooFixedAlloc::theMemory(nullptr);
-
TEST(RefBase, StrongMoves) {
bool isDeleted;
Foo* foo = new Foo(&isDeleted);
@@ -128,91 +90,6 @@
ASSERT_FALSE(isDeleted) << "Deletion on wp destruction should no longer occur";
}
-TEST(RefBase, Comparisons) {
- bool isDeleted, isDeleted2;
- Foo* foo = new Foo(&isDeleted);
- Foo* foo2 = new Foo(&isDeleted2);
- sp<Foo> sp1(foo);
- sp<Foo> sp2(foo2);
- wp<Foo> wp1(sp1);
- wp<Foo> wp2(sp1);
- wp<Foo> wp3(sp2);
- ASSERT_TRUE(wp1 == wp2);
- ASSERT_TRUE(wp1 == sp1);
- ASSERT_TRUE(wp3 == sp2);
- ASSERT_TRUE(wp1 != sp2);
- ASSERT_TRUE(wp1 <= wp2);
- ASSERT_TRUE(wp1 >= wp2);
- ASSERT_FALSE(wp1 != wp2);
- ASSERT_FALSE(wp1 > wp2);
- ASSERT_FALSE(wp1 < wp2);
- ASSERT_FALSE(sp1 == sp2);
- ASSERT_TRUE(sp1 != sp2);
- bool sp1_smaller = sp1 < sp2;
- wp<Foo>wp_smaller = sp1_smaller ? wp1 : wp3;
- wp<Foo>wp_larger = sp1_smaller ? wp3 : wp1;
- ASSERT_TRUE(wp_smaller < wp_larger);
- ASSERT_TRUE(wp_smaller != wp_larger);
- ASSERT_TRUE(wp_smaller <= wp_larger);
- ASSERT_FALSE(wp_smaller == wp_larger);
- ASSERT_FALSE(wp_smaller > wp_larger);
- ASSERT_FALSE(wp_smaller >= wp_larger);
- sp2 = nullptr;
- ASSERT_TRUE(isDeleted2);
- ASSERT_FALSE(isDeleted);
- ASSERT_FALSE(wp3 == sp2);
- // Comparison results on weak pointers should not be affected.
- ASSERT_TRUE(wp_smaller < wp_larger);
- ASSERT_TRUE(wp_smaller != wp_larger);
- ASSERT_TRUE(wp_smaller <= wp_larger);
- ASSERT_FALSE(wp_smaller == wp_larger);
- ASSERT_FALSE(wp_smaller > wp_larger);
- ASSERT_FALSE(wp_smaller >= wp_larger);
- wp2 = nullptr;
- ASSERT_FALSE(wp1 == wp2);
- ASSERT_TRUE(wp1 != wp2);
- wp1.clear();
- ASSERT_TRUE(wp1 == wp2);
- ASSERT_FALSE(wp1 != wp2);
- wp3.clear();
- ASSERT_TRUE(wp1 == wp3);
- ASSERT_FALSE(wp1 != wp3);
- ASSERT_FALSE(isDeleted);
- sp1.clear();
- ASSERT_TRUE(isDeleted);
- ASSERT_TRUE(sp1 == sp2);
-}
-
-// Check whether comparison against dead wp works, even if the object referenced
-// by the new wp happens to be at the same address.
-TEST(RefBase, ReplacedComparison) {
- bool isDeleted, isDeleted2;
- FooFixedAlloc* foo = new FooFixedAlloc(&isDeleted);
- sp<FooFixedAlloc> sp1(foo);
- wp<FooFixedAlloc> wp1(sp1);
- ASSERT_TRUE(wp1 == sp1);
- sp1.clear(); // Deallocates the object.
- ASSERT_TRUE(isDeleted);
- FooFixedAlloc* foo2 = new FooFixedAlloc(&isDeleted2);
- ASSERT_FALSE(isDeleted2);
- ASSERT_EQ(foo, foo2); // Not technically a legal comparison, but ...
- sp<FooFixedAlloc> sp2(foo2);
- wp<FooFixedAlloc> wp2(sp2);
- ASSERT_TRUE(sp2 == wp2);
- ASSERT_FALSE(sp2 != wp2);
- ASSERT_TRUE(sp2 != wp1);
- ASSERT_FALSE(sp2 == wp1);
- ASSERT_FALSE(sp2 == sp1); // sp1 is null.
- ASSERT_FALSE(wp1 == wp2); // wp1 refers to old object.
- ASSERT_TRUE(wp1 != wp2);
- ASSERT_TRUE(wp1 > wp2 || wp1 < wp2);
- ASSERT_TRUE(wp1 >= wp2 || wp1 <= wp2);
- ASSERT_FALSE(wp1 >= wp2 && wp1 <= wp2);
- ASSERT_FALSE(wp1 == nullptr);
- wp1 = sp2;
- ASSERT_TRUE(wp1 == wp2);
- ASSERT_FALSE(wp1 != wp2);
-}
// Set up a situation in which we race with visit2AndRremove() to delete
// 2 strong references. Bar destructor checks that there are no early
diff --git a/libutils/include/utils/RefBase.h b/libutils/include/utils/RefBase.h
index 730d631..1780cf2 100644
--- a/libutils/include/utils/RefBase.h
+++ b/libutils/include/utils/RefBase.h
@@ -171,8 +171,6 @@
#define ANDROID_REF_BASE_H
#include <atomic>
-#include <functional>
-#include <type_traits> // for common_type.
#include <stdint.h>
#include <sys/types.h>
@@ -194,26 +192,19 @@
// ---------------------------------------------------------------------------
#define COMPARE_WEAK(_op_) \
+inline bool operator _op_ (const sp<T>& o) const { \
+ return m_ptr _op_ o.m_ptr; \
+} \
+inline bool operator _op_ (const T* o) const { \
+ return m_ptr _op_ o; \
+} \
+template<typename U> \
+inline bool operator _op_ (const sp<U>& o) const { \
+ return m_ptr _op_ o.m_ptr; \
+} \
template<typename U> \
inline bool operator _op_ (const U* o) const { \
return m_ptr _op_ o; \
-} \
-/* Needed to handle type inference for nullptr: */ \
-inline bool operator _op_ (const T* o) const { \
- return m_ptr _op_ o; \
-}
-
-template<template<typename C> class comparator, typename T, typename U>
-static inline bool _wp_compare_(T* a, U* b) {
- return comparator<typename std::common_type<T*, U*>::type>()(a, b);
-}
-
-// Use std::less and friends to avoid undefined behavior when ordering pointers
-// to different objects.
-#define COMPARE_WEAK_FUNCTIONAL(_op_, _compare_) \
-template<typename U> \
-inline bool operator _op_ (const U* o) const { \
- return _wp_compare_<_compare_>(m_ptr, o); \
}
// ---------------------------------------------------------------------------
@@ -404,51 +395,39 @@
COMPARE_WEAK(==)
COMPARE_WEAK(!=)
- COMPARE_WEAK_FUNCTIONAL(>, std::greater)
- COMPARE_WEAK_FUNCTIONAL(<, std::less)
- COMPARE_WEAK_FUNCTIONAL(<=, std::less_equal)
- COMPARE_WEAK_FUNCTIONAL(>=, std::greater_equal)
+ COMPARE_WEAK(>)
+ COMPARE_WEAK(<)
+ COMPARE_WEAK(<=)
+ COMPARE_WEAK(>=)
+ inline bool operator == (const wp<T>& o) const {
+ return (m_ptr == o.m_ptr) && (m_refs == o.m_refs);
+ }
template<typename U>
inline bool operator == (const wp<U>& o) const {
- return m_refs == o.m_refs; // Implies m_ptr == o.mptr; see invariants below.
+ return m_ptr == o.m_ptr;
}
- template<typename U>
- inline bool operator == (const sp<U>& o) const {
- // Just comparing m_ptr fields is often dangerous, since wp<> may refer to an older
- // object at the same address.
- if (o == nullptr) {
- return m_ptr == nullptr;
- } else {
- return m_refs == o->getWeakRefs(); // Implies m_ptr == o.mptr.
- }
+ inline bool operator > (const wp<T>& o) const {
+ return (m_ptr == o.m_ptr) ? (m_refs > o.m_refs) : (m_ptr > o.m_ptr);
}
-
- template<typename U>
- inline bool operator != (const sp<U>& o) const {
- return !(*this == o);
- }
-
template<typename U>
inline bool operator > (const wp<U>& o) const {
- if (m_ptr == o.m_ptr) {
- return _wp_compare_<std::greater>(m_refs, o.m_refs);
- } else {
- return _wp_compare_<std::greater>(m_ptr, o.m_ptr);
- }
+ return (m_ptr == o.m_ptr) ? (m_refs > o.m_refs) : (m_ptr > o.m_ptr);
}
+ inline bool operator < (const wp<T>& o) const {
+ return (m_ptr == o.m_ptr) ? (m_refs < o.m_refs) : (m_ptr < o.m_ptr);
+ }
template<typename U>
inline bool operator < (const wp<U>& o) const {
- if (m_ptr == o.m_ptr) {
- return _wp_compare_<std::less>(m_refs, o.m_refs);
- } else {
- return _wp_compare_<std::less>(m_ptr, o.m_ptr);
- }
+ return (m_ptr == o.m_ptr) ? (m_refs < o.m_refs) : (m_ptr < o.m_ptr);
}
+ inline bool operator != (const wp<T>& o) const { return m_refs != o.m_refs; }
template<typename U> inline bool operator != (const wp<U>& o) const { return !operator == (o); }
+ inline bool operator <= (const wp<T>& o) const { return !operator > (o); }
template<typename U> inline bool operator <= (const wp<U>& o) const { return !operator > (o); }
+ inline bool operator >= (const wp<T>& o) const { return !operator < (o); }
template<typename U> inline bool operator >= (const wp<U>& o) const { return !operator < (o); }
private:
@@ -467,22 +446,6 @@
// ---------------------------------------------------------------------------
// No user serviceable parts below here.
-// Implementation invariants:
-// Either
-// 1) m_ptr and m_refs are both null, or
-// 2) m_refs == m_ptr->mRefs, or
-// 3) *m_ptr is no longer live, and m_refs points to the weakref_type object that corresponded
-// to m_ptr while it was live. *m_refs remains live while a wp<> refers to it.
-//
-// The m_refs field in a RefBase object is allocated on construction, unique to that RefBase
-// object, and never changes. Thus if two wp's have identical m_refs fields, they are either both
-// null or point to the same object. If two wp's have identical m_ptr fields, they either both
-// point to the same live object and thus have the same m_ref fields, or at least one of the
-// objects is no longer live.
-//
-// Note that the above comparison operations go out of their way to provide an ordering consistent
-// with ordinary pointer comparison; otherwise they could ignore m_ptr, and just compare m_refs.
-
template<typename T>
wp<T>::wp(T* other)
: m_ptr(other)
@@ -632,7 +595,6 @@
{
if (m_ptr) {
m_refs->decWeak(this);
- m_refs = 0;
m_ptr = 0;
}
}
diff --git a/libutils/include/utils/StrongPointer.h b/libutils/include/utils/StrongPointer.h
index 9cd7c75..1571129 100644
--- a/libutils/include/utils/StrongPointer.h
+++ b/libutils/include/utils/StrongPointer.h
@@ -17,9 +17,6 @@
#ifndef ANDROID_STRONG_POINTER_H
#define ANDROID_STRONG_POINTER_H
-#include <functional>
-#include <type_traits> // for common_type.
-
// ---------------------------------------------------------------------------
namespace android {
@@ -27,12 +24,13 @@
// ---------------------------------------------------------------------------
-// TODO: Maybe remove sp<> ? wp<> comparison? These are dangerous: If the wp<>
-// was created before the sp<>, and they point to different objects, they may
-// compare equal even if they are entirely unrelated. E.g. CameraService
-// currently performa such comparisons.
-
-#define COMPARE_STRONG(_op_) \
+#define COMPARE(_op_) \
+inline bool operator _op_ (const sp<T>& o) const { \
+ return m_ptr _op_ o.m_ptr; \
+} \
+inline bool operator _op_ (const T* o) const { \
+ return m_ptr _op_ o; \
+} \
template<typename U> \
inline bool operator _op_ (const sp<U>& o) const { \
return m_ptr _op_ o.m_ptr; \
@@ -41,27 +39,14 @@
inline bool operator _op_ (const U* o) const { \
return m_ptr _op_ o; \
} \
-/* Needed to handle type inference for nullptr: */ \
-inline bool operator _op_ (const T* o) const { \
- return m_ptr _op_ o; \
+inline bool operator _op_ (const wp<T>& o) const { \
+ return m_ptr _op_ o.m_ptr; \
+} \
+template<typename U> \
+inline bool operator _op_ (const wp<U>& o) const { \
+ return m_ptr _op_ o.m_ptr; \
}
-template<template<typename C> class comparator, typename T, typename U>
-static inline bool _sp_compare_(T* a, U* b) {
- return comparator<typename std::common_type<T*, U*>::type>()(a, b);
-}
-
-// Use std::less and friends to avoid undefined behavior when ordering pointers
-// to different objects.
-#define COMPARE_STRONG_FUNCTIONAL(_op_, _compare_) \
-template<typename U> \
-inline bool operator _op_ (const sp<U>& o) const { \
- return _sp_compare_<_compare_>(m_ptr, o.m_ptr); \
-} \
-template<typename U> \
-inline bool operator _op_ (const U* o) const { \
- return _sp_compare_<_compare_>(m_ptr, o); \
-}
// ---------------------------------------------------------------------------
template<typename T>
@@ -104,23 +89,12 @@
// Operators
- COMPARE_STRONG(==)
- COMPARE_STRONG(!=)
- COMPARE_STRONG_FUNCTIONAL(>, std::greater)
- COMPARE_STRONG_FUNCTIONAL(<, std::less)
- COMPARE_STRONG_FUNCTIONAL(<=, std::less_equal)
- COMPARE_STRONG_FUNCTIONAL(>=, std::greater_equal)
-
- // Punt these to the wp<> implementation.
- template<typename U>
- inline bool operator == (const wp<U>& o) const {
- return o == *this;
- }
-
- template<typename U>
- inline bool operator != (const wp<U>& o) const {
- return o != *this;
- }
+ COMPARE(==)
+ COMPARE(!=)
+ COMPARE(>)
+ COMPARE(<)
+ COMPARE(<=)
+ COMPARE(>=)
private:
template<typename Y> friend class sp;
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/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 b769b94..7cac972 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.