]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserOCaml.cpp
MFC r345805: Unify SCSI_STATUS_BUSY retry handling with other cases.
[FreeBSD/FreeBSD.git] / contrib / llvm / tools / lldb / source / Plugins / SymbolFile / DWARF / DWARFASTParserOCaml.cpp
1 //===-- DWARFASTParserOCaml.cpp ---------------------------------*- C++ -*-===//
2
3 #include "DWARFASTParserOCaml.h"
4
5 #include "lldb/Core/Module.h"
6 #include "lldb/Symbol/CompileUnit.h"
7 #include "lldb/Symbol/Function.h"
8 #include "lldb/Symbol/ObjectFile.h"
9 #include "lldb/Symbol/Type.h"
10 #include "lldb/Symbol/TypeList.h"
11 #include "lldb/Utility/Log.h"
12 #include "lldb/Utility/Status.h"
13
14 using namespace lldb;
15 using namespace lldb_private;
16
17 DWARFASTParserOCaml::DWARFASTParserOCaml(OCamlASTContext &ast) : m_ast(ast) {}
18
19 DWARFASTParserOCaml::~DWARFASTParserOCaml() {}
20
21 TypeSP DWARFASTParserOCaml::ParseBaseTypeFromDIE(const DWARFDIE &die) {
22   SymbolFileDWARF *dwarf = die.GetDWARF();
23   dwarf->m_die_to_type[die.GetDIE()] = DIE_IS_BEING_PARSED;
24
25   ConstString type_name;
26   uint64_t byte_size = 0;
27
28   DWARFAttributes attributes;
29   const size_t num_attributes = die.GetAttributes(attributes);
30   for (uint32_t i = 0; i < num_attributes; ++i) {
31     DWARFFormValue form_value;
32     dw_attr_t attr = attributes.AttributeAtIndex(i);
33     if (attributes.ExtractFormValueAtIndex(i, form_value)) {
34       switch (attr) {
35       case DW_AT_name:
36         type_name.SetCString(form_value.AsCString());
37         break;
38       case DW_AT_byte_size:
39         byte_size = form_value.Unsigned();
40         break;
41       case DW_AT_encoding:
42         break;
43       default:
44         assert(false && "Unsupported attribute for DW_TAG_base_type");
45       }
46     }
47   }
48
49   Declaration decl;
50   CompilerType compiler_type = m_ast.CreateBaseType(type_name, byte_size);
51   return std::make_shared<Type>(die.GetID(), dwarf, type_name, byte_size,
52                                 nullptr, LLDB_INVALID_UID, Type::eEncodingIsUID,
53                                 decl, compiler_type, Type::eResolveStateFull);
54 }
55
56 lldb::TypeSP DWARFASTParserOCaml::ParseTypeFromDWARF(const SymbolContext &sc,
57                                                      const DWARFDIE &die,
58                                                      Log *log,
59                                                      bool *type_is_new_ptr) {
60   if (type_is_new_ptr)
61     *type_is_new_ptr = false;
62
63   if (!die)
64     return nullptr;
65
66   SymbolFileDWARF *dwarf = die.GetDWARF();
67
68   Type *type_ptr = dwarf->m_die_to_type.lookup(die.GetDIE());
69   if (type_ptr == DIE_IS_BEING_PARSED)
70     return nullptr;
71   if (type_ptr != nullptr)
72     return type_ptr->shared_from_this();
73
74   TypeSP type_sp;
75   if (type_is_new_ptr)
76     *type_is_new_ptr = true;
77
78   switch (die.Tag()) {
79   case DW_TAG_base_type: {
80     type_sp = ParseBaseTypeFromDIE(die);
81     break;
82   }
83   case DW_TAG_array_type: {
84     break;
85   }
86   case DW_TAG_class_type: {
87     break;
88   }
89   case DW_TAG_reference_type: {
90     break;
91   }
92   }
93
94   if (!type_sp)
95     return nullptr;
96
97   DWARFDIE sc_parent_die = SymbolFileDWARF::GetParentSymbolContextDIE(die);
98   dw_tag_t sc_parent_tag = sc_parent_die.Tag();
99
100   SymbolContextScope *symbol_context_scope = nullptr;
101   if (sc_parent_tag == DW_TAG_compile_unit ||
102       sc_parent_tag == DW_TAG_partial_unit) {
103     symbol_context_scope = sc.comp_unit;
104   } else if (sc.function != nullptr && sc_parent_die) {
105     symbol_context_scope =
106         sc.function->GetBlock(true).FindBlockByID(sc_parent_die.GetID());
107     if (symbol_context_scope == nullptr)
108       symbol_context_scope = sc.function;
109   }
110
111   if (symbol_context_scope != nullptr)
112     type_sp->SetSymbolContextScope(symbol_context_scope);
113
114   dwarf->GetTypeList()->Insert(type_sp);
115   dwarf->m_die_to_type[die.GetDIE()] = type_sp.get();
116
117   return type_sp;
118 }
119
120 Function *DWARFASTParserOCaml::ParseFunctionFromDWARF(const SymbolContext &sc,
121                                                       const DWARFDIE &die) {
122   DWARFRangeList func_ranges;
123   const char *name = NULL;
124   const char *mangled = NULL;
125   int decl_file = 0;
126   int decl_line = 0;
127   int decl_column = 0;
128   int call_file = 0;
129   int call_line = 0;
130   int call_column = 0;
131   DWARFExpression frame_base(die.GetCU());
132
133   Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_LANGUAGE));
134
135   if (die) {
136     SymbolFileDWARF *dwarf = die.GetDWARF();
137     if (log) {
138       dwarf->GetObjectFile()->GetModule()->LogMessage(
139           log, "DWARFASTParserOCaml::ParseFunctionFromDWARF (die = 0x%8.8x) %s "
140                "name = '%s')",
141           die.GetOffset(), DW_TAG_value_to_name(die.Tag()), die.GetName());
142     }
143   }
144
145   assert(die.Tag() == DW_TAG_subprogram);
146
147   if (die.Tag() != DW_TAG_subprogram)
148     return NULL;
149
150   if (die.GetDIENamesAndRanges(name, mangled, func_ranges, decl_file, decl_line,
151                                decl_column, call_file, call_line, call_column,
152                                &frame_base)) {
153     AddressRange func_range;
154     lldb::addr_t lowest_func_addr = func_ranges.GetMinRangeBase(0);
155     lldb::addr_t highest_func_addr = func_ranges.GetMaxRangeEnd(0);
156     if (lowest_func_addr != LLDB_INVALID_ADDRESS &&
157         lowest_func_addr <= highest_func_addr) {
158       ModuleSP module_sp(die.GetModule());
159       func_range.GetBaseAddress().ResolveAddressUsingFileSections(
160           lowest_func_addr, module_sp->GetSectionList());
161       if (func_range.GetBaseAddress().IsValid())
162         func_range.SetByteSize(highest_func_addr - lowest_func_addr);
163     }
164
165     if (func_range.GetBaseAddress().IsValid()) {
166       Mangled func_name;
167
168       func_name.SetValue(ConstString(name), true);
169
170       FunctionSP func_sp;
171       std::unique_ptr<Declaration> decl_ap;
172       if (decl_file != 0 || decl_line != 0 || decl_column != 0)
173         decl_ap.reset(new Declaration(
174             sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(decl_file),
175             decl_line, decl_column));
176
177       SymbolFileDWARF *dwarf = die.GetDWARF();
178       Type *func_type = dwarf->m_die_to_type.lookup(die.GetDIE());
179
180       assert(func_type == NULL || func_type != DIE_IS_BEING_PARSED);
181
182       if (dwarf->FixupAddress(func_range.GetBaseAddress())) {
183         const user_id_t func_user_id = die.GetID();
184         func_sp.reset(new Function(sc.comp_unit,
185                                    func_user_id, // UserID is the DIE offset
186                                    func_user_id, func_name, func_type,
187                                    func_range)); // first address range
188
189         if (func_sp.get() != NULL) {
190           if (frame_base.IsValid())
191             func_sp->GetFrameBaseExpression() = frame_base;
192           sc.comp_unit->AddFunction(func_sp);
193           return func_sp.get();
194         }
195       }
196     }
197   }
198
199   return NULL;
200 }
201
202 lldb_private::CompilerDeclContext
203 DWARFASTParserOCaml::GetDeclContextForUIDFromDWARF(const DWARFDIE &die) {
204   return CompilerDeclContext();
205 }
206
207 lldb_private::CompilerDeclContext
208 DWARFASTParserOCaml::GetDeclContextContainingUIDFromDWARF(const DWARFDIE &die) {
209   return CompilerDeclContext();
210 }