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