1*795d594fSAndroid Build Coastguard Worker /*
2*795d594fSAndroid Build Coastguard Worker * Copyright (C) 2011 The Android Open Source Project
3*795d594fSAndroid Build Coastguard Worker *
4*795d594fSAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License");
5*795d594fSAndroid Build Coastguard Worker * you may not use this file except in compliance with the License.
6*795d594fSAndroid Build Coastguard Worker * You may obtain a copy of the License at
7*795d594fSAndroid Build Coastguard Worker *
8*795d594fSAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0
9*795d594fSAndroid Build Coastguard Worker *
10*795d594fSAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software
11*795d594fSAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS,
12*795d594fSAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*795d594fSAndroid Build Coastguard Worker * See the License for the specific language governing permissions and
14*795d594fSAndroid Build Coastguard Worker * limitations under the License.
15*795d594fSAndroid Build Coastguard Worker */
16*795d594fSAndroid Build Coastguard Worker
17*795d594fSAndroid Build Coastguard Worker #ifndef ART_LIBDEXFILE_DEX_DEX_FILE_INL_H_
18*795d594fSAndroid Build Coastguard Worker #define ART_LIBDEXFILE_DEX_DEX_FILE_INL_H_
19*795d594fSAndroid Build Coastguard Worker
20*795d594fSAndroid Build Coastguard Worker #include "dex_file.h"
21*795d594fSAndroid Build Coastguard Worker
22*795d594fSAndroid Build Coastguard Worker #include "base/casts.h"
23*795d594fSAndroid Build Coastguard Worker #include "base/iteration_range.h"
24*795d594fSAndroid Build Coastguard Worker #include "base/leb128.h"
25*795d594fSAndroid Build Coastguard Worker #include "base/utils.h"
26*795d594fSAndroid Build Coastguard Worker #include "class_iterator.h"
27*795d594fSAndroid Build Coastguard Worker #include "compact_dex_file.h"
28*795d594fSAndroid Build Coastguard Worker #include "dex_instruction_iterator.h"
29*795d594fSAndroid Build Coastguard Worker #include "invoke_type.h"
30*795d594fSAndroid Build Coastguard Worker #include "signature.h"
31*795d594fSAndroid Build Coastguard Worker #include "standard_dex_file.h"
32*795d594fSAndroid Build Coastguard Worker
33*795d594fSAndroid Build Coastguard Worker namespace art {
34*795d594fSAndroid Build Coastguard Worker
CompareDescriptors(std::string_view lhs,std::string_view rhs)35*795d594fSAndroid Build Coastguard Worker inline int DexFile::CompareDescriptors(std::string_view lhs, std::string_view rhs) {
36*795d594fSAndroid Build Coastguard Worker // Note: `std::string_view::compare()` uses lexicographical comparison and treats the `char`
37*795d594fSAndroid Build Coastguard Worker // as unsigned; for Modified-UTF-8 without embedded nulls this is consistent with the
38*795d594fSAndroid Build Coastguard Worker // `CompareModifiedUtf8ToModifiedUtf8AsUtf16CodePointValues()` ordering.
39*795d594fSAndroid Build Coastguard Worker return lhs.compare(rhs);
40*795d594fSAndroid Build Coastguard Worker }
41*795d594fSAndroid Build Coastguard Worker
CompareMemberNames(std::string_view lhs,std::string_view rhs)42*795d594fSAndroid Build Coastguard Worker inline int DexFile::CompareMemberNames(std::string_view lhs, std::string_view rhs) {
43*795d594fSAndroid Build Coastguard Worker // Note: `std::string_view::compare()` uses lexicographical comparison and treats the `char`
44*795d594fSAndroid Build Coastguard Worker // as unsigned; for Modified-UTF-8 without embedded nulls this is consistent with the
45*795d594fSAndroid Build Coastguard Worker // `CompareModifiedUtf8ToModifiedUtf8AsUtf16CodePointValues()` ordering.
46*795d594fSAndroid Build Coastguard Worker return lhs.compare(rhs);
47*795d594fSAndroid Build Coastguard Worker }
48*795d594fSAndroid Build Coastguard Worker
Utf8Length(const char * utf8_data,size_t utf16_length)49*795d594fSAndroid Build Coastguard Worker inline size_t DexFile::Utf8Length(const char* utf8_data, size_t utf16_length) {
50*795d594fSAndroid Build Coastguard Worker return LIKELY(utf8_data[utf16_length] == 0) // Is ASCII?
51*795d594fSAndroid Build Coastguard Worker ? utf16_length
52*795d594fSAndroid Build Coastguard Worker : utf16_length + strlen(utf8_data + utf16_length);
53*795d594fSAndroid Build Coastguard Worker }
54*795d594fSAndroid Build Coastguard Worker
StringViewFromUtf16Length(const char * utf8_data,size_t utf16_length)55*795d594fSAndroid Build Coastguard Worker inline std::string_view DexFile::StringViewFromUtf16Length(const char* utf8_data,
56*795d594fSAndroid Build Coastguard Worker size_t utf16_length) {
57*795d594fSAndroid Build Coastguard Worker return std::string_view(utf8_data, Utf8Length(utf8_data, utf16_length));
58*795d594fSAndroid Build Coastguard Worker }
59*795d594fSAndroid Build Coastguard Worker
60*795d594fSAndroid Build Coastguard Worker ALWAYS_INLINE
GetStringDataAndUtf16Length(const dex::StringId & string_id,uint32_t * utf16_length)61*795d594fSAndroid Build Coastguard Worker inline const char* DexFile::GetStringDataAndUtf16Length(const dex::StringId& string_id,
62*795d594fSAndroid Build Coastguard Worker uint32_t* utf16_length) const {
63*795d594fSAndroid Build Coastguard Worker DCHECK(utf16_length != nullptr) << GetLocation();
64*795d594fSAndroid Build Coastguard Worker const uint8_t* ptr = DataBegin() + string_id.string_data_off_;
65*795d594fSAndroid Build Coastguard Worker *utf16_length = DecodeUnsignedLeb128(&ptr);
66*795d594fSAndroid Build Coastguard Worker return reinterpret_cast<const char*>(ptr);
67*795d594fSAndroid Build Coastguard Worker }
68*795d594fSAndroid Build Coastguard Worker
69*795d594fSAndroid Build Coastguard Worker ALWAYS_INLINE
GetStringDataAndUtf16Length(const dex::StringIndex string_idx,uint32_t * utf16_length)70*795d594fSAndroid Build Coastguard Worker inline const char* DexFile::GetStringDataAndUtf16Length(const dex::StringIndex string_idx,
71*795d594fSAndroid Build Coastguard Worker uint32_t* utf16_length) const {
72*795d594fSAndroid Build Coastguard Worker return GetStringDataAndUtf16Length(GetStringId(string_idx), utf16_length);
73*795d594fSAndroid Build Coastguard Worker }
74*795d594fSAndroid Build Coastguard Worker
75*795d594fSAndroid Build Coastguard Worker ALWAYS_INLINE
GetStringUtf16Length(const dex::StringId & string_id)76*795d594fSAndroid Build Coastguard Worker inline uint32_t DexFile::GetStringUtf16Length(const dex::StringId& string_id) const {
77*795d594fSAndroid Build Coastguard Worker uint32_t utf16_length;
78*795d594fSAndroid Build Coastguard Worker GetStringDataAndUtf16Length(string_id, &utf16_length);
79*795d594fSAndroid Build Coastguard Worker return utf16_length;
80*795d594fSAndroid Build Coastguard Worker }
81*795d594fSAndroid Build Coastguard Worker
82*795d594fSAndroid Build Coastguard Worker ALWAYS_INLINE
GetStringData(const dex::StringId & string_id)83*795d594fSAndroid Build Coastguard Worker inline const char* DexFile::GetStringData(const dex::StringId& string_id) const {
84*795d594fSAndroid Build Coastguard Worker uint32_t ignored;
85*795d594fSAndroid Build Coastguard Worker return GetStringDataAndUtf16Length(string_id, &ignored);
86*795d594fSAndroid Build Coastguard Worker }
87*795d594fSAndroid Build Coastguard Worker
88*795d594fSAndroid Build Coastguard Worker ALWAYS_INLINE
GetStringData(dex::StringIndex string_idx)89*795d594fSAndroid Build Coastguard Worker inline const char* DexFile::GetStringData(dex::StringIndex string_idx) const {
90*795d594fSAndroid Build Coastguard Worker return GetStringData(GetStringId(string_idx));
91*795d594fSAndroid Build Coastguard Worker }
92*795d594fSAndroid Build Coastguard Worker
93*795d594fSAndroid Build Coastguard Worker ALWAYS_INLINE
GetStringView(const dex::StringId & string_id)94*795d594fSAndroid Build Coastguard Worker inline std::string_view DexFile::GetStringView(const dex::StringId& string_id) const {
95*795d594fSAndroid Build Coastguard Worker uint32_t utf16_length;
96*795d594fSAndroid Build Coastguard Worker const char* data = GetStringDataAndUtf16Length(string_id, &utf16_length);
97*795d594fSAndroid Build Coastguard Worker return StringViewFromUtf16Length(data, utf16_length);
98*795d594fSAndroid Build Coastguard Worker }
99*795d594fSAndroid Build Coastguard Worker
100*795d594fSAndroid Build Coastguard Worker ALWAYS_INLINE
GetStringView(dex::StringIndex string_idx)101*795d594fSAndroid Build Coastguard Worker inline std::string_view DexFile::GetStringView(dex::StringIndex string_idx) const {
102*795d594fSAndroid Build Coastguard Worker return GetStringView(GetStringId(string_idx));
103*795d594fSAndroid Build Coastguard Worker }
104*795d594fSAndroid Build Coastguard Worker
GetTypeDescriptor(const dex::TypeId & type_id)105*795d594fSAndroid Build Coastguard Worker inline const char* DexFile::GetTypeDescriptor(const dex::TypeId& type_id) const {
106*795d594fSAndroid Build Coastguard Worker return GetStringData(type_id.descriptor_idx_);
107*795d594fSAndroid Build Coastguard Worker }
108*795d594fSAndroid Build Coastguard Worker
GetTypeDescriptor(dex::TypeIndex type_idx)109*795d594fSAndroid Build Coastguard Worker inline const char* DexFile::GetTypeDescriptor(dex::TypeIndex type_idx) const {
110*795d594fSAndroid Build Coastguard Worker return GetTypeDescriptor(GetTypeId(type_idx));
111*795d594fSAndroid Build Coastguard Worker }
112*795d594fSAndroid Build Coastguard Worker
GetTypeDescriptorView(const dex::TypeId & type_id)113*795d594fSAndroid Build Coastguard Worker inline std::string_view DexFile::GetTypeDescriptorView(const dex::TypeId& type_id) const {
114*795d594fSAndroid Build Coastguard Worker return GetStringView(type_id.descriptor_idx_);
115*795d594fSAndroid Build Coastguard Worker }
116*795d594fSAndroid Build Coastguard Worker
GetTypeDescriptorView(dex::TypeIndex type_idx)117*795d594fSAndroid Build Coastguard Worker inline std::string_view DexFile::GetTypeDescriptorView(dex::TypeIndex type_idx) const {
118*795d594fSAndroid Build Coastguard Worker return GetTypeDescriptorView(GetTypeId(type_idx));
119*795d594fSAndroid Build Coastguard Worker }
120*795d594fSAndroid Build Coastguard Worker
GetFieldDeclaringClassDescriptor(const dex::FieldId & field_id)121*795d594fSAndroid Build Coastguard Worker inline const char* DexFile::GetFieldDeclaringClassDescriptor(const dex::FieldId& field_id) const {
122*795d594fSAndroid Build Coastguard Worker return GetTypeDescriptor(field_id.class_idx_);
123*795d594fSAndroid Build Coastguard Worker }
124*795d594fSAndroid Build Coastguard Worker
GetFieldDeclaringClassDescriptor(uint32_t field_idx)125*795d594fSAndroid Build Coastguard Worker inline const char* DexFile::GetFieldDeclaringClassDescriptor(uint32_t field_idx) const {
126*795d594fSAndroid Build Coastguard Worker return GetFieldDeclaringClassDescriptor(GetFieldId(field_idx));
127*795d594fSAndroid Build Coastguard Worker }
128*795d594fSAndroid Build Coastguard Worker
GetFieldDeclaringClassDescriptorView(const dex::FieldId & field_id)129*795d594fSAndroid Build Coastguard Worker inline std::string_view DexFile::GetFieldDeclaringClassDescriptorView(
130*795d594fSAndroid Build Coastguard Worker const dex::FieldId& field_id) const {
131*795d594fSAndroid Build Coastguard Worker return GetTypeDescriptorView(field_id.class_idx_);
132*795d594fSAndroid Build Coastguard Worker }
133*795d594fSAndroid Build Coastguard Worker
GetFieldDeclaringClassDescriptorView(uint32_t field_idx)134*795d594fSAndroid Build Coastguard Worker inline std::string_view DexFile::GetFieldDeclaringClassDescriptorView(uint32_t field_idx) const {
135*795d594fSAndroid Build Coastguard Worker return GetFieldDeclaringClassDescriptorView(GetFieldId(field_idx));
136*795d594fSAndroid Build Coastguard Worker }
137*795d594fSAndroid Build Coastguard Worker
GetFieldTypeDescriptor(const dex::FieldId & field_id)138*795d594fSAndroid Build Coastguard Worker inline const char* DexFile::GetFieldTypeDescriptor(const dex::FieldId& field_id) const {
139*795d594fSAndroid Build Coastguard Worker return GetTypeDescriptor(field_id.type_idx_);
140*795d594fSAndroid Build Coastguard Worker }
141*795d594fSAndroid Build Coastguard Worker
GetFieldTypeDescriptor(uint32_t field_idx)142*795d594fSAndroid Build Coastguard Worker inline const char* DexFile::GetFieldTypeDescriptor(uint32_t field_idx) const {
143*795d594fSAndroid Build Coastguard Worker return GetFieldTypeDescriptor(GetFieldId(field_idx));
144*795d594fSAndroid Build Coastguard Worker }
145*795d594fSAndroid Build Coastguard Worker
GetFieldTypeDescriptorView(const dex::FieldId & field_id)146*795d594fSAndroid Build Coastguard Worker inline std::string_view DexFile::GetFieldTypeDescriptorView(const dex::FieldId& field_id) const {
147*795d594fSAndroid Build Coastguard Worker return GetTypeDescriptorView(field_id.type_idx_);
148*795d594fSAndroid Build Coastguard Worker }
149*795d594fSAndroid Build Coastguard Worker
GetFieldTypeDescriptorView(uint32_t field_idx)150*795d594fSAndroid Build Coastguard Worker inline std::string_view DexFile::GetFieldTypeDescriptorView(uint32_t field_idx) const {
151*795d594fSAndroid Build Coastguard Worker return GetFieldTypeDescriptorView(GetFieldId(field_idx));
152*795d594fSAndroid Build Coastguard Worker }
153*795d594fSAndroid Build Coastguard Worker
GetFieldName(const dex::FieldId & field_id)154*795d594fSAndroid Build Coastguard Worker inline const char* DexFile::GetFieldName(const dex::FieldId& field_id) const {
155*795d594fSAndroid Build Coastguard Worker return GetStringData(field_id.name_idx_);
156*795d594fSAndroid Build Coastguard Worker }
157*795d594fSAndroid Build Coastguard Worker
GetFieldName(uint32_t field_idx)158*795d594fSAndroid Build Coastguard Worker inline const char* DexFile::GetFieldName(uint32_t field_idx) const {
159*795d594fSAndroid Build Coastguard Worker return GetFieldName(GetFieldId(field_idx));
160*795d594fSAndroid Build Coastguard Worker }
161*795d594fSAndroid Build Coastguard Worker
GetFieldNameView(const dex::FieldId & field_id)162*795d594fSAndroid Build Coastguard Worker inline std::string_view DexFile::GetFieldNameView(const dex::FieldId& field_id) const {
163*795d594fSAndroid Build Coastguard Worker return GetStringView(field_id.name_idx_);
164*795d594fSAndroid Build Coastguard Worker }
165*795d594fSAndroid Build Coastguard Worker
GetFieldNameView(uint32_t field_idx)166*795d594fSAndroid Build Coastguard Worker inline std::string_view DexFile::GetFieldNameView(uint32_t field_idx) const {
167*795d594fSAndroid Build Coastguard Worker return GetFieldNameView(GetFieldId(field_idx));
168*795d594fSAndroid Build Coastguard Worker }
169*795d594fSAndroid Build Coastguard Worker
GetMethodDeclaringClassDescriptor(const dex::MethodId & method_id)170*795d594fSAndroid Build Coastguard Worker inline const char* DexFile::GetMethodDeclaringClassDescriptor(
171*795d594fSAndroid Build Coastguard Worker const dex::MethodId& method_id) const {
172*795d594fSAndroid Build Coastguard Worker return GetTypeDescriptor(method_id.class_idx_);
173*795d594fSAndroid Build Coastguard Worker }
174*795d594fSAndroid Build Coastguard Worker
GetMethodDeclaringClassDescriptor(uint32_t method_idx)175*795d594fSAndroid Build Coastguard Worker inline const char* DexFile::GetMethodDeclaringClassDescriptor(uint32_t method_idx) const {
176*795d594fSAndroid Build Coastguard Worker return GetMethodDeclaringClassDescriptor(GetMethodId(method_idx));
177*795d594fSAndroid Build Coastguard Worker }
178*795d594fSAndroid Build Coastguard Worker
GetMethodDeclaringClassDescriptorView(const dex::MethodId & method_id)179*795d594fSAndroid Build Coastguard Worker inline std::string_view DexFile::GetMethodDeclaringClassDescriptorView(
180*795d594fSAndroid Build Coastguard Worker const dex::MethodId& method_id) const {
181*795d594fSAndroid Build Coastguard Worker return GetTypeDescriptorView(method_id.class_idx_);
182*795d594fSAndroid Build Coastguard Worker }
183*795d594fSAndroid Build Coastguard Worker
GetMethodDeclaringClassDescriptorView(uint32_t method_idx)184*795d594fSAndroid Build Coastguard Worker inline std::string_view DexFile::GetMethodDeclaringClassDescriptorView(uint32_t method_idx) const {
185*795d594fSAndroid Build Coastguard Worker return GetMethodDeclaringClassDescriptorView(GetMethodId(method_idx));
186*795d594fSAndroid Build Coastguard Worker }
187*795d594fSAndroid Build Coastguard Worker
GetMethodSignature(const dex::MethodId & method_id)188*795d594fSAndroid Build Coastguard Worker inline const Signature DexFile::GetMethodSignature(const dex::MethodId& method_id) const {
189*795d594fSAndroid Build Coastguard Worker return Signature(this, GetProtoId(method_id.proto_idx_));
190*795d594fSAndroid Build Coastguard Worker }
191*795d594fSAndroid Build Coastguard Worker
GetProtoSignature(const dex::ProtoId & proto_id)192*795d594fSAndroid Build Coastguard Worker inline const Signature DexFile::GetProtoSignature(const dex::ProtoId& proto_id) const {
193*795d594fSAndroid Build Coastguard Worker return Signature(this, proto_id);
194*795d594fSAndroid Build Coastguard Worker }
195*795d594fSAndroid Build Coastguard Worker
GetMethodName(const dex::MethodId & method_id)196*795d594fSAndroid Build Coastguard Worker inline const char* DexFile::GetMethodName(const dex::MethodId& method_id) const {
197*795d594fSAndroid Build Coastguard Worker return GetStringData(method_id.name_idx_);
198*795d594fSAndroid Build Coastguard Worker }
199*795d594fSAndroid Build Coastguard Worker
GetMethodName(const dex::MethodId & method_id,uint32_t * utf_length)200*795d594fSAndroid Build Coastguard Worker inline const char* DexFile::GetMethodName(const dex::MethodId& method_id, uint32_t* utf_length)
201*795d594fSAndroid Build Coastguard Worker const {
202*795d594fSAndroid Build Coastguard Worker return GetStringDataAndUtf16Length(method_id.name_idx_, utf_length);
203*795d594fSAndroid Build Coastguard Worker }
204*795d594fSAndroid Build Coastguard Worker
GetMethodName(uint32_t method_idx)205*795d594fSAndroid Build Coastguard Worker inline const char* DexFile::GetMethodName(uint32_t method_idx) const {
206*795d594fSAndroid Build Coastguard Worker return GetStringData(GetMethodId(method_idx).name_idx_);
207*795d594fSAndroid Build Coastguard Worker }
208*795d594fSAndroid Build Coastguard Worker
GetMethodName(uint32_t idx,uint32_t * utf_length)209*795d594fSAndroid Build Coastguard Worker inline const char* DexFile::GetMethodName(uint32_t idx, uint32_t* utf_length) const {
210*795d594fSAndroid Build Coastguard Worker return GetStringDataAndUtf16Length(GetMethodId(idx).name_idx_, utf_length);
211*795d594fSAndroid Build Coastguard Worker }
212*795d594fSAndroid Build Coastguard Worker
213*795d594fSAndroid Build Coastguard Worker ALWAYS_INLINE
GetMethodNameView(const dex::MethodId & method_id)214*795d594fSAndroid Build Coastguard Worker inline std::string_view DexFile::GetMethodNameView(const dex::MethodId& method_id) const {
215*795d594fSAndroid Build Coastguard Worker return GetStringView(method_id.name_idx_);
216*795d594fSAndroid Build Coastguard Worker }
217*795d594fSAndroid Build Coastguard Worker
218*795d594fSAndroid Build Coastguard Worker ALWAYS_INLINE
GetMethodNameView(uint32_t method_idx)219*795d594fSAndroid Build Coastguard Worker inline std::string_view DexFile::GetMethodNameView(uint32_t method_idx) const {
220*795d594fSAndroid Build Coastguard Worker return GetMethodNameView(GetMethodId(method_idx));
221*795d594fSAndroid Build Coastguard Worker }
222*795d594fSAndroid Build Coastguard Worker
GetMethodShorty(uint32_t idx)223*795d594fSAndroid Build Coastguard Worker inline const char* DexFile::GetMethodShorty(uint32_t idx) const {
224*795d594fSAndroid Build Coastguard Worker return GetMethodShorty(GetMethodId(idx));
225*795d594fSAndroid Build Coastguard Worker }
226*795d594fSAndroid Build Coastguard Worker
GetMethodShortyView(uint32_t idx)227*795d594fSAndroid Build Coastguard Worker inline std::string_view DexFile::GetMethodShortyView(uint32_t idx) const {
228*795d594fSAndroid Build Coastguard Worker return GetMethodShortyView(GetMethodId(idx));
229*795d594fSAndroid Build Coastguard Worker }
230*795d594fSAndroid Build Coastguard Worker
GetMethodShorty(const dex::MethodId & method_id)231*795d594fSAndroid Build Coastguard Worker inline const char* DexFile::GetMethodShorty(const dex::MethodId& method_id) const {
232*795d594fSAndroid Build Coastguard Worker return GetStringData(GetProtoId(method_id.proto_idx_).shorty_idx_);
233*795d594fSAndroid Build Coastguard Worker }
234*795d594fSAndroid Build Coastguard Worker
GetMethodShorty(const dex::MethodId & method_id,uint32_t * length)235*795d594fSAndroid Build Coastguard Worker inline const char* DexFile::GetMethodShorty(const dex::MethodId& method_id, uint32_t* length)
236*795d594fSAndroid Build Coastguard Worker const {
237*795d594fSAndroid Build Coastguard Worker // Using the UTF16 length is safe here as shorties are guaranteed to be ASCII characters.
238*795d594fSAndroid Build Coastguard Worker return GetStringDataAndUtf16Length(GetProtoId(method_id.proto_idx_).shorty_idx_, length);
239*795d594fSAndroid Build Coastguard Worker }
240*795d594fSAndroid Build Coastguard Worker
GetMethodShortyView(const dex::MethodId & method_id)241*795d594fSAndroid Build Coastguard Worker inline std::string_view DexFile::GetMethodShortyView(const dex::MethodId& method_id) const {
242*795d594fSAndroid Build Coastguard Worker return GetShortyView(method_id.proto_idx_);
243*795d594fSAndroid Build Coastguard Worker }
244*795d594fSAndroid Build Coastguard Worker
GetClassDescriptor(const dex::ClassDef & class_def)245*795d594fSAndroid Build Coastguard Worker inline const char* DexFile::GetClassDescriptor(const dex::ClassDef& class_def) const {
246*795d594fSAndroid Build Coastguard Worker return GetTypeDescriptor(class_def.class_idx_);
247*795d594fSAndroid Build Coastguard Worker }
248*795d594fSAndroid Build Coastguard Worker
GetReturnTypeDescriptor(const dex::ProtoId & proto_id)249*795d594fSAndroid Build Coastguard Worker inline const char* DexFile::GetReturnTypeDescriptor(const dex::ProtoId& proto_id) const {
250*795d594fSAndroid Build Coastguard Worker return GetTypeDescriptor(proto_id.return_type_idx_);
251*795d594fSAndroid Build Coastguard Worker }
252*795d594fSAndroid Build Coastguard Worker
GetShorty(dex::ProtoIndex proto_idx)253*795d594fSAndroid Build Coastguard Worker inline const char* DexFile::GetShorty(dex::ProtoIndex proto_idx) const {
254*795d594fSAndroid Build Coastguard Worker const dex::ProtoId& proto_id = GetProtoId(proto_idx);
255*795d594fSAndroid Build Coastguard Worker return GetStringData(proto_id.shorty_idx_);
256*795d594fSAndroid Build Coastguard Worker }
257*795d594fSAndroid Build Coastguard Worker
258*795d594fSAndroid Build Coastguard Worker ALWAYS_INLINE
GetShortyView(dex::ProtoIndex proto_idx)259*795d594fSAndroid Build Coastguard Worker inline std::string_view DexFile::GetShortyView(dex::ProtoIndex proto_idx) const {
260*795d594fSAndroid Build Coastguard Worker return GetShortyView(GetProtoId(proto_idx));
261*795d594fSAndroid Build Coastguard Worker }
262*795d594fSAndroid Build Coastguard Worker
263*795d594fSAndroid Build Coastguard Worker ALWAYS_INLINE
GetShortyView(const dex::ProtoId & proto_id)264*795d594fSAndroid Build Coastguard Worker inline std::string_view DexFile::GetShortyView(const dex::ProtoId& proto_id) const {
265*795d594fSAndroid Build Coastguard Worker uint32_t shorty_len;
266*795d594fSAndroid Build Coastguard Worker const char* shorty_data = GetStringDataAndUtf16Length(proto_id.shorty_idx_, &shorty_len);
267*795d594fSAndroid Build Coastguard Worker DCHECK_EQ(shorty_data[shorty_len], '\0'); // For a shorty utf16 length == mutf8 length.
268*795d594fSAndroid Build Coastguard Worker return std::string_view(shorty_data, shorty_len);
269*795d594fSAndroid Build Coastguard Worker }
270*795d594fSAndroid Build Coastguard Worker
GetTryItems(const DexInstructionIterator & code_item_end,uint32_t offset)271*795d594fSAndroid Build Coastguard Worker inline const dex::TryItem* DexFile::GetTryItems(const DexInstructionIterator& code_item_end,
272*795d594fSAndroid Build Coastguard Worker uint32_t offset) {
273*795d594fSAndroid Build Coastguard Worker return reinterpret_cast<const dex::TryItem*>
274*795d594fSAndroid Build Coastguard Worker (RoundUp(reinterpret_cast<uintptr_t>(&code_item_end.Inst()), dex::TryItem::kAlignment)) +
275*795d594fSAndroid Build Coastguard Worker offset;
276*795d594fSAndroid Build Coastguard Worker }
277*795d594fSAndroid Build Coastguard Worker
StringEquals(const DexFile * df1,dex::StringIndex sidx1,const DexFile * df2,dex::StringIndex sidx2)278*795d594fSAndroid Build Coastguard Worker inline bool DexFile::StringEquals(const DexFile* df1, dex::StringIndex sidx1,
279*795d594fSAndroid Build Coastguard Worker const DexFile* df2, dex::StringIndex sidx2) {
280*795d594fSAndroid Build Coastguard Worker uint32_t s1_len; // Note: utf16 length != mutf8 length.
281*795d594fSAndroid Build Coastguard Worker const char* s1_data = df1->GetStringDataAndUtf16Length(sidx1, &s1_len);
282*795d594fSAndroid Build Coastguard Worker uint32_t s2_len;
283*795d594fSAndroid Build Coastguard Worker const char* s2_data = df2->GetStringDataAndUtf16Length(sidx2, &s2_len);
284*795d594fSAndroid Build Coastguard Worker return (s1_len == s2_len) && (strcmp(s1_data, s2_data) == 0);
285*795d594fSAndroid Build Coastguard Worker }
286*795d594fSAndroid Build Coastguard Worker
287*795d594fSAndroid Build Coastguard Worker template<typename NewLocalCallback, typename IndexToStringData, typename TypeIndexToStringData>
DecodeDebugLocalInfo(const uint8_t * stream,const std::string & location,const char * declaring_class_descriptor,const std::vector<const char * > & arg_descriptors,const std::string & method_name,bool is_static,uint16_t registers_size,uint16_t ins_size,uint16_t insns_size_in_code_units,const IndexToStringData & index_to_string_data,const TypeIndexToStringData & type_index_to_string_data,const NewLocalCallback & new_local_callback)288*795d594fSAndroid Build Coastguard Worker bool DexFile::DecodeDebugLocalInfo(const uint8_t* stream,
289*795d594fSAndroid Build Coastguard Worker const std::string& location,
290*795d594fSAndroid Build Coastguard Worker const char* declaring_class_descriptor,
291*795d594fSAndroid Build Coastguard Worker const std::vector<const char*>& arg_descriptors,
292*795d594fSAndroid Build Coastguard Worker const std::string& method_name,
293*795d594fSAndroid Build Coastguard Worker bool is_static,
294*795d594fSAndroid Build Coastguard Worker uint16_t registers_size,
295*795d594fSAndroid Build Coastguard Worker uint16_t ins_size,
296*795d594fSAndroid Build Coastguard Worker uint16_t insns_size_in_code_units,
297*795d594fSAndroid Build Coastguard Worker const IndexToStringData& index_to_string_data,
298*795d594fSAndroid Build Coastguard Worker const TypeIndexToStringData& type_index_to_string_data,
299*795d594fSAndroid Build Coastguard Worker const NewLocalCallback& new_local_callback) {
300*795d594fSAndroid Build Coastguard Worker if (stream == nullptr) {
301*795d594fSAndroid Build Coastguard Worker return false;
302*795d594fSAndroid Build Coastguard Worker }
303*795d594fSAndroid Build Coastguard Worker std::vector<LocalInfo> local_in_reg(registers_size);
304*795d594fSAndroid Build Coastguard Worker
305*795d594fSAndroid Build Coastguard Worker uint16_t arg_reg = registers_size - ins_size;
306*795d594fSAndroid Build Coastguard Worker if (!is_static) {
307*795d594fSAndroid Build Coastguard Worker const char* descriptor = declaring_class_descriptor;
308*795d594fSAndroid Build Coastguard Worker local_in_reg[arg_reg].name_ = "this";
309*795d594fSAndroid Build Coastguard Worker local_in_reg[arg_reg].descriptor_ = descriptor;
310*795d594fSAndroid Build Coastguard Worker local_in_reg[arg_reg].signature_ = nullptr;
311*795d594fSAndroid Build Coastguard Worker local_in_reg[arg_reg].start_address_ = 0;
312*795d594fSAndroid Build Coastguard Worker local_in_reg[arg_reg].reg_ = arg_reg;
313*795d594fSAndroid Build Coastguard Worker local_in_reg[arg_reg].is_live_ = true;
314*795d594fSAndroid Build Coastguard Worker arg_reg++;
315*795d594fSAndroid Build Coastguard Worker }
316*795d594fSAndroid Build Coastguard Worker
317*795d594fSAndroid Build Coastguard Worker DecodeUnsignedLeb128(&stream); // Line.
318*795d594fSAndroid Build Coastguard Worker uint32_t parameters_size = DecodeUnsignedLeb128(&stream);
319*795d594fSAndroid Build Coastguard Worker uint32_t i;
320*795d594fSAndroid Build Coastguard Worker if (parameters_size != arg_descriptors.size()) {
321*795d594fSAndroid Build Coastguard Worker LOG(ERROR) << "invalid stream - problem with parameter iterator in " << location
322*795d594fSAndroid Build Coastguard Worker << " for method " << method_name;
323*795d594fSAndroid Build Coastguard Worker return false;
324*795d594fSAndroid Build Coastguard Worker }
325*795d594fSAndroid Build Coastguard Worker for (i = 0; i < parameters_size && i < arg_descriptors.size(); ++i) {
326*795d594fSAndroid Build Coastguard Worker if (arg_reg >= registers_size) {
327*795d594fSAndroid Build Coastguard Worker LOG(ERROR) << "invalid stream - arg reg >= reg size (" << arg_reg
328*795d594fSAndroid Build Coastguard Worker << " >= " << registers_size << ") in " << location;
329*795d594fSAndroid Build Coastguard Worker return false;
330*795d594fSAndroid Build Coastguard Worker }
331*795d594fSAndroid Build Coastguard Worker uint32_t name_idx = DecodeUnsignedLeb128P1(&stream);
332*795d594fSAndroid Build Coastguard Worker const char* descriptor = arg_descriptors[i];
333*795d594fSAndroid Build Coastguard Worker local_in_reg[arg_reg].name_ = index_to_string_data(name_idx);
334*795d594fSAndroid Build Coastguard Worker local_in_reg[arg_reg].descriptor_ = descriptor;
335*795d594fSAndroid Build Coastguard Worker local_in_reg[arg_reg].signature_ = nullptr;
336*795d594fSAndroid Build Coastguard Worker local_in_reg[arg_reg].start_address_ = 0;
337*795d594fSAndroid Build Coastguard Worker local_in_reg[arg_reg].reg_ = arg_reg;
338*795d594fSAndroid Build Coastguard Worker local_in_reg[arg_reg].is_live_ = true;
339*795d594fSAndroid Build Coastguard Worker switch (*descriptor) {
340*795d594fSAndroid Build Coastguard Worker case 'D':
341*795d594fSAndroid Build Coastguard Worker case 'J':
342*795d594fSAndroid Build Coastguard Worker arg_reg += 2;
343*795d594fSAndroid Build Coastguard Worker break;
344*795d594fSAndroid Build Coastguard Worker default:
345*795d594fSAndroid Build Coastguard Worker arg_reg += 1;
346*795d594fSAndroid Build Coastguard Worker break;
347*795d594fSAndroid Build Coastguard Worker }
348*795d594fSAndroid Build Coastguard Worker }
349*795d594fSAndroid Build Coastguard Worker
350*795d594fSAndroid Build Coastguard Worker uint32_t address = 0;
351*795d594fSAndroid Build Coastguard Worker for (;;) {
352*795d594fSAndroid Build Coastguard Worker uint8_t opcode = *stream++;
353*795d594fSAndroid Build Coastguard Worker switch (opcode) {
354*795d594fSAndroid Build Coastguard Worker case DBG_END_SEQUENCE:
355*795d594fSAndroid Build Coastguard Worker // Emit all variables which are still alive at the end of the method.
356*795d594fSAndroid Build Coastguard Worker for (uint16_t reg = 0; reg < registers_size; reg++) {
357*795d594fSAndroid Build Coastguard Worker if (local_in_reg[reg].is_live_) {
358*795d594fSAndroid Build Coastguard Worker local_in_reg[reg].end_address_ = insns_size_in_code_units;
359*795d594fSAndroid Build Coastguard Worker new_local_callback(local_in_reg[reg]);
360*795d594fSAndroid Build Coastguard Worker }
361*795d594fSAndroid Build Coastguard Worker }
362*795d594fSAndroid Build Coastguard Worker return true;
363*795d594fSAndroid Build Coastguard Worker case DBG_ADVANCE_PC:
364*795d594fSAndroid Build Coastguard Worker address += DecodeUnsignedLeb128(&stream);
365*795d594fSAndroid Build Coastguard Worker break;
366*795d594fSAndroid Build Coastguard Worker case DBG_ADVANCE_LINE:
367*795d594fSAndroid Build Coastguard Worker DecodeSignedLeb128(&stream); // Line.
368*795d594fSAndroid Build Coastguard Worker break;
369*795d594fSAndroid Build Coastguard Worker case DBG_START_LOCAL:
370*795d594fSAndroid Build Coastguard Worker case DBG_START_LOCAL_EXTENDED: {
371*795d594fSAndroid Build Coastguard Worker uint16_t reg = DecodeUnsignedLeb128(&stream);
372*795d594fSAndroid Build Coastguard Worker if (reg >= registers_size) {
373*795d594fSAndroid Build Coastguard Worker LOG(ERROR) << "invalid stream - reg >= reg size (" << reg << " >= "
374*795d594fSAndroid Build Coastguard Worker << registers_size << ") in " << location;
375*795d594fSAndroid Build Coastguard Worker return false;
376*795d594fSAndroid Build Coastguard Worker }
377*795d594fSAndroid Build Coastguard Worker
378*795d594fSAndroid Build Coastguard Worker uint32_t name_idx = DecodeUnsignedLeb128P1(&stream);
379*795d594fSAndroid Build Coastguard Worker uint16_t descriptor_idx = DecodeUnsignedLeb128P1(&stream);
380*795d594fSAndroid Build Coastguard Worker uint32_t signature_idx = dex::kDexNoIndex;
381*795d594fSAndroid Build Coastguard Worker if (opcode == DBG_START_LOCAL_EXTENDED) {
382*795d594fSAndroid Build Coastguard Worker signature_idx = DecodeUnsignedLeb128P1(&stream);
383*795d594fSAndroid Build Coastguard Worker }
384*795d594fSAndroid Build Coastguard Worker
385*795d594fSAndroid Build Coastguard Worker // Emit what was previously there, if anything
386*795d594fSAndroid Build Coastguard Worker if (local_in_reg[reg].is_live_) {
387*795d594fSAndroid Build Coastguard Worker local_in_reg[reg].end_address_ = address;
388*795d594fSAndroid Build Coastguard Worker // Parameters with generic types cannot be encoded in the debug_info_item header. So d8
389*795d594fSAndroid Build Coastguard Worker // encodes it as null in the header with start and end address as 0. There will be a
390*795d594fSAndroid Build Coastguard Worker // START_LOCAL_EXTENDED that will declare the parameter with correct signature
391*795d594fSAndroid Build Coastguard Worker // Debuggers get confused when they see empty ranges. So don't emit them.
392*795d594fSAndroid Build Coastguard Worker // See b/297843934 for more details.
393*795d594fSAndroid Build Coastguard Worker if (local_in_reg[reg].end_address_ != 0) {
394*795d594fSAndroid Build Coastguard Worker new_local_callback(local_in_reg[reg]);
395*795d594fSAndroid Build Coastguard Worker }
396*795d594fSAndroid Build Coastguard Worker }
397*795d594fSAndroid Build Coastguard Worker
398*795d594fSAndroid Build Coastguard Worker local_in_reg[reg].name_ = index_to_string_data(name_idx);
399*795d594fSAndroid Build Coastguard Worker local_in_reg[reg].descriptor_ = type_index_to_string_data(descriptor_idx);
400*795d594fSAndroid Build Coastguard Worker local_in_reg[reg].signature_ = index_to_string_data(signature_idx);
401*795d594fSAndroid Build Coastguard Worker local_in_reg[reg].start_address_ = address;
402*795d594fSAndroid Build Coastguard Worker local_in_reg[reg].reg_ = reg;
403*795d594fSAndroid Build Coastguard Worker local_in_reg[reg].is_live_ = true;
404*795d594fSAndroid Build Coastguard Worker break;
405*795d594fSAndroid Build Coastguard Worker }
406*795d594fSAndroid Build Coastguard Worker case DBG_END_LOCAL: {
407*795d594fSAndroid Build Coastguard Worker uint16_t reg = DecodeUnsignedLeb128(&stream);
408*795d594fSAndroid Build Coastguard Worker if (reg >= registers_size) {
409*795d594fSAndroid Build Coastguard Worker LOG(ERROR) << "invalid stream - reg >= reg size (" << reg << " >= "
410*795d594fSAndroid Build Coastguard Worker << registers_size << ") in " << location;
411*795d594fSAndroid Build Coastguard Worker return false;
412*795d594fSAndroid Build Coastguard Worker }
413*795d594fSAndroid Build Coastguard Worker // If the register is live, close it properly. Otherwise, closing an already
414*795d594fSAndroid Build Coastguard Worker // closed register is sloppy, but harmless if no further action is taken.
415*795d594fSAndroid Build Coastguard Worker if (local_in_reg[reg].is_live_) {
416*795d594fSAndroid Build Coastguard Worker local_in_reg[reg].end_address_ = address;
417*795d594fSAndroid Build Coastguard Worker new_local_callback(local_in_reg[reg]);
418*795d594fSAndroid Build Coastguard Worker local_in_reg[reg].is_live_ = false;
419*795d594fSAndroid Build Coastguard Worker }
420*795d594fSAndroid Build Coastguard Worker break;
421*795d594fSAndroid Build Coastguard Worker }
422*795d594fSAndroid Build Coastguard Worker case DBG_RESTART_LOCAL: {
423*795d594fSAndroid Build Coastguard Worker uint16_t reg = DecodeUnsignedLeb128(&stream);
424*795d594fSAndroid Build Coastguard Worker if (reg >= registers_size) {
425*795d594fSAndroid Build Coastguard Worker LOG(ERROR) << "invalid stream - reg >= reg size (" << reg << " >= "
426*795d594fSAndroid Build Coastguard Worker << registers_size << ") in " << location;
427*795d594fSAndroid Build Coastguard Worker return false;
428*795d594fSAndroid Build Coastguard Worker }
429*795d594fSAndroid Build Coastguard Worker // If the register is live, the "restart" is superfluous,
430*795d594fSAndroid Build Coastguard Worker // and we don't want to mess with the existing start address.
431*795d594fSAndroid Build Coastguard Worker if (!local_in_reg[reg].is_live_) {
432*795d594fSAndroid Build Coastguard Worker local_in_reg[reg].start_address_ = address;
433*795d594fSAndroid Build Coastguard Worker local_in_reg[reg].is_live_ = true;
434*795d594fSAndroid Build Coastguard Worker }
435*795d594fSAndroid Build Coastguard Worker break;
436*795d594fSAndroid Build Coastguard Worker }
437*795d594fSAndroid Build Coastguard Worker case DBG_SET_PROLOGUE_END:
438*795d594fSAndroid Build Coastguard Worker case DBG_SET_EPILOGUE_BEGIN:
439*795d594fSAndroid Build Coastguard Worker break;
440*795d594fSAndroid Build Coastguard Worker case DBG_SET_FILE:
441*795d594fSAndroid Build Coastguard Worker DecodeUnsignedLeb128P1(&stream); // name.
442*795d594fSAndroid Build Coastguard Worker break;
443*795d594fSAndroid Build Coastguard Worker default:
444*795d594fSAndroid Build Coastguard Worker address += (opcode - DBG_FIRST_SPECIAL) / DBG_LINE_RANGE;
445*795d594fSAndroid Build Coastguard Worker break;
446*795d594fSAndroid Build Coastguard Worker }
447*795d594fSAndroid Build Coastguard Worker }
448*795d594fSAndroid Build Coastguard Worker }
449*795d594fSAndroid Build Coastguard Worker
450*795d594fSAndroid Build Coastguard Worker template<typename NewLocalCallback>
DecodeDebugLocalInfo(uint32_t registers_size,uint32_t ins_size,uint32_t insns_size_in_code_units,uint32_t debug_info_offset,bool is_static,uint32_t method_idx,const NewLocalCallback & new_local_callback)451*795d594fSAndroid Build Coastguard Worker bool DexFile::DecodeDebugLocalInfo(uint32_t registers_size,
452*795d594fSAndroid Build Coastguard Worker uint32_t ins_size,
453*795d594fSAndroid Build Coastguard Worker uint32_t insns_size_in_code_units,
454*795d594fSAndroid Build Coastguard Worker uint32_t debug_info_offset,
455*795d594fSAndroid Build Coastguard Worker bool is_static,
456*795d594fSAndroid Build Coastguard Worker uint32_t method_idx,
457*795d594fSAndroid Build Coastguard Worker const NewLocalCallback& new_local_callback) const {
458*795d594fSAndroid Build Coastguard Worker const uint8_t* const stream = GetDebugInfoStream(debug_info_offset);
459*795d594fSAndroid Build Coastguard Worker if (stream == nullptr) {
460*795d594fSAndroid Build Coastguard Worker return false;
461*795d594fSAndroid Build Coastguard Worker }
462*795d594fSAndroid Build Coastguard Worker std::vector<const char*> arg_descriptors;
463*795d594fSAndroid Build Coastguard Worker DexFileParameterIterator it(*this, GetMethodPrototype(GetMethodId(method_idx)));
464*795d594fSAndroid Build Coastguard Worker for (; it.HasNext(); it.Next()) {
465*795d594fSAndroid Build Coastguard Worker arg_descriptors.push_back(it.GetDescriptor());
466*795d594fSAndroid Build Coastguard Worker }
467*795d594fSAndroid Build Coastguard Worker return DecodeDebugLocalInfo(stream,
468*795d594fSAndroid Build Coastguard Worker GetLocation(),
469*795d594fSAndroid Build Coastguard Worker GetMethodDeclaringClassDescriptor(GetMethodId(method_idx)),
470*795d594fSAndroid Build Coastguard Worker arg_descriptors,
471*795d594fSAndroid Build Coastguard Worker this->PrettyMethod(method_idx),
472*795d594fSAndroid Build Coastguard Worker is_static,
473*795d594fSAndroid Build Coastguard Worker registers_size,
474*795d594fSAndroid Build Coastguard Worker ins_size,
475*795d594fSAndroid Build Coastguard Worker insns_size_in_code_units,
476*795d594fSAndroid Build Coastguard Worker [this](uint32_t idx) {
477*795d594fSAndroid Build Coastguard Worker dex::StringIndex string_idx(idx);
478*795d594fSAndroid Build Coastguard Worker return string_idx.IsValid() ? GetStringData(string_idx) : nullptr;
479*795d594fSAndroid Build Coastguard Worker },
480*795d594fSAndroid Build Coastguard Worker [this](uint16_t idx) {
481*795d594fSAndroid Build Coastguard Worker dex::TypeIndex type_idx(idx);
482*795d594fSAndroid Build Coastguard Worker return type_idx.IsValid() ? GetTypeDescriptor(type_idx) : nullptr;
483*795d594fSAndroid Build Coastguard Worker },
484*795d594fSAndroid Build Coastguard Worker new_local_callback);
485*795d594fSAndroid Build Coastguard Worker }
486*795d594fSAndroid Build Coastguard Worker
487*795d594fSAndroid Build Coastguard Worker template<typename DexDebugNewPosition, typename IndexToStringData>
DecodeDebugPositionInfo(const uint8_t * stream,IndexToStringData && index_to_string_data,DexDebugNewPosition && position_functor)488*795d594fSAndroid Build Coastguard Worker bool DexFile::DecodeDebugPositionInfo(const uint8_t* stream,
489*795d594fSAndroid Build Coastguard Worker IndexToStringData&& index_to_string_data,
490*795d594fSAndroid Build Coastguard Worker DexDebugNewPosition&& position_functor) {
491*795d594fSAndroid Build Coastguard Worker if (stream == nullptr) {
492*795d594fSAndroid Build Coastguard Worker return false;
493*795d594fSAndroid Build Coastguard Worker }
494*795d594fSAndroid Build Coastguard Worker
495*795d594fSAndroid Build Coastguard Worker PositionInfo entry;
496*795d594fSAndroid Build Coastguard Worker entry.line_ = DecodeDebugInfoParameterNames(&stream, VoidFunctor());
497*795d594fSAndroid Build Coastguard Worker
498*795d594fSAndroid Build Coastguard Worker for (;;) {
499*795d594fSAndroid Build Coastguard Worker uint8_t opcode = *stream++;
500*795d594fSAndroid Build Coastguard Worker switch (opcode) {
501*795d594fSAndroid Build Coastguard Worker case DBG_END_SEQUENCE:
502*795d594fSAndroid Build Coastguard Worker return true; // end of stream.
503*795d594fSAndroid Build Coastguard Worker case DBG_ADVANCE_PC:
504*795d594fSAndroid Build Coastguard Worker entry.address_ += DecodeUnsignedLeb128(&stream);
505*795d594fSAndroid Build Coastguard Worker break;
506*795d594fSAndroid Build Coastguard Worker case DBG_ADVANCE_LINE:
507*795d594fSAndroid Build Coastguard Worker entry.line_ += DecodeSignedLeb128(&stream);
508*795d594fSAndroid Build Coastguard Worker break;
509*795d594fSAndroid Build Coastguard Worker case DBG_START_LOCAL:
510*795d594fSAndroid Build Coastguard Worker DecodeUnsignedLeb128(&stream); // reg.
511*795d594fSAndroid Build Coastguard Worker DecodeUnsignedLeb128P1(&stream); // name.
512*795d594fSAndroid Build Coastguard Worker DecodeUnsignedLeb128P1(&stream); // descriptor.
513*795d594fSAndroid Build Coastguard Worker break;
514*795d594fSAndroid Build Coastguard Worker case DBG_START_LOCAL_EXTENDED:
515*795d594fSAndroid Build Coastguard Worker DecodeUnsignedLeb128(&stream); // reg.
516*795d594fSAndroid Build Coastguard Worker DecodeUnsignedLeb128P1(&stream); // name.
517*795d594fSAndroid Build Coastguard Worker DecodeUnsignedLeb128P1(&stream); // descriptor.
518*795d594fSAndroid Build Coastguard Worker DecodeUnsignedLeb128P1(&stream); // signature.
519*795d594fSAndroid Build Coastguard Worker break;
520*795d594fSAndroid Build Coastguard Worker case DBG_END_LOCAL:
521*795d594fSAndroid Build Coastguard Worker case DBG_RESTART_LOCAL:
522*795d594fSAndroid Build Coastguard Worker DecodeUnsignedLeb128(&stream); // reg.
523*795d594fSAndroid Build Coastguard Worker break;
524*795d594fSAndroid Build Coastguard Worker case DBG_SET_PROLOGUE_END:
525*795d594fSAndroid Build Coastguard Worker entry.prologue_end_ = true;
526*795d594fSAndroid Build Coastguard Worker break;
527*795d594fSAndroid Build Coastguard Worker case DBG_SET_EPILOGUE_BEGIN:
528*795d594fSAndroid Build Coastguard Worker entry.epilogue_begin_ = true;
529*795d594fSAndroid Build Coastguard Worker break;
530*795d594fSAndroid Build Coastguard Worker case DBG_SET_FILE: {
531*795d594fSAndroid Build Coastguard Worker uint32_t name_idx = DecodeUnsignedLeb128P1(&stream);
532*795d594fSAndroid Build Coastguard Worker entry.source_file_ = index_to_string_data(name_idx);
533*795d594fSAndroid Build Coastguard Worker break;
534*795d594fSAndroid Build Coastguard Worker }
535*795d594fSAndroid Build Coastguard Worker default: {
536*795d594fSAndroid Build Coastguard Worker int adjopcode = opcode - DBG_FIRST_SPECIAL;
537*795d594fSAndroid Build Coastguard Worker entry.address_ += adjopcode / DBG_LINE_RANGE;
538*795d594fSAndroid Build Coastguard Worker entry.line_ += DBG_LINE_BASE + (adjopcode % DBG_LINE_RANGE);
539*795d594fSAndroid Build Coastguard Worker if (position_functor(entry)) {
540*795d594fSAndroid Build Coastguard Worker return true; // early exit.
541*795d594fSAndroid Build Coastguard Worker }
542*795d594fSAndroid Build Coastguard Worker entry.prologue_end_ = false;
543*795d594fSAndroid Build Coastguard Worker entry.epilogue_begin_ = false;
544*795d594fSAndroid Build Coastguard Worker break;
545*795d594fSAndroid Build Coastguard Worker }
546*795d594fSAndroid Build Coastguard Worker }
547*795d594fSAndroid Build Coastguard Worker }
548*795d594fSAndroid Build Coastguard Worker }
549*795d594fSAndroid Build Coastguard Worker
AsCompactDexFile()550*795d594fSAndroid Build Coastguard Worker inline const CompactDexFile* DexFile::AsCompactDexFile() const {
551*795d594fSAndroid Build Coastguard Worker DCHECK(IsCompactDexFile());
552*795d594fSAndroid Build Coastguard Worker return down_cast<const CompactDexFile*>(this);
553*795d594fSAndroid Build Coastguard Worker }
554*795d594fSAndroid Build Coastguard Worker
AsStandardDexFile()555*795d594fSAndroid Build Coastguard Worker inline const StandardDexFile* DexFile::AsStandardDexFile() const {
556*795d594fSAndroid Build Coastguard Worker DCHECK(IsStandardDexFile());
557*795d594fSAndroid Build Coastguard Worker return down_cast<const StandardDexFile*>(this);
558*795d594fSAndroid Build Coastguard Worker }
559*795d594fSAndroid Build Coastguard Worker
560*795d594fSAndroid Build Coastguard Worker // Get the base of the encoded data for the given DexCode.
GetCatchHandlerData(const DexInstructionIterator & code_item_end,uint32_t tries_size,uint32_t offset)561*795d594fSAndroid Build Coastguard Worker inline const uint8_t* DexFile::GetCatchHandlerData(const DexInstructionIterator& code_item_end,
562*795d594fSAndroid Build Coastguard Worker uint32_t tries_size,
563*795d594fSAndroid Build Coastguard Worker uint32_t offset) {
564*795d594fSAndroid Build Coastguard Worker const uint8_t* handler_data =
565*795d594fSAndroid Build Coastguard Worker reinterpret_cast<const uint8_t*>(GetTryItems(code_item_end, tries_size));
566*795d594fSAndroid Build Coastguard Worker return handler_data + offset;
567*795d594fSAndroid Build Coastguard Worker }
568*795d594fSAndroid Build Coastguard Worker
GetClasses()569*795d594fSAndroid Build Coastguard Worker inline IterationRange<ClassIterator> DexFile::GetClasses() const {
570*795d594fSAndroid Build Coastguard Worker return { ClassIterator(*this, 0u), ClassIterator(*this, NumClassDefs()) };
571*795d594fSAndroid Build Coastguard Worker }
572*795d594fSAndroid Build Coastguard Worker
573*795d594fSAndroid Build Coastguard Worker // Returns the line number
574*795d594fSAndroid Build Coastguard Worker template <typename Visitor>
DecodeDebugInfoParameterNames(const uint8_t ** debug_info,Visitor && visitor)575*795d594fSAndroid Build Coastguard Worker inline uint32_t DexFile::DecodeDebugInfoParameterNames(const uint8_t** debug_info,
576*795d594fSAndroid Build Coastguard Worker Visitor&& visitor) {
577*795d594fSAndroid Build Coastguard Worker uint32_t line = DecodeUnsignedLeb128(debug_info);
578*795d594fSAndroid Build Coastguard Worker const uint32_t parameters_size = DecodeUnsignedLeb128(debug_info);
579*795d594fSAndroid Build Coastguard Worker for (uint32_t i = 0; i < parameters_size; ++i) {
580*795d594fSAndroid Build Coastguard Worker visitor(dex::StringIndex(DecodeUnsignedLeb128P1(debug_info)));
581*795d594fSAndroid Build Coastguard Worker }
582*795d594fSAndroid Build Coastguard Worker return line;
583*795d594fSAndroid Build Coastguard Worker }
584*795d594fSAndroid Build Coastguard Worker
585*795d594fSAndroid Build Coastguard Worker } // namespace art
586*795d594fSAndroid Build Coastguard Worker
587*795d594fSAndroid Build Coastguard Worker #endif // ART_LIBDEXFILE_DEX_DEX_FILE_INL_H_
588