• 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 StringUtils::StartsWith(GetName(), kRegJNITabPrefixStr);
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 
IsForcedGlobalFunc() const203 bool MIRSymbol::IsForcedGlobalFunc() const
204 {
205     return StringUtils::StartsWith(GetName(), kJavaLangClassStr) ||
206            StringUtils::StartsWith(GetName(), kReflectionClassesPrefixStr) ||
207            StringUtils::StartsWith(GetName(), "Ljava_2Fnio_2FDirectByteBuffer_3B_7C_3Cinit_3E_7C_28JI_29V");
208 }
209 
210 // mrt/maplert/include/mrt_classinfo.h
IsForcedGlobalClassinfo() const211 bool MIRSymbol::IsForcedGlobalClassinfo() const
212 {
213     std::unordered_set<std::string> mrtUse {
214 #include "mrt_direct_classinfo_list.def"
215     };
216     return std::find(mrtUse.begin(), mrtUse.end(), GetName()) != mrtUse.end() ||
217            StringUtils::StartsWith(GetName(), "__cinf_Llibcore_2Freflect_2FGenericSignatureParser_3B");
218 }
219 
IsClassInitBridge() const220 bool MIRSymbol::IsClassInitBridge() const
221 {
222     return StringUtils::StartsWith(GetName(), CLASS_INIT_BRIDGE_PREFIX_STR);
223 }
224 
IsReflectionHashTabBucket() const225 bool MIRSymbol::IsReflectionHashTabBucket() const
226 {
227     return StringUtils::StartsWith(GetName(), kMuidClassMetadataBucketPrefixStr);
228 }
229 
IsReflectionInfo() const230 bool MIRSymbol::IsReflectionInfo() const
231 {
232     return IsReflectionClassInfo() || IsReflectionClassInfoRO() || IsReflectionFieldsInfo() ||
233            IsReflectionFieldsInfoCompact() || IsReflectionMethodsInfo() || IsReflectionPrimitiveClassInfo() ||
234            IsReflectionSuperclassInfo() || IsReflectionMethodsInfoCompact();
235 }
236 
IsReflectionFieldsInfo() const237 bool MIRSymbol::IsReflectionFieldsInfo() const
238 {
239     return StringUtils::StartsWith(GetName(), kFieldsInfoPrefixStr);
240 }
241 
IsReflectionFieldsInfoCompact() const242 bool MIRSymbol::IsReflectionFieldsInfoCompact() const
243 {
244     return StringUtils::StartsWith(GetName(), kFieldsInfoCompactPrefixStr);
245 }
246 
IsReflectionSuperclassInfo() const247 bool MIRSymbol::IsReflectionSuperclassInfo() const
248 {
249     return StringUtils::StartsWith(GetName(), SUPERCLASSINFO_PREFIX_STR);
250 }
251 
IsReflectionFieldOffsetData() const252 bool MIRSymbol::IsReflectionFieldOffsetData() const
253 {
254     return StringUtils::StartsWith(GetName(), kFieldOffsetDataPrefixStr);
255 }
256 
IsReflectionMethodAddrData() const257 bool MIRSymbol::IsReflectionMethodAddrData() const
258 {
259     return (GetName().find(kMethodAddrDataPrefixStr) == 0);
260 }
261 
IsReflectionMethodSignature() const262 bool MIRSymbol::IsReflectionMethodSignature() const
263 {
264     return (GetName().find(kMethodSignaturePrefixStr) == 0);
265 }
266 
IsReflectionClassInfo() const267 bool MIRSymbol::IsReflectionClassInfo() const
268 {
269     return StringUtils::StartsWith(GetName(), CLASSINFO_PREFIX_STR);
270 }
271 
IsReflectionArrayClassInfo() const272 bool MIRSymbol::IsReflectionArrayClassInfo() const
273 {
274     return StringUtils::StartsWith(GetName(), kArrayClassInfoPrefixStr);
275 }
276 
IsReflectionClassInfoPtr() const277 bool MIRSymbol::IsReflectionClassInfoPtr() const
278 {
279     return StringUtils::StartsWith(GetName(), kClassINfoPtrPrefixStr);
280 }
281 
IsReflectionClassInfoRO() const282 bool MIRSymbol::IsReflectionClassInfoRO() const
283 {
284     return StringUtils::StartsWith(GetName(), CLASSINFO_RO_PREFIX_STR);
285 }
286 
IsITabConflictInfo() const287 bool MIRSymbol::IsITabConflictInfo() const
288 {
289     return StringUtils::StartsWith(GetName(), ITAB_CONFLICT_PREFIX_STR);
290 }
291 
IsVTabInfo() const292 bool MIRSymbol::IsVTabInfo() const
293 {
294     return StringUtils::StartsWith(GetName(), VTAB_PREFIX_STR);
295 }
296 
IsITabInfo() const297 bool MIRSymbol::IsITabInfo() const
298 {
299     return StringUtils::StartsWith(GetName(), ITAB_PREFIX_STR);
300 }
301 
IsReflectionPrimitiveClassInfo() const302 bool MIRSymbol::IsReflectionPrimitiveClassInfo() const
303 {
304     return StringUtils::StartsWith(GetName(), PRIMITIVECLASSINFO_PREFIX_STR);
305 }
306 
IsReflectionMethodsInfo() const307 bool MIRSymbol::IsReflectionMethodsInfo() const
308 {
309     return StringUtils::StartsWith(GetName(), kMethodsInfoPrefixStr);
310 }
311 
IsReflectionMethodsInfoCompact() const312 bool MIRSymbol::IsReflectionMethodsInfoCompact() const
313 {
314     return StringUtils::StartsWith(GetName(), kMethodsInfoCompactPrefixStr);
315 }
316 
IsPrimordialObject() const317 bool MIRSymbol::IsPrimordialObject() const
318 {
319     return IsReflectionClassInfo() || IsReflectionPrimitiveClassInfo();
320 }
321 
IsGctibSym() const322 bool MIRSymbol::IsGctibSym() const
323 {
324     return StringUtils::StartsWith(GetName(), GCTIB_PREFIX_STR);
325 }
326 
327 // [Note]
328 // Some symbols are ignored by reference counting as they represent objects not managed by us. These include
329 // string-based exact comparison for "current_vptr", "vtabptr", "itabptr", "funcptr", "env_ptr", "retvar_stubfunc".
330 GStrIdx MIRSymbol::reflectClassNameIdx;
331 GStrIdx MIRSymbol::reflectMethodNameIdx;
332 GStrIdx MIRSymbol::reflectFieldNameIdx;
IgnoreRC() const333 bool MIRSymbol::IgnoreRC() const
334 {
335     if (isDeleted || GetAttr(ATTR_rcunowned)) {
336         return true;
337     }
338     const std::string &name = GetName();
339     // ignore %current_vptr, %vtabptr, %itabptr, %funcptr, %env_ptr
340     if (name == "current_vptr" || name == "vtabptr" || name == "itabptr" || name == "funcptr" || name == "env_ptr" ||
341         name == "retvar_stubfunc" || name == "_dummy_stub_object_retval") {
342         return true;
343     }
344     if (IsReflectionInfo() || IsRegJNITab() || IsRegJNIFuncTab()) {
345         return true;
346     }
347     MIRType *type = GetType();
348     // only consider reference
349     if (type == nullptr || type->GetPrimType() != PTY_ref) {
350         return true;
351     }
352     if ((type->GetKind() == kTypeScalar) && (name != "__mapleRC__")) {
353         return true;
354     }
355     // ignore ptr to types Ljava_2Flang_2FClass_3B,
356     // Ljava_2Flang_2Freflect_2FMethod_3B
357     const auto *pType = static_cast<MIRPtrType *>(type);
358     GStrIdx strIdx = GlobalTables::GetTypeTable().GetTypeFromTyIdx(pType->GetPointedTyIdx())->GetNameStrIdx();
359     if (reflectClassNameIdx == 0u) {
360         reflectClassNameIdx = GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(
361             namemangler::GetInternalNameLiteral("Ljava_2Flang_2FClass_3B"));
362     }
363     return strIdx == reflectClassNameIdx;
364 }
365 
Dump(bool isLocal,int32 indent,bool suppressInit,const MIRSymbolTable * localsymtab) const366 void MIRSymbol::Dump(bool isLocal, int32 indent, bool suppressInit, const MIRSymbolTable *localsymtab) const
367 {
368     if (sKind == kStVar || sKind == kStFunc) {
369         srcPosition.DumpLoc(lastPrintedLineNum, lastPrintedColumnNum);
370     }
371     // exclude unused symbols, formal symbols and extern functions
372     if (GetStorageClass() == kScUnused || GetStorageClass() == kScFormal ||
373         (GetStorageClass() == kScExtern && sKind == kStFunc)) {
374         return;
375     }
376     if (GetIsImported() && !GetAppearsInCode()) {
377         return;
378     }
379     if (GetTyIdx() >= GlobalTables::GetTypeTable().GetTypeTable().size()) {
380         FATAL(kLncFatal, "valid maple_ir with illegal type");
381     }
382     if (GetStorageClass() == kScText && GetFunction() != nullptr) {
383         // without body
384         GetFunction()->Dump(true);
385         return;
386     }
387     const char *ids = isLocal ? "%" : "$";
388     PrintIndentation(indent);
389     if (sKind == kStJavaClass) {
390         LogInfo::MapleLogger() << "javaclass ";
391     } else if (sKind == kStJavaInterface) {
392         LogInfo::MapleLogger() << "javainterface ";
393     } else if (isTmp) {
394         LogInfo::MapleLogger() << "tempvar ";
395     } else {
396         LogInfo::MapleLogger() << "var ";
397     }
398     LogInfo::MapleLogger() << ids << GetName() << " ";
399     if (GetStorageClass() == kScFstatic) {
400         LogInfo::MapleLogger() << "fstatic ";
401     } else if (GetStorageClass() == kScPstatic) {
402         LogInfo::MapleLogger() << "pstatic ";
403     } else if (GetStorageClass() == kScExtern) {
404         LogInfo::MapleLogger() << "extern ";
405     }
406     if (GetTyIdx() != 0u) {
407         GlobalTables::GetTypeTable().GetTypeFromTyIdx(GetTyIdx())->Dump(indent + 1);
408     }
409     if (sectionAttr != UStrIdx(0)) {
410         LogInfo::MapleLogger() << " section (";
411         PrintString(GlobalTables::GetUStrTable().GetStringFromStrIdx(sectionAttr));
412         LogInfo::MapleLogger() << " )";
413     }
414     if (asmAttr != UStrIdx(0)) {
415         LogInfo::MapleLogger() << " asmattr (";
416         PrintString(GlobalTables::GetUStrTable().GetStringFromStrIdx(asmAttr));
417         LogInfo::MapleLogger() << " )";
418     }
419     typeAttrs.DumpAttributes();
420     if (sKind == kStJavaClass || sKind == kStJavaInterface || GetStorageClass() == kScTypeInfoName ||
421         GetStorageClass() == kScTypeInfo || GetStorageClass() == kScTypeCxxAbi) {
422         LogInfo::MapleLogger() << '\n';
423         return;
424     }
425     if (IsConst() && !suppressInit && !(IsLiteral() && GetStorageClass() == kScExtern)) {
426         LogInfo::MapleLogger() << " = ";
427         GetKonst()->Dump(localsymtab);
428     }
429     LogInfo::MapleLogger() << '\n';
430 }
431 
DumpAsLiteralVar() const432 void MIRSymbol::DumpAsLiteralVar() const
433 {
434     if (IsLiteral()) {
435         LogInfo::MapleLogger() << GetName();
436     }
437 }
438 
439 const std::set<std::string> MIRSymbol::staticFinalBlackList {
440     "Ljava_2Flang_2FSystem_3B_7Cout",
441     "Ljava_2Flang_2FSystem_3B_7Cerr",
442     "Ljava_2Flang_2FSystem_3B_7Cin",
443 };
444 
Dump(bool isLocal,int32 indent,bool printDeleted,MIRFlavor flavor) const445 void MIRSymbolTable::Dump(bool isLocal, int32 indent, bool printDeleted, MIRFlavor flavor) const
446 {
447     size_t size = symbolTable.size();
448     for (size_t i = 0; i < size; ++i) {
449         MIRSymbol *symbol = symbolTable[i];
450         if (symbol == nullptr) {
451             continue;
452         }
453         if (!printDeleted && symbol->IsDeleted()) {
454             continue;
455         }
456         if (flavor == kFlavorLmbc && symbol->LMBCAllocateOffSpecialReg()) {
457             continue;
458         }
459         symbol->Dump(isLocal, indent, false /* suppressinit */, this);
460     }
461 }
462 
CreateLabelWithPrefix(char c)463 LabelIdx MIRLabelTable::CreateLabelWithPrefix(char c)
464 {
465     LabelIdx labelIdx = labelTable.size();
466     std::ostringstream labelNameStream;
467     labelNameStream << "@" << c << labelIdx;
468     std::string labelName = labelNameStream.str();
469     GStrIdx nameIdx = GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(labelName);
470     labelTable.push_back(nameIdx);
471     strIdxToLabIdxMap[nameIdx] = labelIdx;
472     return labelIdx;
473 }
474 
GetName(LabelIdx labelIdx) const475 const std::string &MIRLabelTable::GetName(LabelIdx labelIdx) const
476 {
477     CHECK_FATAL(labelIdx < labelTable.size(), "index out of range in MIRLabelTable::GetName");
478     return GlobalTables::GetStrTable().GetStringFromStrIdx(labelTable[labelIdx]);
479 }
480 
AddToStringLabelMap(LabelIdx labelIdx)481 void MIRLabelTable::AddToStringLabelMap(LabelIdx labelIdx)
482 {
483     CHECK_FATAL(labelIdx < labelTable.size(), "index out of range in MIRLabelTable::AddToStringLabelMap");
484     if (labelTable[labelIdx] == 0u) {
485         // generate a label name based on lab_idx
486         std::ostringstream labelNameStream;
487         labelNameStream << "@" << labelIdx;
488         std::string labelName = labelNameStream.str();
489         labelTable[labelIdx] = GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(labelName);
490     }
491     GStrIdx strIdx = labelTable[labelIdx];
492     strIdxToLabIdxMap[strIdx] = labelIdx;
493 }
494 }  // namespace maple
495