1 /* 2 * Copyright (C) 2019 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #ifndef ART_LIBDEXFILE_EXTERNAL_INCLUDE_ART_API_DEX_FILE_SUPPORT_H_ 18 #define ART_LIBDEXFILE_EXTERNAL_INCLUDE_ART_API_DEX_FILE_SUPPORT_H_ 19 20 // C++ wrapper for the dex file external API. 21 22 #include <memory> 23 #include <string> 24 25 #include "art_api/dex_file_external.h" 26 27 namespace art_api { 28 namespace dex { 29 30 #define FOR_EACH_ADEX_FILE_SYMBOL(MACRO) \ 31 MACRO(ADexFile_Error_toString) \ 32 MACRO(ADexFile_Method_getClassDescriptor) \ 33 MACRO(ADexFile_Method_getCodeOffset) \ 34 MACRO(ADexFile_Method_getName) \ 35 MACRO(ADexFile_Method_getQualifiedName) \ 36 MACRO(ADexFile_create) \ 37 MACRO(ADexFile_destroy) \ 38 MACRO(ADexFile_findMethodAtOffset) \ 39 MACRO(ADexFile_forEachMethod) \ 40 41 #define DEFINE_ADEX_FILE_SYMBOL(DLFUNC) extern decltype(DLFUNC)* g_##DLFUNC; 42 FOR_EACH_ADEX_FILE_SYMBOL(DEFINE_ADEX_FILE_SYMBOL) 43 #undef DEFINE_ADEX_FILE_SYMBOL 44 45 // Returns true if libdexfile.so is already loaded. Otherwise tries to 46 // load it and returns true if successful. Otherwise returns false and sets 47 // *error_msg. Thread safe. 48 bool TryLoadLibdexfile(std::string* error_msg); 49 50 // TryLoadLibdexfile and fatally abort process if unsuccessful. 51 void LoadLibdexfile(); 52 53 // API for reading ordinary dex files and CompactDex files. 54 // It is minimal 1:1 C++ wrapper around the C ABI. 55 // See documentation in dex_file_external.h 56 class DexFile { 57 public: 58 struct Method { 59 size_t GetCodeOffset(size_t* out_size = nullptr) const { 60 return g_ADexFile_Method_getCodeOffset(self, out_size); 61 } 62 63 const char* GetName(size_t* out_size = nullptr) const { 64 return g_ADexFile_Method_getName(self, out_size); 65 } 66 67 const char* GetQualifiedName(bool with_params = false, size_t* out_size = nullptr) const { 68 return g_ADexFile_Method_getQualifiedName(self, with_params, out_size); 69 } 70 71 const char* GetClassDescriptor(size_t* out_size = nullptr) const { 72 return g_ADexFile_Method_getClassDescriptor(self, out_size); 73 } 74 75 const ADexFile_Method* const self; 76 }; 77 78 struct Error { ToStringError79 const char* ToString() const { 80 return g_ADexFile_Error_toString(self); 81 } 82 OkError83 bool Ok() const { 84 return self == ADEXFILE_ERROR_OK; 85 } 86 CodeError87 ADexFile_Error Code() { 88 return self; 89 } 90 91 ADexFile_Error const self; 92 }; 93 Create(const void * address,size_t size,size_t * new_size,const char * location,std::unique_ptr<DexFile> * out_dex_file)94 static Error Create(const void* address, 95 size_t size, 96 size_t* new_size, 97 const char* location, 98 /*out*/ std::unique_ptr<DexFile>* out_dex_file) { 99 LoadLibdexfile(); 100 ADexFile* adex = nullptr; 101 ADexFile_Error error = g_ADexFile_create(address, size, new_size, location, &adex); 102 if (adex != nullptr) { 103 *out_dex_file = std::unique_ptr<DexFile>(new DexFile{adex}); 104 } 105 return Error{error}; 106 } 107 ~DexFile()108 virtual ~DexFile() { 109 g_ADexFile_destroy(self_); 110 } 111 112 template<typename T /* lambda which takes (const DexFile::Method&) as argument */> FindMethodAtOffset(uint32_t dex_offset,T callback)113 inline size_t FindMethodAtOffset(uint32_t dex_offset, T callback) { 114 auto cb = [](void* ctx, const ADexFile_Method* m) { (*reinterpret_cast<T*>(ctx))(Method{m}); }; 115 return g_ADexFile_findMethodAtOffset(self_, dex_offset, cb, &callback); 116 } 117 118 template<typename T /* lambda which takes (const DexFile::Method&) as argument */> ForEachMethod(T callback)119 inline size_t ForEachMethod(T callback) { 120 auto cb = [](void* ctx, const ADexFile_Method* m) { (*reinterpret_cast<T*>(ctx))(Method{m}); }; 121 return g_ADexFile_forEachMethod(self_, cb, &callback); 122 } 123 124 protected: DexFile(ADexFile * self)125 explicit DexFile(ADexFile* self) : self_(self) {} 126 127 ADexFile* const self_; 128 129 // Have to expand DISALLOW_COPY_AND_ASSIGN here, since we cannot depend on 130 // libbase headers without re-exporting them, and that may make them override 131 // the non-ABI compatible headers that the libdexfile_support user may have. 132 DexFile(const DexFile&) = delete; 133 void operator=(const DexFile&) = delete; 134 }; 135 136 } // namespace dex 137 } // namespace art_api 138 139 #endif // ART_LIBDEXFILE_EXTERNAL_INCLUDE_ART_API_DEX_FILE_SUPPORT_H_ 140