Load binary to construct Module node. See "include/loader/loader.h".
| 20 | |
| 21 | // Load binary to construct Module node. See "include/loader/loader.h". |
| 22 | Expect<void> Loader::loadModule(AST::Module &Mod, |
| 23 | std::optional<uint64_t> Bound) { |
| 24 | uint64_t StartOffset = FMgr.getOffset(); |
| 25 | auto ReportError = [](auto E) { |
| 26 | spdlog::error(ErrInfo::InfoAST(ASTNodeAttr::Module)); |
| 27 | return E; |
| 28 | }; |
| 29 | |
| 30 | // Variables to record the loaded section types. |
| 31 | HasDataSection = false; |
| 32 | std::vector<uint8_t> Secs = {0x0BU, 0x0AU, 0x0CU, 0x09U, 0x08U, 0x07U, 0x06U, |
| 33 | 0x0DU, 0x05U, 0x04U, 0x03U, 0x02U, 0x01U}; |
| 34 | uint64_t Offset = FMgr.getOffset(); |
| 35 | |
| 36 | // Read Section index and create Section nodes. |
| 37 | while (!Bound.has_value() || Bound.value() > Offset - StartOffset) { |
| 38 | uint8_t NewSectionId = 0x00; |
| 39 | // If not read section ID, seems the end of file and break. |
| 40 | if (auto Res = FMgr.readByte()) { |
| 41 | NewSectionId = *Res; |
| 42 | } else { |
| 43 | if (Res.error() == ErrCode::Value::UnexpectedEnd) { |
| 44 | break; |
| 45 | } else { |
| 46 | return logLoadError(Res.error(), FMgr.getLastOffset(), |
| 47 | ASTNodeAttr::Module); |
| 48 | } |
| 49 | } |
| 50 | |
| 51 | // Sections except the custom section should be unique and in order. |
| 52 | if (NewSectionId > 0x00U && NewSectionId < 0x0EU) { |
| 53 | while (Secs.size() > 0 && Secs.back() != NewSectionId) { |
| 54 | Secs.pop_back(); |
| 55 | } |
| 56 | if (Secs.empty()) { |
| 57 | return logLoadError(ErrCode::Value::JunkSection, FMgr.getLastOffset(), |
| 58 | ASTNodeAttr::Module); |
| 59 | } |
| 60 | Secs.pop_back(); |
| 61 | } |
| 62 | |
| 63 | switch (NewSectionId) { |
| 64 | case 0x00: |
| 65 | Mod.getCustomSections().emplace_back(); |
| 66 | EXPECTED_TRY( |
| 67 | loadSection(Mod.getCustomSections().back()).map_error(ReportError)); |
| 68 | break; |
| 69 | case 0x01: |
| 70 | EXPECTED_TRY(loadSection(Mod.getTypeSection()).map_error(ReportError)); |
| 71 | break; |
| 72 | case 0x02: |
| 73 | EXPECTED_TRY(loadSection(Mod.getImportSection()).map_error(ReportError)); |
| 74 | break; |
| 75 | case 0x03: |
| 76 | EXPECTED_TRY( |
| 77 | loadSection(Mod.getFunctionSection()).map_error(ReportError)); |
| 78 | break; |
| 79 | case 0x04: |
nothing calls this directly
no test coverage detected