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