1 /* 2 * Copyright (C) 2011 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_DEX_DEX_FILE_INL_H_ 18 #define ART_LIBDEXFILE_DEX_DEX_FILE_INL_H_ 19 20 #include "base/casts.h" 21 #include "base/leb128.h" 22 #include "base/stringpiece.h" 23 #include "compact_dex_file.h" 24 #include "dex_file.h" 25 #include "invoke_type.h" 26 #include "standard_dex_file.h" 27 28 namespace art { 29 30 inline int32_t DexFile::GetStringLength(const StringId& string_id) const { 31 const uint8_t* ptr = DataBegin() + string_id.string_data_off_; 32 return DecodeUnsignedLeb128(&ptr); 33 } 34 35 inline const char* DexFile::GetStringDataAndUtf16Length(const StringId& string_id, 36 uint32_t* utf16_length) const { 37 DCHECK(utf16_length != nullptr) << GetLocation(); 38 const uint8_t* ptr = DataBegin() + string_id.string_data_off_; 39 *utf16_length = DecodeUnsignedLeb128(&ptr); 40 return reinterpret_cast<const char*>(ptr); 41 } 42 43 inline const char* DexFile::GetStringData(const StringId& string_id) const { 44 uint32_t ignored; 45 return GetStringDataAndUtf16Length(string_id, &ignored); 46 } 47 48 inline const char* DexFile::StringDataAndUtf16LengthByIdx(dex::StringIndex idx, 49 uint32_t* utf16_length) const { 50 if (!idx.IsValid()) { 51 *utf16_length = 0; 52 return nullptr; 53 } 54 const StringId& string_id = GetStringId(idx); 55 return GetStringDataAndUtf16Length(string_id, utf16_length); 56 } 57 58 inline const char* DexFile::StringDataByIdx(dex::StringIndex idx) const { 59 uint32_t unicode_length; 60 return StringDataAndUtf16LengthByIdx(idx, &unicode_length); 61 } 62 63 inline const char* DexFile::StringByTypeIdx(dex::TypeIndex idx, uint32_t* unicode_length) const { 64 if (!idx.IsValid()) { 65 return nullptr; 66 } 67 const TypeId& type_id = GetTypeId(idx); 68 return StringDataAndUtf16LengthByIdx(type_id.descriptor_idx_, unicode_length); 69 } 70 71 inline const char* DexFile::StringByTypeIdx(dex::TypeIndex idx) const { 72 if (!idx.IsValid()) { 73 return nullptr; 74 } 75 const TypeId& type_id = GetTypeId(idx); 76 return StringDataByIdx(type_id.descriptor_idx_); 77 } 78 79 inline const char* DexFile::GetTypeDescriptor(const TypeId& type_id) const { 80 return StringDataByIdx(type_id.descriptor_idx_); 81 } 82 83 inline const char* DexFile::GetFieldTypeDescriptor(const FieldId& field_id) const { 84 const DexFile::TypeId& type_id = GetTypeId(field_id.type_idx_); 85 return GetTypeDescriptor(type_id); 86 } 87 88 inline const char* DexFile::GetFieldName(const FieldId& field_id) const { 89 return StringDataByIdx(field_id.name_idx_); 90 } 91 92 inline const char* DexFile::GetMethodDeclaringClassDescriptor(const MethodId& method_id) const { 93 const DexFile::TypeId& type_id = GetTypeId(method_id.class_idx_); 94 return GetTypeDescriptor(type_id); 95 } 96 97 inline const Signature DexFile::GetMethodSignature(const MethodId& method_id) const { 98 return Signature(this, GetProtoId(method_id.proto_idx_)); 99 } 100 101 inline const Signature DexFile::GetProtoSignature(const ProtoId& proto_id) const { 102 return Signature(this, proto_id); 103 } 104 105 inline const char* DexFile::GetMethodName(const MethodId& method_id) const { 106 return StringDataByIdx(method_id.name_idx_); 107 } 108 109 inline const char* DexFile::GetMethodShorty(uint32_t idx) const { 110 return StringDataByIdx(GetProtoId(GetMethodId(idx).proto_idx_).shorty_idx_); 111 } 112 113 inline const char* DexFile::GetMethodShorty(const MethodId& method_id) const { 114 return StringDataByIdx(GetProtoId(method_id.proto_idx_).shorty_idx_); 115 } 116 117 inline const char* DexFile::GetMethodShorty(const MethodId& method_id, uint32_t* length) const { 118 // Using the UTF16 length is safe here as shorties are guaranteed to be ASCII characters. 119 return StringDataAndUtf16LengthByIdx(GetProtoId(method_id.proto_idx_).shorty_idx_, length); 120 } 121 122 inline const char* DexFile::GetClassDescriptor(const ClassDef& class_def) const { 123 return StringByTypeIdx(class_def.class_idx_); 124 } 125 126 inline const char* DexFile::GetReturnTypeDescriptor(const ProtoId& proto_id) const { 127 return StringByTypeIdx(proto_id.return_type_idx_); 128 } 129 130 inline const char* DexFile::GetShorty(uint32_t proto_idx) const { 131 const ProtoId& proto_id = GetProtoId(proto_idx); 132 return StringDataByIdx(proto_id.shorty_idx_); 133 } 134 135 inline const DexFile::TryItem* DexFile::GetTryItems(const DexInstructionIterator& code_item_end, 136 uint32_t offset) { 137 return reinterpret_cast<const TryItem*> 138 (RoundUp(reinterpret_cast<uintptr_t>(&code_item_end.Inst()), TryItem::kAlignment)) + offset; 139 } 140 141 static inline bool DexFileStringEquals(const DexFile* df1, dex::StringIndex sidx1, 142 const DexFile* df2, dex::StringIndex sidx2) { 143 uint32_t s1_len; // Note: utf16 length != mutf8 length. 144 const char* s1_data = df1->StringDataAndUtf16LengthByIdx(sidx1, &s1_len); 145 uint32_t s2_len; 146 const char* s2_data = df2->StringDataAndUtf16LengthByIdx(sidx2, &s2_len); 147 return (s1_len == s2_len) && (strcmp(s1_data, s2_data) == 0); 148 } 149 150 inline bool Signature::operator==(const Signature& rhs) const { 151 if (dex_file_ == nullptr) { 152 return rhs.dex_file_ == nullptr; 153 } 154 if (rhs.dex_file_ == nullptr) { 155 return false; 156 } 157 if (dex_file_ == rhs.dex_file_) { 158 return proto_id_ == rhs.proto_id_; 159 } 160 uint32_t lhs_shorty_len; // For a shorty utf16 length == mutf8 length. 161 const char* lhs_shorty_data = dex_file_->StringDataAndUtf16LengthByIdx(proto_id_->shorty_idx_, 162 &lhs_shorty_len); 163 StringPiece lhs_shorty(lhs_shorty_data, lhs_shorty_len); 164 { 165 uint32_t rhs_shorty_len; 166 const char* rhs_shorty_data = 167 rhs.dex_file_->StringDataAndUtf16LengthByIdx(rhs.proto_id_->shorty_idx_, 168 &rhs_shorty_len); 169 StringPiece rhs_shorty(rhs_shorty_data, rhs_shorty_len); 170 if (lhs_shorty != rhs_shorty) { 171 return false; // Shorty mismatch. 172 } 173 } 174 if (lhs_shorty[0] == 'L') { 175 const DexFile::TypeId& return_type_id = dex_file_->GetTypeId(proto_id_->return_type_idx_); 176 const DexFile::TypeId& rhs_return_type_id = 177 rhs.dex_file_->GetTypeId(rhs.proto_id_->return_type_idx_); 178 if (!DexFileStringEquals(dex_file_, return_type_id.descriptor_idx_, 179 rhs.dex_file_, rhs_return_type_id.descriptor_idx_)) { 180 return false; // Return type mismatch. 181 } 182 } 183 if (lhs_shorty.find('L', 1) != StringPiece::npos) { 184 const DexFile::TypeList* params = dex_file_->GetProtoParameters(*proto_id_); 185 const DexFile::TypeList* rhs_params = rhs.dex_file_->GetProtoParameters(*rhs.proto_id_); 186 // We found a reference parameter in the matching shorty, so both lists must be non-empty. 187 DCHECK(params != nullptr); 188 DCHECK(rhs_params != nullptr); 189 uint32_t params_size = params->Size(); 190 DCHECK_EQ(params_size, rhs_params->Size()); // Parameter list size must match. 191 for (uint32_t i = 0; i < params_size; ++i) { 192 const DexFile::TypeId& param_id = dex_file_->GetTypeId(params->GetTypeItem(i).type_idx_); 193 const DexFile::TypeId& rhs_param_id = 194 rhs.dex_file_->GetTypeId(rhs_params->GetTypeItem(i).type_idx_); 195 if (!DexFileStringEquals(dex_file_, param_id.descriptor_idx_, 196 rhs.dex_file_, rhs_param_id.descriptor_idx_)) { 197 return false; // Parameter type mismatch. 198 } 199 } 200 } 201 return true; 202 } 203 204 inline 205 InvokeType ClassDataItemIterator::GetMethodInvokeType(const DexFile::ClassDef& class_def) const { 206 if (HasNextDirectMethod()) { 207 if ((GetRawMemberAccessFlags() & kAccStatic) != 0) { 208 return kStatic; 209 } else { 210 return kDirect; 211 } 212 } else { 213 DCHECK_EQ(GetRawMemberAccessFlags() & kAccStatic, 0U); 214 if ((class_def.access_flags_ & kAccInterface) != 0) { 215 return kInterface; 216 } else if ((GetRawMemberAccessFlags() & kAccConstructor) != 0) { 217 return kSuper; 218 } else { 219 return kVirtual; 220 } 221 } 222 } 223 224 template<typename NewLocalCallback, typename IndexToStringData, typename TypeIndexToStringData> 225 bool DexFile::DecodeDebugLocalInfo(const uint8_t* stream, 226 const std::string& location, 227 const char* declaring_class_descriptor, 228 const std::vector<const char*>& arg_descriptors, 229 const std::string& method_name, 230 bool is_static, 231 uint16_t registers_size, 232 uint16_t ins_size, 233 uint16_t insns_size_in_code_units, 234 IndexToStringData index_to_string_data, 235 TypeIndexToStringData type_index_to_string_data, 236 NewLocalCallback new_local_callback, 237 void* context) { 238 if (stream == nullptr) { 239 return false; 240 } 241 std::vector<LocalInfo> local_in_reg(registers_size); 242 243 uint16_t arg_reg = registers_size - ins_size; 244 if (!is_static) { 245 const char* descriptor = declaring_class_descriptor; 246 local_in_reg[arg_reg].name_ = "this"; 247 local_in_reg[arg_reg].descriptor_ = descriptor; 248 local_in_reg[arg_reg].signature_ = nullptr; 249 local_in_reg[arg_reg].start_address_ = 0; 250 local_in_reg[arg_reg].reg_ = arg_reg; 251 local_in_reg[arg_reg].is_live_ = true; 252 arg_reg++; 253 } 254 255 DecodeUnsignedLeb128(&stream); // Line. 256 uint32_t parameters_size = DecodeUnsignedLeb128(&stream); 257 uint32_t i; 258 if (parameters_size != arg_descriptors.size()) { 259 LOG(ERROR) << "invalid stream - problem with parameter iterator in " << location 260 << " for method " << method_name; 261 return false; 262 } 263 for (i = 0; i < parameters_size && i < arg_descriptors.size(); ++i) { 264 if (arg_reg >= registers_size) { 265 LOG(ERROR) << "invalid stream - arg reg >= reg size (" << arg_reg 266 << " >= " << registers_size << ") in " << location; 267 return false; 268 } 269 uint32_t name_idx = DecodeUnsignedLeb128P1(&stream); 270 const char* descriptor = arg_descriptors[i]; 271 local_in_reg[arg_reg].name_ = index_to_string_data(name_idx); 272 local_in_reg[arg_reg].descriptor_ = descriptor; 273 local_in_reg[arg_reg].signature_ = nullptr; 274 local_in_reg[arg_reg].start_address_ = 0; 275 local_in_reg[arg_reg].reg_ = arg_reg; 276 local_in_reg[arg_reg].is_live_ = true; 277 switch (*descriptor) { 278 case 'D': 279 case 'J': 280 arg_reg += 2; 281 break; 282 default: 283 arg_reg += 1; 284 break; 285 } 286 } 287 288 uint32_t address = 0; 289 for (;;) { 290 uint8_t opcode = *stream++; 291 switch (opcode) { 292 case DBG_END_SEQUENCE: 293 // Emit all variables which are still alive at the end of the method. 294 for (uint16_t reg = 0; reg < registers_size; reg++) { 295 if (local_in_reg[reg].is_live_) { 296 local_in_reg[reg].end_address_ = insns_size_in_code_units; 297 new_local_callback(context, local_in_reg[reg]); 298 } 299 } 300 return true; 301 case DBG_ADVANCE_PC: 302 address += DecodeUnsignedLeb128(&stream); 303 break; 304 case DBG_ADVANCE_LINE: 305 DecodeSignedLeb128(&stream); // Line. 306 break; 307 case DBG_START_LOCAL: 308 case DBG_START_LOCAL_EXTENDED: { 309 uint16_t reg = DecodeUnsignedLeb128(&stream); 310 if (reg >= registers_size) { 311 LOG(ERROR) << "invalid stream - reg >= reg size (" << reg << " >= " 312 << registers_size << ") in " << location; 313 return false; 314 } 315 316 uint32_t name_idx = DecodeUnsignedLeb128P1(&stream); 317 uint16_t descriptor_idx = DecodeUnsignedLeb128P1(&stream); 318 uint32_t signature_idx = dex::kDexNoIndex; 319 if (opcode == DBG_START_LOCAL_EXTENDED) { 320 signature_idx = DecodeUnsignedLeb128P1(&stream); 321 } 322 323 // Emit what was previously there, if anything 324 if (local_in_reg[reg].is_live_) { 325 local_in_reg[reg].end_address_ = address; 326 new_local_callback(context, local_in_reg[reg]); 327 } 328 329 local_in_reg[reg].name_ = index_to_string_data(name_idx); 330 local_in_reg[reg].descriptor_ = type_index_to_string_data(descriptor_idx);; 331 local_in_reg[reg].signature_ = index_to_string_data(signature_idx); 332 local_in_reg[reg].start_address_ = address; 333 local_in_reg[reg].reg_ = reg; 334 local_in_reg[reg].is_live_ = true; 335 break; 336 } 337 case DBG_END_LOCAL: { 338 uint16_t reg = DecodeUnsignedLeb128(&stream); 339 if (reg >= registers_size) { 340 LOG(ERROR) << "invalid stream - reg >= reg size (" << reg << " >= " 341 << registers_size << ") in " << location; 342 return false; 343 } 344 // If the register is live, close it properly. Otherwise, closing an already 345 // closed register is sloppy, but harmless if no further action is taken. 346 if (local_in_reg[reg].is_live_) { 347 local_in_reg[reg].end_address_ = address; 348 new_local_callback(context, local_in_reg[reg]); 349 local_in_reg[reg].is_live_ = false; 350 } 351 break; 352 } 353 case DBG_RESTART_LOCAL: { 354 uint16_t reg = DecodeUnsignedLeb128(&stream); 355 if (reg >= registers_size) { 356 LOG(ERROR) << "invalid stream - reg >= reg size (" << reg << " >= " 357 << registers_size << ") in " << location; 358 return false; 359 } 360 // If the register is live, the "restart" is superfluous, 361 // and we don't want to mess with the existing start address. 362 if (!local_in_reg[reg].is_live_) { 363 local_in_reg[reg].start_address_ = address; 364 local_in_reg[reg].is_live_ = true; 365 } 366 break; 367 } 368 case DBG_SET_PROLOGUE_END: 369 case DBG_SET_EPILOGUE_BEGIN: 370 break; 371 case DBG_SET_FILE: 372 DecodeUnsignedLeb128P1(&stream); // name. 373 break; 374 default: 375 address += (opcode - DBG_FIRST_SPECIAL) / DBG_LINE_RANGE; 376 break; 377 } 378 } 379 } 380 381 template<typename NewLocalCallback> 382 bool DexFile::DecodeDebugLocalInfo(uint32_t registers_size, 383 uint32_t ins_size, 384 uint32_t insns_size_in_code_units, 385 uint32_t debug_info_offset, 386 bool is_static, 387 uint32_t method_idx, 388 NewLocalCallback new_local_callback, 389 void* context) const { 390 const uint8_t* const stream = GetDebugInfoStream(debug_info_offset); 391 if (stream == nullptr) { 392 return false; 393 } 394 std::vector<const char*> arg_descriptors; 395 DexFileParameterIterator it(*this, GetMethodPrototype(GetMethodId(method_idx))); 396 for (; it.HasNext(); it.Next()) { 397 arg_descriptors.push_back(it.GetDescriptor()); 398 } 399 return DecodeDebugLocalInfo(stream, 400 GetLocation(), 401 GetMethodDeclaringClassDescriptor(GetMethodId(method_idx)), 402 arg_descriptors, 403 this->PrettyMethod(method_idx), 404 is_static, 405 registers_size, 406 ins_size, 407 insns_size_in_code_units, 408 [this](uint32_t idx) { 409 return StringDataByIdx(dex::StringIndex(idx)); 410 }, 411 [this](uint32_t idx) { 412 return StringByTypeIdx(dex::TypeIndex( 413 dchecked_integral_cast<uint16_t>(idx))); 414 }, 415 new_local_callback, 416 context); 417 } 418 419 template<typename DexDebugNewPosition, typename IndexToStringData> 420 bool DexFile::DecodeDebugPositionInfo(const uint8_t* stream, 421 IndexToStringData index_to_string_data, 422 DexDebugNewPosition position_functor, 423 void* context) { 424 if (stream == nullptr) { 425 return false; 426 } 427 428 PositionInfo entry = PositionInfo(); 429 entry.line_ = DecodeUnsignedLeb128(&stream); 430 uint32_t parameters_size = DecodeUnsignedLeb128(&stream); 431 for (uint32_t i = 0; i < parameters_size; ++i) { 432 DecodeUnsignedLeb128P1(&stream); // Parameter name. 433 } 434 435 for (;;) { 436 uint8_t opcode = *stream++; 437 switch (opcode) { 438 case DBG_END_SEQUENCE: 439 return true; // end of stream. 440 case DBG_ADVANCE_PC: 441 entry.address_ += DecodeUnsignedLeb128(&stream); 442 break; 443 case DBG_ADVANCE_LINE: 444 entry.line_ += DecodeSignedLeb128(&stream); 445 break; 446 case DBG_START_LOCAL: 447 DecodeUnsignedLeb128(&stream); // reg. 448 DecodeUnsignedLeb128P1(&stream); // name. 449 DecodeUnsignedLeb128P1(&stream); // descriptor. 450 break; 451 case DBG_START_LOCAL_EXTENDED: 452 DecodeUnsignedLeb128(&stream); // reg. 453 DecodeUnsignedLeb128P1(&stream); // name. 454 DecodeUnsignedLeb128P1(&stream); // descriptor. 455 DecodeUnsignedLeb128P1(&stream); // signature. 456 break; 457 case DBG_END_LOCAL: 458 case DBG_RESTART_LOCAL: 459 DecodeUnsignedLeb128(&stream); // reg. 460 break; 461 case DBG_SET_PROLOGUE_END: 462 entry.prologue_end_ = true; 463 break; 464 case DBG_SET_EPILOGUE_BEGIN: 465 entry.epilogue_begin_ = true; 466 break; 467 case DBG_SET_FILE: { 468 uint32_t name_idx = DecodeUnsignedLeb128P1(&stream); 469 entry.source_file_ = index_to_string_data(name_idx); 470 break; 471 } 472 default: { 473 int adjopcode = opcode - DBG_FIRST_SPECIAL; 474 entry.address_ += adjopcode / DBG_LINE_RANGE; 475 entry.line_ += DBG_LINE_BASE + (adjopcode % DBG_LINE_RANGE); 476 if (position_functor(context, entry)) { 477 return true; // early exit. 478 } 479 entry.prologue_end_ = false; 480 entry.epilogue_begin_ = false; 481 break; 482 } 483 } 484 } 485 } 486 487 template<typename DexDebugNewPosition> 488 bool DexFile::DecodeDebugPositionInfo(uint32_t debug_info_offset, 489 DexDebugNewPosition position_functor, 490 void* context) const { 491 return DecodeDebugPositionInfo(GetDebugInfoStream(debug_info_offset), 492 [this](uint32_t idx) { 493 return StringDataByIdx(dex::StringIndex(idx)); 494 }, 495 position_functor, 496 context); 497 } 498 499 inline const CompactDexFile* DexFile::AsCompactDexFile() const { 500 DCHECK(IsCompactDexFile()); 501 return down_cast<const CompactDexFile*>(this); 502 } 503 504 inline const StandardDexFile* DexFile::AsStandardDexFile() const { 505 DCHECK(IsStandardDexFile()); 506 return down_cast<const StandardDexFile*>(this); 507 } 508 509 // Get the base of the encoded data for the given DexCode. 510 inline const uint8_t* DexFile::GetCatchHandlerData(const DexInstructionIterator& code_item_end, 511 uint32_t tries_size, 512 uint32_t offset) { 513 const uint8_t* handler_data = 514 reinterpret_cast<const uint8_t*>(GetTryItems(code_item_end, tries_size)); 515 return handler_data + offset; 516 } 517 518 template <typename Visitor> 519 inline void DexFile::ClassDef::VisitMethods(const DexFile* dex_file, const Visitor& visitor) const { 520 const uint8_t* class_data = dex_file->GetClassData(*this); 521 if (class_data != nullptr) { 522 ClassDataItemIterator it(*dex_file, class_data); 523 it.SkipAllFields(); 524 for (; it.HasNext(); it.Next()) { 525 visitor(it); 526 } 527 } 528 } 529 530 } // namespace art 531 532 #endif // ART_LIBDEXFILE_DEX_DEX_FILE_INL_H_ 533