]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserJava.cpp
MFV r337167: 9442 decrease indirect block size of spacemaps
[FreeBSD/FreeBSD.git] / contrib / llvm / tools / lldb / source / Plugins / SymbolFile / DWARF / DWARFASTParserJava.cpp
1 //===-- DWARFASTParserJava.cpp ----------------------------------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9
10 #include "DWARFASTParserJava.h"
11 #include "DWARFAttribute.h"
12 #include "DWARFCompileUnit.h"
13 #include "DWARFDebugInfoEntry.h"
14 #include "DWARFDebugInfoEntry.h"
15 #include "DWARFDeclContext.h"
16 #include "SymbolFileDWARF.h"
17
18 #include "lldb/Core/Module.h"
19 #include "lldb/Symbol/CompileUnit.h"
20 #include "lldb/Symbol/SymbolContextScope.h"
21 #include "lldb/Symbol/TypeList.h"
22
23 using namespace lldb;
24 using namespace lldb_private;
25
26 DWARFASTParserJava::DWARFASTParserJava(JavaASTContext &ast) : m_ast(ast) {}
27
28 DWARFASTParserJava::~DWARFASTParserJava() {}
29
30 TypeSP DWARFASTParserJava::ParseBaseTypeFromDIE(const DWARFDIE &die) {
31   SymbolFileDWARF *dwarf = die.GetDWARF();
32   dwarf->m_die_to_type[die.GetDIE()] = DIE_IS_BEING_PARSED;
33
34   ConstString type_name;
35   uint64_t byte_size = 0;
36
37   DWARFAttributes attributes;
38   const size_t num_attributes = die.GetAttributes(attributes);
39   for (uint32_t i = 0; i < num_attributes; ++i) {
40     DWARFFormValue form_value;
41     dw_attr_t attr = attributes.AttributeAtIndex(i);
42     if (attributes.ExtractFormValueAtIndex(i, form_value)) {
43       switch (attr) {
44       case DW_AT_name:
45         type_name.SetCString(form_value.AsCString());
46         break;
47       case DW_AT_byte_size:
48         byte_size = form_value.Unsigned();
49         break;
50       case DW_AT_encoding:
51         break;
52       default:
53         assert(false && "Unsupported attribute for DW_TAG_base_type");
54       }
55     }
56   }
57
58   Declaration decl;
59   CompilerType compiler_type = m_ast.CreateBaseType(type_name);
60   return std::make_shared<Type>(die.GetID(), dwarf, type_name, byte_size,
61                                 nullptr, LLDB_INVALID_UID, Type::eEncodingIsUID,
62                                 decl, compiler_type, Type::eResolveStateFull);
63 }
64
65 TypeSP DWARFASTParserJava::ParseArrayTypeFromDIE(const DWARFDIE &die) {
66   SymbolFileDWARF *dwarf = die.GetDWARF();
67   dwarf->m_die_to_type[die.GetDIE()] = DIE_IS_BEING_PARSED;
68
69   ConstString linkage_name;
70   DWARFFormValue type_attr_value;
71   lldb::addr_t data_offset = LLDB_INVALID_ADDRESS;
72   DWARFExpression length_expression(die.GetCU());
73
74   DWARFAttributes attributes;
75   const size_t num_attributes = die.GetAttributes(attributes);
76   for (uint32_t i = 0; i < num_attributes; ++i) {
77     DWARFFormValue form_value;
78     dw_attr_t attr = attributes.AttributeAtIndex(i);
79     if (attributes.ExtractFormValueAtIndex(i, form_value)) {
80       switch (attr) {
81       case DW_AT_linkage_name:
82         linkage_name.SetCString(form_value.AsCString());
83         break;
84       case DW_AT_type:
85         type_attr_value = form_value;
86         break;
87       case DW_AT_data_member_location:
88         data_offset = form_value.Unsigned();
89         break;
90       case DW_AT_declaration:
91         break;
92       default:
93         assert(false && "Unsupported attribute for DW_TAG_array_type");
94       }
95     }
96   }
97
98   for (DWARFDIE child_die = die.GetFirstChild(); child_die.IsValid();
99        child_die = child_die.GetSibling()) {
100     if (child_die.Tag() == DW_TAG_subrange_type) {
101       DWARFAttributes attributes;
102       const size_t num_attributes = child_die.GetAttributes(attributes);
103       for (uint32_t i = 0; i < num_attributes; ++i) {
104         DWARFFormValue form_value;
105         dw_attr_t attr = attributes.AttributeAtIndex(i);
106         if (attributes.ExtractFormValueAtIndex(i, form_value)) {
107           switch (attr) {
108           case DW_AT_count:
109             if (form_value.BlockData())
110               length_expression.CopyOpcodeData(
111                   form_value.BlockData(), form_value.Unsigned(),
112                   child_die.GetCU()->GetByteOrder(),
113                   child_die.GetCU()->GetAddressByteSize());
114             break;
115           default:
116             assert(false && "Unsupported attribute for DW_TAG_subrange_type");
117           }
118         }
119       }
120     } else {
121       assert(false && "Unsupported child for DW_TAG_array_type");
122     }
123   }
124
125   DIERef type_die_ref(type_attr_value);
126   Type *element_type = dwarf->ResolveTypeUID(type_die_ref);
127   if (!element_type)
128     return nullptr;
129
130   CompilerType element_compiler_type = element_type->GetForwardCompilerType();
131   CompilerType array_compiler_type = m_ast.CreateArrayType(
132       linkage_name, element_compiler_type, length_expression, data_offset);
133
134   Declaration decl;
135   TypeSP type_sp(new Type(die.GetID(), dwarf, array_compiler_type.GetTypeName(),
136                           -1, nullptr, type_die_ref.GetUID(dwarf),
137                           Type::eEncodingIsUID, &decl, array_compiler_type,
138                           Type::eResolveStateFull));
139   type_sp->SetEncodingType(element_type);
140   return type_sp;
141 }
142
143 TypeSP DWARFASTParserJava::ParseReferenceTypeFromDIE(const DWARFDIE &die) {
144   SymbolFileDWARF *dwarf = die.GetDWARF();
145   dwarf->m_die_to_type[die.GetDIE()] = DIE_IS_BEING_PARSED;
146
147   Declaration decl;
148   DWARFFormValue type_attr_value;
149
150   DWARFAttributes attributes;
151   const size_t num_attributes = die.GetAttributes(attributes);
152   for (uint32_t i = 0; i < num_attributes; ++i) {
153     DWARFFormValue form_value;
154     dw_attr_t attr = attributes.AttributeAtIndex(i);
155     if (attributes.ExtractFormValueAtIndex(i, form_value)) {
156       switch (attr) {
157       case DW_AT_type:
158         type_attr_value = form_value;
159         break;
160       default:
161         assert(false && "Unsupported attribute for DW_TAG_array_type");
162       }
163     }
164   }
165
166   DIERef type_die_ref(type_attr_value);
167   Type *pointee_type = dwarf->ResolveTypeUID(type_die_ref);
168   if (!pointee_type)
169     return nullptr;
170
171   CompilerType pointee_compiler_type = pointee_type->GetForwardCompilerType();
172   CompilerType reference_compiler_type =
173       m_ast.CreateReferenceType(pointee_compiler_type);
174   TypeSP type_sp(
175       new Type(die.GetID(), dwarf, reference_compiler_type.GetTypeName(), -1,
176                nullptr, type_die_ref.GetUID(dwarf), Type::eEncodingIsUID, &decl,
177                reference_compiler_type, Type::eResolveStateFull));
178   type_sp->SetEncodingType(pointee_type);
179   return type_sp;
180 }
181
182 lldb::TypeSP DWARFASTParserJava::ParseClassTypeFromDIE(const DWARFDIE &die,
183                                                        bool &is_new_type) {
184   SymbolFileDWARF *dwarf = die.GetDWARF();
185   dwarf->m_die_to_type[die.GetDIE()] = DIE_IS_BEING_PARSED;
186
187   Declaration decl;
188   ConstString name;
189   ConstString linkage_name;
190   bool is_forward_declaration = false;
191   uint32_t byte_size = 0;
192
193   DWARFAttributes attributes;
194   const size_t num_attributes = die.GetAttributes(attributes);
195   for (uint32_t i = 0; i < num_attributes; ++i) {
196     DWARFFormValue form_value;
197     dw_attr_t attr = attributes.AttributeAtIndex(i);
198     if (attributes.ExtractFormValueAtIndex(i, form_value)) {
199       switch (attr) {
200       case DW_AT_name:
201         name.SetCString(form_value.AsCString());
202         break;
203       case DW_AT_declaration:
204         is_forward_declaration = form_value.Boolean();
205         break;
206       case DW_AT_byte_size:
207         byte_size = form_value.Unsigned();
208         break;
209       case DW_AT_linkage_name:
210         linkage_name.SetCString(form_value.AsCString());
211         break;
212       default:
213         assert(false && "Unsupported attribute for DW_TAG_class_type");
214       }
215     }
216   }
217
218   UniqueDWARFASTType unique_ast_entry;
219   if (name) {
220     std::string qualified_name;
221     if (die.GetQualifiedName(qualified_name)) {
222       name.SetCString(qualified_name.c_str());
223       if (dwarf->GetUniqueDWARFASTTypeMap().Find(name, die, Declaration(), -1,
224                                                  unique_ast_entry)) {
225         if (unique_ast_entry.m_type_sp) {
226           dwarf->GetDIEToType()[die.GetDIE()] =
227               unique_ast_entry.m_type_sp.get();
228           is_new_type = false;
229           return unique_ast_entry.m_type_sp;
230         }
231       }
232     }
233   }
234
235   if (is_forward_declaration) {
236     DWARFDeclContext die_decl_ctx;
237     die.GetDWARFDeclContext(die_decl_ctx);
238
239     TypeSP type_sp = dwarf->FindDefinitionTypeForDWARFDeclContext(die_decl_ctx);
240     if (type_sp) {
241       // We found a real definition for this type elsewhere so lets use it
242       dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get();
243       is_new_type = false;
244       return type_sp;
245     }
246   }
247
248   CompilerType compiler_type(
249       &m_ast, dwarf->GetForwardDeclDieToClangType().lookup(die.GetDIE()));
250   if (!compiler_type)
251     compiler_type = m_ast.CreateObjectType(name, linkage_name, byte_size);
252
253   is_new_type = true;
254   TypeSP type_sp(new Type(die.GetID(), dwarf, name,
255                           -1, // byte size isn't specified
256                           nullptr, LLDB_INVALID_UID, Type::eEncodingIsUID,
257                           &decl, compiler_type, Type::eResolveStateForward));
258
259   // Add our type to the unique type map
260   unique_ast_entry.m_type_sp = type_sp;
261   unique_ast_entry.m_die = die;
262   unique_ast_entry.m_declaration = decl;
263   unique_ast_entry.m_byte_size = -1;
264   dwarf->GetUniqueDWARFASTTypeMap().Insert(name, unique_ast_entry);
265
266   if (!is_forward_declaration) {
267     // Leave this as a forward declaration until we need to know the details of
268     // the type
269     dwarf->GetForwardDeclDieToClangType()[die.GetDIE()] =
270         compiler_type.GetOpaqueQualType();
271     dwarf->GetForwardDeclClangTypeToDie()[compiler_type.GetOpaqueQualType()] =
272         die.GetDIERef();
273   }
274   return type_sp;
275 }
276
277 lldb::TypeSP DWARFASTParserJava::ParseTypeFromDWARF(
278     const lldb_private::SymbolContext &sc, const DWARFDIE &die,
279     lldb_private::Log *log, bool *type_is_new_ptr) {
280   if (type_is_new_ptr)
281     *type_is_new_ptr = false;
282
283   if (!die)
284     return nullptr;
285
286   SymbolFileDWARF *dwarf = die.GetDWARF();
287
288   Type *type_ptr = dwarf->m_die_to_type.lookup(die.GetDIE());
289   if (type_ptr == DIE_IS_BEING_PARSED)
290     return nullptr;
291   if (type_ptr != nullptr)
292     return type_ptr->shared_from_this();
293
294   TypeSP type_sp;
295   if (type_is_new_ptr)
296     *type_is_new_ptr = true;
297
298   switch (die.Tag()) {
299   case DW_TAG_base_type: {
300     type_sp = ParseBaseTypeFromDIE(die);
301     break;
302   }
303   case DW_TAG_array_type: {
304     type_sp = ParseArrayTypeFromDIE(die);
305     break;
306   }
307   case DW_TAG_class_type: {
308     bool is_new_type = false;
309     type_sp = ParseClassTypeFromDIE(die, is_new_type);
310     if (!is_new_type)
311       return type_sp;
312     break;
313   }
314   case DW_TAG_reference_type: {
315     type_sp = ParseReferenceTypeFromDIE(die);
316     break;
317   }
318   }
319
320   if (!type_sp)
321     return nullptr;
322
323   DWARFDIE sc_parent_die = SymbolFileDWARF::GetParentSymbolContextDIE(die);
324   dw_tag_t sc_parent_tag = sc_parent_die.Tag();
325
326   SymbolContextScope *symbol_context_scope = nullptr;
327   if (sc_parent_tag == DW_TAG_compile_unit) {
328     symbol_context_scope = sc.comp_unit;
329   } else if (sc.function != nullptr && sc_parent_die) {
330     symbol_context_scope =
331         sc.function->GetBlock(true).FindBlockByID(sc_parent_die.GetID());
332     if (symbol_context_scope == nullptr)
333       symbol_context_scope = sc.function;
334   }
335
336   if (symbol_context_scope != nullptr)
337     type_sp->SetSymbolContextScope(symbol_context_scope);
338
339   dwarf->GetTypeList()->Insert(type_sp);
340   dwarf->m_die_to_type[die.GetDIE()] = type_sp.get();
341
342   return type_sp;
343 }
344
345 lldb_private::Function *DWARFASTParserJava::ParseFunctionFromDWARF(
346     const lldb_private::SymbolContext &sc, const DWARFDIE &die) {
347   assert(die.Tag() == DW_TAG_subprogram);
348
349   const char *name = nullptr;
350   const char *mangled = nullptr;
351   int decl_file = 0;
352   int decl_line = 0;
353   int decl_column = 0;
354   int call_file = 0;
355   int call_line = 0;
356   int call_column = 0;
357   DWARFRangeList func_ranges;
358   DWARFExpression frame_base(die.GetCU());
359
360   if (die.GetDIENamesAndRanges(name, mangled, func_ranges, decl_file, decl_line,
361                                decl_column, call_file, call_line, call_column,
362                                &frame_base)) {
363     // Union of all ranges in the function DIE (if the function is
364     // discontiguous)
365     AddressRange func_range;
366     lldb::addr_t lowest_func_addr = func_ranges.GetMinRangeBase(0);
367     lldb::addr_t highest_func_addr = func_ranges.GetMaxRangeEnd(0);
368     if (lowest_func_addr != LLDB_INVALID_ADDRESS &&
369         lowest_func_addr <= highest_func_addr) {
370       ModuleSP module_sp(die.GetModule());
371       func_range.GetBaseAddress().ResolveAddressUsingFileSections(
372           lowest_func_addr, module_sp->GetSectionList());
373       if (func_range.GetBaseAddress().IsValid())
374         func_range.SetByteSize(highest_func_addr - lowest_func_addr);
375     }
376
377     if (func_range.GetBaseAddress().IsValid()) {
378       std::unique_ptr<Declaration> decl_ap;
379       if (decl_file != 0 || decl_line != 0 || decl_column != 0)
380         decl_ap.reset(new Declaration(
381             sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(decl_file),
382             decl_line, decl_column));
383
384       if (die.GetDWARF()->FixupAddress(func_range.GetBaseAddress())) {
385         FunctionSP func_sp(new Function(sc.comp_unit, die.GetID(), die.GetID(),
386                                         Mangled(ConstString(name), false),
387                                         nullptr, // No function types in java
388                                         func_range));
389         if (frame_base.IsValid())
390           func_sp->GetFrameBaseExpression() = frame_base;
391         sc.comp_unit->AddFunction(func_sp);
392
393         return func_sp.get();
394       }
395     }
396   }
397   return nullptr;
398 }
399
400 bool DWARFASTParserJava::CompleteTypeFromDWARF(
401     const DWARFDIE &die, lldb_private::Type *type,
402     lldb_private::CompilerType &java_type) {
403   switch (die.Tag()) {
404   case DW_TAG_class_type: {
405     if (die.GetAttributeValueAsUnsigned(DW_AT_declaration, 0) == 0) {
406       if (die.HasChildren())
407         ParseChildMembers(die, java_type);
408       m_ast.CompleteObjectType(java_type);
409       return java_type.IsValid();
410     }
411   } break;
412   default:
413     assert(false && "Not a forward java type declaration!");
414     break;
415   }
416   return false;
417 }
418
419 void DWARFASTParserJava::ParseChildMembers(const DWARFDIE &parent_die,
420                                            CompilerType &compiler_type) {
421   DWARFCompileUnit *dwarf_cu = parent_die.GetCU();
422   for (DWARFDIE die = parent_die.GetFirstChild(); die.IsValid();
423        die = die.GetSibling()) {
424     switch (die.Tag()) {
425     case DW_TAG_member: {
426       const char *name = nullptr;
427       DWARFFormValue encoding_uid;
428       uint32_t member_byte_offset = UINT32_MAX;
429       DWARFExpression member_location_expression(dwarf_cu);
430
431       DWARFAttributes attributes;
432       size_t num_attributes = die.GetAttributes(attributes);
433       for (size_t i = 0; i < num_attributes; ++i) {
434         DWARFFormValue form_value;
435         if (attributes.ExtractFormValueAtIndex(i, form_value)) {
436           switch (attributes.AttributeAtIndex(i)) {
437           case DW_AT_name:
438             name = form_value.AsCString();
439             break;
440           case DW_AT_type:
441             encoding_uid = form_value;
442             break;
443           case DW_AT_data_member_location:
444             if (form_value.BlockData())
445               member_location_expression.CopyOpcodeData(
446                   form_value.BlockData(), form_value.Unsigned(),
447                   dwarf_cu->GetByteOrder(), dwarf_cu->GetAddressByteSize());
448             else
449               member_byte_offset = form_value.Unsigned();
450             break;
451           case DW_AT_artificial:
452             static_cast<void>(form_value.Boolean());
453             break;
454           case DW_AT_accessibility:
455             // TODO: Handle when needed
456             break;
457           default:
458             assert(false && "Unhandled attribute for DW_TAG_member");
459             break;
460           }
461         }
462       }
463
464       if (strcmp(name, ".dynamic_type") == 0)
465         m_ast.SetDynamicTypeId(compiler_type, member_location_expression);
466       else {
467         if (Type *member_type = die.ResolveTypeUID(DIERef(encoding_uid)))
468           m_ast.AddMemberToObject(compiler_type, ConstString(name),
469                                   member_type->GetFullCompilerType(),
470                                   member_byte_offset);
471       }
472       break;
473     }
474     case DW_TAG_inheritance: {
475       DWARFFormValue encoding_uid;
476       uint32_t member_byte_offset = UINT32_MAX;
477
478       DWARFAttributes attributes;
479       size_t num_attributes = die.GetAttributes(attributes);
480       for (size_t i = 0; i < num_attributes; ++i) {
481         DWARFFormValue form_value;
482         if (attributes.ExtractFormValueAtIndex(i, form_value)) {
483           switch (attributes.AttributeAtIndex(i)) {
484           case DW_AT_type:
485             encoding_uid = form_value;
486             break;
487           case DW_AT_data_member_location:
488             member_byte_offset = form_value.Unsigned();
489             break;
490           case DW_AT_accessibility:
491             // In java all base class is public so we can ignore this attribute
492             break;
493           default:
494             assert(false && "Unhandled attribute for DW_TAG_member");
495             break;
496           }
497         }
498       }
499       if (Type *base_type = die.ResolveTypeUID(DIERef(encoding_uid)))
500         m_ast.AddBaseClassToObject(compiler_type,
501                                    base_type->GetFullCompilerType(),
502                                    member_byte_offset);
503       break;
504     }
505     default:
506       break;
507     }
508   }
509 }