Skip to content

Commit 305d48d

Browse files
committed
Add ABI parse in BytecodeUtil
Signed-off-by: Takeshi Yoneda <[email protected]>
1 parent 0f7eac3 commit 305d48d

File tree

3 files changed

+79
-0
lines changed

3 files changed

+79
-0
lines changed

src/common/bytecode_util.cc

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,68 @@ bool BytecodeUtil::checkWasmHeader(std::string_view bytecode) {
2323
return bytecode.size() < 8 || !::memcmp(bytecode.data(), wasm_magic_number, 4);
2424
}
2525

26+
bool BytecodeUtil::getAbiVersion(std::string_view bytecode, proxy_wasm::AbiVersion &ret) {
27+
ret = proxy_wasm::AbiVersion::Unknown;
28+
// Check Wasm header.
29+
if (!checkWasmHeader(bytecode)) {
30+
return false;
31+
}
32+
// Skip the Wasm header.
33+
const char *pos = bytecode.data() + 8;
34+
const char *end = bytecode.data() + bytecode.size();
35+
while (pos < end) {
36+
if (pos + 1 > end) {
37+
return false;
38+
}
39+
const auto section_type = *pos++;
40+
uint32_t section_len = 0;
41+
if (!parseVarint(pos, end, section_len) || pos + section_len > end) {
42+
return false;
43+
}
44+
if (section_type == 7 /* export section */) {
45+
uint32_t export_vector_size = 0;
46+
if (!parseVarint(pos, end, export_vector_size) || pos + export_vector_size > end) {
47+
return false;
48+
}
49+
// Search thourgh exports.
50+
for (uint32_t i = 0; i < export_vector_size; i++) {
51+
// Parse name of the export.
52+
uint32_t export_name_size = 0;
53+
if (!parseVarint(pos, end, export_name_size) || pos + export_name_size > end) {
54+
return false;
55+
}
56+
const std::string export_name = {pos, export_name_size};
57+
pos += export_name_size;
58+
if (pos + 1 > end) {
59+
return false;
60+
}
61+
// Check if it is a function type export
62+
if (*pos++ == 0x00) {
63+
// Check the name of the function.
64+
if (export_name == "proxy_abi_version_0_1_0") {
65+
ret = AbiVersion::ProxyWasm_0_1_0;
66+
return true;
67+
} else if (export_name == "proxy_abi_version_0_2_0") {
68+
ret = AbiVersion::ProxyWasm_0_2_0;
69+
return true;
70+
} else if (export_name == "proxy_abi_version_0_2_1") {
71+
ret = AbiVersion::ProxyWasm_0_2_1;
72+
return true;
73+
}
74+
}
75+
// Skip export's index.
76+
if (!parseVarint(pos, end, export_name_size)) {
77+
return false;
78+
}
79+
}
80+
return false;
81+
} else {
82+
pos += section_len;
83+
}
84+
}
85+
return true;
86+
}
87+
2688
bool BytecodeUtil::getCustomSection(std::string_view bytecode, std::string_view name,
2789
std::string_view &ret) {
2890
// Check Wasm header.

src/common/bytecode_util.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@
1717
#include <vector>
1818
#include <unordered_map>
1919

20+
#include "include/proxy-wasm/wasm_vm.h"
21+
2022
namespace proxy_wasm {
2123
namespace common {
2224

@@ -30,6 +32,14 @@ class BytecodeUtil {
3032
*/
3133
static bool checkWasmHeader(std::string_view bytecode);
3234

35+
/**
36+
* checkWasmHeader extracts ABI version from the bytecode.
37+
* @param bytecode is the target bytecode.
38+
* @param ret is the reference to store the extracted ABI version or UnKnonw if it doesn't exist.
39+
* @return indicates whether parsing succeeded or not.
40+
*/
41+
static bool getAbiVersion(std::string_view bytecode, proxy_wasm::AbiVersion &ret);
42+
3343
/**
3444
* getCustomSection extract the view of the custom section for a given name.
3545
* @param bytecode is the target bytecode.

test/common/bytecode_util_test.cc

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,5 +107,12 @@ TEST(TestWasmCommonUtil, getStrippedSource) {
107107
EXPECT_EQ(actual.size(), source.size() - custom_section.size());
108108
}
109109

110+
TEST(TestWasmCommonUtil, getAbiVersion) {
111+
const auto source = readTestWasmFile("abi_export.wasm");
112+
proxy_wasm::AbiVersion actual;
113+
EXPECT_TRUE(BytecodeUtil::getAbiVersion(source, actual));
114+
EXPECT_EQ(actual, proxy_wasm::AbiVersion::ProxyWasm_0_2_0);
115+
}
116+
110117
} // namespace common
111118
} // namespace proxy_wasm

0 commit comments

Comments
 (0)