1 /*
2 * Copyright (c) 2023 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "debug_info.h"
17 #include "mir_builder.h"
18 #include "printing.h"
19 #include "maple_string.h"
20 #include "global_tables.h"
21 #include "mir_type.h"
22 #include <cstring>
23 #include "securec.h"
24 #include "mpl_logging.h"
25 #include "version.h"
26 #include "debug_info_util.h"
27
28 namespace maple {
29 constexpr uint32 kIndx2 = 2;
30 constexpr uint32 kStructDBGSize = 8888;
31
32 // DBGDie methods
DBGDie(MIRModule * m,DwTag tag)33 DBGDie::DBGDie(MIRModule *m, DwTag tag)
34 : module(m),
35 tag(tag),
36 id(m->GetDbgInfo()->GetMaxId()),
37 withChildren(false),
38 sibling(nullptr),
39 firstChild(nullptr),
40 abbrevId(0),
41 tyIdx(0),
42 offset(0),
43 size(0),
44 attrVec(m->GetMPAllocator().Adapter()),
45 subDieVec(m->GetMPAllocator().Adapter())
46 {
47 if (module->GetDbgInfo()->GetParentDieSize()) {
48 parent = module->GetDbgInfo()->GetParentDie();
49 } else {
50 parent = nullptr;
51 }
52 m->GetDbgInfo()->SetIdDieMap(m->GetDbgInfo()->GetIncMaxId(), this);
53 attrVec.clear();
54 subDieVec.clear();
55 }
56
ResetParentDie()57 void DBGDie::ResetParentDie()
58 {
59 module->GetDbgInfo()->ResetParentDie();
60 }
61
AddAttr(DwAt at,DwForm form,uint64 val)62 DBGDieAttr *DBGDie::AddAttr(DwAt at, DwForm form, uint64 val)
63 {
64 // collect strps which need label
65 if (form == DW_FORM_strp) {
66 module->GetDbgInfo()->AddStrps(static_cast<uint32>(val));
67 }
68 DBGDieAttr *attr = module->GetDbgInfo()->CreateAttr(at, form, val);
69 AddAttr(attr);
70 return attr;
71 }
72
AddSimpLocAttr(DwAt at,DwForm form,uint64 val)73 DBGDieAttr *DBGDie::AddSimpLocAttr(DwAt at, DwForm form, uint64 val)
74 {
75 DBGExprLoc *p = module->GetMemPool()->New<DBGExprLoc>(module, DW_OP_fbreg);
76 if (val != kDbgDefaultVal) {
77 p->AddSimpLocOpnd(val);
78 }
79 DBGDieAttr *attr = module->GetDbgInfo()->CreateAttr(at, form, reinterpret_cast<uint64>(p));
80 AddAttr(attr);
81 return attr;
82 }
83
AddGlobalLocAttr(DwAt at,DwForm form,uint64 val)84 DBGDieAttr *DBGDie::AddGlobalLocAttr(DwAt at, DwForm form, uint64 val)
85 {
86 DBGExprLoc *p = module->GetMemPool()->New<DBGExprLoc>(module, DW_OP_addr);
87 p->SetGvarStridx(static_cast<int>(val));
88 DBGDieAttr *attr = module->GetDbgInfo()->CreateAttr(at, form, reinterpret_cast<uint64>(p));
89 AddAttr(attr);
90 return attr;
91 }
92
AddFrmBaseAttr(DwAt at,DwForm form)93 DBGDieAttr *DBGDie::AddFrmBaseAttr(DwAt at, DwForm form)
94 {
95 DBGExprLoc *p = module->GetMemPool()->New<DBGExprLoc>(module, DW_OP_call_frame_cfa);
96 DBGDieAttr *attr = module->GetDbgInfo()->CreateAttr(at, form, reinterpret_cast<uint64>(p));
97 AddAttr(attr);
98 return attr;
99 }
100
GetExprLoc()101 DBGExprLoc *DBGDie::GetExprLoc()
102 {
103 for (auto it : attrVec) {
104 if (it->GetDwAt() == DW_AT_location) {
105 return it->GetPtr();
106 }
107 }
108 return nullptr;
109 }
110
SetAttr(DwAt attr,uint64 val)111 bool DBGDie::SetAttr(DwAt attr, uint64 val)
112 {
113 for (auto it : attrVec) {
114 if (it->GetDwAt() == attr) {
115 it->SetU(val);
116 return true;
117 }
118 }
119 return false;
120 }
121
SetAttr(DwAt attr,int val)122 bool DBGDie::SetAttr(DwAt attr, int val)
123 {
124 for (auto it : attrVec) {
125 if (it->GetDwAt() == attr) {
126 it->SetI(val);
127 return true;
128 }
129 }
130 return false;
131 }
132
SetAttr(DwAt attr,uint32 val)133 bool DBGDie::SetAttr(DwAt attr, uint32 val)
134 {
135 for (auto it : attrVec) {
136 if (it->GetDwAt() == attr) {
137 it->SetId(val);
138 return true;
139 }
140 }
141 return false;
142 }
143
SetAttr(DwAt attr,int64 val)144 bool DBGDie::SetAttr(DwAt attr, int64 val)
145 {
146 for (auto it : attrVec) {
147 if (it->GetDwAt() == attr) {
148 it->SetJ(val);
149 return true;
150 }
151 }
152 return false;
153 }
154
SetAttr(DwAt attr,float val)155 bool DBGDie::SetAttr(DwAt attr, float val)
156 {
157 for (auto it : attrVec) {
158 if (it->GetDwAt() == attr) {
159 it->SetF(val);
160 return true;
161 }
162 }
163 return false;
164 }
165
SetAttr(DwAt attr,double val)166 bool DBGDie::SetAttr(DwAt attr, double val)
167 {
168 for (auto it : attrVec) {
169 if (it->GetDwAt() == attr) {
170 it->SetD(val);
171 return true;
172 }
173 }
174 return false;
175 }
176
SetAttr(DwAt attr,DBGExprLoc * ptr)177 bool DBGDie::SetAttr(DwAt attr, DBGExprLoc *ptr)
178 {
179 for (auto it : attrVec) {
180 if (it->GetDwAt() == attr) {
181 it->SetPtr(ptr);
182 return true;
183 }
184 }
185 return false;
186 }
187
AddAttr(DBGDieAttr * attr)188 void DBGDie::AddAttr(DBGDieAttr *attr)
189 {
190 for (auto it : attrVec) {
191 if (it->GetDwAt() == attr->GetDwAt()) {
192 return;
193 }
194 }
195 attrVec.push_back(attr);
196 }
197
AddSubVec(DBGDie * die)198 void DBGDie::AddSubVec(DBGDie *die)
199 {
200 if (!die)
201 return;
202 for (auto it : subDieVec) {
203 if (it->GetId() == die->GetId()) {
204 return;
205 }
206 }
207 subDieVec.push_back(die);
208 die->parent = this;
209 }
210
211 // DBGAbbrevEntry methods
DBGAbbrevEntry(MIRModule * m,DBGDie * die)212 DBGAbbrevEntry::DBGAbbrevEntry(MIRModule *m, DBGDie *die) : attrPairs(m->GetMPAllocator().Adapter())
213 {
214 tag = die->GetTag();
215 abbrevId = 0;
216 withChildren = die->GetWithChildren();
217 for (auto it : die->GetAttrVec()) {
218 attrPairs.push_back(it->GetDwAt());
219 attrPairs.push_back(it->GetDwForm());
220 }
221 }
222
Equalto(DBGAbbrevEntry * entry)223 bool DBGAbbrevEntry::Equalto(DBGAbbrevEntry *entry)
224 {
225 if (attrPairs.size() != entry->attrPairs.size()) {
226 return false;
227 }
228 if (withChildren != entry->GetWithChildren()) {
229 return false;
230 }
231 for (uint32 i = 0; i < attrPairs.size(); i++) {
232 if (attrPairs[i] != entry->attrPairs[i]) {
233 return false;
234 }
235 }
236 return true;
237 }
238
239 // DebugInfo methods
Init()240 void DebugInfo::Init()
241 {
242 mplSrcIdx = GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(module->GetFileName());
243 compUnit = module->GetMemPool()->New<DBGDie>(module, DW_TAG_compile_unit);
244 module->SetWithDbgInfo(true);
245 ResetParentDie();
246 if (module->GetSrcLang() == kSrcLangC) {
247 varPtrPrefix = "";
248 }
249 }
250
SetupCU()251 void DebugInfo::SetupCU()
252 {
253 compUnit->SetWithChildren(true);
254 /* Add the Producer (Compiler) Information */
255 std::string producer = std::string("Maple Version ") + Version::GetVersionStr();
256 GStrIdx strIdx = module->GetMIRBuilder()->GetOrCreateStringIndex(producer.c_str());
257 compUnit->AddAttr(DW_AT_producer, DW_FORM_strp, strIdx.GetIdx());
258
259 /* Source Languate */
260 compUnit->AddAttr(DW_AT_language, DW_FORM_data4, DW_LANG_C99);
261
262 /* Add the compiled source file information */
263 compUnit->AddAttr(DW_AT_name, DW_FORM_strp, mplSrcIdx.GetIdx());
264 strIdx = module->GetMIRBuilder()->GetOrCreateStringIndex("/to/be/done/current/path");
265 compUnit->AddAttr(DW_AT_comp_dir, DW_FORM_strp, strIdx.GetIdx());
266
267 compUnit->AddAttr(DW_AT_low_pc, DW_FORM_addr, kDbgDefaultVal);
268 compUnit->AddAttr(DW_AT_high_pc, DW_FORM_data8, kDbgDefaultVal);
269
270 compUnit->AddAttr(DW_AT_stmt_list, DW_FORM_sec_offset, kDbgDefaultVal);
271 }
272
AddScopeDie(MIRScope * scope)273 void DebugInfo::AddScopeDie(MIRScope *scope)
274 {
275 if (!scope->NeedEmitAliasInfo()) {
276 return;
277 }
278
279 if (scope->GetLevel() != 0) {
280 DBGDie *die = module->GetMemPool()->New<DBGDie>(module, DW_TAG_lexical_block);
281 die->AddAttr(DW_AT_low_pc, DW_FORM_addr, kDbgDefaultVal);
282 die->AddAttr(DW_AT_high_pc, DW_FORM_data8, kDbgDefaultVal);
283
284 // add die to parent
285 GetParentDie()->AddSubVec(die);
286
287 PushParentDie(die);
288 }
289
290 // process aliasVarMap
291 AddAliasDies(scope->GetAliasVarMap());
292
293 if (scope->GetSubScopes().size() > 0) {
294 // process subScopes
295 for (auto it : scope->GetSubScopes()) {
296 AddScopeDie(it);
297 }
298 }
299
300 if (scope->GetLevel() != 0) {
301 PopParentDie();
302 }
303 }
304
AddAliasDies(MapleMap<GStrIdx,MIRAliasVars> & aliasMap)305 void DebugInfo::AddAliasDies(MapleMap<GStrIdx, MIRAliasVars> &aliasMap)
306 {
307 MIRFunction *func = GetCurFunction();
308 for (auto &i : aliasMap) {
309 // maple var
310 MIRSymbol *var = nullptr;
311 if (i.second.isLocal) {
312 var = func->GetSymTab()->GetSymbolFromStrIdx(i.second.mplStrIdx);
313 } else {
314 var = GlobalTables::GetGsymTable().GetSymbolFromStrIdx(i.second.mplStrIdx);
315 }
316 DEBUG_ASSERT(var, "can not find symbol");
317
318 // create alias die using maple var except name
319 DBGDie *vdie = CreateVarDie(var, i.first);
320
321 GetParentDie()->AddSubVec(vdie);
322
323 // add alias var name to debug_str section
324 strps.insert(i.first.GetIdx());
325 }
326 }
327
Finish()328 void DebugInfo::Finish()
329 {
330 SetupCU();
331 FillTypeAttrWithDieId();
332 // build tree from root DIE compUnit
333 BuildDieTree();
334 BuildAbbrev();
335 ComputeSizeAndOffsets();
336 }
337
BuildDebugInfo()338 void DebugInfo::BuildDebugInfo()
339 {
340 DEBUG_ASSERT(module->GetDbgInfo(), "null dbgInfo");
341
342 Init();
343
344 // containner types
345 for (auto it : module->GetTypeNameTab()->GetGStrIdxToTyIdxMap()) {
346 GStrIdx strIdx = it.first;
347 TyIdx tyIdx = it.second;
348 MIRType *type = GlobalTables::GetTypeTable().GetTypeFromTyIdx(tyIdx.GetIdx());
349
350 switch (type->GetKind()) {
351 case kTypeClass:
352 case kTypeClassIncomplete:
353 case kTypeInterface:
354 case kTypeInterfaceIncomplete:
355 case kTypeStruct:
356 case kTypeStructIncomplete:
357 case kTypeUnion: {
358 (void)GetOrCreateStructTypeDie(type);
359 break;
360 }
361 default:
362 LogInfo::MapleLogger() << "named type "
363 << GlobalTables::GetStrTable().GetStringFromStrIdx(strIdx).c_str() << "\n";
364 break;
365 }
366 }
367
368 for (size_t i = 0; i < GlobalTables::GetGsymTable().GetSymbolTableSize(); ++i) {
369 MIRSymbol *mirSymbol = GlobalTables::GetGsymTable().GetSymbolFromStidx(static_cast<uint32>(i));
370 if (mirSymbol == nullptr || mirSymbol->IsDeleted() || mirSymbol->GetStorageClass() == kScUnused ||
371 mirSymbol->GetStorageClass() == kScExtern) {
372 continue;
373 }
374 if (module->IsCModule() && mirSymbol->IsGlobal() && mirSymbol->IsVar()) {
375 DBGDie *vdie = CreateVarDie(mirSymbol);
376 compUnit->AddSubVec(vdie);
377 }
378 }
379
380 // setup debug info for functions
381 for (auto func : GlobalTables::GetFunctionTable().GetFuncTable()) {
382 // the first one in funcTable is nullptr
383 if (!func) {
384 continue;
385 }
386 SetCurFunction(func);
387 // function decl
388 if (stridxDieIdMap.find(func->GetNameStrIdx().GetIdx()) == stridxDieIdMap.end()) {
389 DBGDie *fdie = GetOrCreateFuncDeclDie(func);
390 if (!func->GetClassTyIdx().GetIdx() && func->GetBody()) {
391 compUnit->AddSubVec(fdie);
392 }
393 }
394 // function def
395 if (funcDefStrIdxDieIdMap.find(func->GetNameStrIdx().GetIdx()) == funcDefStrIdxDieIdMap.end()) {
396 DBGDie *fdie = GetOrCreateFuncDefDie(func, 0);
397 if (!func->GetClassTyIdx().GetIdx() && func->GetBody()) {
398 compUnit->AddSubVec(fdie);
399 }
400 }
401 }
402
403 // finalize debug info
404 Finish();
405 }
406
CreateAttr(DwAt at,DwForm form,uint64 val)407 DBGDieAttr *DebugInfo::CreateAttr(DwAt at, DwForm form, uint64 val)
408 {
409 DBGDieAttr *attr = module->GetMemPool()->New<DBGDieAttr>(kDwAt);
410 attr->SetDwAt(at);
411 attr->SetDwForm(form);
412 attr->SetU(val);
413 return attr;
414 }
415
SetLocalDie(MIRFunction * func,GStrIdx strIdx,const DBGDie * die)416 void DebugInfo::SetLocalDie(MIRFunction *func, GStrIdx strIdx, const DBGDie *die)
417 {
418 (funcLstrIdxDieIdMap[func])[strIdx.GetIdx()] = die->GetId();
419 }
420
GetLocalDie(MIRFunction * func,GStrIdx strIdx)421 DBGDie *DebugInfo::GetLocalDie(MIRFunction *func, GStrIdx strIdx)
422 {
423 uint32 id = (funcLstrIdxDieIdMap[func])[strIdx.GetIdx()];
424 return idDieMap[id];
425 }
426
SetLocalDie(GStrIdx strIdx,const DBGDie * die)427 void DebugInfo::SetLocalDie(GStrIdx strIdx, const DBGDie *die)
428 {
429 (funcLstrIdxDieIdMap[GetCurFunction()])[strIdx.GetIdx()] = die->GetId();
430 }
431
GetLocalDie(GStrIdx strIdx)432 DBGDie *DebugInfo::GetLocalDie(GStrIdx strIdx)
433 {
434 uint32 id = (funcLstrIdxDieIdMap[GetCurFunction()])[strIdx.GetIdx()];
435 return idDieMap[id];
436 }
437
SetLabelIdx(MIRFunction * func,GStrIdx strIdx,LabelIdx labidx)438 void DebugInfo::SetLabelIdx(MIRFunction *func, GStrIdx strIdx, LabelIdx labidx)
439 {
440 (funcLstrIdxLabIdxMap[func])[strIdx.GetIdx()] = labidx;
441 }
442
GetLabelIdx(MIRFunction * func,GStrIdx strIdx)443 LabelIdx DebugInfo::GetLabelIdx(MIRFunction *func, GStrIdx strIdx)
444 {
445 LabelIdx labidx = (funcLstrIdxLabIdxMap[func])[strIdx.GetIdx()];
446 return labidx;
447 }
448
SetLabelIdx(GStrIdx strIdx,LabelIdx labidx)449 void DebugInfo::SetLabelIdx(GStrIdx strIdx, LabelIdx labidx)
450 {
451 (funcLstrIdxLabIdxMap[GetCurFunction()])[strIdx.GetIdx()] = labidx;
452 }
453
GetLabelIdx(GStrIdx strIdx)454 LabelIdx DebugInfo::GetLabelIdx(GStrIdx strIdx)
455 {
456 LabelIdx labidx = (funcLstrIdxLabIdxMap[GetCurFunction()])[strIdx.GetIdx()];
457 return labidx;
458 }
459
CreateFormalParaDie(MIRFunction * func,MIRType * type,MIRSymbol * sym)460 DBGDie *DebugInfo::CreateFormalParaDie(MIRFunction *func, MIRType *type, MIRSymbol *sym)
461 {
462 DBGDie *die = module->GetMemPool()->New<DBGDie>(module, DW_TAG_formal_parameter);
463
464 (void)GetOrCreateTypeDie(type);
465 ASSERT_NOT_NULL(type);
466 die->AddAttr(DW_AT_type, DW_FORM_ref4, type->GetTypeIndex().GetIdx());
467
468 /* var Name */
469 if (sym) {
470 die->AddAttr(DW_AT_name, DW_FORM_strp, sym->GetNameStrIdx().GetIdx());
471 die->AddAttr(DW_AT_decl_file, DW_FORM_data4, sym->GetSrcPosition().FileNum());
472 die->AddAttr(DW_AT_decl_line, DW_FORM_data4, sym->GetSrcPosition().LineNum());
473 die->AddAttr(DW_AT_decl_column, DW_FORM_data4, sym->GetSrcPosition().Column());
474 die->AddSimpLocAttr(DW_AT_location, DW_FORM_exprloc, kDbgDefaultVal);
475 SetLocalDie(func, sym->GetNameStrIdx(), die);
476 }
477 return die;
478 }
479
GetOrCreateLabelDie(LabelIdx labid)480 DBGDie *DebugInfo::GetOrCreateLabelDie(LabelIdx labid)
481 {
482 MIRFunction *func = GetCurFunction();
483 CHECK(labid < func->GetLabelTab()->GetLabelTableSize(), "index out of range in DebugInfo::GetOrCreateLabelDie");
484 GStrIdx strid = func->GetLabelTab()->GetSymbolFromStIdx(labid);
485 if ((funcLstrIdxDieIdMap[func]).size() &&
486 (funcLstrIdxDieIdMap[func]).find(strid.GetIdx()) != (funcLstrIdxDieIdMap[func]).end()) {
487 return GetLocalDie(strid);
488 }
489
490 DBGDie *die = module->GetMemPool()->New<DBGDie>(module, DW_TAG_label);
491 die->AddAttr(DW_AT_name, DW_FORM_strp, strid.GetIdx());
492 die->AddAttr(DW_AT_decl_file, DW_FORM_data4, mplSrcIdx.GetIdx());
493 die->AddAttr(DW_AT_decl_line, DW_FORM_data4, lexer->GetLineNum());
494 die->AddAttr(DW_AT_low_pc, DW_FORM_addr, kDbgDefaultVal);
495 GetParentDie()->AddSubVec(die);
496 SetLocalDie(strid, die);
497 SetLabelIdx(strid, labid);
498 return die;
499 }
500
CreateVarDie(MIRSymbol * sym)501 DBGDie *DebugInfo::CreateVarDie(MIRSymbol *sym)
502 {
503 // filter vtab
504 if (sym->GetName().find(VTAB_PREFIX_STR) == 0) {
505 return nullptr;
506 }
507
508 if (sym->GetName().find(GCTIB_PREFIX_STR) == 0) {
509 return nullptr;
510 }
511
512 if (sym->GetStorageClass() == kScFormal) {
513 return nullptr;
514 }
515
516 bool isLocal = sym->IsLocal();
517 GStrIdx strIdx = sym->GetNameStrIdx();
518
519 if (isLocal) {
520 MIRFunction *func = GetCurFunction();
521 if ((funcLstrIdxDieIdMap[func]).size() &&
522 (funcLstrIdxDieIdMap[func]).find(strIdx.GetIdx()) != (funcLstrIdxDieIdMap[func]).end()) {
523 return GetLocalDie(strIdx);
524 }
525 } else {
526 if (stridxDieIdMap.find(strIdx.GetIdx()) != stridxDieIdMap.end()) {
527 uint32 id = stridxDieIdMap[strIdx.GetIdx()];
528 return idDieMap[id];
529 }
530 }
531
532 DBGDie *die = CreateVarDie(sym, strIdx);
533
534 GetParentDie()->AddSubVec(die);
535 if (isLocal) {
536 SetLocalDie(strIdx, die);
537 } else {
538 stridxDieIdMap[strIdx.GetIdx()] = die->GetId();
539 }
540
541 return die;
542 }
543
CreateVarDie(MIRSymbol * sym,GStrIdx strIdx)544 DBGDie *DebugInfo::CreateVarDie(MIRSymbol *sym, GStrIdx strIdx)
545 {
546 DBGDie *die = module->GetMemPool()->New<DBGDie>(module, DW_TAG_variable);
547 DEBUG_ASSERT(sym != nullptr, "nullptr check");
548
549 /* var Name */
550 die->AddAttr(DW_AT_name, DW_FORM_strp, strIdx.GetIdx());
551 die->AddAttr(DW_AT_decl_file, DW_FORM_data4, sym->GetSrcPosition().FileNum());
552 die->AddAttr(DW_AT_decl_line, DW_FORM_data4, sym->GetSrcPosition().LineNum());
553 die->AddAttr(DW_AT_decl_column, DW_FORM_data4, sym->GetSrcPosition().Column());
554
555 bool isLocal = sym->IsLocal();
556 if (isLocal) {
557 die->AddSimpLocAttr(DW_AT_location, DW_FORM_exprloc, kDbgDefaultVal);
558 } else {
559 // global var just use its name as address in .s
560 uint64 idx = strIdx.GetIdx();
561 if ((sym->IsReflectionClassInfo() && !sym->IsReflectionArrayClassInfo()) || sym->IsStatic()) {
562 std::string ptrName = varPtrPrefix + sym->GetName();
563 idx = GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(ptrName).GetIdx();
564 }
565 die->AddGlobalLocAttr(DW_AT_location, DW_FORM_exprloc, idx);
566 }
567
568 MIRType *type = sym->GetType();
569 (void)GetOrCreateTypeDie(type);
570 ASSERT_NOT_NULL(type);
571 die->AddAttr(DW_AT_type, DW_FORM_ref4, type->GetTypeIndex().GetIdx());
572
573 return die;
574 }
575
GetOrCreateFuncDeclDie(MIRFunction * func)576 DBGDie *DebugInfo::GetOrCreateFuncDeclDie(MIRFunction *func)
577 {
578 uint32 funcnameidx = func->GetNameStrIdx().GetIdx();
579 if (stridxDieIdMap.find(funcnameidx) != stridxDieIdMap.end()) {
580 uint32 id = stridxDieIdMap[funcnameidx];
581 return idDieMap[id];
582 }
583
584 DBGDie *die = module->GetMemPool()->New<DBGDie>(module, DW_TAG_subprogram);
585 stridxDieIdMap[funcnameidx] = die->GetId();
586
587 die->AddAttr(DW_AT_external, DW_FORM_flag_present, 1);
588
589 // Function Name
590 MIRSymbol *sym = GlobalTables::GetGsymTable().GetSymbolFromStidx(func->GetStIdx().Idx());
591 DEBUG_ASSERT(sym != nullptr, "nullptr check");
592 die->AddAttr(DW_AT_name, DW_FORM_strp, funcnameidx);
593 die->AddAttr(DW_AT_decl_file, DW_FORM_data4, sym->GetSrcPosition().FileNum());
594 die->AddAttr(DW_AT_decl_line, DW_FORM_data4, sym->GetSrcPosition().LineNum());
595 die->AddAttr(DW_AT_decl_column, DW_FORM_data4, sym->GetSrcPosition().Column());
596
597 // Attributes for DW_AT_accessibility
598 uint32 access = 0;
599 if (func->IsPublic()) {
600 access = DW_ACCESS_public;
601 } else if (func->IsPrivate()) {
602 access = DW_ACCESS_private;
603 } else if (func->IsProtected()) {
604 access = DW_ACCESS_protected;
605 }
606 if (access) {
607 die->AddAttr(DW_AT_accessibility, DW_FORM_data4, access);
608 }
609
610 die->AddAttr(DW_AT_GNU_all_tail_call_sites, DW_FORM_flag_present, kDbgDefaultVal);
611
612 PushParentDie(die);
613
614 // formal parameter
615 for (uint32 i = 0; i < func->GetFormalCount(); i++) {
616 MIRType *type = GlobalTables::GetTypeTable().GetTypeFromTyIdx(func->GetFormalDefAt(i).formalTyIdx);
617 DBGDie *param = CreateFormalParaDie(func, type, nullptr);
618 die->AddSubVec(param);
619 }
620
621 PopParentDie();
622
623 return die;
624 }
625
LIsCompilerGenerated(const MIRFunction * func)626 bool LIsCompilerGenerated(const MIRFunction *func)
627 {
628 return ((func->GetName().c_str())[0] != 'L');
629 }
630
GetOrCreateFuncDefDie(MIRFunction * func,uint32 lnum)631 DBGDie *DebugInfo::GetOrCreateFuncDefDie(MIRFunction *func, uint32 lnum)
632 {
633 uint32 funcnameidx = func->GetNameStrIdx().GetIdx();
634 if (funcDefStrIdxDieIdMap.find(funcnameidx) != funcDefStrIdxDieIdMap.end()) {
635 uint32 id = funcDefStrIdxDieIdMap[funcnameidx];
636 return idDieMap[id];
637 }
638
639 DBGDie *funcdecldie = GetOrCreateFuncDeclDie(func);
640 DBGDie *die = module->GetMemPool()->New<DBGDie>(module, DW_TAG_subprogram);
641 // update funcDefStrIdxDieIdMap and leave stridxDieIdMap for the func decl
642 funcDefStrIdxDieIdMap[funcnameidx] = die->GetId();
643
644 die->AddAttr(DW_AT_specification, DW_FORM_ref4, funcdecldie->GetId());
645 die->AddAttr(DW_AT_decl_line, DW_FORM_data4, lnum);
646
647 if (!func->IsReturnVoid()) {
648 auto returnType = func->GetReturnType();
649 (void)GetOrCreateTypeDie(returnType);
650 ASSERT_NOT_NULL(returnType);
651 die->AddAttr(DW_AT_type, DW_FORM_ref4, returnType->GetTypeIndex().GetIdx());
652 }
653
654 die->AddAttr(DW_AT_low_pc, DW_FORM_addr, kDbgDefaultVal);
655 die->AddAttr(DW_AT_high_pc, DW_FORM_data8, kDbgDefaultVal);
656 die->AddFrmBaseAttr(DW_AT_frame_base, DW_FORM_exprloc);
657 if (!func->IsStatic() && !LIsCompilerGenerated(func)) {
658 die->AddAttr(DW_AT_object_pointer, DW_FORM_ref4, kDbgDefaultVal);
659 }
660 die->AddAttr(DW_AT_GNU_all_tail_call_sites, DW_FORM_flag_present, kDbgDefaultVal);
661
662 PushParentDie(die);
663
664 // formal parameter
665 for (uint32 i = 0; i < func->GetFormalCount(); i++) {
666 MIRType *type = GlobalTables::GetTypeTable().GetTypeFromTyIdx(func->GetFormalDefAt(i).formalTyIdx);
667 DBGDie *pdie = CreateFormalParaDie(func, type, func->GetFormalDefAt(i).formalSym);
668 die->AddSubVec(pdie);
669 }
670
671 if (func->GetSymTab()) {
672 // local variables, start from 1
673 for (uint32 i = 1; i < func->GetSymTab()->GetSymbolTableSize(); i++) {
674 MIRSymbol *var = func->GetSymTab()->GetSymbolFromStIdx(i);
675 DBGDie *vdie = CreateVarDie(var);
676 die->AddSubVec(vdie);
677 }
678 }
679
680 // add scope die
681 AddScopeDie(func->GetScope());
682
683 PopParentDie();
684
685 return die;
686 }
687
GetOrCreatePrimTypeDie(MIRType * ty)688 DBGDie *DebugInfo::GetOrCreatePrimTypeDie(MIRType *ty)
689 {
690 PrimType pty = ty->GetPrimType();
691 uint32 tid = static_cast<uint32>(pty);
692 if (tyIdxDieIdMap.find(tid) != tyIdxDieIdMap.end()) {
693 uint32 id = tyIdxDieIdMap[tid];
694 return idDieMap[id];
695 }
696
697 DBGDie *die = module->GetMemPool()->New<DBGDie>(module, DW_TAG_base_type);
698 die->SetTyIdx(static_cast<uint32>(pty));
699
700 if (ty->GetNameStrIdx().GetIdx() == 0) {
701 const char *name = GetPrimTypeName(ty->GetPrimType());
702 std::string pname = std::string(name);
703 GStrIdx strIdx = GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(pname);
704 ty->SetNameStrIdx(strIdx);
705 }
706
707 die->AddAttr(DW_AT_byte_size, DW_FORM_data4, GetPrimTypeSize(pty));
708 die->AddAttr(DW_AT_encoding, DW_FORM_data4, GetAteFromPTY(pty));
709 die->AddAttr(DW_AT_name, DW_FORM_strp, ty->GetNameStrIdx().GetIdx());
710
711 compUnit->AddSubVec(die);
712 tyIdxDieIdMap[static_cast<uint32>(pty)] = die->GetId();
713 return die;
714 }
715
CreatePointedFuncTypeDie(MIRFuncType * ftype)716 DBGDie *DebugInfo::CreatePointedFuncTypeDie(MIRFuncType *ftype)
717 {
718 DBGDie *die = module->GetMemPool()->New<DBGDie>(module, DW_TAG_subroutine_type);
719
720 die->AddAttr(DW_AT_prototyped, DW_FORM_data4, static_cast<int>(ftype->GetParamTypeList().size() > 0));
721 MIRType *rtype = GlobalTables::GetTypeTable().GetTypeFromTyIdx(ftype->GetRetTyIdx());
722 (void)GetOrCreateTypeDie(rtype);
723 die->AddAttr(DW_AT_type, DW_FORM_ref4, ftype->GetRetTyIdx().GetIdx());
724
725 compUnit->AddSubVec(die);
726
727 for (uint32 i = 0; i < ftype->GetParamTypeList().size(); i++) {
728 DBGDie *paramdie = module->GetMemPool()->New<DBGDie>(module, DW_TAG_formal_parameter);
729 MIRType *ptype = GlobalTables::GetTypeTable().GetTypeFromTyIdx(ftype->GetNthParamType(i));
730 (void)GetOrCreateTypeDie(ptype);
731 paramdie->AddAttr(DW_AT_type, DW_FORM_ref4, ftype->GetNthParamType(i).GetIdx());
732 die->AddSubVec(paramdie);
733 }
734
735 tyIdxDieIdMap[ftype->GetTypeIndex().GetIdx()] = die->GetId();
736 return die;
737 }
738
GetOrCreateTypeDie(MIRType * type)739 DBGDie *DebugInfo::GetOrCreateTypeDie(MIRType *type)
740 {
741 if (type == nullptr) {
742 return nullptr;
743 }
744
745 uint32 tid = type->GetTypeIndex().GetIdx();
746 if (tyIdxDieIdMap.find(tid) != tyIdxDieIdMap.end()) {
747 uint32 id = tyIdxDieIdMap[tid];
748 return idDieMap[id];
749 }
750
751 uint32 sid = type->GetNameStrIdx().GetIdx();
752 if (sid)
753 if (stridxDieIdMap.find(sid) != stridxDieIdMap.end()) {
754 uint32 id = stridxDieIdMap[sid];
755 return idDieMap[id];
756 }
757
758 if (type->GetTypeIndex() == static_cast<uint32>(type->GetPrimType())) {
759 return GetOrCreatePrimTypeDie(type);
760 }
761
762 DBGDie *die = nullptr;
763 switch (type->GetKind()) {
764 case kTypePointer: {
765 MIRPtrType *ptype = static_cast<MIRPtrType *>(type);
766 die = GetOrCreatePointTypeDie(ptype);
767 break;
768 }
769 case kTypeFunction: {
770 MIRFuncType *ftype = static_cast<MIRFuncType *>(type);
771 die = CreatePointedFuncTypeDie(ftype);
772 break;
773 }
774 case kTypeArray:
775 case kTypeFArray:
776 case kTypeJArray: {
777 MIRArrayType *atype = static_cast<MIRArrayType *>(type);
778 die = GetOrCreateArrayTypeDie(atype);
779 break;
780 }
781 case kTypeUnion:
782 case kTypeStruct:
783 case kTypeStructIncomplete:
784 case kTypeClass:
785 case kTypeClassIncomplete:
786 case kTypeInterface:
787 case kTypeInterfaceIncomplete: {
788 die = GetOrCreateStructTypeDie(type);
789 break;
790 }
791 case kTypeBitField:
792 break;
793 default:
794 CHECK_FATAL(false, "Not support type now");
795 break;
796 }
797
798 return die;
799 }
800
GetOrCreatePointTypeDie(const MIRPtrType * ptrtype)801 DBGDie *DebugInfo::GetOrCreatePointTypeDie(const MIRPtrType *ptrtype)
802 {
803 uint32 tid = ptrtype->GetTypeIndex().GetIdx();
804 if (tyIdxDieIdMap.find(tid) != tyIdxDieIdMap.end()) {
805 uint32 id = tyIdxDieIdMap[tid];
806 return idDieMap[id];
807 }
808
809 MIRType *type = ptrtype->GetPointedType();
810 // for <* void>
811 if ((type != nullptr) && (type->GetPrimType() == PTY_void || type->GetKind() == kTypeFunction)) {
812 DBGDie *die = module->GetMemPool()->New<DBGDie>(module, DW_TAG_pointer_type);
813 die->AddAttr(DW_AT_byte_size, DW_FORM_data4, k8BitSize);
814 if (type->GetKind() == kTypeFunction) {
815 DBGDie *pdie = GetOrCreateTypeDie(type);
816 die->AddAttr(DW_AT_type, DW_FORM_ref4, type->GetTypeIndex().GetIdx());
817 tyIdxDieIdMap[type->GetTypeIndex().GetIdx()] = pdie->GetId();
818 }
819 tyIdxDieIdMap[ptrtype->GetTypeIndex().GetIdx()] = die->GetId();
820 compUnit->AddSubVec(die);
821 return die;
822 }
823
824 (void)GetOrCreateTypeDie(type);
825 ASSERT_NOT_NULL(type);
826 if (typeDefTyIdxMap.find(type->GetTypeIndex().GetIdx()) != typeDefTyIdxMap.end()) {
827 uint32 tyIdx = typeDefTyIdxMap[type->GetTypeIndex().GetIdx()];
828 if (pointedPointerMap.find(tyIdx) != pointedPointerMap.end()) {
829 uint32 tyid = pointedPointerMap[tyIdx];
830 if (tyIdxDieIdMap.find(tyid) != tyIdxDieIdMap.end()) {
831 uint32 dieid = tyIdxDieIdMap[tyid];
832 DBGDie *die = idDieMap[dieid];
833 return die;
834 }
835 }
836 }
837
838 // update incomplete type from stridxDieIdMap to tyIdxDieIdMap
839 MIRStructType *stype = static_cast<MIRStructType *>(type);
840 if ((stype != nullptr) && stype->IsIncomplete()) {
841 uint32 sid = stype->GetNameStrIdx().GetIdx();
842 if (stridxDieIdMap.find(sid) != stridxDieIdMap.end()) {
843 uint32 dieid = stridxDieIdMap[sid];
844 if (dieid) {
845 tyIdxDieIdMap[stype->GetTypeIndex().GetIdx()] = dieid;
846 }
847 }
848 }
849
850 DBGDie *die = module->GetMemPool()->New<DBGDie>(module, DW_TAG_pointer_type);
851 die->AddAttr(DW_AT_byte_size, DW_FORM_data4, k8BitSize);
852 // fill with type idx instead of typedie->id to avoid nullptr typedie of
853 // forward reference of class types
854 die->AddAttr(DW_AT_type, DW_FORM_ref4, type->GetTypeIndex().GetIdx());
855 tyIdxDieIdMap[ptrtype->GetTypeIndex().GetIdx()] = die->GetId();
856
857 compUnit->AddSubVec(die);
858
859 return die;
860 }
861
GetOrCreateArrayTypeDie(const MIRArrayType * arraytype)862 DBGDie *DebugInfo::GetOrCreateArrayTypeDie(const MIRArrayType *arraytype)
863 {
864 uint32 tid = arraytype->GetTypeIndex().GetIdx();
865 if (tyIdxDieIdMap.find(tid) != tyIdxDieIdMap.end()) {
866 uint32 id = tyIdxDieIdMap[tid];
867 return idDieMap[id];
868 }
869
870 MIRType *type = arraytype->GetElemType();
871 (void)GetOrCreateTypeDie(type);
872
873 DBGDie *die = module->GetMemPool()->New<DBGDie>(module, DW_TAG_array_type);
874 die->AddAttr(DW_AT_byte_size, DW_FORM_data4, k8BitSize);
875 // fill with type idx instead of typedie->id to avoid nullptr typedie of
876 // forward reference of class types
877 die->AddAttr(DW_AT_type, DW_FORM_ref4, type->GetTypeIndex().GetIdx());
878 tyIdxDieIdMap[arraytype->GetTypeIndex().GetIdx()] = die->GetId();
879
880 compUnit->AddSubVec(die);
881
882 // maple uses array of 1D array to represent 2D array
883 // so only one DW_TAG_subrange_type entry is needed
884 DBGDie *rangedie = module->GetMemPool()->New<DBGDie>(module, DW_TAG_subrange_type);
885 (void)GetOrCreatePrimTypeDie(GlobalTables::GetTypeTable().GetUInt32());
886 rangedie->AddAttr(DW_AT_type, DW_FORM_ref4, PTY_u32);
887 rangedie->AddAttr(DW_AT_upper_bound, DW_FORM_data4, arraytype->GetSizeArrayItem(0));
888
889 die->AddSubVec(rangedie);
890
891 return die;
892 }
893
CreateFieldDie(maple::FieldPair pair,uint32 lnum)894 DBGDie *DebugInfo::CreateFieldDie(maple::FieldPair pair, uint32 lnum)
895 {
896 DBGDie *die = module->GetMemPool()->New<DBGDie>(module, DW_TAG_member);
897 die->AddAttr(DW_AT_name, DW_FORM_strp, pair.first.GetIdx());
898 die->AddAttr(DW_AT_decl_file, DW_FORM_data4, mplSrcIdx.GetIdx());
899 die->AddAttr(DW_AT_decl_line, DW_FORM_data4, lnum);
900
901 MIRType *type = GlobalTables::GetTypeTable().GetTypeFromTyIdx(pair.second.first);
902 (void)GetOrCreateTypeDie(type);
903 // fill with type idx instead of typedie->id to avoid nullptr typedie of
904 // forward reference of class types
905 ASSERT_NOT_NULL(type);
906 die->AddAttr(DW_AT_type, DW_FORM_ref4, type->GetTypeIndex().GetIdx());
907
908 die->AddAttr(DW_AT_data_member_location, DW_FORM_data4, kDbgDefaultVal);
909
910 return die;
911 }
912
CreateBitfieldDie(const MIRBitFieldType * type,GStrIdx sidx,uint32 prevBits)913 DBGDie *DebugInfo::CreateBitfieldDie(const MIRBitFieldType *type, GStrIdx sidx, uint32 prevBits)
914 {
915 DBGDie *die = module->GetMemPool()->New<DBGDie>(module, DW_TAG_member);
916
917 die->AddAttr(DW_AT_name, DW_FORM_strp, sidx.GetIdx());
918 die->AddAttr(DW_AT_decl_file, DW_FORM_data4, mplSrcIdx.GetIdx());
919 die->AddAttr(DW_AT_decl_line, DW_FORM_data4, 0);
920
921 MIRType *ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(type->GetPrimType());
922 (void)GetOrCreateTypeDie(ty);
923 ASSERT_NOT_NULL(ty);
924 die->AddAttr(DW_AT_type, DW_FORM_ref4, ty->GetTypeIndex().GetIdx());
925
926 die->AddAttr(DW_AT_byte_size, DW_FORM_data4, GetPrimTypeSize(type->GetPrimType()));
927 die->AddAttr(DW_AT_bit_size, DW_FORM_data4, type->GetFieldSize());
928 die->AddAttr(DW_AT_bit_offset, DW_FORM_data4,
929 GetPrimTypeSize(type->GetPrimType()) * k8BitSize - type->GetFieldSize() - prevBits);
930 die->AddAttr(DW_AT_data_member_location, DW_FORM_data4, 0);
931
932 return die;
933 }
934
GetOrCreateStructTypeDie(const MIRType * type)935 DBGDie *DebugInfo::GetOrCreateStructTypeDie(const MIRType *type)
936 {
937 DEBUG_ASSERT(type, "null struture type");
938 GStrIdx strIdx = type->GetNameStrIdx();
939 DEBUG_ASSERT(strIdx.GetIdx(), "struture type missing name");
940
941 if (tyIdxDieIdMap.find(type->GetTypeIndex().GetIdx()) != tyIdxDieIdMap.end()) {
942 uint32 id = tyIdxDieIdMap[type->GetTypeIndex().GetIdx()];
943 return idDieMap[id];
944 }
945
946 DBGDie *die = nullptr;
947 switch (type->GetKind()) {
948 case kTypeClass:
949 case kTypeClassIncomplete: {
950 const MIRClassType *classtype = static_cast<const MIRClassType *>(type);
951 die = CreateClassTypeDie(strIdx, classtype);
952 break;
953 }
954 case kTypeInterface:
955 case kTypeInterfaceIncomplete: {
956 const MIRInterfaceType *interfacetype = static_cast<const MIRInterfaceType *>(type);
957 die = CreateInterfaceTypeDie(strIdx, interfacetype);
958 break;
959 }
960 case kTypeStruct:
961 case kTypeStructIncomplete:
962 case kTypeUnion: {
963 const MIRStructType *stype = static_cast<const MIRStructType *>(type);
964 die = CreateStructTypeDie(strIdx, stype, false);
965 break;
966 }
967 default:
968 LogInfo::MapleLogger() << "named type " << GlobalTables::GetStrTable().GetStringFromStrIdx(strIdx).c_str()
969 << "\n";
970 break;
971 }
972
973 GlobalTables::GetTypeNameTable().SetGStrIdxToTyIdx(strIdx, type->GetTypeIndex());
974 return die;
975 }
976
977 // shared between struct and union
CreateStructTypeDie(GStrIdx strIdx,const MIRStructType * structtype,bool update)978 DBGDie *DebugInfo::CreateStructTypeDie(GStrIdx strIdx, const MIRStructType *structtype, bool update)
979 {
980 DBGDie *die = nullptr;
981
982 if (update) {
983 uint32 id = tyIdxDieIdMap[structtype->GetTypeIndex().GetIdx()];
984 die = idDieMap[id];
985 DEBUG_ASSERT(die, "update type die not exist");
986 } else {
987 DwTag tag = structtype->GetKind() == kTypeStruct ? DW_TAG_structure_type : DW_TAG_union_type;
988 die = module->GetMemPool()->New<DBGDie>(module, tag);
989 tyIdxDieIdMap[structtype->GetTypeIndex().GetIdx()] = die->GetId();
990 }
991
992 if (strIdx.GetIdx()) {
993 stridxDieIdMap[strIdx.GetIdx()] = die->GetId();
994 }
995
996 compUnit->AddSubVec(die);
997
998 die->AddAttr(DW_AT_decl_line, DW_FORM_data4, kStructDBGSize);
999 die->AddAttr(DW_AT_name, DW_FORM_strp, strIdx.GetIdx());
1000 die->AddAttr(DW_AT_byte_size, DW_FORM_data4, kDbgDefaultVal);
1001 die->AddAttr(DW_AT_decl_file, DW_FORM_data4, mplSrcIdx.GetIdx());
1002
1003 PushParentDie(die);
1004
1005 // fields
1006 uint32 prevBits = 0;
1007 for (size_t i = 0; i < structtype->GetFieldsSize(); i++) {
1008 MIRType *ety = structtype->GetElemType(static_cast<uint32>(i));
1009 FieldPair fp = structtype->GetFieldsElemt(i);
1010 if (ety->IsMIRBitFieldType()) {
1011 MIRBitFieldType *bfty = static_cast<MIRBitFieldType *>(ety);
1012 DBGDie *bfdie = CreateBitfieldDie(bfty, fp.first, prevBits);
1013 prevBits += bfty->GetFieldSize();
1014 die->AddSubVec(bfdie);
1015 } else {
1016 prevBits = 0;
1017 DBGDie *fdie = CreateFieldDie(fp, 0);
1018 die->AddSubVec(fdie);
1019 }
1020 }
1021
1022 // parentFields
1023 for (size_t i = 0; i < structtype->GetParentFieldsSize(); i++) {
1024 FieldPair fp = structtype->GetParentFieldsElemt(i);
1025 DBGDie *fdie = CreateFieldDie(fp, 0);
1026 die->AddSubVec(fdie);
1027 }
1028
1029 // member functions decl
1030 for (auto fp : structtype->GetMethods()) {
1031 MIRSymbol *symbol = GlobalTables::GetGsymTable().GetSymbolFromStidx(fp.first.Idx());
1032 DEBUG_ASSERT((symbol != nullptr) && symbol->GetSKind() == kStFunc, "member function symbol not exist");
1033 MIRFunction *func = symbol->GetValue().mirFunc;
1034 DEBUG_ASSERT(func, "member function not exist");
1035 DBGDie *fdie = GetOrCreateFuncDeclDie(func);
1036 die->AddSubVec(fdie);
1037 }
1038
1039 PopParentDie();
1040
1041 // member functions defination, these die are global
1042 for (auto fp : structtype->GetMethods()) {
1043 MIRSymbol *symbol = GlobalTables::GetGsymTable().GetSymbolFromStidx(fp.first.Idx());
1044 DEBUG_ASSERT(symbol && symbol->GetSKind() == kStFunc, "member function symbol not exist");
1045 MIRFunction *func = symbol->GetValue().mirFunc;
1046 if (!func->GetBody()) {
1047 continue;
1048 }
1049 DEBUG_ASSERT(func, "member function not exist");
1050 DBGDie *fdie = GetOrCreateFuncDefDie(func, 0);
1051 compUnit->AddSubVec(fdie);
1052 }
1053
1054 return die;
1055 }
1056
CreateClassTypeDie(GStrIdx strIdx,const MIRClassType * classtype)1057 DBGDie *DebugInfo::CreateClassTypeDie(GStrIdx strIdx, const MIRClassType *classtype)
1058 {
1059 DBGDie *die = module->GetMemPool()->New<DBGDie>(module, DW_TAG_class_type);
1060
1061 PushParentDie(die);
1062
1063 // parent
1064 uint32 ptid = classtype->GetParentTyIdx().GetIdx();
1065 if (ptid) {
1066 MIRType *parenttype = GlobalTables::GetTypeTable().GetTypeFromTyIdx(classtype->GetParentTyIdx());
1067 DBGDie *parentdie = GetOrCreateTypeDie(parenttype);
1068 if (parentdie) {
1069 parentdie = module->GetMemPool()->New<DBGDie>(module, DW_TAG_inheritance);
1070 parentdie->AddAttr(DW_AT_name, DW_FORM_strp, parenttype->GetNameStrIdx().GetIdx());
1071 parentdie->AddAttr(DW_AT_type, DW_FORM_ref4, ptid);
1072
1073 // set to DW_ACCESS_public for now
1074 parentdie->AddAttr(DW_AT_accessibility, DW_FORM_data4, DW_ACCESS_public);
1075 die->AddSubVec(parentdie);
1076 }
1077 }
1078
1079 PopParentDie();
1080
1081 // update common fields
1082 tyIdxDieIdMap[classtype->GetTypeIndex().GetIdx()] = die->GetId();
1083 DBGDie *die1 = CreateStructTypeDie(strIdx, classtype, true);
1084 DEBUG_ASSERT(die == die1, "ClassTypeDie update wrong die");
1085
1086 return die1;
1087 }
1088
CreateInterfaceTypeDie(GStrIdx strIdx,const MIRInterfaceType * interfacetype)1089 DBGDie *DebugInfo::CreateInterfaceTypeDie(GStrIdx strIdx, const MIRInterfaceType *interfacetype)
1090 {
1091 DBGDie *die = module->GetMemPool()->New<DBGDie>(module, DW_TAG_interface_type);
1092
1093 PushParentDie(die);
1094
1095 // parents
1096 for (auto it : interfacetype->GetParentsTyIdx()) {
1097 MIRType *type = GlobalTables::GetTypeTable().GetTypeFromTyIdx(it);
1098 DBGDie *parentdie = GetOrCreateTypeDie(type);
1099 if (parentdie) {
1100 continue;
1101 }
1102 parentdie = module->GetMemPool()->New<DBGDie>(module, DW_TAG_inheritance);
1103 parentdie->AddAttr(DW_AT_name, DW_FORM_strp, type->GetNameStrIdx().GetIdx());
1104 parentdie->AddAttr(DW_AT_type, DW_FORM_ref4, it.GetIdx());
1105 parentdie->AddAttr(DW_AT_data_member_location, DW_FORM_data4, kDbgDefaultVal);
1106
1107 // set to DW_ACCESS_public for now
1108 parentdie->AddAttr(DW_AT_accessibility, DW_FORM_data4, DW_ACCESS_public);
1109 die->AddSubVec(parentdie);
1110 }
1111
1112 PopParentDie();
1113
1114 // update common fields
1115 tyIdxDieIdMap[interfacetype->GetTypeIndex().GetIdx()] = die->GetId();
1116 DBGDie *die1 = CreateStructTypeDie(strIdx, interfacetype, true);
1117 DEBUG_ASSERT(die == die1, "InterfaceTypeDie update wrong die");
1118
1119 return die1;
1120 }
1121
GetAbbrevId(DBGAbbrevEntryVec * vec,DBGAbbrevEntry * entry)1122 uint32 DebugInfo::GetAbbrevId(DBGAbbrevEntryVec *vec, DBGAbbrevEntry *entry)
1123 {
1124 for (auto it : vec->GetEntryvec()) {
1125 if (it->Equalto(entry)) {
1126 return it->GetAbbrevId();
1127 ;
1128 }
1129 }
1130 return 0;
1131 }
1132
BuildAbbrev()1133 void DebugInfo::BuildAbbrev()
1134 {
1135 uint32 abbrevid = 1;
1136 for (uint32 i = 1; i < maxId; i++) {
1137 DBGDie *die = idDieMap[i];
1138 DBGAbbrevEntry *entry = module->GetMemPool()->New<DBGAbbrevEntry>(module, die);
1139
1140 if (!tagAbbrevMap[die->GetTag()]) {
1141 tagAbbrevMap[die->GetTag()] = module->GetMemPool()->New<DBGAbbrevEntryVec>(module, die->GetTag());
1142 }
1143
1144 uint32 id = GetAbbrevId(tagAbbrevMap[die->GetTag()], entry);
1145 if (id) {
1146 // using existing abbrev id
1147 die->SetAbbrevId(id);
1148 } else {
1149 // add entry to vector
1150 entry->SetAbbrevId(abbrevid++);
1151 tagAbbrevMap[die->GetTag()]->GetEntryvec().push_back(entry);
1152 abbrevVec.push_back(entry);
1153 // update abbrevid in die
1154 die->SetAbbrevId(entry->GetAbbrevId());
1155 }
1156 }
1157 for (uint32 i = 1; i < maxId; i++) {
1158 DBGDie *die = idDieMap[i];
1159 if (die->GetAbbrevId() == 0) {
1160 LogInfo::MapleLogger() << "0 abbrevId i = " << i << " die->id = " << die->GetId() << std::endl;
1161 }
1162 }
1163 }
1164
BuildDieTree()1165 void DebugInfo::BuildDieTree()
1166 {
1167 for (auto it : idDieMap) {
1168 if (!it.first) {
1169 continue;
1170 }
1171 DBGDie *die = it.second;
1172 uint32 size = die->GetSubDieVecSize();
1173 die->SetWithChildren(size > 0);
1174 if (size) {
1175 die->SetFirstChild(die->GetSubDieVecAt(0));
1176 for (uint32 i = 0; i < size - 1; i++) {
1177 DBGDie *it0 = die->GetSubDieVecAt(i);
1178 DBGDie *it1 = die->GetSubDieVecAt(i + 1);
1179 if (it0->GetSubDieVecSize()) {
1180 it0->SetSibling(it1);
1181 (void)it0->AddAttr(DW_AT_sibling, DW_FORM_ref4, it1->GetId());
1182 }
1183 }
1184 }
1185 }
1186 }
1187
FillTypeAttrWithDieId()1188 void DebugInfo::FillTypeAttrWithDieId()
1189 {
1190 for (auto it : idDieMap) {
1191 DBGDie *die = it.second;
1192 for (auto at : die->GetAttrVec()) {
1193 if (at->GetDwAt() == DW_AT_type) {
1194 uint32 tid = at->GetId();
1195 MIRType *type = GlobalTables::GetTypeTable().GetTypeFromTyIdx(TyIdx(tid));
1196 if (type) {
1197 uint32 dieid = tyIdxDieIdMap[tid];
1198 if (dieid) {
1199 at->SetId(dieid);
1200 } else {
1201 LogInfo::MapleLogger() << "dieid not found, typeKind = " << type->GetKind()
1202 << " primType = " << type->GetPrimType()
1203 << " nameStrIdx = " << type->GetNameStrIdx().GetIdx() << std::endl;
1204 }
1205 } else {
1206 LogInfo::MapleLogger() << "type not found, tid = " << tid << std::endl;
1207 }
1208 break;
1209 }
1210 }
1211 }
1212 }
1213
GetDie(const MIRFunction * func)1214 DBGDie *DebugInfo::GetDie(const MIRFunction *func)
1215 {
1216 uint32 id = stridxDieIdMap[func->GetNameStrIdx().GetIdx()];
1217 if (id) {
1218 return idDieMap[id];
1219 }
1220 return nullptr;
1221 }
1222
GetFuncDie(const MIRFunction & func,bool isDeclDie)1223 DBGDie *DebugInfo::GetFuncDie(const MIRFunction &func, bool isDeclDie)
1224 {
1225 uint32 id = isDeclDie ? stridxDieIdMap[func.GetNameStrIdx().GetIdx()]
1226 : funcDefStrIdxDieIdMap[func.GetNameStrIdx().GetIdx()];
1227 if (id != 0) {
1228 return idDieMap[id];
1229 }
1230 return nullptr;
1231 }
1232
1233 // Methods for calculating Offset and Size of DW_AT_xxx
SizeOf(DBGDieAttr * attr)1234 size_t DBGDieAttr::SizeOf(DBGDieAttr *attr)
1235 {
1236 DwForm form = attr->dwForm;
1237 switch (form) {
1238 // case DW_FORM_implicitconst:
1239 case DW_FORM_flag_present:
1240 return 0; // Not handled yet.
1241 case DW_FORM_flag:
1242 case DW_FORM_ref1:
1243 case DW_FORM_data1:
1244 return sizeof(int8);
1245 case DW_FORM_ref2:
1246 case DW_FORM_data2:
1247 return sizeof(int16);
1248 case DW_FORM_ref4:
1249 case DW_FORM_data4:
1250 return sizeof(int32);
1251 case DW_FORM_ref8:
1252 case DW_FORM_ref_sig8:
1253 case DW_FORM_data8:
1254 return sizeof(int64);
1255 case DW_FORM_addr:
1256 return sizeof(int64);
1257 case DW_FORM_sec_offset:
1258 case DW_FORM_ref_addr:
1259 case DW_FORM_strp:
1260 case DW_FORM_GNU_ref_alt:
1261 // case DW_FORM_codeLinestrp:
1262 // case DW_FORM_strp_sup:
1263 // case DW_FORM_ref_sup:
1264 return k4BitSize; // DWARF32, 8 if DWARF64
1265
1266 case DW_FORM_string: {
1267 GStrIdx stridx(attr->value.id);
1268 const std::string &str = GlobalTables::GetStrTable().GetStringFromStrIdx(stridx);
1269 return str.length() + 1; /* 1 for ` terminal null byte */
1270 }
1271 case DW_FORM_exprloc: {
1272 DBGExprLoc *ptr = attr->value.ptr;
1273 CHECK_FATAL(ptr != (DBGExprLoc *)(0xdeadbeef), "wrong ptr");
1274 switch (ptr->GetOp()) {
1275 case DW_OP_call_frame_cfa:
1276 return k2BitSize; // size 1 byte + DW_OP_call_frame_cfa 1 byte
1277 case DW_OP_fbreg: {
1278 // DW_OP_fbreg 1 byte
1279 size_t size = 1 + namemangler::GetSleb128Size(ptr->GetFboffset());
1280 return size + namemangler::GetUleb128Size(size);
1281 }
1282 case DW_OP_addr: {
1283 return namemangler::GetUleb128Size(k9BitSize) + k9BitSize;
1284 }
1285 default:
1286 return k4BitSize;
1287 }
1288 }
1289 default:
1290 CHECK_FATAL(maple::GetDwFormName(form) != nullptr,
1291 "GetDwFormName return null in DebugInfo::FillTypeAttrWithDieId");
1292 LogInfo::MapleLogger() << "unhandled SizeOf: " << maple::GetDwFormName(form) << std::endl;
1293 return 0;
1294 }
1295 }
1296
ComputeSizeAndOffsets()1297 void DebugInfo::ComputeSizeAndOffsets()
1298 {
1299 // CU-relative offset is reset to 0 here.
1300 uint32 cuOffset = sizeof(int32_t) // Length of Unit Info
1301 + sizeof(int16) // DWARF version number : 0x0004
1302 + sizeof(int32) // Offset into Abbrev. Section : 0x0000
1303 + sizeof(int8); // Pointer Size (in bytes) : 0x08
1304
1305 // After returning from this function, the length value is the size
1306 // of the .debug_info section
1307 ComputeSizeAndOffset(compUnit, cuOffset);
1308 debugInfoLength = cuOffset - sizeof(int32_t);
1309 }
1310
1311 // Compute the size and offset of a DIE. The Offset is relative to start of the CU.
1312 // It returns the offset after laying out the DIE.
ComputeSizeAndOffset(DBGDie * die,uint32 & cuOffset)1313 void DebugInfo::ComputeSizeAndOffset(DBGDie *die, uint32 &cuOffset)
1314 {
1315 uint32 cuOffsetOrg = cuOffset;
1316 die->SetOffset(cuOffset);
1317
1318 // Add the byte size of the abbreviation code
1319 cuOffset += static_cast<uint32>(namemangler::GetUleb128Size(uint64_t(die->GetAbbrevId())));
1320
1321 // Add the byte size of all the DIE attributes.
1322 for (const auto &attr : die->GetAttrVec()) {
1323 cuOffset += static_cast<uint32>(attr->SizeOf(attr));
1324 }
1325
1326 die->SetSize(cuOffset - cuOffsetOrg);
1327
1328 // Let the children compute their offsets.
1329 if (die->GetWithChildren()) {
1330 uint32 size = die->GetSubDieVecSize();
1331
1332 for (uint32 i = 0; i < size; i++) {
1333 DBGDie *childDie = die->GetSubDieVecAt(i);
1334 ComputeSizeAndOffset(childDie, cuOffset);
1335 }
1336
1337 // Each child chain is terminated with a zero byte, adjust the offset.
1338 cuOffset += sizeof(int8);
1339 }
1340 }
1341
Dump(int indent)1342 void DebugInfo::Dump(int indent)
1343 {
1344 LogInfo::MapleLogger() << "\n" << std::endl;
1345 LogInfo::MapleLogger() << "maple_debug_information {"
1346 << " Length: " << HEX(debugInfoLength) << std::endl;
1347 compUnit->Dump(indent + 1);
1348 LogInfo::MapleLogger() << "}\n" << std::endl;
1349 LogInfo::MapleLogger() << "maple_debug_abbrev {" << std::endl;
1350 for (uint32 i = 1; i < abbrevVec.size(); i++) {
1351 abbrevVec[i]->Dump(indent + 1);
1352 }
1353 LogInfo::MapleLogger() << "}" << std::endl;
1354 return;
1355 }
1356
Dump()1357 void DBGExprLoc::Dump()
1358 {
1359 LogInfo::MapleLogger() << " " << HEX(GetOp());
1360 for (auto it : simpLoc->GetOpnd()) {
1361 LogInfo::MapleLogger() << " " << HEX(it);
1362 }
1363 }
1364
Dump(int indent)1365 void DBGDieAttr::Dump(int indent)
1366 {
1367 PrintIndentation(indent);
1368 CHECK_FATAL(GetDwFormName(dwForm) && GetDwAtName(dwAttr), "null ptr check");
1369 LogInfo::MapleLogger() << GetDwAtName(dwAttr) << " " << GetDwFormName(dwForm);
1370 if (dwForm == DW_FORM_string || dwForm == DW_FORM_strp) {
1371 GStrIdx idx(value.id);
1372 LogInfo::MapleLogger() << " 0x" << std::hex << value.u << std::dec;
1373 LogInfo::MapleLogger() << " \"" << GlobalTables::GetStrTable().GetStringFromStrIdx(idx).c_str() << "\"";
1374 } else if (dwForm == DW_FORM_ref4) {
1375 LogInfo::MapleLogger() << " <" << HEX(value.id) << ">";
1376 } else if (dwAttr == DW_AT_encoding) {
1377 CHECK_FATAL(GetDwAteName(static_cast<uint32>(value.u)), "null ptr check");
1378 LogInfo::MapleLogger() << " " << GetDwAteName(static_cast<uint32>(value.u));
1379 } else if (dwAttr == DW_AT_location) {
1380 value.ptr->Dump();
1381 } else {
1382 LogInfo::MapleLogger() << " 0x" << std::hex << value.u << std::dec;
1383 }
1384 LogInfo::MapleLogger() << std::endl;
1385 }
1386
Dump(int indent)1387 void DBGDie::Dump(int indent)
1388 {
1389 PrintIndentation(indent);
1390 LogInfo::MapleLogger() << "<" << HEX(id) << "><" << HEX(offset);
1391 LogInfo::MapleLogger() << "><" << HEX(size) << "><"
1392 << "> abbrev id: " << HEX(abbrevId);
1393 CHECK_FATAL(GetDwTagName(tag), "null ptr check");
1394 LogInfo::MapleLogger() << " (" << GetDwTagName(tag) << ") ";
1395 if (parent) {
1396 LogInfo::MapleLogger() << "parent <" << HEX(parent->GetId());
1397 }
1398 LogInfo::MapleLogger() << "> {";
1399 if (tyIdx) {
1400 MIRType *type = GlobalTables::GetTypeTable().GetTypeFromTyIdx(TyIdx(tyIdx));
1401 if (type->GetKind() == kTypeStruct || type->GetKind() == kTypeClass || type->GetKind() == kTypeInterface) {
1402 MIRStructType *stype = static_cast<MIRStructType *>(type);
1403 LogInfo::MapleLogger() << " # " << stype->GetName();
1404 } else {
1405 LogInfo::MapleLogger() << " # " << GetPrimTypeName(type->GetPrimType());
1406 }
1407 }
1408 LogInfo::MapleLogger() << std::endl;
1409 ;
1410 for (auto it : attrVec) {
1411 it->Dump(indent + 1);
1412 }
1413 PrintIndentation(indent);
1414 LogInfo::MapleLogger() << "} ";
1415 if (subDieVec.size()) {
1416 LogInfo::MapleLogger() << " {" << std::endl;
1417 for (auto it : subDieVec) {
1418 it->Dump(indent + 1);
1419 }
1420 PrintIndentation(indent);
1421 LogInfo::MapleLogger() << "}";
1422 }
1423 LogInfo::MapleLogger() << std::endl;
1424 return;
1425 }
1426
Dump(int indent)1427 void DBGAbbrevEntry::Dump(int indent)
1428 {
1429 PrintIndentation(indent);
1430 CHECK_FATAL(GetDwTagName(tag), "null ptr check ");
1431 LogInfo::MapleLogger() << "<" << HEX(abbrevId) << "> " << GetDwTagName(tag);
1432 if (GetWithChildren()) {
1433 LogInfo::MapleLogger() << " [with children] {" << std::endl;
1434 } else {
1435 LogInfo::MapleLogger() << " [no children] {" << std::endl;
1436 }
1437 for (uint32 i = 0; i < attrPairs.size(); i += k2BitSize) {
1438 PrintIndentation(indent + 1);
1439 CHECK_FATAL(GetDwAtName(attrPairs[i]) && GetDwFormName(attrPairs[i + 1]), "NULLPTR CHECK");
1440
1441 LogInfo::MapleLogger() << " " << GetDwAtName(attrPairs[i]) << " " << GetDwFormName(attrPairs[i + 1]) << " "
1442 << std::endl;
1443 }
1444 PrintIndentation(indent);
1445 LogInfo::MapleLogger() << "}" << std::endl;
1446 return;
1447 }
1448
Dump(int indent)1449 void DBGAbbrevEntryVec::Dump(int indent)
1450 {
1451 for (auto it : entryVec) {
1452 PrintIndentation(indent);
1453 it->Dump(indent);
1454 }
1455 return;
1456 }
1457
1458 // DBGCompileMsgInfo methods
ClearLine(uint32 n)1459 void DBGCompileMsgInfo::ClearLine(uint32 n)
1460 {
1461 errno_t eNum = memset_s(codeLine[n], MAXLINELEN, 0, MAXLINELEN);
1462 if (eNum) {
1463 FATAL(kLncFatal, "memset_s failed");
1464 }
1465 }
1466
DBGCompileMsgInfo()1467 DBGCompileMsgInfo::DBGCompileMsgInfo() : startLine(0), errPos(0)
1468 {
1469 lineNum[0] = 0;
1470 lineNum[1] = 0;
1471 lineNum[kIndx2] = 0;
1472 ClearLine(0);
1473 ClearLine(1);
1474 ClearLine(kIndx2);
1475 errLNum = 0;
1476 errCNum = 0;
1477 }
1478
SetErrPos(uint32 lnum,uint32 cnum)1479 void DBGCompileMsgInfo::SetErrPos(uint32 lnum, uint32 cnum)
1480 {
1481 errLNum = lnum;
1482 errCNum = cnum;
1483 }
1484
UpdateMsg(uint32 lnum,const char * line)1485 void DBGCompileMsgInfo::UpdateMsg(uint32 lnum, const char *line)
1486 {
1487 size_t size = strlen(line);
1488 if (size > MAXLINELEN - 1) {
1489 size = MAXLINELEN - 1;
1490 }
1491 startLine = (startLine + k2BitSize) % k3BitSize;
1492 ClearLine(startLine);
1493 errno_t eNum = memcpy_s(codeLine[startLine], MAXLINELEN, line, size);
1494 if (eNum) {
1495 FATAL(kLncFatal, "memcpy_s failed");
1496 }
1497 codeLine[startLine][size] = '\0';
1498 lineNum[startLine] = lnum;
1499 }
1500
EmitMsg()1501 void DBGCompileMsgInfo::EmitMsg()
1502 {
1503 char str[MAXLINELEN + 1];
1504
1505 errPos = errCNum;
1506 errPos = (errPos < k2BitSize) ? k2BitSize : errPos;
1507 errPos = (errPos > MAXLINELEN) ? MAXLINELEN : errPos;
1508 for (uint32 i = 0; i < errPos - 1; i++) {
1509 str[i] = ' ';
1510 }
1511 str[errPos - 1] = '^';
1512 str[errPos] = '\0';
1513
1514 fprintf(stderr, "\n===================================================================\n");
1515 fprintf(stderr, "==================");
1516 fprintf(stderr, BOLD YEL " Compilation Error Diagnosis " RESET);
1517 fprintf(stderr, "==================\n");
1518 fprintf(stderr, "===================================================================\n");
1519 fprintf(stderr, "line %4u %s\n", lineNum[(startLine + k2BitSize) % k3BitSize],
1520 reinterpret_cast<char *>(codeLine[(startLine + k2BitSize) % k3BitSize]));
1521 fprintf(stderr, "line %4u %s\n", lineNum[(startLine + 1) % k3BitSize],
1522 reinterpret_cast<char *>(codeLine[(startLine + 1) % k3BitSize]));
1523 fprintf(stderr, "line %4u %s\n", lineNum[(startLine) % k3BitSize],
1524 reinterpret_cast<char *>(codeLine[(startLine) % k3BitSize]));
1525 fprintf(stderr, BOLD RED " %s\n" RESET, str);
1526 fprintf(stderr, "===================================================================\n");
1527 }
1528 } // namespace maple
1529