summaryrefslogtreecommitdiff
path: root/libdexfile/external/dex_file_supp.cc
diff options
context:
space:
mode:
author David Srbecky <dsrbecky@google.com> 2021-03-24 16:11:49 +0000
committer David Srbecky <dsrbecky@google.com> 2021-04-21 18:57:13 +0000
commit30d4d2f8dba0d7cd29cb0eeee53883d73542b7cc (patch)
treef670c2fed029ac132b1be91544bd470310f66efc /libdexfile/external/dex_file_supp.cc
parent18584d13da8af452c79e3909617f969fc1f3f455 (diff)
Rewrite libdexfile C API to follow NDK guidelines better.
Bug: 123517037 Bug: 145347927 Test: test-art-host-gtest-art_libdexfile_support_tests64 Test: test-art-host-gtest-art_libdexfile_external_tests64 Change-Id: I9673872585456937d2f54abb63e3dbd8aad4e9ad
Diffstat (limited to 'libdexfile/external/dex_file_supp.cc')
-rw-r--r--libdexfile/external/dex_file_supp.cc127
1 files changed, 16 insertions, 111 deletions
diff --git a/libdexfile/external/dex_file_supp.cc b/libdexfile/external/dex_file_supp.cc
index 6313afea06..23fc88a3a9 100644
--- a/libdexfile/external/dex_file_supp.cc
+++ b/libdexfile/external/dex_file_supp.cc
@@ -33,21 +33,15 @@
namespace art_api {
namespace dex {
-#define FOR_ALL_DLFUNCS(MACRO) \
- MACRO(DexFile, ExtDexFileOpenFromMemory) \
- MACRO(DexFile, ExtDexFileGetMethodInfoForOffset) \
- MACRO(DexFile, ExtDexFileGetAllMethodInfos) \
- MACRO(DexFile, ExtDexFileClose)
-
-#ifdef STATIC_LIB
-#define DEFINE_DLFUNC_PTR(CLASS, DLFUNC) decltype(DLFUNC)* CLASS::g_##DLFUNC = DLFUNC;
+#if defined(STATIC_LIB)
+#define DEFINE_ADEX_FILE_SYMBOL(DLFUNC) decltype(DLFUNC)* g_##DLFUNC = DLFUNC;
#else
-#define DEFINE_DLFUNC_PTR(CLASS, DLFUNC) decltype(DLFUNC)* CLASS::g_##DLFUNC = nullptr;
+#define DEFINE_ADEX_FILE_SYMBOL(DLFUNC) decltype(DLFUNC)* g_##DLFUNC = nullptr;
#endif
-FOR_ALL_DLFUNCS(DEFINE_DLFUNC_PTR)
-#undef DEFINE_DLFUNC_PTR
+FOR_EACH_ADEX_FILE_SYMBOL(DEFINE_ADEX_FILE_SYMBOL)
+#undef DEFINE_ADEX_FILE_SYMBOL
-bool TryLoadLibdexfileExternal([[maybe_unused]] std::string* err_msg) {
+bool TryLoadLibdexfile([[maybe_unused]] std::string* err_msg) {
#if defined(STATIC_LIB)
// Nothing to do here since all function pointers are initialised statically.
return true;
@@ -76,18 +70,18 @@ bool TryLoadLibdexfileExternal([[maybe_unused]] std::string* err_msg) {
return false;
}
-#define RESOLVE_DLFUNC_PTR(CLASS, DLFUNC) \
- decltype(DLFUNC)* DLFUNC##_ptr = reinterpret_cast<decltype(DLFUNC)*>(dlsym(handle, #DLFUNC)); \
- if ((DLFUNC) == nullptr) { \
+#define RESOLVE_ADEX_FILE_SYMBOL(DLFUNC) \
+ auto DLFUNC##_ptr = reinterpret_cast<decltype(DLFUNC)*>(dlsym(handle, #DLFUNC)); \
+ if (DLFUNC##_ptr == nullptr) { \
*err_msg = dlerror(); \
return false; \
}
- FOR_ALL_DLFUNCS(RESOLVE_DLFUNC_PTR);
-#undef RESOLVE_DLFUNC_PTR
+FOR_EACH_ADEX_FILE_SYMBOL(RESOLVE_ADEX_FILE_SYMBOL)
+#undef RESOLVE_ADEX_FILE_SYMBOL
-#define SET_DLFUNC_PTR(CLASS, DLFUNC) CLASS::g_##DLFUNC = DLFUNC##_ptr;
- FOR_ALL_DLFUNCS(SET_DLFUNC_PTR);
-#undef SET_DLFUNC_PTR
+#define SET_ADEX_FILE_SYMBOL(DLFUNC) g_##DLFUNC = DLFUNC##_ptr;
+ FOR_EACH_ADEX_FILE_SYMBOL(SET_ADEX_FILE_SYMBOL);
+#undef SET_ADEX_FILE_SYMBOL
is_loaded = true;
}
@@ -96,102 +90,13 @@ bool TryLoadLibdexfileExternal([[maybe_unused]] std::string* err_msg) {
#endif // !defined(NO_DEXFILE_SUPPORT) && !defined(STATIC_LIB)
}
-void LoadLibdexfileExternal() {
+void LoadLibdexfile() {
#ifndef STATIC_LIB
- if (std::string err_msg; !TryLoadLibdexfileExternal(&err_msg)) {
+ if (std::string err_msg; !TryLoadLibdexfile(&err_msg)) {
LOG_ALWAYS_FATAL("%s", err_msg.c_str());
}
#endif
}
-DexFile::~DexFile() { g_ExtDexFileClose(ext_dex_file_); }
-
-std::unique_ptr<DexFile> DexFile::OpenFromMemory(const void* addr,
- 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;
- int res = g_ExtDexFileOpenFromMemory(addr, size, location.c_str(), &ext_dex_file);
- switch (static_cast<ExtDexFileError>(res)) {
- case kExtDexFileOk:
- return std::unique_ptr<DexFile>(new DexFile(ext_dex_file));
- case kExtDexFileInvalidHeader:
- *error_msg = std::string("Invalid DexFile header ") + location;
- return nullptr;
- case kExtDexFileNotEnoughData:
- *error_msg = std::string("Not enough data");
- return nullptr;
- case kExtDexFileError:
- break;
- }
- *error_msg = std::string("Failed to open DexFile ") + location;
- return nullptr;
-}
-
-std::unique_ptr<DexFile> DexFile::OpenFromFd(int fd,
- off_t offset,
- const std::string& location,
- /*out*/ std::string* error_msg) {
- using android::base::StringPrintf;
- size_t length;
- {
- struct stat sbuf;
- std::memset(&sbuf, 0, sizeof(sbuf));
- if (fstat(fd, &sbuf) == -1) {
- *error_msg = StringPrintf("fstat '%s' failed: %s", location.c_str(), std::strerror(errno));
- return nullptr;
- }
- if (S_ISDIR(sbuf.st_mode)) {
- *error_msg = StringPrintf("Attempt to mmap directory '%s'", location.c_str());
- return nullptr;
- }
- length = sbuf.st_size;
- }
-
- if (static_cast<off_t>(length) < offset) {
- *error_msg = StringPrintf(
- "Offset %" PRId64 " too large for '%s' of size %zu",
- int64_t{offset},
- location.c_str(),
- length);
- return nullptr;
- }
- length -= offset;
-
- std::unique_ptr<android::base::MappedFile> map;
- map = android::base::MappedFile::FromFd(fd, offset, length, PROT_READ);
- if (map == nullptr) {
- *error_msg = StringPrintf("mmap '%s' failed: %s", location.c_str(), std::strerror(errno));
- return nullptr;
- }
-
- std::unique_ptr<DexFile> dex = OpenFromMemory(map->data(), &length, location, error_msg);
- if (dex != nullptr) {
- dex->map_ = std::move(map); // Ensure the map gets freed with the dex file.
- }
- return dex;
-}
-
-MethodInfo DexFile::GetMethodInfoForOffset(int64_t dex_offset, bool with_signature) {
- MethodInfo res{};
- auto set_method = [&res](ExtDexFileMethodInfo* info) { res = AbsorbMethodInfo(info); };
- uint32_t flags = with_signature ? kExtDexFileWithSignature : 0;
- GetMethodInfoForOffset(dex_offset, set_method, flags);
- return res;
-}
-
-std::vector<MethodInfo> DexFile::GetAllMethodInfos(bool with_signature) {
- std::vector<MethodInfo> res;
- auto add_method = [&res](ExtDexFileMethodInfo* info) { res.push_back(AbsorbMethodInfo(info)); };
- uint32_t flags = with_signature ? kExtDexFileWithSignature : 0;
- GetAllMethodInfos(add_method, flags);
- return res;
-}
-
} // namespace dex
} // namespace art_api