Merge "Workaround for "required" dependencies not being followed in APEXes."
diff --git a/build/apex/Android.bp b/build/apex/Android.bp
index 42e8a38..533f61c 100644
--- a/build/apex/Android.bp
+++ b/build/apex/Android.bp
@@ -132,6 +132,16 @@
private_key: "com.android.runtime.pem",
}
+android_app_certificate {
+ name: "com.android.runtime.debug.certificate",
+ certificate: "com.android.runtime.debug",
+}
+
+android_app_certificate {
+ name: "com.android.runtime.release.certificate",
+ certificate: "com.android.runtime.release",
+}
+
prebuilt_etc {
name: "com.android.runtime.ld.config.txt",
src: "ld.config.txt",
@@ -170,6 +180,7 @@
prebuilts: art_runtime_data_file_prebuilts
+ ["com.android.runtime.ld.config.txt"],
key: "com.android.runtime.key",
+ certificate: ":com.android.runtime.release.certificate",
}
// "Debug" version of the Runtime APEX module (containing both release and
@@ -204,6 +215,7 @@
prebuilts: art_runtime_data_file_prebuilts
+ ["com.android.runtime.ld.config.txt"],
key: "com.android.runtime.key",
+ certificate: ":com.android.runtime.debug.certificate",
}
// TODO: Do this better. art_apex will disable host builds when
diff --git a/build/apex/com.android.runtime.debug.pk8 b/build/apex/com.android.runtime.debug.pk8
new file mode 100644
index 0000000..5eec5d8
--- /dev/null
+++ b/build/apex/com.android.runtime.debug.pk8
Binary files differ
diff --git a/build/apex/com.android.runtime.debug.x509.pem b/build/apex/com.android.runtime.debug.x509.pem
new file mode 100644
index 0000000..73402f5
--- /dev/null
+++ b/build/apex/com.android.runtime.debug.x509.pem
@@ -0,0 +1,34 @@
+-----BEGIN CERTIFICATE-----
+MIIF0DCCA7igAwIBAgIJALbaJLNNAiRDMA0GCSqGSIb3DQEBCwUAMHwxCzAJBgNV
+BAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMRYwFAYDVQQHDA1Nb3VudGFpbiBW
+aWV3MRAwDgYDVQQKDAdBbmRyb2lkMRAwDgYDVQQLDAdBbmRyb2lkMRwwGgYDVQQD
+DBNjb20uYW5kcm9pZC5ydW50aW1lMCAXDTE5MDEyNTE3MTQ1NloYDzQ3NTYxMjIx
+MTcxNDU2WjB8MQswCQYDVQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTEWMBQG
+A1UEBwwNTW91bnRhaW4gVmlldzEQMA4GA1UECgwHQW5kcm9pZDEQMA4GA1UECwwH
+QW5kcm9pZDEcMBoGA1UEAwwTY29tLmFuZHJvaWQucnVudGltZTCCAiIwDQYJKoZI
+hvcNAQEBBQADggIPADCCAgoCggIBAN1Ns75c0ZdLKnUvEuEotzJ0xyOLzOHYP3y6
+RzcwFyPf84aADc7rQDtjbmEuf9g9QpJhZAxe7G2Jg/wxqaxMW6wCfkpuElW5CAcj
+XQ0i12hRVtqePs5Z5bjzJ/8C7luWh82Vb/s2YoRPoKNXVWFT16CB4RMnw2nW5Uyo
+RHZ98N4MgFSGilafIc6Z0DImreTTwlEvcyKihVUSuzeyPG8CRjshw0C1Hqxt4a8J
+rxAgfPpd84Xo4etYePpVr2K5+vNAVwLpUdD48Y7q9peOJ0tbL8DSohudkzvZsQUo
+CfEfrVBfZv7aPnt6ZJYhcFo1WRBMYczKP4jWb0KgmF963ee3zliU1pXtIYsNBNth
+Mdvy3ml301tI7CKE5A3Yevm40VVqo+IDt7FNxoV3rKPhnO9vi/YqzX/1xMvAto8E
+9A5NvMTqHmS2P0wt1pt9KSuXXjoIAWaHZOATDkVI+jLjDrYFNdhqXVgbAaVtI60j
+lRaSWxzBr4o+g2W8ks/JgM2mwJ6qaTNoDMzg823MKzy/t3935sxm5GhFs9AY9Qz/
+4B3exqYUEFJLN6dJLCVppCmFCdCONSxN7bXPo+3b9LlZuKAOP17N04+eKcwXVeYz
+Z3a7SfyMzq+DtLhAn/TSliSbbCAVUxiOZnVX1nM0Gs3/BYCs0TUh2tSqO48pwDrx
+Pw7z9+m5AgMBAAGjUzBRMB0GA1UdDgQWBBRT9s/tu4uqtrglUFjQbwY5p+17DjAf
+BgNVHSMEGDAWgBRT9s/tu4uqtrglUFjQbwY5p+17DjAPBgNVHRMBAf8EBTADAQH/
+MA0GCSqGSIb3DQEBCwUAA4ICAQBNY5giwZCM0sE93Dj2zEe8qCRwIaV4bvSe744X
+Y1+405vdrNEHKPUfFn1xLSnhiGU3loZrP15lexmWvxycLNEy0UxZgq3eR7HuW6xp
+GIm9ttYDZEP+pL9hwew3jiR38NRRR1Ur1MsBNkZnCELC1W8RFWIi77Fsb4fj2mGn
+2R+2voBvVS5kjkytW079CEIsZN9RVYfERiKPCfJDa87kk0xduqyh7sDegQl0B2Ot
+R9KnD1dJZjbii2GRkhpJ/Ig17CQH3J8PY/SIt9L+QAchnIEF051sjbBRUJuPK9gL
+eBEkZkwD1JLqGO6fxkcjNx7MIevTnIBjX2Epr8luyRy7eR3TdBT3aRQcCUqBCi3i
+WxAVR5sOZ90INTXftFbztoklitpQ9mxKXgFr+xggL6u3BdJk1Nt9BsYmRzh5Bg+6
+1eMDBumy3JEA7whE8p75X9cSnKTNrDQU3DA5XzpIhmI91XJArBhBfxgqGxaTf0uq
+SfZRDfnaO456ZsZdKUy62mry6Vg/hvzX52x/HxDlSQWbpYp5t03hshaWxtNE376q
+GdqOoGRRWCvyWi/UOYzabp6czTjwV1JH9IU379CsqIO5UNJ2MM2re4TDXofefU1C
+6eiYihy28xDfIiCdretLRlvFYFF/5X5xby/XWsDA9sGlL5OOiXC6o0Pl9vbek2+T
+Ibx3Nw==
+-----END CERTIFICATE-----
diff --git a/build/apex/com.android.runtime.release.pk8 b/build/apex/com.android.runtime.release.pk8
new file mode 100644
index 0000000..c63efb8
--- /dev/null
+++ b/build/apex/com.android.runtime.release.pk8
Binary files differ
diff --git a/build/apex/com.android.runtime.release.x509.pem b/build/apex/com.android.runtime.release.x509.pem
new file mode 100644
index 0000000..4a7607a
--- /dev/null
+++ b/build/apex/com.android.runtime.release.x509.pem
@@ -0,0 +1,34 @@
+-----BEGIN CERTIFICATE-----
+MIIF0DCCA7igAwIBAgIJAMtsu/wrkZurMA0GCSqGSIb3DQEBCwUAMHwxCzAJBgNV
+BAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMRYwFAYDVQQHDA1Nb3VudGFpbiBW
+aWV3MRAwDgYDVQQKDAdBbmRyb2lkMRAwDgYDVQQLDAdBbmRyb2lkMRwwGgYDVQQD
+DBNjb20uYW5kcm9pZC5ydW50aW1lMCAXDTE5MDEyNTE3MTU0MFoYDzQ3NTYxMjIx
+MTcxNTQwWjB8MQswCQYDVQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTEWMBQG
+A1UEBwwNTW91bnRhaW4gVmlldzEQMA4GA1UECgwHQW5kcm9pZDEQMA4GA1UECwwH
+QW5kcm9pZDEcMBoGA1UEAwwTY29tLmFuZHJvaWQucnVudGltZTCCAiIwDQYJKoZI
+hvcNAQEBBQADggIPADCCAgoCggIBAL+aGSc+HU69vV1VbZb6WjXMDrE2Jo+JjXLU
+yVS3o8qlQeqN0RFbsbwnihnwg2xBnM6JiskAcuocz87dDuEt1zUEInC3Hpt/C2eg
+GUZepbq8po+v+b04YlX3aTaYTFqMjU0aQkjOqhnmVxg+KHpvudlvKB3VhH3D61al
+RReQzgM/Q6aUxcr4Z8XwvzV3i0K5NjiSuSt14K2yIaheh2OTbbwtvm3d+0sQDco6
+1gl0l4rM4e+GjxgWVqx8mfKhd4HTS3YIBDWXR6DFPBARzVBIpZu2QK4U6Jdsy2wI
+xg8+d5KWAoNQb7IQK6LQy7Fbw3PNJDo4Ph39G2wNgeMemz8uSQ9FZujc0AgxBom6
+J+ad7zlJBhYFC4UIKBYrRfJCHTN3GLuLvhu0p0jNMfdQXF6Tv/iG9g8JdZ0QjeWm
+/K+h1p6LUAIUV0UP7j8nIdp0j6NqMywkoeRDYlVQV/XdI7BiQe9Z8yNbF5Y3CxWT
+hMfN9iby11ImPilzpgv39ORVjDQdxxcwhJg2Xuu1752cBxcHu3ZcR8AiB7PCksXu
+EpUrjjOH8eVxoG1JJ/na5elUg/H35Or+JYYd8I8Ad1/GRkPrnIBAGzuyntOsNs4t
+2CEnhmV6EkEH8KP8miTdaa5NdPIwFRIHVBHcrqsqdmrINvoJhaVRH7YwmFjv48ak
+N4OyW3oLAgMBAAGjUzBRMB0GA1UdDgQWBBRqVJ0tsEOyqhKiZOrOfRD1+jQFMDAf
+BgNVHSMEGDAWgBRqVJ0tsEOyqhKiZOrOfRD1+jQFMDAPBgNVHRMBAf8EBTADAQH/
+MA0GCSqGSIb3DQEBCwUAA4ICAQAs+I1tRWRPmhA+FqcRdlAcY2Vy7NO12hjWXCT9
+hqenGk1/VnhH8aZT5lXZNaWeKonT5W7XydyrjiF09ndZBGew0rEZh6sMXH+G/drT
+9JxvfHsCQGrmX32V1XgAoRjV1VpUYIb2747fFWHHbl5frowNj955pkfseeKilSnF
+orUl5uGNxr6iNaVEUDfXBWkHwipYVyejAqdHkCQDhLtDBWsiskKpLWmmNKuy2QXQ
+uoyUyfeSR1Y+pT83qgmGb1LFLiOqL9ZKPrsIP+tG4lYB8L4SrYJf4MgfoJaKQ8ed
+2jsd42MegvOB2vdMyLgkf7EM/9DpE4BLpAy2mNd1AccL9YQ+0ezruxh6sYklJWGe
+2bHEbZk0duoNPsA87ZNKfFVV2cNVwSg/22HHjGieMUyPIwyGIzsHId8XiwXpZhLX
+VyacOVRd0SjTWK5Pxj6g21NrrcMXvFeCbveucf2ljKVxBVSbQKt67YlXxd9nLZjN
+zHnJWzDwlWXbyvxheLVVGEo0cqRbhxYMxXd9dM01EXJmIWqS8t0+aw90KKPFITNv
+qpxXnF5JJm1CzeBDtpmfepDupUR1bWansOd0sUuiDF/H1UcDiuBUC643RET1vjhv
+MllsShSeC6KGm3WwE0bhcvA9IdZC8CA3Btzw2J9aJO1gbVZ6vRkH+21cfR07so4N
+yXgprQ==
+-----END CERTIFICATE-----
diff --git a/libdexfile/Android.bp b/libdexfile/Android.bp
index feb5e38..2289a9c 100644
--- a/libdexfile/Android.bp
+++ b/libdexfile/Android.bp
@@ -205,6 +205,8 @@
cc_library_headers {
name: "libdexfile_external_headers",
host_supported: true,
+ vendor_available: true,
+ recovery_available: true,
header_libs: ["libbase_headers"],
export_header_lib_headers: ["libbase_headers"],
export_include_dirs: ["external/include"],
@@ -245,23 +247,37 @@
}
// Support library with a C++ API for accessing the libdexfile API for external
-// (non-ART) users. They should link to their own instance of this (either
-// statically or through linker namespaces).
+// (non-ART) users.
+//
+// This library dlopens libdexfile_external on first use, so there is no build
+// time dependency on dex file logic. It is therefore safe to use from binaries
+// compiled without dex file support, given they won't encounter any dex file
+// stack frames.
cc_library {
name: "libdexfile_support",
host_supported: true,
+ vendor_available: true,
+ recovery_available: true,
srcs: [
"external/dex_file_supp.cc",
],
+ required: ["libdexfile_external"],
+ shared_libs: ["liblog"],
header_libs: ["libdexfile_external_headers"],
- shared_libs: ["libdexfile_external"],
export_header_lib_headers: ["libdexfile_external_headers"],
+ target: {
+ recovery: {
+ cflags: ["-DNO_DEXFILE_SUPPORT"],
+ },
+ vendor: {
+ cflags: ["-DNO_DEXFILE_SUPPORT"],
+ },
+ },
}
art_cc_test {
name: "art_libdexfile_support_tests",
host_supported: true,
- test_per_src: true, // For consistency with other ART gtests.
srcs: [
"external/dex_file_supp_test.cc",
],
@@ -272,3 +288,36 @@
"libdexfile_support",
],
}
+
+cc_library_static {
+ name: "libdexfile_support_static",
+ host_supported: true,
+ defaults: ["libdexfile_static_defaults"],
+ srcs: [
+ "external/dex_file_supp.cc",
+ ],
+ cflags: ["-DSTATIC_LIB"],
+ // Using whole_static_libs here only as a "poor man's transitivity" kludge.
+ whole_static_libs: [
+ "libbase",
+ "libdexfile",
+ "libdexfile_external",
+ "liblog",
+ "libz",
+ "libziparchive",
+ ],
+ header_libs: ["libdexfile_external_headers"],
+ export_header_lib_headers: ["libdexfile_external_headers"],
+}
+
+art_cc_test {
+ name: "art_libdexfile_support_static_tests",
+ host_supported: true,
+ srcs: [
+ "external/dex_file_supp_test.cc",
+ ],
+ static_libs: [
+ "libbase",
+ "libdexfile_support_static",
+ ],
+}
diff --git a/libdexfile/external/dex_file_supp.cc b/libdexfile/external/dex_file_supp.cc
index 5bd25fc..ba684fe 100644
--- a/libdexfile/external/dex_file_supp.cc
+++ b/libdexfile/external/dex_file_supp.cc
@@ -16,10 +16,74 @@
#include "art_api/dex_file_support.h"
+#include <dlfcn.h>
+#include <mutex>
+
+#ifndef STATIC_LIB
+// Not used in the static lib, so avoid a dependency on this header in
+// libdexfile_support_static.
+#include <log/log.h>
+#endif
+
namespace art_api {
namespace dex {
-DexFile::~DexFile() { ExtDexFileFree(ext_dex_file_); }
+#ifdef STATIC_LIB
+#define DEFINE_DLFUNC_PTR(CLASS, DLFUNC) decltype(DLFUNC)* CLASS::g_##DLFUNC = DLFUNC
+#else
+#define DEFINE_DLFUNC_PTR(CLASS, DLFUNC) decltype(DLFUNC)* CLASS::g_##DLFUNC = nullptr
+#endif
+
+DEFINE_DLFUNC_PTR(DexString, ExtDexFileMakeString);
+DEFINE_DLFUNC_PTR(DexString, ExtDexFileGetString);
+DEFINE_DLFUNC_PTR(DexString, ExtDexFileFreeString);
+DEFINE_DLFUNC_PTR(DexFile, ExtDexFileOpenFromMemory);
+DEFINE_DLFUNC_PTR(DexFile, ExtDexFileOpenFromFd);
+DEFINE_DLFUNC_PTR(DexFile, ExtDexFileGetMethodInfoForOffset);
+DEFINE_DLFUNC_PTR(DexFile, ExtDexFileGetAllMethodInfos);
+DEFINE_DLFUNC_PTR(DexFile, ExtDexFileFree);
+
+#undef DEFINE_DLFUNC_PTR
+
+void LoadLibdexfileExternal() {
+#if defined(STATIC_LIB)
+ // Nothing to do here since all function pointers are initialised statically.
+#elif defined(NO_DEXFILE_SUPPORT)
+ LOG_FATAL("Dex file support not available.");
+#else
+ static std::once_flag dlopen_once;
+ std::call_once(dlopen_once, []() {
+ constexpr char kLibdexfileExternalLib[] = "libdexfile_external.so";
+ void* handle =
+ dlopen(kLibdexfileExternalLib, RTLD_NOW | RTLD_GLOBAL | RTLD_NODELETE);
+ LOG_ALWAYS_FATAL_IF(handle == nullptr, "Failed to load %s: %s",
+ kLibdexfileExternalLib, dlerror());
+
+#define SET_DLFUNC_PTR(CLASS, DLFUNC) \
+ do { \
+ CLASS::g_##DLFUNC = reinterpret_cast<decltype(DLFUNC)*>(dlsym(handle, #DLFUNC)); \
+ LOG_ALWAYS_FATAL_IF(CLASS::g_##DLFUNC == nullptr, \
+ "Failed to find %s in %s: %s", \
+ #DLFUNC, \
+ kLibdexfileExternalLib, \
+ dlerror()); \
+ } while (0)
+
+ SET_DLFUNC_PTR(DexString, ExtDexFileMakeString);
+ SET_DLFUNC_PTR(DexString, ExtDexFileGetString);
+ SET_DLFUNC_PTR(DexString, ExtDexFileFreeString);
+ SET_DLFUNC_PTR(DexFile, ExtDexFileOpenFromMemory);
+ SET_DLFUNC_PTR(DexFile, ExtDexFileOpenFromFd);
+ SET_DLFUNC_PTR(DexFile, ExtDexFileGetMethodInfoForOffset);
+ SET_DLFUNC_PTR(DexFile, ExtDexFileGetAllMethodInfos);
+ SET_DLFUNC_PTR(DexFile, ExtDexFileFree);
+
+#undef SET_DLFUNC_PTR
+ });
+#endif // !defined(NO_DEXFILE_SUPPORT) && !defined(STATIC_LIB)
+}
+
+DexFile::~DexFile() { g_ExtDexFileFree(ext_dex_file_); }
MethodInfo DexFile::AbsorbMethodInfo(const ExtDexFileMethodInfo& ext_method_info) {
return {ext_method_info.offset, ext_method_info.len, DexString(ext_method_info.name)};
diff --git a/libdexfile/external/include/art_api/dex_file_support.h b/libdexfile/external/include/art_api/dex_file_support.h
index 24222af..a98ff0e 100644
--- a/libdexfile/external/include/art_api/dex_file_support.h
+++ b/libdexfile/external/include/art_api/dex_file_support.h
@@ -33,17 +33,22 @@
namespace art_api {
namespace dex {
+// Loads the libdexfile_external.so library and sets up function pointers.
+// Aborts with a fatal error on any error. For internal use by the classes
+// below.
+void LoadLibdexfileExternal();
+
// Minimal std::string look-alike for a string returned from libdexfile.
class DexString final {
public:
DexString(DexString&& dex_str) noexcept : ext_string_(dex_str.ext_string_) {
- dex_str.ext_string_ = ExtDexFileMakeString("", 0);
+ dex_str.ext_string_ = MakeExtDexFileString("", 0);
}
explicit DexString(const char* str = "")
- : ext_string_(ExtDexFileMakeString(str, std::strlen(str))) {}
+ : ext_string_(MakeExtDexFileString(str, std::strlen(str))) {}
explicit DexString(std::string_view str)
- : ext_string_(ExtDexFileMakeString(str.data(), str.size())) {}
- ~DexString() { ExtDexFileFreeString(ext_string_); }
+ : ext_string_(MakeExtDexFileString(str.data(), str.size())) {}
+ ~DexString() { g_ExtDexFileFreeString(ext_string_); }
DexString& operator=(DexString&& dex_str) noexcept {
std::swap(ext_string_, dex_str.ext_string_);
@@ -52,36 +57,48 @@
const char* data() const {
size_t ignored;
- return ExtDexFileGetString(ext_string_, &ignored);
+ return g_ExtDexFileGetString(ext_string_, &ignored);
}
const char* c_str() const { return data(); }
size_t size() const {
size_t len;
- (void)ExtDexFileGetString(ext_string_, &len);
+ (void)g_ExtDexFileGetString(ext_string_, &len);
return len;
}
size_t length() const { return size(); }
operator std::string_view() const {
size_t len;
- const char* chars = ExtDexFileGetString(ext_string_, &len);
+ const char* chars = g_ExtDexFileGetString(ext_string_, &len);
return std::string_view(chars, len);
}
private:
+ friend void LoadLibdexfileExternal();
friend class DexFile;
friend bool operator==(const DexString&, const DexString&);
explicit DexString(const ExtDexFileString* ext_string) : ext_string_(ext_string) {}
const ExtDexFileString* ext_string_; // Owned instance. Never nullptr.
+ static decltype(ExtDexFileMakeString)* g_ExtDexFileMakeString;
+ static decltype(ExtDexFileGetString)* g_ExtDexFileGetString;
+ static decltype(ExtDexFileFreeString)* g_ExtDexFileFreeString;
+
+ static const struct ExtDexFileString* MakeExtDexFileString(const char* str, size_t size) {
+ if (UNLIKELY(g_ExtDexFileMakeString == nullptr)) {
+ LoadLibdexfileExternal();
+ }
+ return g_ExtDexFileMakeString(str, size);
+ }
+
DISALLOW_COPY_AND_ASSIGN(DexString);
};
inline bool operator==(const DexString& s1, const DexString& s2) {
size_t l1, l2;
- const char* str1 = ExtDexFileGetString(s1.ext_string_, &l1);
- const char* str2 = ExtDexFileGetString(s2.ext_string_, &l2);
+ const char* str1 = DexString::g_ExtDexFileGetString(s1.ext_string_, &l1);
+ const char* str2 = DexString::g_ExtDexFileGetString(s2.ext_string_, &l2);
// Use memcmp to avoid assumption about absence of null characters in the strings.
return l1 == l2 && !std::memcmp(str1, str2, l1);
}
@@ -120,9 +137,14 @@
size_t* size,
const std::string& location,
/*out*/ std::string* error_msg) {
+ if (UNLIKELY(g_ExtDexFileOpenFromMemory == nullptr)) {
+ // Load libdexfile_external.so in this factory function, so instance
+ // methods don't need to check this.
+ LoadLibdexfileExternal();
+ }
ExtDexFile* ext_dex_file;
const ExtDexFileString* ext_error_msg = nullptr;
- if (ExtDexFileOpenFromMemory(addr, size, location.c_str(), &ext_error_msg, &ext_dex_file)) {
+ if (g_ExtDexFileOpenFromMemory(addr, size, location.c_str(), &ext_error_msg, &ext_dex_file)) {
return std::unique_ptr<DexFile>(new DexFile(ext_dex_file));
}
*error_msg = (ext_error_msg == nullptr) ? "" : std::string(DexString(ext_error_msg));
@@ -138,9 +160,14 @@
off_t offset,
const std::string& location,
/*out*/ std::string* error_msg) {
+ if (UNLIKELY(g_ExtDexFileOpenFromFd == nullptr)) {
+ // Load libdexfile_external.so in this factory function, so instance
+ // methods don't need to check this.
+ LoadLibdexfileExternal();
+ }
ExtDexFile* ext_dex_file;
const ExtDexFileString* ext_error_msg = nullptr;
- if (ExtDexFileOpenFromFd(fd, offset, location.c_str(), &ext_error_msg, &ext_dex_file)) {
+ if (g_ExtDexFileOpenFromFd(fd, offset, location.c_str(), &ext_error_msg, &ext_dex_file)) {
return std::unique_ptr<DexFile>(new DexFile(ext_dex_file));
}
*error_msg = std::string(DexString(ext_error_msg));
@@ -154,10 +181,10 @@
// class and method name only.
MethodInfo GetMethodInfoForOffset(int64_t dex_offset, bool with_signature) {
ExtDexFileMethodInfo ext_method_info;
- if (ExtDexFileGetMethodInfoForOffset(ext_dex_file_,
- dex_offset,
- with_signature,
- &ext_method_info)) {
+ if (g_ExtDexFileGetMethodInfoForOffset(ext_dex_file_,
+ dex_offset,
+ with_signature,
+ &ext_method_info)) {
return AbsorbMethodInfo(ext_method_info);
}
return {/*offset=*/0, /*len=*/0, /*name=*/DexString()};
@@ -168,14 +195,15 @@
// gets the class and method name only.
std::vector<MethodInfo> GetAllMethodInfos(bool with_signature) {
MethodInfoVector res;
- ExtDexFileGetAllMethodInfos(ext_dex_file_,
- with_signature,
- AddMethodInfoCallback,
- static_cast<void*>(&res));
+ g_ExtDexFileGetAllMethodInfos(ext_dex_file_,
+ with_signature,
+ AddMethodInfoCallback,
+ static_cast<void*>(&res));
return res;
}
private:
+ friend void LoadLibdexfileExternal();
explicit DexFile(ExtDexFile* ext_dex_file) : ext_dex_file_(ext_dex_file) {}
ExtDexFile* ext_dex_file_; // Owned instance. nullptr only in moved-from zombies.
@@ -184,6 +212,12 @@
static MethodInfo AbsorbMethodInfo(const ExtDexFileMethodInfo& ext_method_info);
static void AddMethodInfoCallback(const ExtDexFileMethodInfo* ext_method_info, void* user_data);
+ static decltype(ExtDexFileOpenFromMemory)* g_ExtDexFileOpenFromMemory;
+ static decltype(ExtDexFileOpenFromFd)* g_ExtDexFileOpenFromFd;
+ static decltype(ExtDexFileGetMethodInfoForOffset)* g_ExtDexFileGetMethodInfoForOffset;
+ static decltype(ExtDexFileGetAllMethodInfos)* g_ExtDexFileGetAllMethodInfos;
+ static decltype(ExtDexFileFree)* g_ExtDexFileFree;
+
DISALLOW_COPY_AND_ASSIGN(DexFile);
};