• 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 "mir_symbol.h"
17 #include "mir_function.h"
18 #include "class_init.h"
19 #include "reflection_analysis.h"
20 #include "printing.h"
21 #include "literalstrname.h"
22 #include "string_utils.h"
23 
24 namespace maple {
25 using namespace namemangler;
26 
27 uint32 MIRSymbol::lastPrintedLineNum = 0;
28 uint16 MIRSymbol::lastPrintedColumnNum = 0;
29 
NeedPIC() const30 bool MIRSymbol::NeedPIC() const
31 {
32     return (storageClass == kScGlobal) || (storageClass == kScExtern) ||
33            (sKind == kStFunc && !GetFunction()->IsStatic());
34 }
35 
IsTypeVolatile(int fieldID) const36 bool MIRSymbol::IsTypeVolatile(int fieldID) const
37 {
38     const MIRType *ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(GetTyIdx());
39     return ty->IsVolatile(fieldID);
40 }
41 
SetNameStrIdx(const std::string & name)42 void MIRSymbol::SetNameStrIdx(const std::string &name)
43 {
44     nameStrIdx = GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(name);
45 }
46 
HasAddrOfValues() const47 bool MIRSymbol::HasAddrOfValues() const
48 {
49     return StringUtils::StartsWith(GetName(), VTAB_PREFIX_STR) || StringUtils::StartsWith(GetName(), ITAB_PREFIX_STR) ||
50            StringUtils::StartsWith(GetName(), kVtabOffsetTabStr) ||
51            StringUtils::StartsWith(GetName(), kDecoupleStaticKeyStr) || IsClassInitBridge() || IsReflectionInfo() ||
52            IsReflectionHashTabBucket() || IsReflectionStrTab() || IsITabConflictInfo() || IsRegJNITab() ||
53            IsRegJNIFuncTab() || IsLiteral();
54 }
55 
IsLiteral() const56 bool MIRSymbol::IsLiteral() const
57 {
58     return StringUtils::StartsWith(GetName(), kConstString);
59 }
60 
IsLiteralPtr() const61 bool MIRSymbol::IsLiteralPtr() const
62 {
63     return StringUtils::StartsWith(GetName(), kConstStringPtr);
64 }
65 
GetType() const66 MIRType *MIRSymbol::GetType() const
67 {
68     return GlobalTables::GetTypeTable().GetTypeFromTyIdx(tyIdx);
69 }
70 
PointsToConstString() const71 bool MIRSymbol::PointsToConstString() const
72 {
73     MIRType *origType = GlobalTables::GetTypeTable().GetTypeFromTyIdx(tyIdx);
74     if (origType->GetKind() == kTypePointer) {
75         return static_cast<MIRPtrType *>(origType)->PointsToConstString();
76     }
77     return false;
78 }
79 
IsConstString() const80 bool MIRSymbol::IsConstString() const
81 {
82     return typeAttrs.GetAttr(ATTR_static) && typeAttrs.GetAttr(ATTR_final) && PointsToConstString();
83 }
84 
IsReflectionStrTab() const85 bool MIRSymbol::IsReflectionStrTab() const
86 {
87     return StringUtils::StartsWith(GetName(), kReflectionStrtabPrefixStr) ||
88            StringUtils::StartsWith(GetName(), kReflectionStartHotStrtabPrefixStr) ||
89            StringUtils::StartsWith(GetName(), kReflectionBothHotStrTabPrefixStr) ||
90            StringUtils::StartsWith(GetName(), kReflectionRunHotStrtabPrefixStr) ||
91            StringUtils::StartsWith(GetName(), kReflectionNoEmitStrtabPrefixStr);
92 }
93 
IsRegJNITab() const94 bool MIRSymbol::IsRegJNITab() const
95 {
96     return false;
97 }
98 
IsRegJNIFuncTab() const99 bool MIRSymbol::IsRegJNIFuncTab() const
100 {
101     return StringUtils::StartsWith(GetName(), kRegJNIFuncTabPrefixStr);
102 }
103 
IsMuidTab() const104 bool MIRSymbol::IsMuidTab() const
105 {
106     return StringUtils::StartsWith(GetName(), kMuidPrefixStr);
107 }
108 
IsMuidRoTab() const109 bool MIRSymbol::IsMuidRoTab() const
110 {
111     return StringUtils::StartsWith(GetName(), kMuidRoPrefixStr);
112 }
113 
IsCodeLayoutInfo() const114 bool MIRSymbol::IsCodeLayoutInfo() const
115 {
116     return StringUtils::StartsWith(GetName(), kFunctionLayoutStr);
117 }
118 
GetMuidTabName() const119 std::string MIRSymbol::GetMuidTabName() const
120 {
121     if (!IsMuidTab()) {
122         return "";
123     }
124     size_t idx = GetName().find(kFileNameSplitterStr);
125     return (idx != std::string::npos) ? GetName().substr(0, idx) : "";
126 }
127 
IsMuidFuncDefTab() const128 bool MIRSymbol::IsMuidFuncDefTab() const
129 {
130     return StringUtils::StartsWith(GetName(), kMuidFuncDefTabPrefixStr);
131 }
132 
IsMuidFuncDefOrigTab() const133 bool MIRSymbol::IsMuidFuncDefOrigTab() const
134 {
135     return StringUtils::StartsWith(GetName(), kMuidFuncDefOrigTabPrefixStr);
136 }
137 
IsMuidFuncInfTab() const138 bool MIRSymbol::IsMuidFuncInfTab() const
139 {
140     return StringUtils::StartsWith(GetName(), kMuidFuncInfTabPrefixStr);
141 }
142 
IsMuidFuncUndefTab() const143 bool MIRSymbol::IsMuidFuncUndefTab() const
144 {
145     return StringUtils::StartsWith(GetName(), kMuidFuncUndefTabPrefixStr);
146 }
147 
IsMuidDataDefTab() const148 bool MIRSymbol::IsMuidDataDefTab() const
149 {
150     return StringUtils::StartsWith(GetName(), kMuidDataDefTabPrefixStr);
151 }
152 
IsMuidDataDefOrigTab() const153 bool MIRSymbol::IsMuidDataDefOrigTab() const
154 {
155     return StringUtils::StartsWith(GetName(), kMuidDataDefOrigTabPrefixStr);
156 }
157 
IsMuidDataUndefTab() const158 bool MIRSymbol::IsMuidDataUndefTab() const
159 {
160     return StringUtils::StartsWith(GetName(), kMuidDataUndefTabPrefixStr);
161 }
162 
IsMuidFuncDefMuidTab() const163 bool MIRSymbol::IsMuidFuncDefMuidTab() const
164 {
165     return StringUtils::StartsWith(GetName(), kMuidFuncDefMuidTabPrefixStr);
166 }
167 
IsMuidFuncUndefMuidTab() const168 bool MIRSymbol::IsMuidFuncUndefMuidTab() const
169 {
170     return StringUtils::StartsWith(GetName(), kMuidFuncUndefMuidTabPrefixStr);
171 }
172 
IsMuidDataDefMuidTab() const173 bool MIRSymbol::IsMuidDataDefMuidTab() const
174 {
175     return StringUtils::StartsWith(GetName(), kMuidDataDefMuidTabPrefixStr);
176 }
177 
IsMuidDataUndefMuidTab() const178 bool MIRSymbol::IsMuidDataUndefMuidTab() const
179 {
180     return StringUtils::StartsWith(GetName(), kMuidDataUndefMuidTabPrefixStr);
181 }
182 
IsMuidFuncMuidIdxMuidTab() const183 bool MIRSymbol::IsMuidFuncMuidIdxMuidTab() const
184 {
185     return StringUtils::StartsWith(GetName(), kMuidFuncMuidIdxTabPrefixStr);
186 }
187 
IsMuidRangeTab() const188 bool MIRSymbol::IsMuidRangeTab() const
189 {
190     return StringUtils::StartsWith(GetName(), kMuidRangeTabPrefixStr);
191 }
192 
IsArrayClassCache() const193 bool MIRSymbol::IsArrayClassCache() const
194 {
195     return StringUtils::StartsWith(GetName(), kArrayClassCacheTable);
196 }
197 
IsArrayClassCacheName() const198 bool MIRSymbol::IsArrayClassCacheName() const
199 {
200     return StringUtils::StartsWith(GetName(), kArrayClassCacheNameTable);
201 }
202 
203 // mrt/maplert/include/mrt_classinfo.h
IsForcedGlobalClassinfo() const204 bool MIRSymbol::IsForcedGlobalClassinfo() const
205 {
206     return StringUtils::StartsWith(GetName(), "__cinf_Llibcore_2Freflect_2FGenericSignatureParser_3B");
207 }
208 
IsClassInitBridge() const209 bool MIRSymbol::IsClassInitBridge() const
210 {
211     return StringUtils::StartsWith(GetName(), CLASS_INIT_BRIDGE_PREFIX_STR);
212 }
213 
IsReflectionHashTabBucket() const214 bool MIRSymbol::IsReflectionHashTabBucket() const
215 {
216     return StringUtils::StartsWith(GetName(), kMuidClassMetadataBucketPrefixStr);
217 }
218 
IsReflectionInfo() const219 bool MIRSymbol::IsReflectionInfo() const
220 {
221     return IsReflectionClassInfo() || IsReflectionClassInfoRO() || IsReflectionFieldsInfo() ||
222            IsReflectionFieldsInfoCompact() || IsReflectionMethodsInfo() || IsReflectionPrimitiveClassInfo() ||
223            IsReflectionSuperclassInfo() || IsReflectionMethodsInfoCompact();
224 }
225 
IsReflectionFieldsInfo() const226 bool MIRSymbol::IsReflectionFieldsInfo() const
227 {
228     return StringUtils::StartsWith(GetName(), kFieldsInfoPrefixStr);
229 }
230 
IsReflectionFieldsInfoCompact() const231 bool MIRSymbol::IsReflectionFieldsInfoCompact() const
232 {
233     return StringUtils::StartsWith(GetName(), kFieldsInfoCompactPrefixStr);
234 }
235 
IsReflectionSuperclassInfo() const236 bool MIRSymbol::IsReflectionSuperclassInfo() const
237 {
238     return StringUtils::StartsWith(GetName(), SUPERCLASSINFO_PREFIX_STR);
239 }
240 
IsReflectionFieldOffsetData() const241 bool MIRSymbol::IsReflectionFieldOffsetData() const
242 {
243     return StringUtils::StartsWith(GetName(), kFieldOffsetDataPrefixStr);
244 }
245 
IsReflectionMethodAddrData() const246 bool MIRSymbol::IsReflectionMethodAddrData() const
247 {
248     return (GetName().find(kMethodAddrDataPrefixStr) == 0);
249 }
250 
IsReflectionMethodSignature() const251 bool MIRSymbol::IsReflectionMethodSignature() const
252 {
253     return (GetName().find(kMethodSignaturePrefixStr) == 0);
254 }
255 
IsReflectionClassInfo() const256 bool MIRSymbol::IsReflectionClassInfo() const
257 {
258     return StringUtils::StartsWith(GetName(), CLASSINFO_PREFIX_STR);
259 }
260 
IsReflectionArrayClassInfo() const261 bool MIRSymbol::IsReflectionArrayClassInfo() const
262 {
263     return StringUtils::StartsWith(GetName(), kArrayClassInfoPrefixStr);
264 }
265 
IsReflectionClassInfoPtr() const266 bool MIRSymbol::IsReflectionClassInfoPtr() const
267 {
268     return StringUtils::StartsWith(GetName(), kClassINfoPtrPrefixStr);
269 }
270 
IsReflectionClassInfoRO() const271 bool MIRSymbol::IsReflectionClassInfoRO() const
272 {
273     return StringUtils::StartsWith(GetName(), CLASSINFO_RO_PREFIX_STR);
274 }
275 
IsITabConflictInfo() const276 bool MIRSymbol::IsITabConflictInfo() const
277 {
278     return StringUtils::StartsWith(GetName(), ITAB_CONFLICT_PREFIX_STR);
279 }
280 
IsVTabInfo() const281 bool MIRSymbol::IsVTabInfo() const
282 {
283     return StringUtils::StartsWith(GetName(), VTAB_PREFIX_STR);
284 }
285 
IsITabInfo() const286 bool MIRSymbol::IsITabInfo() const
287 {
288     return StringUtils::StartsWith(GetName(), ITAB_PREFIX_STR);
289 }
290 
IsReflectionPrimitiveClassInfo() const291 bool MIRSymbol::IsReflectionPrimitiveClassInfo() const
292 {
293     return StringUtils::StartsWith(GetName(), PRIMITIVECLASSINFO_PREFIX_STR);
294 }
295 
IsReflectionMethodsInfo() const296 bool MIRSymbol::IsReflectionMethodsInfo() const
297 {
298     return StringUtils::StartsWith(GetName(), kMethodsInfoPrefixStr);
299 }
300 
IsReflectionMethodsInfoCompact() const301 bool MIRSymbol::IsReflectionMethodsInfoCompact() const
302 {
303     return StringUtils::StartsWith(GetName(), kMethodsInfoCompactPrefixStr);
304 }
305 
IsPrimordialObject() const306 bool MIRSymbol::IsPrimordialObject() const
307 {
308     return IsReflectionClassInfo() || IsReflectionPrimitiveClassInfo();
309 }
310 
IsGctibSym() const311 bool MIRSymbol::IsGctibSym() const
312 {
313     return StringUtils::StartsWith(GetName(), GCTIB_PREFIX_STR);
314 }
315 
316 // [Note]
317 // Some symbols are ignored by reference counting as they represent objects not managed by us. These include
318 // string-based exact comparison for "current_vptr", "vtabptr", "itabptr", "funcptr", "env_ptr", "retvar_stubfunc".
319 GStrIdx MIRSymbol::reflectClassNameIdx;
320 GStrIdx MIRSymbol::reflectMethodNameIdx;
321 GStrIdx MIRSymbol::reflectFieldNameIdx;
IgnoreRC() const322 bool MIRSymbol::IgnoreRC() const
323 {
324     if (isDeleted || GetAttr(ATTR_rcunowned)) {
325         return true;
326     }
327     const std::string &name = GetName();
328     // ignore %current_vptr, %vtabptr, %itabptr, %funcptr, %env_ptr
329     if (name == "current_vptr" || name == "vtabptr" || name == "itabptr" || name == "funcptr" || name == "env_ptr" ||
330         name == "retvar_stubfunc" || name == "_dummy_stub_object_retval") {
331         return true;
332     }
333     if (IsReflectionInfo() || IsRegJNITab() || IsRegJNIFuncTab()) {
334         return true;
335     }
336     MIRType *type = GetType();
337     // only consider reference
338     if (type == nullptr || type->GetPrimType() != PTY_ref) {
339         return true;
340     }
341     if ((type->GetKind() == kTypeScalar) && (name != "__mapleRC__")) {
342         return true;
343     }
344     const auto *pType = static_cast<MIRPtrType *>(type);
345     GStrIdx strIdx = GlobalTables::GetTypeTable().GetTypeFromTyIdx(pType->GetPointedTyIdx())->GetNameStrIdx();
346     return strIdx == reflectClassNameIdx;
347 }
348 
Dump(bool isLocal,int32 indent,bool suppressInit,const MIRSymbolTable * localsymtab) const349 void MIRSymbol::Dump(bool isLocal, int32 indent, bool suppressInit, const MIRSymbolTable *localsymtab) const
350 {
351     if (sKind == kStVar || sKind == kStFunc) {
352         srcPosition.DumpLoc(lastPrintedLineNum, lastPrintedColumnNum);
353     }
354     // exclude unused symbols, formal symbols and extern functions
355     if (GetStorageClass() == kScUnused || GetStorageClass() == kScFormal ||
356         (GetStorageClass() == kScExtern && sKind == kStFunc)) {
357         return;
358     }
359     if (GetIsImported() && !GetAppearsInCode()) {
360         return;
361     }
362     if (GetTyIdx() >= GlobalTables::GetTypeTable().GetTypeTable().size()) {
363         FATAL(kLncFatal, "valid maple_ir with illegal type");
364     }
365     if (GetStorageClass() == kScText && GetFunction() != nullptr) {
366         // without body
367         GetFunction()->Dump(true);
368         return;
369     }
370     const char *ids = isLocal ? "%" : "$";
371     PrintIndentation(indent);
372     if (isTmp) {
373         LogInfo::MapleLogger() << "tempvar ";
374     } else {
375         LogInfo::MapleLogger() << "var ";
376     }
377     LogInfo::MapleLogger() << ids << GetName() << " ";
378     if (GetStorageClass() == kScFstatic) {
379         LogInfo::MapleLogger() << "fstatic ";
380     } else if (GetStorageClass() == kScPstatic) {
381         LogInfo::MapleLogger() << "pstatic ";
382     } else if (GetStorageClass() == kScExtern) {
383         LogInfo::MapleLogger() << "extern ";
384     }
385     if (GetTyIdx() != 0u) {
386         GlobalTables::GetTypeTable().GetTypeFromTyIdx(GetTyIdx())->Dump(indent + 1);
387     }
388     if (sectionAttr != UStrIdx(0)) {
389         LogInfo::MapleLogger() << " section (";
390         PrintString(GlobalTables::GetUStrTable().GetStringFromStrIdx(sectionAttr));
391         LogInfo::MapleLogger() << " )";
392     }
393     if (asmAttr != UStrIdx(0)) {
394         LogInfo::MapleLogger() << " asmattr (";
395         PrintString(GlobalTables::GetUStrTable().GetStringFromStrIdx(asmAttr));
396         LogInfo::MapleLogger() << " )";
397     }
398     typeAttrs.DumpAttributes();
399     if (GetStorageClass() == kScTypeInfoName || GetStorageClass() == kScTypeInfo ||
400         GetStorageClass() == kScTypeCxxAbi) {
401         LogInfo::MapleLogger() << '\n';
402         return;
403     }
404     if (IsConst() && !suppressInit && !(IsLiteral() && GetStorageClass() == kScExtern)) {
405         LogInfo::MapleLogger() << " = ";
406         GetKonst()->Dump(localsymtab);
407     }
408     LogInfo::MapleLogger() << '\n';
409 }
410 
DumpAsLiteralVar() const411 void MIRSymbol::DumpAsLiteralVar() const
412 {
413     if (IsLiteral()) {
414         LogInfo::MapleLogger() << GetName();
415     }
416 }
417 
Dump(bool isLocal,int32 indent,bool printDeleted,MIRFlavor flavor) const418 void MIRSymbolTable::Dump(bool isLocal, int32 indent, bool printDeleted, MIRFlavor flavor) const
419 {
420     size_t size = symbolTable.size();
421     for (size_t i = 0; i < size; ++i) {
422         MIRSymbol *symbol = symbolTable[i];
423         if (symbol == nullptr) {
424             continue;
425         }
426         if (!printDeleted && symbol->IsDeleted()) {
427             continue;
428         }
429         if (flavor == kFlavorLmbc && symbol->LMBCAllocateOffSpecialReg()) {
430             continue;
431         }
432         symbol->Dump(isLocal, indent, false /* suppressinit */, this);
433     }
434 }
435 
CreateLabelWithPrefix(char c)436 LabelIdx MIRLabelTable::CreateLabelWithPrefix(char c)
437 {
438     LabelIdx labelIdx = labelTable.size();
439     std::ostringstream labelNameStream;
440     labelNameStream << "@" << c << labelIdx;
441     std::string labelName = labelNameStream.str();
442     GStrIdx nameIdx = GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(labelName);
443     labelTable.push_back(nameIdx);
444     strIdxToLabIdxMap[nameIdx] = labelIdx;
445     return labelIdx;
446 }
447 
GetName(LabelIdx labelIdx) const448 const std::string &MIRLabelTable::GetName(LabelIdx labelIdx) const
449 {
450     CHECK_FATAL(labelIdx < labelTable.size(), "index out of range in MIRLabelTable::GetName");
451     return GlobalTables::GetStrTable().GetStringFromStrIdx(labelTable[labelIdx]);
452 }
453 
AddToStringLabelMap(LabelIdx labelIdx)454 void MIRLabelTable::AddToStringLabelMap(LabelIdx labelIdx)
455 {
456     CHECK_FATAL(labelIdx < labelTable.size(), "index out of range in MIRLabelTable::AddToStringLabelMap");
457     if (labelTable[labelIdx] == 0u) {
458         // generate a label name based on lab_idx
459         std::ostringstream labelNameStream;
460         labelNameStream << "@" << labelIdx;
461         std::string labelName = labelNameStream.str();
462         labelTable[labelIdx] = GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(labelName);
463     }
464     GStrIdx strIdx = labelTable[labelIdx];
465     strIdxToLabIdxMap[strIdx] = labelIdx;
466 }
467 }  // namespace maple
468