-
Notifications
You must be signed in to change notification settings - Fork 797
Expand file tree
/
Copy pathwasm_loader_common.c
More file actions
226 lines (207 loc) · 6.89 KB
/
wasm_loader_common.c
File metadata and controls
226 lines (207 loc) · 6.89 KB
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
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
/*
* Copyright (C) 2024 Amazon Inc. All rights reserved.
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
*/
#include "wasm_loader_common.h"
#include "bh_leb128.h"
#include "bh_log.h"
#if WASM_ENABLE_GC != 0
#include "../common/gc/gc_type.h"
#endif
void
wasm_loader_set_error_buf(char *error_buf, uint32 error_buf_size,
const char *string, bool is_aot)
{
if (error_buf != NULL) {
snprintf(error_buf, error_buf_size, "%s module load failed: %s",
is_aot ? "AOT" : "WASM", string);
}
}
#if WASM_ENABLE_MEMORY64 != 0
bool
check_memory64_flags_consistency(WASMModule *module, char *error_buf,
uint32 error_buf_size, bool is_aot)
{
uint32 i;
bool wasm64_flag, all_wasm64 = true, none_wasm64 = true;
for (i = 0; i < module->import_memory_count; ++i) {
wasm64_flag =
module->import_memories[i].u.memory.mem_type.flags & MEMORY64_FLAG;
all_wasm64 &= wasm64_flag;
none_wasm64 &= !wasm64_flag;
}
for (i = 0; i < module->memory_count; ++i) {
wasm64_flag = module->memories[i].flags & MEMORY64_FLAG;
all_wasm64 &= wasm64_flag;
none_wasm64 &= !wasm64_flag;
}
if (!(all_wasm64 || none_wasm64)) {
wasm_loader_set_error_buf(
error_buf, error_buf_size,
"inconsistent limits wasm64 flags for memory sections", is_aot);
return false;
}
return true;
}
#endif
bool
wasm_memory_check_flags(const uint8 mem_flag, char *error_buf,
uint32 error_buf_size, bool is_aot)
{
/* Check whether certain features indicated by mem_flag are enabled in
* runtime */
if (mem_flag > MAX_PAGE_COUNT_FLAG) {
#if WASM_ENABLE_SHARED_MEMORY == 0
if (mem_flag & SHARED_MEMORY_FLAG) {
LOG_VERBOSE("shared memory flag was found, please enable shared "
"memory, lib-pthread or lib-wasi-threads");
wasm_loader_set_error_buf(error_buf, error_buf_size,
"invalid limits flags", is_aot);
return false;
}
#endif
#if WASM_ENABLE_MEMORY64 == 0
if (mem_flag & MEMORY64_FLAG) {
LOG_VERBOSE("memory64 flag was found, please enable memory64");
wasm_loader_set_error_buf(error_buf, error_buf_size,
"invalid limits flags", is_aot);
return false;
}
#endif
}
if (mem_flag > MAX_PAGE_COUNT_FLAG + SHARED_MEMORY_FLAG + MEMORY64_FLAG) {
wasm_loader_set_error_buf(error_buf, error_buf_size,
"invalid limits flags", is_aot);
return false;
}
else if ((mem_flag & SHARED_MEMORY_FLAG)
&& !(mem_flag & MAX_PAGE_COUNT_FLAG)) {
wasm_loader_set_error_buf(error_buf, error_buf_size,
"shared memory must have maximum", is_aot);
return false;
}
return true;
}
bool
wasm_table_check_flags(const uint8 table_flag, char *error_buf,
uint32 error_buf_size, bool is_aot)
{
/* Check whether certain features indicated by mem_flag are enabled in
* runtime */
if (table_flag > MAX_TABLE_SIZE_FLAG) {
if (table_flag & SHARED_TABLE_FLAG) {
wasm_loader_set_error_buf(error_buf, error_buf_size,
"tables cannot be shared", is_aot);
}
#if WASM_ENABLE_MEMORY64 == 0
if (table_flag & TABLE64_FLAG) {
wasm_loader_set_error_buf(error_buf, error_buf_size,
"invalid limits flags(table64 flag was "
"found, please enable memory64)",
is_aot);
return false;
}
#endif
}
if (table_flag > MAX_TABLE_SIZE_FLAG + TABLE64_FLAG) {
wasm_loader_set_error_buf(error_buf, error_buf_size,
"invalid limits flags", is_aot);
return false;
}
return true;
}
/*
* compare with a bigger type set in `wasm_value_type_size_internal()`,
* this function will only cover global value type, function's param
* value type and function's result value type.
*
* please feel free to add more if there are more requirements
*/
bool
is_valid_value_type(uint8 type)
{
if (/* I32/I64/F32/F64, 0x7C to 0x7F */
(type >= VALUE_TYPE_F64 && type <= VALUE_TYPE_I32)
#if WASM_ENABLE_GC != 0
/* reference types, 0x65 to 0x70 */
|| wasm_is_type_reftype(type)
#elif WASM_ENABLE_REF_TYPES != 0
|| (type == VALUE_TYPE_FUNCREF || type == VALUE_TYPE_EXTERNREF)
#endif
#if WASM_ENABLE_SIMD != 0
|| type == VALUE_TYPE_V128 /* 0x7B */
#endif
)
return true;
return false;
}
bool
is_valid_value_type_for_interpreter(uint8 value_type)
{
#if (WASM_ENABLE_WAMR_COMPILER == 0) && (WASM_ENABLE_JIT == 0) \
&& (WASM_ENABLE_FAST_INTERP == 0)
/*
* Note: regardless of WASM_ENABLE_SIMD, our interpreters don't have
* SIMD implemented. It's safer to reject v128, especially for the
* fast interpreter.
*/
if (value_type == VALUE_TYPE_V128)
return false;
#endif
return is_valid_value_type(value_type);
}
bool
is_valid_func_type(const WASMFuncType *func_type)
{
unsigned i;
for (i = 0;
i < (unsigned)(func_type->param_count + func_type->result_count);
i++) {
if (!is_valid_value_type(func_type->types[i]))
return false;
}
return true;
}
/*
* Indices are represented as a u32.
*/
bool
is_indices_overflow(uint32 import, uint32 other, char *error_buf,
uint32 error_buf_size)
{
if (import > UINT32_MAX - other) {
snprintf(error_buf, error_buf_size,
"too many items in the index space(%" PRIu32 "+%" PRIu32 ").",
import, other);
return true;
}
return false;
}
bool
read_leb(uint8 **p_buf, const uint8 *buf_end, uint32 maxbits, bool sign,
uint64 *p_result, char *error_buf, uint32 error_buf_size)
{
size_t offset = 0;
bh_leb_read_status_t status =
bh_leb_read(*p_buf, buf_end, maxbits, sign, p_result, &offset);
switch (status) {
case BH_LEB_READ_SUCCESS:
*p_buf += offset;
return true;
case BH_LEB_READ_TOO_LONG:
wasm_loader_set_error_buf(error_buf, error_buf_size,
"integer representation too long", false);
return false;
case BH_LEB_READ_OVERFLOW:
wasm_loader_set_error_buf(error_buf, error_buf_size,
"integer too large", false);
return false;
case BH_LEB_READ_UNEXPECTED_END:
wasm_loader_set_error_buf(error_buf, error_buf_size,
"unexpected end", false);
return false;
default:
bh_assert(false);
return false;
}
}