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