1 /* 2 * Copyright (C) 2016 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_COMPILER_DEBUG_ELF_DEBUG_INFO_WRITER_H_ 18 #define ART_COMPILER_DEBUG_ELF_DEBUG_INFO_WRITER_H_ 19 20 #include <map> 21 #include <unordered_set> 22 #include <vector> 23 24 #include "art_field-inl.h" 25 #include "debug/elf_compilation_unit.h" 26 #include "debug/elf_debug_loc_writer.h" 27 #include "debug/method_debug_info.h" 28 #include "dex/code_item_accessors-inl.h" 29 #include "dex/dex_file-inl.h" 30 #include "dex/dex_file.h" 31 #include "dwarf/debug_abbrev_writer.h" 32 #include "dwarf/debug_info_entry_writer.h" 33 #include "elf/elf_builder.h" 34 #include "heap_poisoning.h" 35 #include "linear_alloc.h" 36 #include "mirror/array.h" 37 #include "mirror/class-inl.h" 38 #include "mirror/class.h" 39 #include "oat_file.h" 40 #include "obj_ptr-inl.h" 41 42 namespace art { 43 namespace debug { 44 45 static std::vector<const char*> GetParamNames(const MethodDebugInfo* mi) { 46 std::vector<const char*> names; 47 DCHECK(mi->dex_file != nullptr); 48 CodeItemDebugInfoAccessor accessor(*mi->dex_file, mi->code_item, mi->dex_method_index); 49 if (accessor.HasCodeItem()) { 50 accessor.VisitParameterNames([&](const dex::StringIndex& id) { 51 names.push_back(mi->dex_file->StringDataByIdx(id)); 52 }); 53 } 54 return names; 55 } 56 57 // Helper class to write .debug_info and its supporting sections. 58 template<typename ElfTypes> 59 class ElfDebugInfoWriter { 60 using Elf_Addr = typename ElfTypes::Addr; 61 62 public: 63 explicit ElfDebugInfoWriter(ElfBuilder<ElfTypes>* builder) 64 : builder_(builder), 65 debug_abbrev_(&debug_abbrev_buffer_) { 66 } 67 68 void Start() { 69 builder_->GetDebugInfo()->Start(); 70 } 71 72 void End() { 73 builder_->GetDebugInfo()->End(); 74 builder_->WriteSection(".debug_abbrev", &debug_abbrev_buffer_); 75 if (!debug_loc_.empty()) { 76 builder_->WriteSection(".debug_loc", &debug_loc_); 77 } 78 if (!debug_ranges_.empty()) { 79 builder_->WriteSection(".debug_ranges", &debug_ranges_); 80 } 81 } 82 83 private: 84 ElfBuilder<ElfTypes>* builder_; 85 std::vector<uint8_t> debug_abbrev_buffer_; 86 dwarf::DebugAbbrevWriter<> debug_abbrev_; 87 std::vector<uint8_t> debug_loc_; 88 std::vector<uint8_t> debug_ranges_; 89 90 std::unordered_set<const char*> defined_dex_classes_; // For CHECKs only. 91 92 template<typename ElfTypes2> 93 friend class ElfCompilationUnitWriter; 94 }; 95 96 // Helper class to write one compilation unit. 97 // It holds helper methods and temporary state. 98 template<typename ElfTypes> 99 class ElfCompilationUnitWriter { 100 using Elf_Addr = typename ElfTypes::Addr; 101 102 public: 103 explicit ElfCompilationUnitWriter(ElfDebugInfoWriter<ElfTypes>* owner) 104 : owner_(owner), 105 info_(Is64BitInstructionSet(owner_->builder_->GetIsa()), &owner->debug_abbrev_) { 106 } 107 108 void Write(const ElfCompilationUnit& compilation_unit) { 109 CHECK(!compilation_unit.methods.empty()); 110 const Elf_Addr base_address = compilation_unit.is_code_address_text_relative 111 ? owner_->builder_->GetText()->GetAddress() 112 : 0; 113 const bool is64bit = Is64BitInstructionSet(owner_->builder_->GetIsa()); 114 using namespace dwarf; // NOLINT. For easy access to DWARF constants. 115 116 info_.StartTag(DW_TAG_compile_unit); 117 info_.WriteString(DW_AT_producer, "Android dex2oat"); 118 info_.WriteData1(DW_AT_language, DW_LANG_Java); 119 info_.WriteString(DW_AT_comp_dir, "$JAVA_SRC_ROOT"); 120 // The low_pc acts as base address for several other addresses/ranges. 121 info_.WriteAddr(DW_AT_low_pc, base_address + compilation_unit.code_address); 122 info_.WriteSecOffset(DW_AT_stmt_list, compilation_unit.debug_line_offset); 123 124 // Write .debug_ranges entries covering code ranges of the whole compilation unit. 125 dwarf::Writer<> debug_ranges(&owner_->debug_ranges_); 126 info_.WriteSecOffset(DW_AT_ranges, owner_->debug_ranges_.size()); 127 for (auto mi : compilation_unit.methods) { 128 uint64_t low_pc = mi->code_address - compilation_unit.code_address; 129 uint64_t high_pc = low_pc + mi->code_size; 130 if (is64bit) { 131 debug_ranges.PushUint64(low_pc); 132 debug_ranges.PushUint64(high_pc); 133 } else { 134 debug_ranges.PushUint32(low_pc); 135 debug_ranges.PushUint32(high_pc); 136 } 137 } 138 if (is64bit) { 139 debug_ranges.PushUint64(0); // End of list. 140 debug_ranges.PushUint64(0); 141 } else { 142 debug_ranges.PushUint32(0); // End of list. 143 debug_ranges.PushUint32(0); 144 } 145 146 const char* last_dex_class_desc = nullptr; 147 for (auto mi : compilation_unit.methods) { 148 DCHECK(mi->dex_file != nullptr); 149 const DexFile* dex = mi->dex_file; 150 CodeItemDebugInfoAccessor accessor(*dex, mi->code_item, mi->dex_method_index); 151 const dex::MethodId& dex_method = dex->GetMethodId(mi->dex_method_index); 152 const dex::ProtoId& dex_proto = dex->GetMethodPrototype(dex_method); 153 const dex::TypeList* dex_params = dex->GetProtoParameters(dex_proto); 154 const char* dex_class_desc = dex->GetMethodDeclaringClassDescriptor(dex_method); 155 const bool is_static = (mi->access_flags & kAccStatic) != 0; 156 157 // Enclose the method in correct class definition. 158 if (last_dex_class_desc != dex_class_desc) { 159 if (last_dex_class_desc != nullptr) { 160 EndClassTag(); 161 } 162 // Write reference tag for the class we are about to declare. 163 size_t reference_tag_offset = info_.StartTag(DW_TAG_reference_type); 164 type_cache_.emplace(std::string(dex_class_desc), reference_tag_offset); 165 size_t type_attrib_offset = info_.size(); 166 info_.WriteRef4(DW_AT_type, 0); 167 info_.EndTag(); 168 // Declare the class that owns this method. 169 size_t class_offset = StartClassTag(dex_class_desc); 170 info_.UpdateUint32(type_attrib_offset, class_offset); 171 info_.WriteFlagPresent(DW_AT_declaration); 172 // Check that each class is defined only once. 173 bool unique = owner_->defined_dex_classes_.insert(dex_class_desc).second; 174 CHECK(unique) << "Redefinition of " << dex_class_desc; 175 last_dex_class_desc = dex_class_desc; 176 } 177 178 int start_depth = info_.Depth(); 179 info_.StartTag(DW_TAG_subprogram); 180 WriteName(dex->GetMethodName(dex_method)); 181 info_.WriteAddr(DW_AT_low_pc, base_address + mi->code_address); 182 info_.WriteUdata(DW_AT_high_pc, mi->code_size); 183 std::vector<uint8_t> expr_buffer; 184 Expression expr(&expr_buffer); 185 expr.WriteOpCallFrameCfa(); 186 info_.WriteExprLoc(DW_AT_frame_base, expr); 187 WriteLazyType(dex->GetReturnTypeDescriptor(dex_proto)); 188 189 // Decode dex register locations for all stack maps. 190 // It might be expensive, so do it just once and reuse the result. 191 std::unique_ptr<const CodeInfo> code_info; 192 std::vector<DexRegisterMap> dex_reg_maps; 193 if (accessor.HasCodeItem() && mi->code_info != nullptr) { 194 code_info.reset(new CodeInfo(mi->code_info)); 195 for (StackMap stack_map : code_info->GetStackMaps()) { 196 dex_reg_maps.push_back(code_info->GetDexRegisterMapOf(stack_map)); 197 } 198 } 199 200 // Write parameters. DecodeDebugLocalInfo returns them as well, but it does not 201 // guarantee order or uniqueness so it is safer to iterate over them manually. 202 // DecodeDebugLocalInfo might not also be available if there is no debug info. 203 std::vector<const char*> param_names = GetParamNames(mi); 204 uint32_t arg_reg = 0; 205 if (!is_static) { 206 info_.StartTag(DW_TAG_formal_parameter); 207 WriteName("this"); 208 info_.WriteFlagPresent(DW_AT_artificial); 209 WriteLazyType(dex_class_desc); 210 if (accessor.HasCodeItem()) { 211 // Write the stack location of the parameter. 212 const uint32_t vreg = accessor.RegistersSize() - accessor.InsSize() + arg_reg; 213 const bool is64bitValue = false; 214 WriteRegLocation(mi, dex_reg_maps, vreg, is64bitValue, compilation_unit.code_address); 215 } 216 arg_reg++; 217 info_.EndTag(); 218 } 219 if (dex_params != nullptr) { 220 for (uint32_t i = 0; i < dex_params->Size(); ++i) { 221 info_.StartTag(DW_TAG_formal_parameter); 222 // Parameter names may not be always available. 223 if (i < param_names.size()) { 224 WriteName(param_names[i]); 225 } 226 // Write the type. 227 const char* type_desc = dex->StringByTypeIdx(dex_params->GetTypeItem(i).type_idx_); 228 WriteLazyType(type_desc); 229 const bool is64bitValue = type_desc[0] == 'D' || type_desc[0] == 'J'; 230 if (accessor.HasCodeItem()) { 231 // Write the stack location of the parameter. 232 const uint32_t vreg = accessor.RegistersSize() - accessor.InsSize() + arg_reg; 233 WriteRegLocation(mi, dex_reg_maps, vreg, is64bitValue, compilation_unit.code_address); 234 } 235 arg_reg += is64bitValue ? 2 : 1; 236 info_.EndTag(); 237 } 238 if (accessor.HasCodeItem()) { 239 DCHECK_EQ(arg_reg, accessor.InsSize()); 240 } 241 } 242 243 // Write local variables. 244 std::vector<DexFile::LocalInfo> local_infos; 245 if (accessor.DecodeDebugLocalInfo(is_static, 246 mi->dex_method_index, 247 [&](const DexFile::LocalInfo& entry) { 248 local_infos.push_back(entry); 249 })) { 250 for (const DexFile::LocalInfo& var : local_infos) { 251 if (var.reg_ < accessor.RegistersSize() - accessor.InsSize()) { 252 info_.StartTag(DW_TAG_variable); 253 WriteName(var.name_); 254 WriteLazyType(var.descriptor_); 255 bool is64bitValue = var.descriptor_[0] == 'D' || var.descriptor_[0] == 'J'; 256 WriteRegLocation(mi, 257 dex_reg_maps, 258 var.reg_, 259 is64bitValue, 260 compilation_unit.code_address, 261 var.start_address_, 262 var.end_address_); 263 info_.EndTag(); 264 } 265 } 266 } 267 268 info_.EndTag(); 269 CHECK_EQ(info_.Depth(), start_depth); // Balanced start/end. 270 } 271 if (last_dex_class_desc != nullptr) { 272 EndClassTag(); 273 } 274 FinishLazyTypes(); 275 CloseNamespacesAboveDepth(0); 276 info_.EndTag(); // DW_TAG_compile_unit 277 CHECK_EQ(info_.Depth(), 0); 278 std::vector<uint8_t> buffer; 279 buffer.reserve(info_.data()->size() + KB); 280 // All compilation units share single table which is at the start of .debug_abbrev. 281 const size_t debug_abbrev_offset = 0; 282 WriteDebugInfoCU(debug_abbrev_offset, info_, &buffer); 283 owner_->builder_->GetDebugInfo()->WriteFully(buffer.data(), buffer.size()); 284 } 285 286 void Write(const ArrayRef<mirror::Class*>& types) REQUIRES_SHARED(Locks::mutator_lock_) { 287 using namespace dwarf; // NOLINT. For easy access to DWARF constants. 288 289 info_.StartTag(DW_TAG_compile_unit); 290 info_.WriteString(DW_AT_producer, "Android dex2oat"); 291 info_.WriteData1(DW_AT_language, DW_LANG_Java); 292 293 // Base class references to be patched at the end. 294 std::map<size_t, mirror::Class*> base_class_references; 295 296 // Already written declarations or definitions. 297 std::map<mirror::Class*, size_t> class_declarations; 298 299 std::vector<uint8_t> expr_buffer; 300 for (mirror::Class* type : types) { 301 if (type->IsPrimitive()) { 302 // For primitive types the definition and the declaration is the same. 303 if (type->GetPrimitiveType() != Primitive::kPrimVoid) { 304 WriteTypeDeclaration(type->GetDescriptor(nullptr)); 305 } 306 } else if (type->IsArrayClass()) { 307 ObjPtr<mirror::Class> element_type = type->GetComponentType(); 308 uint32_t component_size = type->GetComponentSize(); 309 uint32_t data_offset = mirror::Array::DataOffset(component_size).Uint32Value(); 310 uint32_t length_offset = mirror::Array::LengthOffset().Uint32Value(); 311 312 CloseNamespacesAboveDepth(0); // Declare in root namespace. 313 info_.StartTag(DW_TAG_array_type); 314 std::string descriptor_string; 315 WriteLazyType(element_type->GetDescriptor(&descriptor_string)); 316 WriteLinkageName(type); 317 info_.WriteUdata(DW_AT_data_member_location, data_offset); 318 info_.StartTag(DW_TAG_subrange_type); 319 Expression count_expr(&expr_buffer); 320 count_expr.WriteOpPushObjectAddress(); 321 count_expr.WriteOpPlusUconst(length_offset); 322 count_expr.WriteOpDerefSize(4); // Array length is always 32-bit wide. 323 info_.WriteExprLoc(DW_AT_count, count_expr); 324 info_.EndTag(); // DW_TAG_subrange_type. 325 info_.EndTag(); // DW_TAG_array_type. 326 } else if (type->IsInterface()) { 327 // Skip. Variables cannot have an interface as a dynamic type. 328 // We do not expose the interface information to the debugger in any way. 329 } else { 330 std::string descriptor_string; 331 const char* desc = type->GetDescriptor(&descriptor_string); 332 size_t class_offset = StartClassTag(desc); 333 class_declarations.emplace(type, class_offset); 334 335 if (!type->IsVariableSize()) { 336 info_.WriteUdata(DW_AT_byte_size, type->GetObjectSize()); 337 } 338 339 WriteLinkageName(type); 340 341 if (type->IsObjectClass()) { 342 // Generate artificial member which is used to get the dynamic type of variable. 343 // The run-time value of this field will correspond to linkage name of some type. 344 // We need to do it only once in j.l.Object since all other types inherit it. 345 info_.StartTag(DW_TAG_member); 346 WriteName(".dynamic_type"); 347 WriteLazyType(sizeof(uintptr_t) == 8 ? "J" : "I"); 348 info_.WriteFlagPresent(DW_AT_artificial); 349 // Create DWARF expression to get the value of the methods_ field. 350 Expression expr(&expr_buffer); 351 // The address of the object has been implicitly pushed on the stack. 352 // Dereference the klass_ field of Object (32-bit; possibly poisoned). 353 DCHECK_EQ(type->ClassOffset().Uint32Value(), 0u); 354 DCHECK_EQ(sizeof(mirror::HeapReference<mirror::Class>), 4u); 355 expr.WriteOpDerefSize(4); 356 if (kPoisonHeapReferences) { 357 expr.WriteOpNeg(); 358 // DWARF stack is pointer sized. Ensure that the high bits are clear. 359 expr.WriteOpConstu(0xFFFFFFFF); 360 expr.WriteOpAnd(); 361 } 362 // Add offset to the methods_ field. 363 expr.WriteOpPlusUconst(mirror::Class::MethodsOffset().Uint32Value()); 364 // Top of stack holds the location of the field now. 365 info_.WriteExprLoc(DW_AT_data_member_location, expr); 366 info_.EndTag(); // DW_TAG_member. 367 } 368 369 // Base class. 370 ObjPtr<mirror::Class> base_class = type->GetSuperClass(); 371 if (base_class != nullptr) { 372 info_.StartTag(DW_TAG_inheritance); 373 base_class_references.emplace(info_.size(), base_class.Ptr()); 374 info_.WriteRef4(DW_AT_type, 0); 375 info_.WriteUdata(DW_AT_data_member_location, 0); 376 info_.WriteSdata(DW_AT_accessibility, DW_ACCESS_public); 377 info_.EndTag(); // DW_TAG_inheritance. 378 } 379 380 // Member variables. 381 for (uint32_t i = 0, count = type->NumInstanceFields(); i < count; ++i) { 382 ArtField* field = type->GetInstanceField(i); 383 info_.StartTag(DW_TAG_member); 384 WriteName(field->GetName()); 385 WriteLazyType(field->GetTypeDescriptor()); 386 info_.WriteUdata(DW_AT_data_member_location, field->GetOffset().Uint32Value()); 387 uint32_t access_flags = field->GetAccessFlags(); 388 if (access_flags & kAccPublic) { 389 info_.WriteSdata(DW_AT_accessibility, DW_ACCESS_public); 390 } else if (access_flags & kAccProtected) { 391 info_.WriteSdata(DW_AT_accessibility, DW_ACCESS_protected); 392 } else if (access_flags & kAccPrivate) { 393 info_.WriteSdata(DW_AT_accessibility, DW_ACCESS_private); 394 } 395 info_.EndTag(); // DW_TAG_member. 396 } 397 398 if (type->IsStringClass()) { 399 // Emit debug info about an artifical class member for java.lang.String which represents 400 // the first element of the data stored in a string instance. Consumers of the debug 401 // info will be able to read the content of java.lang.String based on the count (real 402 // field) and based on the location of this data member. 403 info_.StartTag(DW_TAG_member); 404 WriteName("value"); 405 // We don't support fields with C like array types so we just say its type is java char. 406 WriteLazyType("C"); // char. 407 info_.WriteUdata(DW_AT_data_member_location, 408 mirror::String::ValueOffset().Uint32Value()); 409 info_.WriteSdata(DW_AT_accessibility, DW_ACCESS_private); 410 info_.EndTag(); // DW_TAG_member. 411 } 412 413 EndClassTag(); 414 } 415 } 416 417 // Write base class declarations. 418 for (const auto& base_class_reference : base_class_references) { 419 size_t reference_offset = base_class_reference.first; 420 mirror::Class* base_class = base_class_reference.second; 421 const auto it = class_declarations.find(base_class); 422 if (it != class_declarations.end()) { 423 info_.UpdateUint32(reference_offset, it->second); 424 } else { 425 // Declare base class. We can not use the standard WriteLazyType 426 // since we want to avoid the DW_TAG_reference_tag wrapping. 427 std::string tmp_storage; 428 const char* base_class_desc = base_class->GetDescriptor(&tmp_storage); 429 size_t base_class_declaration_offset = StartClassTag(base_class_desc); 430 info_.WriteFlagPresent(DW_AT_declaration); 431 WriteLinkageName(base_class); 432 EndClassTag(); 433 class_declarations.emplace(base_class, base_class_declaration_offset); 434 info_.UpdateUint32(reference_offset, base_class_declaration_offset); 435 } 436 } 437 438 FinishLazyTypes(); 439 CloseNamespacesAboveDepth(0); 440 info_.EndTag(); // DW_TAG_compile_unit. 441 CHECK_EQ(info_.Depth(), 0); 442 std::vector<uint8_t> buffer; 443 buffer.reserve(info_.data()->size() + KB); 444 // All compilation units share single table which is at the start of .debug_abbrev. 445 const size_t debug_abbrev_offset = 0; 446 WriteDebugInfoCU(debug_abbrev_offset, info_, &buffer); 447 owner_->builder_->GetDebugInfo()->WriteFully(buffer.data(), buffer.size()); 448 } 449 450 // Write table into .debug_loc which describes location of dex register. 451 // The dex register might be valid only at some points and it might 452 // move between machine registers and stack. 453 void WriteRegLocation(const MethodDebugInfo* method_info, 454 const std::vector<DexRegisterMap>& dex_register_maps, 455 uint16_t vreg, 456 bool is64bitValue, 457 uint64_t compilation_unit_code_address, 458 uint32_t dex_pc_low = 0, 459 uint32_t dex_pc_high = 0xFFFFFFFF) { 460 WriteDebugLocEntry(method_info, 461 dex_register_maps, 462 vreg, 463 is64bitValue, 464 compilation_unit_code_address, 465 dex_pc_low, 466 dex_pc_high, 467 owner_->builder_->GetIsa(), 468 &info_, 469 &owner_->debug_loc_, 470 &owner_->debug_ranges_); 471 } 472 473 // Linkage name uniquely identifies type. 474 // It is used to determine the dynamic type of objects. 475 // We use the methods_ field of class since it is unique and it is not moved by the GC. 476 void WriteLinkageName(mirror::Class* type) REQUIRES_SHARED(Locks::mutator_lock_) { 477 auto* methods_ptr = type->GetMethodsPtr(); 478 if (methods_ptr == nullptr) { 479 // Some types might have no methods. Allocate empty array instead. 480 LinearAlloc* allocator = Runtime::Current()->GetLinearAlloc(); 481 void* storage = allocator->Alloc(Thread::Current(), sizeof(LengthPrefixedArray<ArtMethod>)); 482 methods_ptr = new (storage) LengthPrefixedArray<ArtMethod>(0); 483 type->SetMethodsPtr(methods_ptr, 0, 0); 484 DCHECK(type->GetMethodsPtr() != nullptr); 485 } 486 char name[32]; 487 snprintf(name, sizeof(name), "0x%" PRIXPTR, reinterpret_cast<uintptr_t>(methods_ptr)); 488 info_.WriteString(dwarf::DW_AT_linkage_name, name); 489 } 490 491 // Some types are difficult to define as we go since they need 492 // to be enclosed in the right set of namespaces. Therefore we 493 // just define all types lazily at the end of compilation unit. 494 void WriteLazyType(const char* type_descriptor) { 495 if (type_descriptor != nullptr && type_descriptor[0] != 'V') { 496 lazy_types_.emplace(std::string(type_descriptor), info_.size()); 497 info_.WriteRef4(dwarf::DW_AT_type, 0); 498 } 499 } 500 501 void FinishLazyTypes() { 502 for (const auto& lazy_type : lazy_types_) { 503 info_.UpdateUint32(lazy_type.second, WriteTypeDeclaration(lazy_type.first)); 504 } 505 lazy_types_.clear(); 506 } 507 508 private: 509 void WriteName(const char* name) { 510 if (name != nullptr) { 511 info_.WriteString(dwarf::DW_AT_name, name); 512 } 513 } 514 515 // Convert dex type descriptor to DWARF. 516 // Returns offset in the compilation unit. 517 size_t WriteTypeDeclaration(const std::string& desc) { 518 using namespace dwarf; // NOLINT. For easy access to DWARF constants. 519 520 DCHECK(!desc.empty()); 521 const auto it = type_cache_.find(desc); 522 if (it != type_cache_.end()) { 523 return it->second; 524 } 525 526 size_t offset; 527 if (desc[0] == 'L') { 528 // Class type. For example: Lpackage/name; 529 size_t class_offset = StartClassTag(desc.c_str()); 530 info_.WriteFlagPresent(DW_AT_declaration); 531 EndClassTag(); 532 // Reference to the class type. 533 offset = info_.StartTag(DW_TAG_reference_type); 534 info_.WriteRef(DW_AT_type, class_offset); 535 info_.EndTag(); 536 } else if (desc[0] == '[') { 537 // Array type. 538 size_t element_type = WriteTypeDeclaration(desc.substr(1)); 539 CloseNamespacesAboveDepth(0); // Declare in root namespace. 540 size_t array_type = info_.StartTag(DW_TAG_array_type); 541 info_.WriteFlagPresent(DW_AT_declaration); 542 info_.WriteRef(DW_AT_type, element_type); 543 info_.EndTag(); 544 offset = info_.StartTag(DW_TAG_reference_type); 545 info_.WriteRef4(DW_AT_type, array_type); 546 info_.EndTag(); 547 } else { 548 // Primitive types. 549 DCHECK_EQ(desc.size(), 1u); 550 551 const char* name; 552 uint32_t encoding; 553 uint32_t byte_size; 554 switch (desc[0]) { 555 case 'B': 556 name = "byte"; 557 encoding = DW_ATE_signed; 558 byte_size = 1; 559 break; 560 case 'C': 561 name = "char"; 562 encoding = DW_ATE_UTF; 563 byte_size = 2; 564 break; 565 case 'D': 566 name = "double"; 567 encoding = DW_ATE_float; 568 byte_size = 8; 569 break; 570 case 'F': 571 name = "float"; 572 encoding = DW_ATE_float; 573 byte_size = 4; 574 break; 575 case 'I': 576 name = "int"; 577 encoding = DW_ATE_signed; 578 byte_size = 4; 579 break; 580 case 'J': 581 name = "long"; 582 encoding = DW_ATE_signed; 583 byte_size = 8; 584 break; 585 case 'S': 586 name = "short"; 587 encoding = DW_ATE_signed; 588 byte_size = 2; 589 break; 590 case 'Z': 591 name = "boolean"; 592 encoding = DW_ATE_boolean; 593 byte_size = 1; 594 break; 595 case 'V': 596 LOG(FATAL) << "Void type should not be encoded"; 597 UNREACHABLE(); 598 default: 599 LOG(FATAL) << "Unknown dex type descriptor: \"" << desc << "\""; 600 UNREACHABLE(); 601 } 602 CloseNamespacesAboveDepth(0); // Declare in root namespace. 603 offset = info_.StartTag(DW_TAG_base_type); 604 WriteName(name); 605 info_.WriteData1(DW_AT_encoding, encoding); 606 info_.WriteData1(DW_AT_byte_size, byte_size); 607 info_.EndTag(); 608 } 609 610 type_cache_.emplace(desc, offset); 611 return offset; 612 } 613 614 // Start DW_TAG_class_type tag nested in DW_TAG_namespace tags. 615 // Returns offset of the class tag in the compilation unit. 616 size_t StartClassTag(const char* desc) { 617 std::string name = SetNamespaceForClass(desc); 618 size_t offset = info_.StartTag(dwarf::DW_TAG_class_type); 619 WriteName(name.c_str()); 620 return offset; 621 } 622 623 void EndClassTag() { 624 info_.EndTag(); 625 } 626 627 // Set the current namespace nesting to one required by the given class. 628 // Returns the class name with namespaces, 'L', and ';' stripped. 629 std::string SetNamespaceForClass(const char* desc) { 630 DCHECK(desc != nullptr && desc[0] == 'L'); 631 desc++; // Skip the initial 'L'. 632 size_t depth = 0; 633 for (const char* end; (end = strchr(desc, '/')) != nullptr; desc = end + 1, ++depth) { 634 // Check whether the name at this depth is already what we need. 635 if (depth < current_namespace_.size()) { 636 const std::string& name = current_namespace_[depth]; 637 if (name.compare(0, name.size(), desc, end - desc) == 0) { 638 continue; 639 } 640 } 641 // Otherwise we need to open a new namespace tag at this depth. 642 CloseNamespacesAboveDepth(depth); 643 info_.StartTag(dwarf::DW_TAG_namespace); 644 std::string name(desc, end - desc); 645 WriteName(name.c_str()); 646 current_namespace_.push_back(std::move(name)); 647 } 648 CloseNamespacesAboveDepth(depth); 649 return std::string(desc, strchr(desc, ';') - desc); 650 } 651 652 // Close namespace tags to reach the given nesting depth. 653 void CloseNamespacesAboveDepth(size_t depth) { 654 DCHECK_LE(depth, current_namespace_.size()); 655 while (current_namespace_.size() > depth) { 656 info_.EndTag(); 657 current_namespace_.pop_back(); 658 } 659 } 660 661 // For access to the ELF sections. 662 ElfDebugInfoWriter<ElfTypes>* owner_; 663 // Temporary buffer to create and store the entries. 664 dwarf::DebugInfoEntryWriter<> info_; 665 // Cache of already translated type descriptors. 666 std::map<std::string, size_t> type_cache_; // type_desc -> definition_offset. 667 // 32-bit references which need to be resolved to a type later. 668 // Given type may be used multiple times. Therefore we need a multimap. 669 std::multimap<std::string, size_t> lazy_types_; // type_desc -> patch_offset. 670 // The current set of open namespace tags which are active and not closed yet. 671 std::vector<std::string> current_namespace_; 672 }; 673 674 } // namespace debug 675 } // namespace art 676 677 #endif // ART_COMPILER_DEBUG_ELF_DEBUG_INFO_WRITER_H_ 678 679