• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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