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 "bin_mpl_import.h"
17 #include <sstream>
18 #include <vector>
19 #include <unordered_set>
20 #include <limits>
21 #include "bin_mplt.h"
22 #include "mir_function.h"
23 #include "namemangler.h"
24 #include "opcode_info.h"
25 #include "mir_pragma.h"
26 #include "mir_builder.h"
27
28 namespace maple {
Read()29 uint8 BinaryMplImport::Read()
30 {
31 CHECK_FATAL(bufI < buf.size(), "Index out of bound in BinaryMplImport::Read()");
32 return buf[bufI++];
33 }
34
35 // Little endian
ReadInt()36 int32 BinaryMplImport::ReadInt()
37 {
38 uint32 x0 = static_cast<uint32>(Read());
39 uint32 x1 = static_cast<uint32>(Read());
40 uint32 x2 = static_cast<uint32>(Read());
41 uint32 x3 = static_cast<uint32>(Read());
42 return (((((x3 << 8u) + x2) << 8u) + x1) << 8u) + x0;
43 }
44
ReadInt64()45 int64 BinaryMplImport::ReadInt64()
46 {
47 // casts to avoid sign extension
48 uint32 x0 = static_cast<uint32>(ReadInt());
49 uint64 x1 = static_cast<uint32>(ReadInt());
50 return static_cast<int64>((x1 << 32) + x0); // x1 left shift 32 bit to join with x0
51 }
52
53 // LEB128
ReadNum()54 int64 BinaryMplImport::ReadNum()
55 {
56 uint64 n = 0;
57 int64 y = 0;
58 uint64 b = static_cast<uint64>(Read());
59 while (b >= 0x80) {
60 y += ((b - 0x80) << n);
61 n += k7BitSize;
62 b = static_cast<uint64>(Read());
63 }
64 b = (b & 0x3F) - (b & 0x40);
65 return y + (b << n);
66 }
67
ReadAsciiStr(std::string & str)68 void BinaryMplImport::ReadAsciiStr(std::string &str)
69 {
70 int64 n = ReadNum();
71 for (int64 i = 0; i < n; i++) {
72 uint8 ch = Read();
73 str.push_back(static_cast<char>(ch));
74 }
75 }
76
ReadFileAt(const std::string & name,int32 offset)77 void BinaryMplImport::ReadFileAt(const std::string &name, int32 offset)
78 {
79 FILE *f = fopen(name.c_str(), "rb");
80 CHECK_FATAL(f != nullptr, "Error while reading the binary file: %s", name.c_str());
81
82 int seekRet = fseek(f, 0, SEEK_END);
83 CHECK_FATAL(seekRet == 0, "call fseek failed");
84
85 long size = ftell(f);
86 size -= offset;
87
88 CHECK_FATAL(size >= 0, "should not be negative");
89
90 seekRet = fseek(f, offset, SEEK_SET);
91 CHECK_FATAL(seekRet == 0, "call fseek failed");
92 buf.resize(size);
93
94 size_t result = fread(&buf[0], sizeof(uint8), static_cast<size_t>(size), f);
95 fclose(f);
96 CHECK_FATAL(result == static_cast<size_t>(size), "Error while reading the binary file: %s", name.c_str());
97 }
98
ImportConstBase(MIRConstKind & kind,MIRTypePtr & type)99 void BinaryMplImport::ImportConstBase(MIRConstKind &kind, MIRTypePtr &type)
100 {
101 kind = static_cast<MIRConstKind>(ReadNum());
102 TyIdx tyidx = mod.IsJavaModule() ? ImportType() : ImportTypeNonJava();
103 type = GlobalTables::GetTypeTable().GetTypeFromTyIdx(tyidx);
104 }
105
ImportConst(MIRFunction * func)106 MIRConst *BinaryMplImport::ImportConst(MIRFunction *func)
107 {
108 int64 tag = ReadNum();
109 if (tag == 0) {
110 return nullptr;
111 }
112
113 MIRConstKind kind;
114 MIRType *type = nullptr;
115 MemPool *memPool = mod.GetMemPool();
116
117 ImportConstBase(kind, type);
118 switch (tag) {
119 case kBinKindConstInt:
120 return GlobalTables::GetIntConstTable().GetOrCreateIntConst(ReadNum(), *type);
121 case kBinKindConstAddrof: {
122 MIRSymbol *sym = InSymbol(func);
123 CHECK_FATAL(sym != nullptr, "null ptr check");
124 FieldID fi = ReadNum();
125 int32 ofst = static_cast<int32>(ReadNum());
126 // do not use "type"; instead, get exprTy from sym
127 TyIdx ptyIdx = sym->GetTyIdx();
128 MIRPtrType ptrType(ptyIdx, (mod.IsJavaModule() ? PTY_ref : GetExactPtrPrimType()));
129 ptyIdx = GlobalTables::GetTypeTable().GetOrCreateMIRType(&ptrType);
130 MIRType *exprTy = GlobalTables::GetTypeTable().GetTypeFromTyIdx(ptyIdx);
131 return memPool->New<MIRAddrofConst>(sym->GetStIdx(), fi, *exprTy, ofst);
132 }
133 case kBinKindConstAddrofLocal: {
134 MIRSymbol *sym = ImportLocalSymbol(func);
135 FieldID fi = static_cast<FieldID>(ReadNum());
136 int32 ofst = static_cast<int32>(ReadNum());
137 return memPool->New<MIRAddrofConst>(sym->GetStIdx(), fi, *type, ofst);
138 }
139 case kBinKindConstAddrofFunc: {
140 PUIdx puIdx = ImportFunction();
141 MIRFunction *f = GlobalTables::GetFunctionTable().GetFuncTable()[puIdx];
142 f->GetFuncSymbol()->SetAppearsInCode(true);
143 mod.SetCurFunction(func);
144 return memPool->New<MIRAddroffuncConst>(puIdx, *type);
145 }
146 case kBinKindConstAddrofLabel: {
147 LabelIdx lidx = ImportLabel(func);
148 PUIdx puIdx = func->GetPuidx();
149 MIRLblConst *lblConst = memPool->New<MIRLblConst>(lidx, puIdx, *type);
150 (void)func->GetLabelTab()->addrTakenLabels.insert(lidx);
151 return lblConst;
152 }
153 case kBinKindConstStr: {
154 UStrIdx ustr = ImportUsrStr();
155 return memPool->New<MIRStrConst>(ustr, *type);
156 }
157 case kBinKindConstStr16: {
158 Conststr16Node *cs;
159 cs = memPool->New<Conststr16Node>();
160 cs->SetPrimType(type->GetPrimType());
161 int64 len = ReadNum();
162 std::ostringstream ostr;
163 for (int64 i = 0; i < len; ++i) {
164 ostr << Read();
165 }
166 std::u16string str16;
167 (void)namemangler::UTF8ToUTF16(str16, ostr.str());
168 cs->SetStrIdx(GlobalTables::GetU16StrTable().GetOrCreateStrIdxFromName(str16));
169 return memPool->New<MIRStr16Const>(cs->GetStrIdx(), *type);
170 }
171 case kBinKindConstFloat: {
172 union {
173 float fvalue;
174 int32 ivalue;
175 } value;
176
177 value.ivalue = ReadNum();
178 return GlobalTables::GetFpConstTable().GetOrCreateFloatConst(value.fvalue);
179 }
180 case kBinKindConstDouble: {
181 union {
182 double dvalue;
183 int64 ivalue;
184 } value;
185
186 value.ivalue = ReadNum();
187 return GlobalTables::GetFpConstTable().GetOrCreateDoubleConst(value.dvalue);
188 }
189 case kBinKindConstAgg: {
190 MIRAggConst *aggConst = mod.GetMemPool()->New<MIRAggConst>(mod, *type);
191 int64 size = ReadNum();
192 for (int64 i = 0; i < size; ++i) {
193 auto fieldId = static_cast<uint32>(ReadNum());
194 auto fieldConst = ImportConst(func);
195 aggConst->AddItem(fieldConst, fieldId);
196 }
197 return aggConst;
198 }
199 case kBinKindConstSt: {
200 MIRStConst *stConst = mod.GetMemPool()->New<MIRStConst>(mod, *type);
201 int64 size = ReadNum();
202 for (int64 i = 0; i < size; ++i) {
203 stConst->PushbackSymbolToSt(InSymbol(func));
204 }
205 size = ReadNum();
206 for (int64 i = 0; i < size; ++i) {
207 stConst->PushbackOffsetToSt(ReadNum());
208 }
209 return stConst;
210 }
211 default:
212 CHECK_FATAL(false, "Unhandled const type");
213 }
214 }
215
ImportStr()216 GStrIdx BinaryMplImport::ImportStr()
217 {
218 int64 tag = ReadNum();
219 if (tag == 0) {
220 return GStrIdx(0);
221 }
222 if (tag < 0) {
223 CHECK_FATAL(-tag < static_cast<int64>(gStrTab.size()), "index out of range in BinaryMplt::ImportStr");
224 return gStrTab[-tag];
225 }
226 CHECK_FATAL(tag == kBinString, "expecting kBinString");
227 std::string str;
228 ReadAsciiStr(str);
229 GStrIdx strIdx = GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(str);
230 gStrTab.push_back(strIdx);
231 return strIdx;
232 }
233
ImportUsrStr()234 UStrIdx BinaryMplImport::ImportUsrStr()
235 {
236 int64 tag = ReadNum();
237 if (tag == 0) {
238 return UStrIdx(0);
239 }
240 if (tag < 0) {
241 CHECK_FATAL(-tag < static_cast<int64>(uStrTab.size()), "index out of range in BinaryMplt::InUsrStr");
242 return uStrTab[-tag];
243 }
244 CHECK_FATAL(tag == kBinUsrString, "expecting kBinUsrString");
245 std::string str;
246 ReadAsciiStr(str);
247 UStrIdx strIdx = GlobalTables::GetUStrTable().GetOrCreateStrIdxFromName(str);
248 uStrTab.push_back(strIdx);
249 return strIdx;
250 }
251
ImportPragmaElement()252 MIRPragmaElement *BinaryMplImport::ImportPragmaElement()
253 {
254 MIRPragmaElement *element = mod.GetPragmaMemPool()->New<MIRPragmaElement>(mod);
255 element->SetNameStrIdx(ImportStr());
256 element->SetTypeStrIdx(ImportStr());
257 element->SetType(static_cast<PragmaValueType>(ReadNum()));
258 if (element->GetType() == kValueString || element->GetType() == kValueType || element->GetType() == kValueField ||
259 element->GetType() == kValueMethod || element->GetType() == kValueEnum) {
260 element->SetI32Val(static_cast<int32>(ImportStr()));
261 } else {
262 element->SetU64Val(static_cast<uint64>(ReadInt64()));
263 }
264 int64 size = ReadNum();
265 for (int64 i = 0; i < size; ++i) {
266 element->SubElemVecPushBack(ImportPragmaElement());
267 }
268 return element;
269 }
270
ImportPragma()271 MIRPragma *BinaryMplImport::ImportPragma()
272 {
273 MIRPragma *p = mod.GetPragmaMemPool()->New<MIRPragma>(mod);
274 p->SetKind(static_cast<PragmaKind>(ReadNum()));
275 p->SetVisibility(ReadNum());
276 p->SetStrIdx(ImportStr());
277 if (mod.IsJavaModule()) {
278 p->SetTyIdx(ImportType());
279 p->SetTyIdxEx(ImportType());
280 } else {
281 p->SetTyIdx(ImportTypeNonJava());
282 p->SetTyIdxEx(ImportTypeNonJava());
283 }
284 p->SetParamNum(ReadNum());
285 int64 size = ReadNum();
286 for (int64 i = 0; i < size; ++i) {
287 p->PushElementVector(ImportPragmaElement());
288 }
289 return p;
290 }
291
ImportFieldPair(FieldPair & fp)292 void BinaryMplImport::ImportFieldPair(FieldPair &fp)
293 {
294 fp.first = ImportStr();
295 fp.second.first = mod.IsJavaModule() ? ImportType() : ImportTypeNonJava();
296 fp.second.second.SetAttrFlag(ReadNum());
297 fp.second.second.SetAlignValue(ReadNum());
298 FieldAttrs fa = fp.second.second;
299 if (fa.GetAttr(FLDATTR_static) && fa.GetAttr(FLDATTR_final) &&
300 (fa.GetAttr(FLDATTR_public) || fa.GetAttr(FLDATTR_protected))) {
301 int64 tag = ReadNum();
302 if (tag == kBinInitConst) {
303 GlobalTables::GetConstPool().InsertConstPool(fp.first, ImportConst(nullptr));
304 }
305 }
306 }
307
ImportMethodPair(MethodPair & memPool)308 void BinaryMplImport::ImportMethodPair(MethodPair &memPool)
309 {
310 std::string funcName;
311 ReadAsciiStr(funcName);
312 TyIdx funcTyIdx = ImportType();
313 int64 x = ReadNum();
314 CHECK_FATAL(x >= 0, "ReadNum error, x: %d", x);
315 auto attrFlag = static_cast<uint64>(x);
316
317 GStrIdx strIdx = GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(funcName);
318 MIRSymbol *prevFuncSt = GlobalTables::GetGsymTable().GetSymbolFromStrIdx(strIdx);
319 MIRSymbol *funcSt = nullptr;
320 MIRFunction *fn = nullptr;
321
322 if (prevFuncSt != nullptr && (prevFuncSt->GetStorageClass() == kScText && prevFuncSt->GetSKind() == kStFunc)) {
323 funcSt = prevFuncSt;
324 fn = funcSt->GetFunction();
325 } else {
326 funcSt = GlobalTables::GetGsymTable().CreateSymbol(kScopeGlobal);
327 funcSt->SetNameStrIdx(strIdx);
328 GlobalTables::GetGsymTable().AddToStringSymbolMap(*funcSt);
329 funcSt->SetStorageClass(kScText);
330 funcSt->SetSKind(kStFunc);
331 funcSt->SetTyIdx(funcTyIdx);
332 funcSt->SetIsImported(imported);
333 funcSt->SetIsImportedDecl(imported);
334 methodSymbols.push_back(funcSt);
335
336 fn = mod.GetMemPool()->New<MIRFunction>(&mod, funcSt->GetStIdx());
337 fn->SetPuidx(GlobalTables::GetFunctionTable().GetFuncTable().size());
338 GlobalTables::GetFunctionTable().GetFuncTable().push_back(fn);
339 funcSt->SetFunction(fn);
340 auto *funcType = static_cast<MIRFuncType *>(funcSt->GetType());
341 fn->SetMIRFuncType(funcType);
342 fn->SetFileIndex(0);
343 fn->SetBaseClassFuncNames(funcSt->GetNameStrIdx());
344 fn->SetFuncAttrs(attrFlag);
345 }
346 memPool.first.SetFullIdx(funcSt->GetStIdx().FullIdx());
347 memPool.second.first.reset(funcTyIdx);
348 memPool.second.second.SetAttrFlag(attrFlag);
349 }
350
UpdateMethodSymbols()351 void BinaryMplImport::UpdateMethodSymbols()
352 {
353 for (auto sym : methodSymbols) {
354 MIRFunction *fn = sym->GetFunction();
355 CHECK_FATAL(fn != nullptr, "fn is null");
356 auto *funcType = static_cast<MIRFuncType *>(GlobalTables::GetTypeTable().GetTypeFromTyIdx(sym->GetTyIdx()));
357 fn->SetMIRFuncType(funcType);
358 fn->SetReturnStruct(*GlobalTables::GetTypeTable().GetTypeFromTyIdx(funcType->GetRetTyIdx()));
359 if (fn->GetFormalDefVec().size() != 0) {
360 continue; // already updated in ImportFunction()
361 }
362 for (size_t i = 0; i < funcType->GetParamTypeList().size(); ++i) {
363 FormalDef formalDef(nullptr, funcType->GetParamTypeList()[i], funcType->GetParamAttrsList()[i]);
364 fn->GetFormalDefVec().push_back(formalDef);
365 }
366 }
367 }
368
ImportFieldsOfStructType(FieldVector & fields,uint32 methodSize)369 void BinaryMplImport::ImportFieldsOfStructType(FieldVector &fields, uint32 methodSize)
370 {
371 int64 size = ReadNum();
372 int64 initSize = fields.size() + methodSize;
373 for (int64 i = 0; i < size; ++i) {
374 FieldPair fp;
375 ImportFieldPair(fp);
376 if (initSize == 0) {
377 fields.push_back(fp);
378 }
379 }
380 }
381
ImportMethodsOfStructType(MethodVector & methods)382 void BinaryMplImport::ImportMethodsOfStructType(MethodVector &methods)
383 {
384 int64 size = ReadNum();
385 bool isEmpty = methods.empty();
386 for (int64 i = 0; i < size; ++i) {
387 MethodPair memPool;
388 ImportMethodPair(memPool);
389 if (isEmpty) {
390 methods.push_back(memPool);
391 }
392 }
393 }
394
ImportStructTypeData(MIRStructType & type)395 void BinaryMplImport::ImportStructTypeData(MIRStructType &type)
396 {
397 uint32 methodSize = type.GetMethods().size();
398 ImportFieldsOfStructType(type.GetFields(), methodSize);
399 ImportFieldsOfStructType(type.GetStaticFields(), methodSize);
400 ImportFieldsOfStructType(type.GetParentFields(), methodSize);
401 ImportMethodsOfStructType(type.GetMethods());
402 type.SetIsImported(imported);
403 }
404
ImportInterfacesOfClassType(std::vector<TyIdx> & interfaces)405 void BinaryMplImport::ImportInterfacesOfClassType(std::vector<TyIdx> &interfaces)
406 {
407 int64 size = ReadNum();
408 bool isEmpty = interfaces.empty();
409 for (int64 i = 0; i < size; ++i) {
410 TyIdx idx = ImportType();
411 if (isEmpty) {
412 interfaces.push_back(idx);
413 }
414 }
415 }
416
ImportInfoIsStringOfStructType(MIRStructType & type)417 void BinaryMplImport::ImportInfoIsStringOfStructType(MIRStructType &type)
418 {
419 int64 size = ReadNum();
420 bool isEmpty = type.GetInfoIsString().empty();
421
422 for (int64 i = 0; i < size; ++i) {
423 auto isString = static_cast<bool>(ReadNum());
424
425 if (isEmpty) {
426 type.PushbackIsString(isString);
427 }
428 }
429 }
430
ImportInfoOfStructType(MIRStructType & type)431 void BinaryMplImport::ImportInfoOfStructType(MIRStructType &type)
432 {
433 uint64 size = static_cast<uint64>(ReadNum());
434 bool isEmpty = type.GetInfo().empty();
435 for (size_t i = 0; i < size; ++i) {
436 GStrIdx idx = ImportStr();
437 int64 x = (type.GetInfoIsStringElemt(i)) ? static_cast<int64>(ImportStr()) : ReadNum();
438 CHECK_FATAL(x >= 0, "ReadNum nagative, x: %d", x);
439 CHECK_FATAL(x <= std::numeric_limits<uint32_t>::max(), "ReadNum too large, x: %d", x);
440 if (isEmpty) {
441 type.PushbackMIRInfo(MIRInfoPair(idx, static_cast<uint32>(x)));
442 }
443 }
444 }
445
ImportPragmaOfStructType(MIRStructType & type)446 void BinaryMplImport::ImportPragmaOfStructType(MIRStructType &type)
447 {
448 int64 size = ReadNum();
449 bool isEmpty = type.GetPragmaVec().empty();
450 for (int64 i = 0; i < size; ++i) {
451 MIRPragma *pragma = ImportPragma();
452 if (isEmpty) {
453 type.PushbackPragma(pragma);
454 }
455 }
456 }
457
SetClassTyidxOfMethods(MIRStructType & type)458 void BinaryMplImport::SetClassTyidxOfMethods(MIRStructType &type)
459 {
460 if (type.GetTypeIndex() != 0u) {
461 // set up classTyIdx for methods
462 for (size_t i = 0; i < type.GetMethods().size(); ++i) {
463 StIdx stidx = type.GetMethodsElement(i).first;
464 MIRSymbol *st = GlobalTables::GetGsymTable().GetSymbolFromStidx(stidx.Idx());
465 CHECK_FATAL(st != nullptr, "st is null");
466 CHECK_FATAL(st->GetSKind() == kStFunc, "unexpected st->sKind");
467 st->GetFunction()->SetClassTyIdx(type.GetTypeIndex());
468 }
469 }
470 }
471
ImportClassTypeData(MIRClassType & type)472 void BinaryMplImport::ImportClassTypeData(MIRClassType &type)
473 {
474 TyIdx tempType = ImportType();
475 // Keep the parent_tyidx we first met.
476 if (type.GetParentTyIdx() == 0u) {
477 type.SetParentTyIdx(tempType);
478 }
479 ImportInterfacesOfClassType(type.GetInterfaceImplemented());
480 ImportInfoIsStringOfStructType(type);
481 if (!inIPA) {
482 ImportInfoOfStructType(type);
483 ImportPragmaOfStructType(type);
484 }
485 SetClassTyidxOfMethods(type);
486 }
487
ImportInterfaceTypeData(MIRInterfaceType & type)488 void BinaryMplImport::ImportInterfaceTypeData(MIRInterfaceType &type)
489 {
490 ImportInterfacesOfClassType(type.GetParentsTyIdx());
491 ImportInfoIsStringOfStructType(type);
492 if (!inIPA) {
493 ImportInfoOfStructType(type);
494 ImportPragmaOfStructType(type);
495 }
496 SetClassTyidxOfMethods(type);
497 }
498
Reset()499 void BinaryMplImport::Reset()
500 {
501 buf.clear();
502 bufI = 0;
503 gStrTab.clear();
504 uStrTab.clear();
505 typTab.clear();
506 funcTab.clear();
507 symTab.clear();
508 methodSymbols.clear();
509 definedLabels.clear();
510 gStrTab.push_back(GStrIdx(0)); // Dummy
511 uStrTab.push_back(UStrIdx(0)); // Dummy
512 symTab.push_back(nullptr); // Dummy
513 funcTab.push_back(nullptr); // Dummy
514 eaCgTab.push_back(nullptr);
515 for (int32 pti = static_cast<int32>(PTY_begin); pti < static_cast<int32>(PTY_end); ++pti) {
516 typTab.push_back(TyIdx(pti));
517 }
518 }
519
ImportTypeAttrs()520 TypeAttrs BinaryMplImport::ImportTypeAttrs()
521 {
522 TypeAttrs ta;
523 ta.SetAttrFlag(static_cast<uint64>(ReadNum()));
524 ta.SetAlignValue(static_cast<uint8>(ReadNum()));
525 ta.SetPack(static_cast<uint32>(ReadNum()));
526 return ta;
527 }
528
ImportTypePairs(std::vector<TypePair> & insVecType)529 void BinaryMplImport::ImportTypePairs(std::vector<TypePair> &insVecType)
530 {
531 int64 size = ReadNum();
532 for (int64 i = 0; i < size; ++i) {
533 TyIdx t0 = ImportType();
534 TyIdx t1 = ImportType();
535 TypePair tp(t0, t1);
536 insVecType.push_back(tp);
537 }
538 }
539
CompleteAggInfo(TyIdx tyIdx)540 void BinaryMplImport::CompleteAggInfo(TyIdx tyIdx)
541 {
542 MIRType *type = GlobalTables::GetTypeTable().GetTypeFromTyIdx(tyIdx);
543 CHECK_FATAL(type != nullptr, "MIRType is null");
544 if (type->GetKind() == kTypeInterface) {
545 auto *interfaceType = static_cast<MIRInterfaceType *>(type);
546 ImportStructTypeData(*interfaceType);
547 ImportInterfaceTypeData(*interfaceType);
548 } else if (type->GetKind() == kTypeClass) {
549 auto *classType = static_cast<MIRClassType *>(type);
550 ImportStructTypeData(*classType);
551 ImportClassTypeData(*classType);
552 } else if (type->GetKind() == kTypeStruct || type->GetKind() == kTypeUnion) {
553 auto *structType = static_cast<MIRStructType *>(type);
554 ImportStructTypeData(*structType);
555 } else {
556 ERR(kLncErr, "in BinaryMplImport::CompleteAggInfo, MIRType error");
557 }
558 }
559
IsIncomplete(const MIRType & type)560 inline static bool IsIncomplete(const MIRType &type)
561 {
562 return (type.GetKind() == kTypeInterfaceIncomplete || type.GetKind() == kTypeClassIncomplete ||
563 type.GetKind() == kTypeStructIncomplete);
564 }
565
ImportType(bool forPointedType)566 TyIdx BinaryMplImport::ImportType(bool forPointedType)
567 {
568 int64 tag = ReadNum();
569 static MIRType *typeNeedsComplete = nullptr;
570 static int ptrLev = 0;
571 if (tag == 0) {
572 return TyIdx(0);
573 }
574 if (tag < 0) {
575 CHECK_FATAL(static_cast<size_t>(-tag) < typTab.size(), "index out of bounds");
576 return typTab.at(static_cast<uint64>(-tag));
577 }
578 PrimType primType = static_cast<PrimType>(0);
579 GStrIdx strIdx(0);
580 bool nameIsLocal = false;
581 ImportTypeBase(primType, strIdx, nameIsLocal);
582
583 switch (tag) {
584 case kBinKindTypeScalar:
585 return TyIdx(primType);
586 case kBinKindTypePointer: {
587 MIRPtrType type(primType, strIdx);
588 type.SetNameIsLocal(nameIsLocal);
589 size_t idx = typTab.size();
590 typTab.push_back(TyIdx(0));
591 type.SetTypeAttrs(ImportTypeAttrs());
592 ++ptrLev;
593 type.SetPointedTyIdx(ImportType(true));
594 --ptrLev;
595 MIRType *origType = &InsertInTypeTables(type);
596 typTab[idx] = origType->GetTypeIndex();
597 if (typeNeedsComplete != nullptr && ptrLev == 0) {
598 TyIdx tyIdxNeedsComplete = typeNeedsComplete->GetTypeIndex();
599 typeNeedsComplete = nullptr;
600 CompleteAggInfo(tyIdxNeedsComplete);
601 }
602 return origType->GetTypeIndex();
603 }
604 case kBinKindTypeFArray: {
605 MIRFarrayType type(strIdx);
606 type.SetNameIsLocal(nameIsLocal);
607 size_t idx = typTab.size();
608 typTab.push_back(TyIdx(0));
609 type.SetElemtTyIdx(ImportType(forPointedType));
610 MIRType *origType = &InsertInTypeTables(type);
611 typTab[idx] = origType->GetTypeIndex();
612 return origType->GetTypeIndex();
613 }
614 case kBinKindTypeJarray: {
615 MIRJarrayType type(strIdx);
616 type.SetNameIsLocal(nameIsLocal);
617 size_t idx = typTab.size();
618 typTab.push_back(TyIdx(0));
619 type.SetElemtTyIdx(ImportType(forPointedType));
620 MIRType *origType = &InsertInTypeTables(type);
621 typTab[idx] = origType->GetTypeIndex();
622 return origType->GetTypeIndex();
623 }
624 case kBinKindTypeArray: {
625 MIRArrayType type(strIdx);
626 type.SetNameIsLocal(nameIsLocal);
627 type.SetDim(ReadNum());
628 CHECK_FATAL(type.GetDim() < kMaxArrayDim, "array index out of range");
629 for (uint16 i = 0; i < type.GetDim(); ++i) {
630 type.SetSizeArrayItem(i, ReadNum());
631 }
632 size_t idx = typTab.size();
633 typTab.push_back(TyIdx(0));
634 type.SetElemTyIdx(ImportType(forPointedType));
635 type.SetTypeAttrs(ImportTypeAttrs());
636 MIRType *origType = &InsertInTypeTables(type);
637 typTab[idx] = origType->GetTypeIndex();
638 return origType->GetTypeIndex();
639 }
640 case kBinKindTypeFunction: {
641 MIRFuncType type(strIdx);
642 type.SetNameIsLocal(nameIsLocal);
643 size_t idx = typTab.size();
644 typTab.push_back(TyIdx(0));
645 type.SetRetTyIdx(ImportType());
646 type.funcAttrs.SetAttrFlag(ReadNum());
647 int64 size = ReadNum();
648 for (int64 i = 0; i < size; ++i) {
649 type.GetParamTypeList().push_back(ImportType());
650 }
651 size = ReadNum();
652 for (int64 i = 0; i < size; ++i) {
653 type.GetParamAttrsList().push_back(ImportTypeAttrs());
654 }
655 MIRType *origType = &InsertInTypeTables(type);
656 typTab[idx] = origType->GetTypeIndex();
657 return origType->GetTypeIndex();
658 }
659 case kBinKindTypeParam: {
660 MIRTypeParam type(strIdx);
661 type.SetNameIsLocal(nameIsLocal);
662 MIRType *origType = &InsertInTypeTables(type);
663 typTab.push_back(origType->GetTypeIndex());
664 return origType->GetTypeIndex();
665 }
666 case kBinKindTypeInstantVector: {
667 auto kind = static_cast<MIRTypeKind>(ReadNum());
668 MIRInstantVectorType type(kind, strIdx);
669 type.SetNameIsLocal(nameIsLocal);
670 auto *origType = static_cast<MIRInstantVectorType *>(&InsertInTypeTables(type));
671 typTab.push_back(origType->GetTypeIndex());
672 ImportTypePairs(origType->GetInstantVec());
673 return origType->GetTypeIndex();
674 }
675 case kBinKindTypeGenericInstant: {
676 MIRGenericInstantType type(strIdx);
677 type.SetNameIsLocal(nameIsLocal);
678 auto *origType = static_cast<MIRGenericInstantType *>(&InsertInTypeTables(type));
679 typTab.push_back(origType->GetTypeIndex());
680 ImportTypePairs(origType->GetInstantVec());
681 origType->SetGenericTyIdx(ImportType());
682 return origType->GetTypeIndex();
683 }
684 case kBinKindTypeBitField: {
685 uint8 fieldSize = ReadNum();
686 MIRBitFieldType type(fieldSize, primType, strIdx);
687 type.SetNameIsLocal(nameIsLocal);
688 MIRType *origType = &InsertInTypeTables(type);
689 typTab.push_back(origType->GetTypeIndex());
690 return origType->GetTypeIndex();
691 }
692 case kBinKindTypeStruct: {
693 auto kind = static_cast<MIRTypeKind>(ReadNum());
694 MIRStructType type(kind, strIdx);
695 type.SetNameIsLocal(nameIsLocal);
696 type.SetTypeAttrs(ImportTypeAttrs());
697 MIRStructType &origType = static_cast<MIRStructType &>(InsertInTypeTables(type));
698 typTab.push_back(origType.GetTypeIndex());
699 if (kind != kTypeStructIncomplete) {
700 if (forPointedType) {
701 typeNeedsComplete = &origType;
702 } else {
703 ImportStructTypeData(origType);
704 }
705 }
706 return origType.GetTypeIndex();
707 }
708 case kBinKindTypeClass: {
709 auto kind = static_cast<MIRTypeKind>(ReadNum());
710 MIRClassType type(kind, strIdx);
711 type.SetNameIsLocal(nameIsLocal);
712 auto &origType = static_cast<MIRClassType &>(InsertInTypeTables(type));
713 typTab.push_back(origType.GetTypeIndex());
714 if (kind != kTypeClassIncomplete) {
715 if (forPointedType) {
716 typeNeedsComplete = &origType;
717 } else {
718 ImportStructTypeData(origType);
719 ImportClassTypeData(origType);
720 }
721 }
722 return origType.GetTypeIndex();
723 }
724 case kBinKindTypeInterface: {
725 auto kind = static_cast<MIRTypeKind>(ReadNum());
726 MIRInterfaceType type(kind, strIdx);
727 type.SetNameIsLocal(nameIsLocal);
728 auto &origType = static_cast<MIRInterfaceType &>(InsertInTypeTables(type));
729 typTab.push_back(origType.GetTypeIndex());
730 if (kind != kTypeInterfaceIncomplete) {
731 if (forPointedType) {
732 typeNeedsComplete = &origType;
733 } else {
734 ImportStructTypeData(origType);
735 ImportInterfaceTypeData(origType);
736 }
737 }
738 return origType.GetTypeIndex();
739 }
740 default:
741 CHECK_FATAL(false, "Unexpected binary kind");
742 }
743 }
744
ImportTypeNonJava()745 TyIdx BinaryMplImport::ImportTypeNonJava()
746 {
747 int64 tag = ReadNum();
748 if (tag == 0) {
749 return TyIdx(0);
750 }
751 if (tag < 0) {
752 CHECK_FATAL(static_cast<size_t>(-tag) < typTab.size(), "index out of bounds");
753 return typTab[static_cast<uint64>(-tag)];
754 }
755 PrimType primType = static_cast<PrimType>(0);
756 GStrIdx strIdx(0);
757 bool nameIsLocal = false;
758 ImportTypeBase(primType, strIdx, nameIsLocal);
759 TyIdx tyIdxUsed(GlobalTables::GetTypeTable().GetTypeTableSize());
760 if (tag != kBinKindTypeScalar) {
761 GlobalTables::GetTypeTable().PushNull();
762 typTab.push_back(tyIdxUsed);
763 }
764
765 switch (tag) {
766 case kBinKindTypeScalar:
767 return TyIdx(primType);
768 case kBinKindTypePointer: {
769 MIRPtrType type(primType, strIdx);
770 type.SetNameIsLocal(nameIsLocal);
771 type.SetTypeAttrs(ImportTypeAttrs());
772 type.SetPointedTyIdx(ImportTypeNonJava());
773 GlobalTables::GetTypeTable().CreateMirTypeNodeAt(type, tyIdxUsed, &mod, false, false);
774 return tyIdxUsed;
775 }
776 case kBinKindTypeFArray: {
777 MIRFarrayType type(strIdx);
778 type.SetNameIsLocal(nameIsLocal);
779 type.SetElemtTyIdx(ImportTypeNonJava());
780 GlobalTables::GetTypeTable().CreateMirTypeNodeAt(type, tyIdxUsed, &mod, false, false);
781 return tyIdxUsed;
782 }
783 case kBinKindTypeJarray: {
784 MIRJarrayType type(strIdx);
785 type.SetNameIsLocal(nameIsLocal);
786 type.SetElemtTyIdx(ImportTypeNonJava());
787 GlobalTables::GetTypeTable().CreateMirTypeNodeAt(type, tyIdxUsed, &mod, false, false);
788 return tyIdxUsed;
789 }
790 case kBinKindTypeArray: {
791 MIRArrayType type(strIdx);
792 type.SetNameIsLocal(nameIsLocal);
793 type.SetDim(ReadNum());
794 CHECK_FATAL(type.GetDim() < kMaxArrayDim, "array index out of range");
795 for (uint16 i = 0; i < type.GetDim(); ++i) {
796 type.SetSizeArrayItem(i, ReadNum());
797 }
798 type.SetElemTyIdx(ImportTypeNonJava());
799 type.SetTypeAttrs(ImportTypeAttrs());
800 GlobalTables::GetTypeTable().CreateMirTypeNodeAt(type, tyIdxUsed, &mod, false, false);
801 return tyIdxUsed;
802 }
803 case kBinKindTypeFunction: {
804 MIRFuncType type(strIdx);
805 type.SetNameIsLocal(nameIsLocal);
806 type.SetRetTyIdx(ImportTypeNonJava());
807 type.funcAttrs.SetAttrFlag(ReadNum());
808 int64 size = ReadNum();
809 for (int64 i = 0; i < size; ++i) {
810 type.GetParamTypeList().push_back(ImportTypeNonJava());
811 }
812 size = ReadNum();
813 for (int64 i = 0; i < size; ++i) {
814 type.GetParamAttrsList().push_back(ImportTypeAttrs());
815 }
816 GlobalTables::GetTypeTable().CreateMirTypeNodeAt(type, tyIdxUsed, &mod, false, false);
817 return tyIdxUsed;
818 }
819 case kBinKindTypeParam: {
820 MIRTypeParam type(strIdx);
821 type.SetNameIsLocal(nameIsLocal);
822 GlobalTables::GetTypeTable().CreateMirTypeNodeAt(type, tyIdxUsed, &mod, false, false);
823 return tyIdxUsed;
824 }
825 case kBinKindTypeInstantVector: {
826 auto kind = static_cast<MIRTypeKind>(ReadNum());
827 MIRInstantVectorType type(kind, strIdx);
828 type.SetNameIsLocal(nameIsLocal);
829 ImportTypePairs(type.GetInstantVec());
830 GlobalTables::GetTypeTable().CreateMirTypeNodeAt(type, tyIdxUsed, &mod, false, false);
831 return tyIdxUsed;
832 }
833 case kBinKindTypeGenericInstant: {
834 MIRGenericInstantType type(strIdx);
835 type.SetNameIsLocal(nameIsLocal);
836 ImportTypePairs(type.GetInstantVec());
837 type.SetGenericTyIdx(ImportTypeNonJava());
838 GlobalTables::GetTypeTable().CreateMirTypeNodeAt(type, tyIdxUsed, &mod, false, false);
839 return tyIdxUsed;
840 }
841 case kBinKindTypeBitField: {
842 uint8 fieldSize = ReadNum();
843 MIRBitFieldType type(fieldSize, primType, strIdx);
844 type.SetNameIsLocal(nameIsLocal);
845 GlobalTables::GetTypeTable().CreateMirTypeNodeAt(type, tyIdxUsed, &mod, false, false);
846 return tyIdxUsed;
847 }
848 case kBinKindTypeStruct: {
849 auto kind = static_cast<MIRTypeKind>(ReadNum());
850 MIRStructType type(kind, strIdx);
851 type.SetNameIsLocal(nameIsLocal);
852 type.SetTypeAttrs(ImportTypeAttrs());
853 if (kind != kTypeStructIncomplete) {
854 ImportStructTypeData(type);
855 }
856 GlobalTables::GetTypeTable().CreateMirTypeNodeAt(type, tyIdxUsed, &mod, false, IsIncomplete(type));
857 return tyIdxUsed;
858 }
859 case kBinKindTypeClass: {
860 auto kind = static_cast<MIRTypeKind>(ReadNum());
861 MIRClassType type(kind, strIdx);
862 type.SetNameIsLocal(nameIsLocal);
863 if (kind != kTypeClassIncomplete) {
864 ImportStructTypeData(type);
865 ImportClassTypeData(type);
866 }
867 GlobalTables::GetTypeTable().CreateMirTypeNodeAt(type, tyIdxUsed, &mod, true, IsIncomplete(type));
868 return tyIdxUsed;
869 }
870 case kBinKindTypeInterface: {
871 auto kind = static_cast<MIRTypeKind>(ReadNum());
872 MIRInterfaceType type(kind, strIdx);
873 type.SetNameIsLocal(nameIsLocal);
874 if (kind != kTypeInterfaceIncomplete) {
875 ImportStructTypeData(type);
876 ImportInterfaceTypeData(type);
877 }
878 GlobalTables::GetTypeTable().CreateMirTypeNodeAt(type, tyIdxUsed, &mod, true, IsIncomplete(type));
879 return tyIdxUsed;
880 }
881 default:
882 CHECK_FATAL(false, "Unexpected binary kind");
883 }
884 }
885
ImportTypeBase(PrimType & primType,GStrIdx & strIdx,bool & nameIsLocal)886 void BinaryMplImport::ImportTypeBase(PrimType &primType, GStrIdx &strIdx, bool &nameIsLocal)
887 {
888 primType = static_cast<PrimType>(ReadNum());
889 strIdx = ImportStr();
890 nameIsLocal = ReadNum();
891 }
892
IsObject(const MIRType & type)893 inline static bool IsObject(const MIRType &type)
894 {
895 return (type.GetKind() == kTypeClass || type.GetKind() == kTypeClassIncomplete ||
896 type.GetKind() == kTypeInterface || type.GetKind() == kTypeInterfaceIncomplete);
897 }
898
InsertInTypeTables(MIRType & type)899 MIRType &BinaryMplImport::InsertInTypeTables(MIRType &type)
900 {
901 MIRType *resultTypePtr = &type;
902 TyIdx prevTyIdx = mod.GetTypeNameTab()->GetTyIdxFromGStrIdx(type.GetNameStrIdx());
903 if (prevTyIdx != 0u && !type.IsNameIsLocal()) {
904 MIRType *prevType = GlobalTables::GetTypeTable().GetTypeFromTyIdx(prevTyIdx);
905 if (!prevType->IsMIRTypeByName() &&
906 ((IsIncomplete(*prevType) && IsIncomplete(type)) || (!IsIncomplete(*prevType) && !IsIncomplete(type)) ||
907 (!IsIncomplete(*prevType) && IsIncomplete(type)))) {
908 resultTypePtr = prevType->CopyMIRTypeNode();
909 if (resultTypePtr->GetKind() == kTypeStruct || resultTypePtr->GetKind() == kTypeUnion ||
910 resultTypePtr->GetKind() == kTypeStructIncomplete) {
911 tmpStruct.push_back(static_cast<MIRStructType *>(resultTypePtr));
912 } else if (resultTypePtr->GetKind() == kTypeClass || resultTypePtr->GetKind() == kTypeClassIncomplete) {
913 tmpClass.push_back(static_cast<MIRClassType *>(resultTypePtr));
914 } else if (resultTypePtr->GetKind() == kTypeInterface ||
915 resultTypePtr->GetKind() == kTypeInterfaceIncomplete) {
916 tmpInterface.push_back(static_cast<MIRInterfaceType *>(resultTypePtr));
917 }
918 } else {
919 // New definition wins
920 type.SetTypeIndex(prevTyIdx);
921 CHECK_FATAL(GlobalTables::GetTypeTable().GetTypeTable().empty() == false, "container check");
922 GlobalTables::GetTypeTable().SetTypeWithTyIdx(prevTyIdx, *type.CopyMIRTypeNode());
923 resultTypePtr = GlobalTables::GetTypeTable().GetTypeFromTyIdx(prevTyIdx);
924 if (!IsIncomplete(*resultTypePtr)) {
925 GlobalTables::GetTypeNameTable().SetGStrIdxToTyIdx(resultTypePtr->GetNameStrIdx(),
926 resultTypePtr->GetTypeIndex());
927 }
928 }
929 } else {
930 // New type, no previous definition or anonymous type
931 TyIdx tyIdx = GlobalTables::GetTypeTable().GetOrCreateMIRType(&type);
932 resultTypePtr = GlobalTables::GetTypeTable().GetTypeFromTyIdx(tyIdx);
933 if (tyIdx + 1 == GlobalTables::GetTypeTable().GetTypeTable().size() && !resultTypePtr->IsNameIsLocal()) {
934 GStrIdx stridx = resultTypePtr->GetNameStrIdx();
935 if (stridx != 0u) {
936 mod.GetTypeNameTab()->SetGStrIdxToTyIdx(stridx, tyIdx);
937 mod.PushbackTypeDefOrder(stridx);
938 if (IsObject(*resultTypePtr)) {
939 mod.AddClass(tyIdx);
940 if (!IsIncomplete(*resultTypePtr)) {
941 GlobalTables::GetTypeNameTable().SetGStrIdxToTyIdx(stridx, tyIdx);
942 }
943 }
944 }
945 }
946 }
947 return *resultTypePtr;
948 }
949
SetupEHRootType()950 void BinaryMplImport::SetupEHRootType()
951 {
952 // setup eh root type with most recent Ljava_2Flang_2FObject_3B
953 GStrIdx gStrIdx = GlobalTables::GetStrTable().GetStrIdxFromName(namemangler::kJavaLangObjectStr);
954 if (gStrIdx == 0u) {
955 return;
956 }
957
958 TyIdx tyIdx = GlobalTables::GetTypeNameTable().GetTyIdxFromGStrIdx(gStrIdx);
959 if (tyIdx != 0u) {
960 mod.SetThrowableTyIdx(tyIdx);
961 }
962 }
963
GetOrCreateSymbol(TyIdx tyIdx,GStrIdx strIdx,MIRSymKind mclass,MIRStorageClass sclass,MIRFunction * func,uint8 scpID)964 MIRSymbol *BinaryMplImport::GetOrCreateSymbol(TyIdx tyIdx, GStrIdx strIdx, MIRSymKind mclass, MIRStorageClass sclass,
965 MIRFunction *func, uint8 scpID)
966 {
967 MIRSymbol *st = GlobalTables::GetGsymTable().GetSymbolFromStrIdx(strIdx);
968 if (st != nullptr && st->GetStorageClass() == sclass && st->GetSKind() == mclass && scpID == kScopeGlobal) {
969 return st;
970 }
971 return mirBuilder.CreateSymbol(tyIdx, strIdx, mclass, sclass, func, scpID);
972 }
973
InSymbol(MIRFunction * func)974 MIRSymbol *BinaryMplImport::InSymbol(MIRFunction *func)
975 {
976 int64 tag = ReadNum();
977 if (tag == 0) {
978 return nullptr;
979 } else if (tag < 0) {
980 CHECK_FATAL(static_cast<size_t>(-tag) < symTab.size(), "index out of bounds");
981 return symTab.at(-tag);
982 } else {
983 CHECK_FATAL(tag == kBinSymbol, "expecting kBinSymbol");
984 int64 scope = ReadNum();
985 GStrIdx stridx = ImportStr();
986 UStrIdx secAttr = ImportUsrStr();
987 UStrIdx asmAttr = ImportUsrStr();
988 auto skind = static_cast<MIRSymKind>(ReadNum());
989 auto sclass = static_cast<MIRStorageClass>(ReadNum());
990 TyIdx tyTmp(0);
991 MIRSymbol *sym = GetOrCreateSymbol(tyTmp, stridx, skind, sclass, func, scope);
992 if (secAttr != 0u) {
993 sym->sectionAttr = secAttr;
994 }
995 if (asmAttr != 0u) {
996 sym->SetAsmAttr(asmAttr);
997 }
998 symTab.push_back(sym);
999 sym->SetAttrs(ImportTypeAttrs());
1000 sym->SetIsTmp(ReadNum() != 0);
1001 sym->SetIsImported(imported);
1002 uint32 thepregno = 0;
1003 if (skind == kStPreg) {
1004 CHECK_FATAL(scope == kScopeLocal && func != nullptr, "Expecting kScopeLocal");
1005 thepregno = static_cast<uint32>(ReadNum());
1006 } else if (skind == kStConst || skind == kStVar) {
1007 sym->SetKonst(ImportConst(func));
1008 } else if (skind == kStFunc) {
1009 PUIdx puidx = ImportFunction();
1010 mod.SetCurFunction(func);
1011 if (puidx != 0) {
1012 sym->SetFunction(GlobalTables::GetFunctionTable().GetFunctionFromPuidx(puidx));
1013 }
1014 }
1015 if (skind == kStVar || skind == kStFunc) {
1016 ImportSrcPos(sym->GetSrcPosition());
1017 }
1018 TyIdx tyIdx = mod.IsJavaModule() ? ImportType() : ImportTypeNonJava();
1019 sym->SetTyIdx(tyIdx);
1020 if (skind == kStPreg) {
1021 MIRType *mirType = GlobalTables::GetTypeTable().GetTypeFromTyIdx(sym->GetTyIdx());
1022 PregIdx pregidx = func->GetPregTab()->EnterPregNo(thepregno, mirType->GetPrimType(), mirType);
1023 MIRPregTable *pregTab = func->GetPregTab();
1024 MIRPreg *preg = pregTab->PregFromPregIdx(pregidx);
1025 preg->SetPrimType(mirType->GetPrimType());
1026 sym->SetPreg(preg);
1027 }
1028 return sym;
1029 }
1030 }
1031
ImportFunction()1032 PUIdx BinaryMplImport::ImportFunction()
1033 {
1034 int64 tag = ReadNum();
1035 if (tag == 0) {
1036 mod.SetCurFunction(nullptr);
1037 return 0;
1038 } else if (tag < 0) {
1039 CHECK_FATAL(static_cast<uint64>(-tag) <= funcTab.size(), "index out of bounds");
1040 if (static_cast<uint64>(-tag) == funcTab.size()) { // function was exported before its symbol
1041 return static_cast<PUIdx>(0);
1042 }
1043 PUIdx puIdx = funcTab[static_cast<uint64>(-tag)]->GetPuidx();
1044 mod.SetCurFunction(GlobalTables::GetFunctionTable().GetFunctionFromPuidx(puIdx));
1045 return puIdx;
1046 }
1047 CHECK_FATAL(tag == kBinFunction, "expecting kBinFunction");
1048 MIRSymbol *funcSt = InSymbol(nullptr);
1049 CHECK_FATAL(funcSt != nullptr, "null ptr check");
1050 MIRFunction *func = nullptr;
1051 if (funcSt->GetFunction() == nullptr) {
1052 maple::MIRBuilder builder(&mod);
1053 func = builder.CreateFunction(funcSt->GetStIdx());
1054 funcTab.push_back(func);
1055 } else {
1056 func = funcSt->GetFunction();
1057 funcTab.push_back(func);
1058 }
1059 funcSt->SetFunction(func);
1060 methodSymbols.push_back(funcSt);
1061 if (mod.IsJavaModule()) {
1062 func->SetBaseClassFuncNames(funcSt->GetNameStrIdx());
1063 }
1064 TyIdx funcTyIdx = mod.IsJavaModule() ? ImportType() : ImportTypeNonJava();
1065 func->SetMIRFuncType(static_cast<MIRFuncType *>(GlobalTables::GetTypeTable().GetTypeFromTyIdx(funcTyIdx)));
1066
1067 func->SetStIdx(funcSt->GetStIdx());
1068 if (!inCG) {
1069 func->SetFuncAttrs(ReadNum()); // merge side effect
1070 } else {
1071 if (!func->IsDirty()) {
1072 func->SetDirty(true);
1073 func->SetFuncAttrs(ReadNum()); // merge side effect
1074 } else {
1075 FuncAttrs tmp;
1076 tmp.SetAttrFlag(ReadNum());
1077 if (func->IsNoDefArgEffect() != tmp.GetAttr(FUNCATTR_nodefargeffect)) {
1078 tmp.SetAttr(FUNCATTR_nodefargeffect, true);
1079 }
1080 if (func->IsNoDefEffect() != tmp.GetAttr(FUNCATTR_nodefeffect)) {
1081 tmp.SetAttr(FUNCATTR_nodefeffect, true);
1082 }
1083 if (func->IsNoRetGlobal() != tmp.GetAttr(FUNCATTR_noretglobal)) {
1084 tmp.SetAttr(FUNCATTR_noretglobal, true);
1085 }
1086 if (func->IsNoThrowException() != tmp.GetAttr(FUNCATTR_nothrow_exception)) {
1087 tmp.SetAttr(FUNCATTR_nothrow_exception, true);
1088 }
1089 if (func->IsIpaSeen() != tmp.GetAttr(FUNCATTR_ipaseen)) {
1090 tmp.SetAttr(FUNCATTR_ipaseen);
1091 }
1092 if (func->IsPure() != tmp.GetAttr(FUNCATTR_pure)) {
1093 tmp.SetAttr(FUNCATTR_pure, true);
1094 }
1095 if (func->IsNoRetArg() != tmp.GetAttr(FUNCATTR_noretarg)) {
1096 tmp.SetAttr(FUNCATTR_noretarg, true);
1097 }
1098 if (func->IsNoPrivateDefEffect() != tmp.GetAttr(FUNCATTR_noprivate_defeffect)) {
1099 tmp.SetAttr(FUNCATTR_noprivate_defeffect, true);
1100 }
1101 func->SetFuncAttrs(tmp);
1102 }
1103 }
1104
1105 auto &attributes = func->GetFuncAttrs();
1106 if (attributes.GetAttr(FUNCATTR_constructor_priority)) {
1107 attributes.SetConstructorPriority(static_cast<int>(ReadNum()));
1108 }
1109 if (attributes.GetAttr(FUNCATTR_destructor_priority)) {
1110 attributes.SetDestructorPriority(static_cast<int>(ReadNum()));
1111 }
1112
1113 func->SetFlag(ReadNum());
1114 if (mod.IsJavaModule()) {
1115 (void)ImportType(); // not set the field to mimic parser
1116 } else {
1117 (void)ImportTypeNonJava(); // not set the field to mimic parser
1118 }
1119 size_t size = static_cast<size_t>(ReadNum());
1120 if (func->GetFormalDefVec().size() == 0) {
1121 for (size_t i = 0; i < size; i++) {
1122 GStrIdx strIdx = ImportStr();
1123 TyIdx tyIdx = mod.IsJavaModule() ? ImportType() : ImportTypeNonJava();
1124 FormalDef formalDef(strIdx, nullptr, tyIdx, TypeAttrs());
1125 formalDef.formalAttrs.SetAttrFlag(static_cast<uint64>(ReadNum()));
1126 func->GetFormalDefVec().push_back(formalDef);
1127 }
1128 } else {
1129 CHECK_FATAL(func->GetFormalDefVec().size() >= size, "ImportFunction: inconsistent number of formals");
1130 for (size_t i = 0; i < size; i++) {
1131 func->GetFormalDefVec()[i].formalStrIdx = ImportStr();
1132 func->GetFormalDefVec()[i].formalTyIdx = mod.IsJavaModule() ? ImportType() : ImportTypeNonJava();
1133 func->GetFormalDefVec()[i].formalAttrs.SetAttrFlag(static_cast<uint64>(ReadNum()));
1134 }
1135 }
1136
1137 mod.SetCurFunction(func);
1138 return func->GetPuidx();
1139 }
1140
SkipTotalSize()1141 inline void BinaryMplImport::SkipTotalSize()
1142 {
1143 ReadInt();
1144 }
1145
ReadStrField()1146 void BinaryMplImport::ReadStrField()
1147 {
1148 SkipTotalSize();
1149
1150 int32 size = ReadInt();
1151 for (int64 i = 0; i < size; ++i) {
1152 GStrIdx stridx = ImportStr();
1153 GlobalTables::GetConstPool().PutLiteralNameAsImported(stridx);
1154 }
1155 int64 tag = 0;
1156 tag = ReadNum();
1157 CHECK_FATAL(tag == ~kBinStrStart, "pattern mismatch in Read STR");
1158 }
1159
ReadHeaderField()1160 void BinaryMplImport::ReadHeaderField()
1161 {
1162 SkipTotalSize();
1163 mod.SetFlavor(static_cast<MIRFlavor>(ReadNum()));
1164 mod.SetSrcLang(static_cast<MIRSrcLang>(ReadNum()));
1165 mod.SetID(static_cast<uint16>(ReadNum()));
1166 if (mod.GetFlavor() == kFlavorLmbc) {
1167 mod.SetGlobalMemSize(static_cast<uint32>(ReadNum()));
1168 mod.SetWithDbgInfo(static_cast<uint32>(ReadNum()));
1169 }
1170 mod.SetNumFuncs(static_cast<uint32>(ReadNum()));
1171 std::string inStr;
1172 ReadAsciiStr(inStr);
1173 mod.SetEntryFuncName(inStr);
1174 ImportInfoVector(mod.GetFileInfo(), mod.GetFileInfoIsString());
1175
1176 int32 size = static_cast<int32>(ReadNum());
1177 MIRInfoPair infopair;
1178 for (int32 i = 0; i < size; i++) {
1179 infopair.first = ImportStr();
1180 infopair.second = static_cast<uint32>(ReadNum());
1181 mod.PushbackFileInfo(infopair);
1182 }
1183
1184 size = static_cast<int32>(ReadNum());
1185 for (int32 i = 0; i < size; i++) {
1186 GStrIdx gStrIdx = ImportStr();
1187 mod.GetImportFiles().push_back(gStrIdx);
1188 std::string importfilename = GlobalTables::GetStrTable().GetStringFromStrIdx(gStrIdx);
1189 // record the imported file for later reading summary info, if exists
1190 mod.PushbackImportedMplt(importfilename);
1191 BinaryMplt *binMplt = new BinaryMplt(mod);
1192 binMplt->GetBinImport().imported = true;
1193
1194 INFO(kLncInfo, "importing %s", importfilename.c_str());
1195 if (!binMplt->GetBinImport().Import(importfilename, false)) { // not a binary mplt
1196 FATAL(kLncFatal, "cannot open binary MPLT file: %s\n", importfilename.c_str());
1197 } else {
1198 INFO(kLncInfo, "finished import of %s", importfilename.c_str());
1199 }
1200 if (i == 0) {
1201 binMplt->SetImportFileName(importfilename);
1202 mod.SetBinMplt(binMplt);
1203 } else {
1204 delete binMplt;
1205 }
1206 }
1207
1208 size = static_cast<int32>(ReadNum());
1209 for (int32 i = 0; i < size; i++) {
1210 std::string str;
1211 ReadAsciiStr(str);
1212 mod.GetAsmDecls().emplace_back(MapleString(str, mod.GetMemPool()));
1213 }
1214
1215 int32 tag = static_cast<int32>(ReadNum());
1216 CHECK_FATAL(tag == ~kBinHeaderStart, "pattern mismatch in Read Import");
1217 return;
1218 }
1219
ReadTypeField()1220 void BinaryMplImport::ReadTypeField()
1221 {
1222 SkipTotalSize();
1223
1224 int32 size = ReadInt();
1225 if (mod.IsJavaModule()) {
1226 for (int64 i = 0; i < size; ++i) {
1227 ImportType();
1228 }
1229 } else {
1230 for (int64 i = 0; i < size; ++i) {
1231 (void)ImportTypeNonJava();
1232 }
1233 }
1234 int64 tag = 0;
1235 tag = ReadNum();
1236 CHECK_FATAL(tag == ~kBinTypeStart, "pattern mismatch in Read TYPE");
1237 }
1238
ImportCallInfo()1239 CallInfo *BinaryMplImport::ImportCallInfo()
1240 {
1241 int64 tag = ReadNum();
1242 if (tag < 0) {
1243 CHECK_FATAL(static_cast<size_t>(-tag) < callInfoTab.size(), "index out of bounds");
1244 return callInfoTab.at(-tag);
1245 }
1246 CHECK_FATAL(tag == kBinCallinfo, "expecting kBinCallinfo");
1247 CallType ctype = static_cast<CallType>(ReadNum()); // call type
1248 uint32 loopDepth = static_cast<uint32>(ReadInt());
1249 uint32 id = static_cast<uint32>(ReadInt());
1250 bool argLocal = Read() == 1;
1251 MIRSymbol *funcSym = InSymbol(nullptr);
1252 CHECK_FATAL(funcSym != nullptr, "func_sym is null in BinaryMplImport::InCallInfo");
1253 CallInfo *ret = mod.GetMemPool()->New<CallInfo>(ctype, *funcSym->GetFunction(), static_cast<StmtNode *>(nullptr),
1254 loopDepth, id, argLocal);
1255 callInfoTab.push_back(ret);
1256 return ret;
1257 }
1258
MergeDuplicated(PUIdx methodPuidx,std::vector<CallInfo * > & targetSet,std::vector<CallInfo * > & newSet)1259 void BinaryMplImport::MergeDuplicated(PUIdx methodPuidx, std::vector<CallInfo *> &targetSet,
1260 std::vector<CallInfo *> &newSet)
1261 {
1262 if (targetSet.empty()) {
1263 (void)targetSet.insert(targetSet.begin(), newSet.begin(), newSet.end());
1264 std::unordered_set<uint32> tmp;
1265 mod.AddValueToMethod2TargetHash(methodPuidx, tmp);
1266 for (size_t i = 0; i < newSet.size(); ++i) {
1267 mod.InsertTargetHash(methodPuidx, newSet[i]->GetID());
1268 }
1269 } else {
1270 for (size_t i = 0; i < newSet.size(); ++i) {
1271 CallInfo *newItem = newSet[i];
1272 if (!mod.HasTargetHash(methodPuidx, newItem->GetID())) {
1273 targetSet.push_back(newItem);
1274 mod.InsertTargetHash(methodPuidx, newItem->GetID());
1275 }
1276 }
1277 }
1278 }
1279
ReadCgField()1280 void BinaryMplImport::ReadCgField()
1281 {
1282 SkipTotalSize();
1283
1284 int32 size = ReadInt();
1285 int64 tag = 0;
1286
1287 for (int i = 0; i < size; ++i) {
1288 tag = ReadNum();
1289 CHECK_FATAL(tag == kStartMethod, " should be start point of method");
1290 MIRSymbol *tmpInSymbol = InSymbol(nullptr);
1291 CHECK_FATAL(tmpInSymbol != nullptr, "null ptr check");
1292 PUIdx methodPuidx = tmpInSymbol->GetFunction()->GetPuidx();
1293 CHECK_FATAL(methodPuidx, "should not be 0");
1294 if (mod.GetMethod2TargetMap().find(methodPuidx) == mod.GetMethod2TargetMap().end()) {
1295 std::vector<CallInfo *> targetSetTmp;
1296 mod.AddMemToMethod2TargetMap(methodPuidx, targetSetTmp);
1297 }
1298 int32 targSize = ReadInt();
1299 std::vector<CallInfo *> targetSet;
1300 callInfoTab.clear();
1301 callInfoTab.push_back(nullptr);
1302 for (int32 j = 0; j < targSize; ++j) {
1303 CallInfo *callInfo = ImportCallInfo();
1304 targetSet.push_back(callInfo);
1305 }
1306 MergeDuplicated(methodPuidx, mod.GetMemFromMethod2TargetMap(methodPuidx), targetSet);
1307 tag = ReadNum();
1308 CHECK_FATAL(tag == ~kStartMethod, " should be start point of method");
1309 }
1310 tag = ReadNum();
1311 CHECK_FATAL(tag == ~kBinCgStart, "pattern mismatch in Read CG");
1312 }
1313
ReadEaField()1314 void BinaryMplImport::ReadEaField()
1315 {
1316 ReadInt();
1317 int size = ReadInt();
1318 for (int i = 0; i < size; ++i) {
1319 GStrIdx funcName = ImportStr();
1320 int nodesSize = ReadInt();
1321 EAConnectionGraph *newEaCg =
1322 mod.GetMemPool()->New<EAConnectionGraph>(&mod, &mod.GetMPAllocator(), funcName, true);
1323 newEaCg->ResizeNodes(nodesSize, nullptr);
1324 InEaCgNode(*newEaCg);
1325 int eaSize = ReadInt();
1326 for (int j = 0; j < eaSize; ++j) {
1327 EACGBaseNode *node = &InEaCgNode(*newEaCg);
1328 newEaCg->funcArgNodes.push_back(node);
1329 }
1330 mod.SetEAConnectionGraph(funcName, newEaCg);
1331 }
1332 CHECK_FATAL(ReadNum() == ~kBinEaStart, "pattern mismatch in Read EA");
1333 }
1334
ReadSeField()1335 void BinaryMplImport::ReadSeField()
1336 {
1337 SkipTotalSize();
1338
1339 int32 size = ReadInt();
1340 #ifdef MPLT_DEBUG
1341 LogInfo::MapleLogger() << "SE SIZE : " << size << '\n';
1342 #endif
1343 for (int32 i = 0; i < size; ++i) {
1344 GStrIdx funcName = ImportStr();
1345 uint8 specialEffect = Read();
1346 TyIdx tyIdx = kInitTyIdx;
1347 if ((specialEffect & kPureFunc) == kPureFunc) {
1348 tyIdx = ImportType();
1349 }
1350 const std::string &funcStr = GlobalTables::GetStrTable().GetStringFromStrIdx(funcName);
1351 if (funcStr == "Ljava_2Flang_2FObject_3B_7Cwait_7C_28_29V") {
1352 specialEffect = 0;
1353 }
1354 auto *funcSymbol =
1355 GlobalTables::GetGsymTable().GetSymbolFromStrIdx(GlobalTables::GetStrTable().GetStrIdxFromName(funcStr));
1356 MIRFunction *func = funcSymbol != nullptr ? mirBuilder.GetFunctionFromSymbol(*funcSymbol) : nullptr;
1357 if (func != nullptr) {
1358 func->SetAttrsFromSe(specialEffect);
1359 } else if ((specialEffect & kPureFunc) == kPureFunc) {
1360 func = mirBuilder.GetOrCreateFunction(funcStr, tyIdx);
1361 func->SetAttrsFromSe(specialEffect);
1362 }
1363 }
1364 int64 tag = ReadNum();
1365 CHECK_FATAL(tag == ~kBinSeStart, "pattern mismatch in Read TYPE");
1366 }
1367
InEaCgBaseNode(EACGBaseNode & base,EAConnectionGraph & newEaCg,bool firstPart)1368 void BinaryMplImport::InEaCgBaseNode(EACGBaseNode &base, EAConnectionGraph &newEaCg, bool firstPart)
1369 {
1370 if (firstPart) {
1371 base.SetEAStatus(static_cast<EAStatus>(ReadNum()));
1372 base.SetID(ReadInt());
1373 } else {
1374 // start to in points to
1375 int size = ReadInt();
1376 for (int i = 0; i < size; ++i) {
1377 EACGBaseNode *point2Node = &InEaCgNode(newEaCg);
1378 CHECK_FATAL(point2Node->IsObjectNode(), "must be");
1379 (void)base.pointsTo.insert(static_cast<EACGObjectNode *>(point2Node));
1380 }
1381 // start to in in
1382 size = ReadInt();
1383 for (int i = 0; i < size; ++i) {
1384 EACGBaseNode *point2Node = &InEaCgNode(newEaCg);
1385 base.InsertInSet(point2Node);
1386 }
1387 // start to in out
1388 size = ReadInt();
1389 for (int i = 0; i < size; ++i) {
1390 EACGBaseNode *point2Node = &InEaCgNode(newEaCg);
1391 base.InsertOutSet(point2Node);
1392 }
1393 }
1394 }
1395
InEaCgActNode(EACGActualNode & actual)1396 void BinaryMplImport::InEaCgActNode(EACGActualNode &actual)
1397 {
1398 actual.isPhantom = Read() == 1;
1399 actual.isReturn = Read() == 1;
1400 actual.argIdx = Read();
1401 actual.callSiteInfo = static_cast<uint32>(ReadInt());
1402 }
1403
InEaCgFieldNode(EACGFieldNode & field,EAConnectionGraph & newEaCg)1404 void BinaryMplImport::InEaCgFieldNode(EACGFieldNode &field, EAConnectionGraph &newEaCg)
1405 {
1406 field.SetFieldID(ReadInt());
1407 int size = ReadInt();
1408 for (int i = 0; i < size; ++i) {
1409 EACGBaseNode *node = &InEaCgNode(newEaCg);
1410 CHECK_FATAL(node->IsObjectNode(), "must be");
1411 (void)field.belongsTo.insert(static_cast<EACGObjectNode *>(node));
1412 }
1413 field.isPhantom = Read() == 1;
1414 }
1415
InEaCgObjNode(EACGObjectNode & obj,EAConnectionGraph & newEaCg)1416 void BinaryMplImport::InEaCgObjNode(EACGObjectNode &obj, EAConnectionGraph &newEaCg)
1417 {
1418 Read();
1419 obj.isPhantom = true;
1420 int size = ReadInt();
1421 for (int i = 0; i < size; ++i) {
1422 EACGBaseNode *node = &InEaCgNode(newEaCg);
1423 CHECK_FATAL(node->IsFieldNode(), "must be");
1424 auto *field = static_cast<EACGFieldNode *>(node);
1425 obj.fieldNodes[static_cast<EACGFieldNode *>(field)->GetFieldID()] = field;
1426 }
1427 // start to in point by
1428 size = ReadInt();
1429 for (int i = 0; i < size; ++i) {
1430 EACGBaseNode *point2Node = &InEaCgNode(newEaCg);
1431 (void)obj.pointsBy.insert(point2Node);
1432 }
1433 }
1434
InEaCgRefNode(EACGRefNode & ref)1435 void BinaryMplImport::InEaCgRefNode(EACGRefNode &ref)
1436 {
1437 ref.isStaticField = Read() == 1 ? true : false;
1438 }
1439
InEaCgNode(EAConnectionGraph & newEaCg)1440 EACGBaseNode &BinaryMplImport::InEaCgNode(EAConnectionGraph &newEaCg)
1441 {
1442 int64 tag = ReadNum();
1443 if (tag < 0) {
1444 CHECK_FATAL(static_cast<uint64>(-tag) < eaCgTab.size(), "index out of bounds");
1445 return *eaCgTab[-tag];
1446 }
1447 CHECK_FATAL(tag == kBinEaCgNode, "must be");
1448 NodeKind kind = static_cast<NodeKind>(ReadNum());
1449 EACGBaseNode *node = nullptr;
1450 switch (kind) {
1451 case kObejectNode:
1452 node = new EACGObjectNode(&mod, &mod.GetMPAllocator(), &newEaCg);
1453 break;
1454 case kReferenceNode:
1455 node = new EACGRefNode(&mod, &mod.GetMPAllocator(), &newEaCg);
1456 break;
1457 case kFieldNode:
1458 node = new EACGFieldNode(&mod, &mod.GetMPAllocator(), &newEaCg);
1459 break;
1460 case kActualNode:
1461 node = new EACGActualNode(&mod, &mod.GetMPAllocator(), &newEaCg);
1462 break;
1463 default:
1464 CHECK_FATAL(false, "impossible");
1465 }
1466 node->SetEACG(&newEaCg);
1467 eaCgTab.push_back(node);
1468 InEaCgBaseNode(*node, newEaCg, true);
1469 newEaCg.SetNodeAt(node->id - 1, node);
1470 if (node->IsActualNode()) {
1471 CHECK_FATAL(ReadNum() == kBinEaCgActNode, "must be");
1472 InEaCgActNode(static_cast<EACGActualNode &>(*node));
1473 } else if (node->IsFieldNode()) {
1474 CHECK_FATAL(ReadNum() == kBinEaCgFieldNode, "must be");
1475 InEaCgFieldNode(static_cast<EACGFieldNode &>(*node), newEaCg);
1476 } else if (node->IsObjectNode()) {
1477 CHECK_FATAL(ReadNum() == kBinEaCgObjNode, "must be");
1478 InEaCgObjNode(static_cast<EACGObjectNode &>(*node), newEaCg);
1479 } else if (node->IsReferenceNode()) {
1480 CHECK_FATAL(ReadNum() == kBinEaCgRefNode, "must be");
1481 InEaCgRefNode(static_cast<EACGRefNode &>(*node));
1482 }
1483 InEaCgBaseNode(*node, newEaCg, false);
1484 CHECK_FATAL(ReadNum() == ~kBinEaCgNode, "must be");
1485 return *node;
1486 }
1487
ReadEaCgField()1488 EAConnectionGraph *BinaryMplImport::ReadEaCgField()
1489 {
1490 if (ReadNum() == ~kBinEaCgStart) {
1491 return nullptr;
1492 }
1493 ReadInt();
1494 GStrIdx funcStr = ImportStr();
1495 int nodesSize = ReadInt();
1496 EAConnectionGraph *newEaCg = mod.GetMemPool()->New<EAConnectionGraph>(&mod, &mod.GetMPAllocator(), funcStr, true);
1497 newEaCg->ResizeNodes(nodesSize, nullptr);
1498 InEaCgNode(*newEaCg);
1499 CHECK_FATAL(newEaCg->GetNode(kFirstOpnd)->IsObjectNode(), "must be");
1500 CHECK_FATAL(newEaCg->GetNode(kSecondOpnd)->IsReferenceNode(), "must be");
1501 CHECK_FATAL(newEaCg->GetNode(kThirdOpnd)->IsFieldNode(), "must be");
1502 newEaCg->globalField = static_cast<EACGFieldNode *>(newEaCg->GetNode(kThirdOpnd));
1503 newEaCg->globalObj = static_cast<EACGObjectNode *>(newEaCg->GetNode(kFirstOpnd));
1504 newEaCg->globalRef = static_cast<EACGRefNode *>(newEaCg->GetNode(kSecondOpnd));
1505 CHECK_FATAL(newEaCg->globalField && newEaCg->globalObj && newEaCg->globalRef, "must be");
1506 int32 nodeSize = ReadInt();
1507 for (int j = 0; j < nodeSize; ++j) {
1508 EACGBaseNode *node = &InEaCgNode(*newEaCg);
1509 newEaCg->funcArgNodes.push_back(node);
1510 }
1511
1512 int32 callSitesize = ReadInt();
1513 for (int i = 0; i < callSitesize; ++i) {
1514 uint32 id = static_cast<uint32>(ReadInt());
1515 newEaCg->callSite2Nodes[id] =
1516 mod.GetMemPool()->New<MapleVector<EACGBaseNode *>>(mod.GetMPAllocator().Adapter());
1517 int32 calleeArgSize = ReadInt();
1518 for (int j = 0; j < calleeArgSize; ++j) {
1519 EACGBaseNode *node = &InEaCgNode(*newEaCg);
1520 newEaCg->callSite2Nodes[id]->push_back(node);
1521 }
1522 }
1523
1524 #ifdef DEBUG
1525 for (EACGBaseNode *node : newEaCg->GetNodes()) {
1526 if (node == nullptr) {
1527 continue;
1528 }
1529 node->CheckAllConnectionInNodes();
1530 }
1531 #endif
1532 CHECK_FATAL(ReadNum() == ~kBinEaCgStart, "pattern mismatch in Read EACG");
1533 return newEaCg;
1534 }
1535
ReadSymField()1536 void BinaryMplImport::ReadSymField()
1537 {
1538 SkipTotalSize();
1539 int32 size = ReadInt();
1540 for (int64 i = 0; i < size; i++) {
1541 (void)InSymbol(nullptr);
1542 }
1543 int64 tag = ReadNum();
1544 CHECK_FATAL(tag == ~kBinSymStart, "pattern mismatch in Read SYM");
1545 return;
1546 }
1547
ReadSymTabField()1548 void BinaryMplImport::ReadSymTabField()
1549 {
1550 SkipTotalSize();
1551 int32 size = ReadInt();
1552 for (int64 i = 0; i < size; i++) {
1553 std::string str;
1554 ReadAsciiStr(str);
1555 }
1556 int64 tag = ReadNum();
1557 CHECK_FATAL(tag == ~kBinSymTabStart, "pattern mismatch in Read TYPE");
1558 return;
1559 }
1560
ReadContentField()1561 void BinaryMplImport::ReadContentField()
1562 {
1563 SkipTotalSize();
1564
1565 int32 size = ReadInt();
1566 int64 item;
1567 int32 offset;
1568 for (int32 i = 0; i < size; ++i) {
1569 item = ReadNum();
1570 offset = ReadInt();
1571 content[item] = offset;
1572 }
1573 CHECK_FATAL(ReadNum() == ~kBinContentStart, "pattern mismatch in Read CONTENT");
1574 }
1575
Jump2NextField()1576 void BinaryMplImport::Jump2NextField()
1577 {
1578 uint32 totalSize = static_cast<uint32>(ReadInt());
1579 bufI += (totalSize - sizeof(uint32));
1580 ReadNum(); // skip end tag for this field
1581 }
1582
ImportForSrcLang(const std::string & fname,MIRSrcLang & srcLang)1583 bool BinaryMplImport::ImportForSrcLang(const std::string &fname, MIRSrcLang &srcLang)
1584 {
1585 Reset();
1586 ReadFileAt(fname, 0);
1587 int32 magic = ReadInt();
1588 if (kMpltMagicNumber != magic && (kMpltMagicNumber + 0x10) != magic) {
1589 buf.clear();
1590 return false;
1591 }
1592 importingFromMplt = kMpltMagicNumber == magic;
1593 int64 fieldID = ReadNum();
1594 while (fieldID != kBinFinish) {
1595 switch (fieldID) {
1596 case kBinHeaderStart: {
1597 SkipTotalSize();
1598 (void)ReadNum(); // skip flavor
1599 srcLang = static_cast<MIRSrcLang>(ReadNum());
1600 return true;
1601 }
1602 default: {
1603 Jump2NextField();
1604 break;
1605 }
1606 }
1607 fieldID = ReadNum();
1608 }
1609 return false;
1610 }
1611
Import(const std::string & fname,bool readSymbols,bool readSe)1612 bool BinaryMplImport::Import(const std::string &fname, bool readSymbols, bool readSe)
1613 {
1614 Reset();
1615 ReadFileAt(fname, 0);
1616 int32 magic = ReadInt();
1617 if (kMpltMagicNumber != magic && (kMpltMagicNumber + 0x10) != magic) {
1618 buf.clear();
1619 return false;
1620 }
1621 importingFromMplt = kMpltMagicNumber == magic;
1622 int64 fieldID = ReadNum();
1623 if (readSe) {
1624 while (fieldID != kBinFinish) {
1625 if (fieldID == kBinSeStart) {
1626 #ifdef MPLT_DEBUG
1627 LogInfo::MapleLogger() << "read SE of : " << fname << '\n';
1628 #endif
1629 BinaryMplImport tmp(mod);
1630 tmp.Reset();
1631 tmp.buf = buf;
1632 tmp.bufI = bufI;
1633 tmp.importFileName = fname;
1634 tmp.ReadSeField();
1635 Jump2NextField();
1636 } else if (fieldID == kBinEaStart) {
1637 BinaryMplImport tmp(mod);
1638 tmp.Reset();
1639 tmp.buf = buf;
1640 tmp.bufI = bufI;
1641 tmp.importFileName = fname;
1642 tmp.ReadEaField();
1643 Jump2NextField();
1644 } else {
1645 Jump2NextField();
1646 }
1647 fieldID = ReadNum();
1648 }
1649 return true;
1650 }
1651 while (fieldID != kBinFinish) {
1652 switch (fieldID) {
1653 case kBinContentStart: {
1654 ReadContentField();
1655 break;
1656 }
1657 case kBinStrStart: {
1658 ReadStrField();
1659 break;
1660 }
1661 case kBinHeaderStart: {
1662 ReadHeaderField();
1663 break;
1664 }
1665 case kBinTypeStart: {
1666 ReadTypeField();
1667 break;
1668 }
1669 case kBinSymStart: {
1670 if (readSymbols) {
1671 ReadSymField();
1672 } else {
1673 Jump2NextField();
1674 }
1675 break;
1676 }
1677 case kBinSymTabStart: {
1678 ReadSymTabField();
1679 break;
1680 }
1681 case kBinCgStart: {
1682 if (readSymbols) {
1683 #ifdef MPLT_DEBUG
1684 LogInfo::MapleLogger() << "read CG of : " << fname << '\n';
1685 #endif
1686 BinaryMplImport tmp(mod);
1687 tmp.Reset();
1688 tmp.inIPA = true;
1689 tmp.buf = buf;
1690 tmp.bufI = bufI;
1691 tmp.importFileName = fname;
1692 tmp.ReadCgField();
1693 tmp.UpdateMethodSymbols();
1694 Jump2NextField();
1695 } else {
1696 Jump2NextField();
1697 }
1698 break;
1699 }
1700 case kBinSeStart: {
1701 Jump2NextField();
1702 break;
1703 }
1704 case kBinEaStart: {
1705 if (readSymbols) {
1706 #ifdef MPLT_DEBUG
1707 LogInfo::MapleLogger() << "read EA of : " << fname << '\n';
1708 #endif
1709 BinaryMplImport tmp(mod);
1710 tmp.Reset();
1711 tmp.buf = buf;
1712 tmp.bufI = bufI;
1713 tmp.importFileName = fname;
1714 tmp.ReadEaField();
1715 Jump2NextField();
1716 } else {
1717 Jump2NextField();
1718 }
1719 break;
1720 }
1721 case kBinFunctionBodyStart: {
1722 ReadFunctionBodyField();
1723 break;
1724 }
1725 default:
1726 CHECK_FATAL(false, "should not run here");
1727 }
1728 fieldID = ReadNum();
1729 }
1730 UpdateMethodSymbols();
1731 SetupEHRootType();
1732 return true;
1733 }
1734 } // namespace maple
1735