blob: 1a041c940666e3fa38e449e3efa1c3fc2c1bb32d (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
|
// Copyright (C) 2025 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#include "wasmbinary.h"
#include <QFile>
#include <iostream>
WasmBinary::WasmBinary(QString filepath)
{
QFile file(filepath);
if (!file.open(QIODevice::ReadOnly)) {
std::cout << "ERROR: Cannot open the file " << filepath.toStdString() << std::endl;
std::cout << file.errorString().toStdString() << std::endl;
type = WasmBinary::Type::INVALID;
return;
}
auto bytes = file.readAll();
if (!parsePreambule(bytes)) {
type = WasmBinary::Type::INVALID;
}
}
bool WasmBinary::parsePreambule(QByteArrayView data)
{
const auto preambuleSize = 24;
if (data.size() < preambuleSize) {
std::cout << "ERROR: Preambule of binary shorter than expected!" << std::endl;
return false;
}
uint32_t int32View[6];
std::memcpy(int32View, data.data(), sizeof(int32View));
if (int32View[0] != 0x6d736100) {
std::cout << "ERROR: Magic WASM number not found in binary. Binary corrupted?" << std::endl;
return false;
}
if (data[8] != 0) {
type = WasmBinary::Type::STATIC;
return true;
} else {
type = WasmBinary::Type::SHARED;
}
const auto sectionStart = 9;
size_t offset = sectionStart;
auto sectionSize = getLeb(data, offset);
auto sectionEnd = sectionStart + sectionSize;
auto name = getString(data, offset);
if (name != "dylink.0") {
type = WasmBinary::Type::INVALID;
std::cout << "ERROR: dylink.0 was not found in supposedly dynamically linked module"
<< std::endl;
return false;
}
const auto WASM_DYLINK_NEEDED = 0x2;
while (offset < sectionEnd) {
auto subsectionType = data[offset++];
auto subsectionSize = getLeb(data, offset);
if (subsectionType == WASM_DYLINK_NEEDED) {
auto neededDynlibsCount = getLeb(data, offset);
while (neededDynlibsCount--) {
dependencies.append(getString(data, offset));
}
} else {
offset += subsectionSize;
}
}
return true;
}
size_t WasmBinary::getLeb(QByteArrayView data, size_t &offset)
{
auto ret = 0;
auto mul = 1;
while (true) {
auto byte = data[offset++];
ret += (byte & 0x7f) * mul;
mul *= 0x80;
if (!(byte & 0x80))
break;
}
return ret;
}
QString WasmBinary::getString(QByteArrayView data, size_t &offset)
{
auto length = getLeb(data, offset);
offset += length;
return QString::fromUtf8(data.sliced(offset - length, length));
}
|