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