diff options
author | 2021-03-24 16:11:49 +0000 | |
---|---|---|
committer | 2021-04-21 18:57:13 +0000 | |
commit | 30d4d2f8dba0d7cd29cb0eeee53883d73542b7cc (patch) | |
tree | f670c2fed029ac132b1be91544bd470310f66efc /libdexfile/external/dex_file_supp.cc | |
parent | 18584d13da8af452c79e3909617f969fc1f3f455 (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.cc | 127 |
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 |