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