| 76 | } |
| 77 | |
| 78 | AST::CustomSection createCorestack( |
| 79 | Loader::Serializer &Ser, Span<const Runtime::StackManager::Frame> Frames, |
| 80 | Span<const Runtime::StackManager::Value> ValueStack, bool ForWasmgdb) { |
| 81 | AST::CustomSection CoreStack; |
| 82 | CoreStack.setName("corestack"); |
| 83 | auto &Content = CoreStack.getContent(); |
| 84 | // thread-info type 0x00 for wasmedbg |
| 85 | Content.push_back(0x00); |
| 86 | |
| 87 | // Thread name size |
| 88 | Content.push_back(0x04); |
| 89 | |
| 90 | std::string ThreadName = "main"; |
| 91 | Content.insert(Content.end(), ThreadName.begin(), ThreadName.end()); |
| 92 | auto FramesSize = Frames.size() - 1; |
| 93 | Ser.serializeU32(static_cast<uint32_t>(FramesSize), Content); |
| 94 | for (size_t Idx = FramesSize; Idx > 0; Idx--) { |
| 95 | if (Frames[Idx].Module == nullptr) { |
| 96 | continue; |
| 97 | } |
| 98 | // frame type 0x00 for wasmedbg |
| 99 | Content.push_back(0x00); |
| 100 | // TODO: fix main Funcidx is 0 |
| 101 | auto Funcidx = Frames[Idx].From->getTargetIndex(); |
| 102 | auto Codeoffset = Frames[Idx].From->getOffset(); |
| 103 | uint32_t Lstart = Frames[Idx].VPos - Frames[Idx].Locals; |
| 104 | uint32_t Lend = Frames[Idx].VPos; |
| 105 | uint32_t Vstart = Frames[Idx].VPos; |
| 106 | uint32_t Vend = (Idx != FramesSize) |
| 107 | ? Frames[Idx + 1].VPos - Frames[Idx + 1].Locals |
| 108 | : static_cast<uint32_t>(ValueStack.size()); |
| 109 | |
| 110 | uint32_t Lsize = Lend - Lstart; |
| 111 | uint32_t Vsize = Vend - Vstart; |
| 112 | assuming(Lstart + Lsize <= ValueStack.size()); |
| 113 | auto Locals = Span<const Runtime::StackManager::Value>( |
| 114 | ValueStack.begin() + Lstart, Lsize); |
| 115 | assuming(Vstart + Vsize <= ValueStack.size()); |
| 116 | Span<const Runtime::StackManager::Value> Stacks; |
| 117 | if (!ForWasmgdb) { |
| 118 | Stacks = Span<const Runtime::StackManager::Value>( |
| 119 | ValueStack.begin() + Vstart, Vsize); |
| 120 | } |
| 121 | Ser.serializeU32(Funcidx, Content); |
| 122 | Ser.serializeU32(Codeoffset, Content); |
| 123 | // locals size |
| 124 | Ser.serializeU32(Frames[Idx].Locals, Content); |
| 125 | // stack size |
| 126 | Ser.serializeU32(Vsize, Content); |
| 127 | for (auto &Iter : Locals) { |
| 128 | // 0x7F implies i32. i128 is not supported here, and wasmgdb does not |
| 129 | // support i64. |
| 130 | Content.push_back(0x7F); |
| 131 | auto Value = Iter.unwrap(); |
| 132 | std::vector<Byte> ValueBytes(4); |
| 133 | std::memcpy(ValueBytes.data(), &Value, sizeof(int64_t)); |
| 134 | Content.insert(Content.end(), ValueBytes.begin(), ValueBytes.end()); |
| 135 | } |
no test coverage detected