1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
|
/*
* Copyright (C) 2019 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef ART_LIBDEXFILE_EXTERNAL_INCLUDE_ART_API_DEX_FILE_SUPPORT_H_
#define ART_LIBDEXFILE_EXTERNAL_INCLUDE_ART_API_DEX_FILE_SUPPORT_H_
// C++ wrapper for the dex file external API.
#include <memory>
#include <string>
#include <android-base/macros.h>
#include "art_api/dex_file_external.h"
namespace art_api {
namespace dex {
#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. Thread safe.
bool TryLoadLibdexfile(std::string* error_msg);
// TryLoadLibdexfile and fatally abort process if unsuccessful.
void LoadLibdexfile();
// 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:
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() {
g_ADexFile_destroy(self_);
}
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);
}
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);
}
protected:
explicit DexFile(ADexFile* self) : self_(self) {}
ADexFile* const self_;
DISALLOW_COPY_AND_ASSIGN(DexFile);
};
} // namespace dex
} // namespace art_api
#endif // ART_LIBDEXFILE_EXTERNAL_INCLUDE_ART_API_DEX_FILE_SUPPORT_H_
|