summaryrefslogtreecommitdiff
path: root/libdexfile/external/include/art_api/dex_file_support.h
diff options
context:
space:
mode:
Diffstat (limited to 'libdexfile/external/include/art_api/dex_file_support.h')
-rw-r--r--libdexfile/external/include/art_api/dex_file_support.h187
1 files changed, 84 insertions, 103 deletions
diff --git a/libdexfile/external/include/art_api/dex_file_support.h b/libdexfile/external/include/art_api/dex_file_support.h
index 7c4ff5c13a..2361bf9211 100644
--- a/libdexfile/external/include/art_api/dex_file_support.h
+++ b/libdexfile/external/include/art_api/dex_file_support.h
@@ -19,133 +19,114 @@
// C++ wrapper for the dex file external API.
-#include <cstring>
#include <memory>
#include <string>
-#include <string_view>
-#include <utility>
-#include <vector>
#include <android-base/macros.h>
-#include <android-base/mapped_file.h>
#include "art_api/dex_file_external.h"
namespace art_api {
namespace dex {
-// Returns true if libdexfile_external.so is already loaded. Otherwise tries to
+#define FOR_EACH_ADEX_FILE_SYMBOL(MACRO) \
+ MACRO(ADexFile_Error_toString) \
+ MACRO(ADexFile_Method_getClassDescriptor) \
+ MACRO(ADexFile_Method_getCodeOffset) \
+ MACRO(ADexFile_Method_getName) \
+ MACRO(ADexFile_Method_getQualifiedName) \
+ MACRO(ADexFile_create) \
+ MACRO(ADexFile_destroy) \
+ MACRO(ADexFile_findMethodAtOffset) \
+ MACRO(ADexFile_forEachMethod) \
+
+#define DEFINE_ADEX_FILE_SYMBOL(DLFUNC) extern decltype(DLFUNC)* g_##DLFUNC;
+FOR_EACH_ADEX_FILE_SYMBOL(DEFINE_ADEX_FILE_SYMBOL)
+#undef DEFINE_ADEX_FILE_SYMBOL
+
+// Returns true if libdexfile.so is already loaded. Otherwise tries to
// load it and returns true if successful. Otherwise returns false and sets
-// *error_msg. If false is returned then calling any function below may abort
-// the process. Thread safe.
-bool TryLoadLibdexfileExternal(std::string* error_msg);
+// *error_msg. Thread safe.
+bool TryLoadLibdexfile(std::string* error_msg);
-// 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();
+// TryLoadLibdexfile and fatally abort process if unsuccessful.
+void LoadLibdexfile();
-using DexString = std::string;
-
-struct MethodInfo {
- uint32_t offset = 0; // Code offset relative to the start of the dex file header
- uint32_t len = 0; // Code length
- DexString name;
-};
-
-inline bool operator==(const MethodInfo& s1, const MethodInfo& s2) {
- return s1.offset == s2.offset && s1.len == s2.len && s1.name == s2.name;
-}
-
-// External stable API to access ordinary dex files and CompactDex. This wraps
-// the stable C ABI and handles instance ownership. Thread-compatible but not
-// thread-safe.
+// API for reading ordinary dex files and CompactDex files.
+// It is minimal 1:1 C++ wrapper around the C ABI.
+// See documentation in dex_file_external.h
class DexFile {
public:
- DexFile(DexFile&& dex_file) noexcept {
- std::swap(ext_dex_file_, dex_file.ext_dex_file_);
- std::swap(map_, dex_file.map_);
- }
-
- explicit DexFile(std::unique_ptr<DexFile>& dex_file) noexcept {
- std::swap(ext_dex_file_, dex_file->ext_dex_file_);
- std::swap(map_, dex_file->map_);
- dex_file.reset();
+ struct Method {
+ size_t GetCodeOffset(size_t* out_size = nullptr) const {
+ return g_ADexFile_Method_getCodeOffset(self, out_size);
+ }
+
+ const char* GetName(size_t* out_size = nullptr) const {
+ return g_ADexFile_Method_getName(self, out_size);
+ }
+
+ const char* GetQualifiedName(bool with_params = false, size_t* out_size = nullptr) const {
+ return g_ADexFile_Method_getQualifiedName(self, with_params, out_size);
+ }
+
+ const char* GetClassDescriptor(size_t* out_size = nullptr) const {
+ return g_ADexFile_Method_getClassDescriptor(self, out_size);
+ }
+
+ const ADexFile_Method* const self;
+ };
+
+ struct Error {
+ const char* ToString() const {
+ return g_ADexFile_Error_toString(self);
+ }
+
+ bool Ok() const {
+ return self == ADEXFILE_ERROR_OK;
+ }
+
+ ADexFile_Error Code() {
+ return self;
+ }
+
+ ADexFile_Error const self;
+ };
+
+ static Error Create(const void* address,
+ size_t size,
+ size_t* new_size,
+ const char* location,
+ /*out*/ std::unique_ptr<DexFile>* out_dex_file) {
+ LoadLibdexfile();
+ ADexFile* adex = nullptr;
+ ADexFile_Error error = g_ADexFile_create(address, size, new_size, location, &adex);
+ if (adex != nullptr) {
+ *out_dex_file = std::unique_ptr<DexFile>(new DexFile{adex});
+ }
+ return Error{error};
}
- virtual ~DexFile();
-
- // Interprets a chunk of memory as a dex file. As long as *size is too small,
- // returns nullptr, sets *size to a new size to try again with, and sets
- // *error_msg. That might happen repeatedly. Also returns nullptr
- // on error in which case *error_msg is set to a nonempty string.
- //
- // location is a string that describes the dex file, and is preferably its
- // path. It is mostly used to make error messages better, and may be "".
- //
- // The caller must retain the memory.
- static std::unique_ptr<DexFile> OpenFromMemory(const void* addr,
- size_t* size,
- const std::string& location,
- /*out*/ std::string* error_msg);
-
- // mmaps the given file offset in the open fd and reads a dexfile from there.
- // Returns nullptr on error in which case *error_msg is set.
- //
- // location is a string that describes the dex file, and is preferably its
- // path. It is mostly used to make error messages better, and may be "".
- static std::unique_ptr<DexFile> OpenFromFd(int fd,
- off_t offset,
- const std::string& location,
- /*out*/ std::string* error_msg);
-
- // Given an offset relative to the start of the dex file header, if there is a
- // method whose instruction range includes that offset then calls the provided
- // callback with ExtDexFileMethodInfo* (which is live only during the callback).
- template<typename T /* lambda taking (ExtDexFileMethodInfo*) */>
- void GetMethodInfoForOffset(int64_t dex_offset, T& callback, uint32_t flags = 0) {
- auto cb = [](void* ctx, ExtDexFileMethodInfo* info) { (*reinterpret_cast<T*>(ctx))(info); };
- g_ExtDexFileGetMethodInfoForOffset(ext_dex_file_, dex_offset, flags, cb, &callback);
+ virtual ~DexFile() {
+ g_ADexFile_destroy(self_);
}
- // Given an offset relative to the start of the dex file header, if there is a
- // method whose instruction range includes that offset then returns info about
- // it, otherwise returns a struct with offset == 0. MethodInfo.name receives
- // the full function signature if with_signature is set, otherwise it gets the
- // class and method name only.
- MethodInfo GetMethodInfoForOffset(int64_t dex_offset, bool with_signature);
-
- // Call the provided callback for all dex methods.
- template<typename T /* lambda taking (ExtDexFileMethodInfo*) */>
- void GetAllMethodInfos(T& callback, uint32_t flags = 0) {
- auto cb = [](void* ctx, ExtDexFileMethodInfo* info) { (*reinterpret_cast<T*>(ctx))(info); };
- g_ExtDexFileGetAllMethodInfos(ext_dex_file_, flags, cb, &callback);
+ template<typename T /* lambda which takes (const DexFile::Method&) as argument */>
+ inline size_t FindMethodAtOffset(uint32_t dex_offset, T callback) {
+ auto cb = [](void* ctx, const ADexFile_Method* m) { (*reinterpret_cast<T*>(ctx))(Method{m}); };
+ return g_ADexFile_findMethodAtOffset(self_, dex_offset, cb, &callback);
}
- // Returns info structs about all methods in the dex file. MethodInfo.name
- // receives the full function signature if with_signature is set, otherwise it
- // gets the class and method name only.
- std::vector<MethodInfo> GetAllMethodInfos(bool with_signature);
-
- private:
- static inline MethodInfo AbsorbMethodInfo(const ExtDexFileMethodInfo* info) {
- return {
- .offset = info->addr,
- .len = info->size,
- .name = std::string(info->name, info->name_size)
- };
+ template<typename T /* lambda which takes (const DexFile::Method&) as argument */>
+ inline size_t ForEachMethod(T callback) {
+ auto cb = [](void* ctx, const ADexFile_Method* m) { (*reinterpret_cast<T*>(ctx))(Method{m}); };
+ return g_ADexFile_forEachMethod(self_, cb, &callback);
}
- friend bool TryLoadLibdexfileExternal(std::string* error_msg);
- explicit DexFile(ExtDexFile* ext_dex_file) : ext_dex_file_(ext_dex_file) {}
- ExtDexFile* ext_dex_file_ = nullptr; // Owned instance. nullptr only in moved-from zombies.
- std::unique_ptr<android::base::MappedFile> map_; // Owned map (if we allocated one).
+ protected:
+ explicit DexFile(ADexFile* self) : self_(self) {}
- // These are initialized by TryLoadLibdexfileExternal.
- static decltype(ExtDexFileOpenFromMemory)* g_ExtDexFileOpenFromMemory;
- static decltype(ExtDexFileGetMethodInfoForOffset)* g_ExtDexFileGetMethodInfoForOffset;
- static decltype(ExtDexFileGetAllMethodInfos)* g_ExtDexFileGetAllMethodInfos;
- static decltype(ExtDexFileClose)* g_ExtDexFileClose;
+ ADexFile* const self_;
DISALLOW_COPY_AND_ASSIGN(DexFile);
};