wasm_loader_common.c 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256
  1. /*
  2. * Copyright (C) 2024 Amazon Inc. All rights reserved.
  3. * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  4. */
  5. #include "wasm_loader_common.h"
  6. #include "bh_leb128.h"
  7. #include "bh_log.h"
  8. #if WASM_ENABLE_GC != 0
  9. #include "../common/gc/gc_type.h"
  10. #endif
  11. void
  12. wasm_loader_set_error_buf(char *error_buf, uint32 error_buf_size,
  13. const char *string, bool is_aot)
  14. {
  15. if (error_buf != NULL) {
  16. snprintf(error_buf, error_buf_size, "%s module load failed: %s",
  17. is_aot ? "AOT" : "WASM", string);
  18. }
  19. }
  20. #if WASM_ENABLE_MEMORY64 != 0
  21. bool
  22. check_memory64_flags_consistency(WASMModule *module, char *error_buf,
  23. uint32 error_buf_size, bool is_aot)
  24. {
  25. uint32 i;
  26. bool wasm64_flag, all_wasm64 = true, none_wasm64 = true;
  27. for (i = 0; i < module->import_memory_count; ++i) {
  28. wasm64_flag =
  29. module->import_memories[i].u.memory.mem_type.flags & MEMORY64_FLAG;
  30. all_wasm64 &= wasm64_flag;
  31. none_wasm64 &= !wasm64_flag;
  32. }
  33. for (i = 0; i < module->memory_count; ++i) {
  34. wasm64_flag = module->memories[i].flags & MEMORY64_FLAG;
  35. all_wasm64 &= wasm64_flag;
  36. none_wasm64 &= !wasm64_flag;
  37. }
  38. if (!(all_wasm64 || none_wasm64)) {
  39. wasm_loader_set_error_buf(
  40. error_buf, error_buf_size,
  41. "inconsistent limits wasm64 flags for memory sections", is_aot);
  42. return false;
  43. }
  44. return true;
  45. }
  46. #endif
  47. bool
  48. wasm_memory_check_flags(const uint8 mem_flag, char *error_buf,
  49. uint32 error_buf_size, bool is_aot)
  50. {
  51. /* Check whether certain features indicated by mem_flag are enabled in
  52. * runtime */
  53. if (mem_flag > MAX_PAGE_COUNT_FLAG) {
  54. #if WASM_ENABLE_SHARED_MEMORY == 0
  55. if (mem_flag & SHARED_MEMORY_FLAG) {
  56. LOG_VERBOSE("shared memory flag was found, please enable shared "
  57. "memory, lib-pthread or lib-wasi-threads");
  58. wasm_loader_set_error_buf(error_buf, error_buf_size,
  59. "invalid limits flags", is_aot);
  60. return false;
  61. }
  62. #endif
  63. #if WASM_ENABLE_MEMORY64 == 0
  64. if (mem_flag & MEMORY64_FLAG) {
  65. LOG_VERBOSE("memory64 flag was found, please enable memory64");
  66. wasm_loader_set_error_buf(error_buf, error_buf_size,
  67. "invalid limits flags", is_aot);
  68. return false;
  69. }
  70. #endif
  71. }
  72. if (mem_flag > MAX_PAGE_COUNT_FLAG + SHARED_MEMORY_FLAG + MEMORY64_FLAG) {
  73. wasm_loader_set_error_buf(error_buf, error_buf_size,
  74. "invalid limits flags", is_aot);
  75. return false;
  76. }
  77. else if ((mem_flag & SHARED_MEMORY_FLAG)
  78. && !(mem_flag & MAX_PAGE_COUNT_FLAG)) {
  79. wasm_loader_set_error_buf(error_buf, error_buf_size,
  80. "shared memory must have maximum", is_aot);
  81. return false;
  82. }
  83. return true;
  84. }
  85. bool
  86. wasm_table_check_flags(const uint8 table_flag, char *error_buf,
  87. uint32 error_buf_size, bool is_aot)
  88. {
  89. /* Check whether certain features indicated by mem_flag are enabled in
  90. * runtime */
  91. if (table_flag > MAX_TABLE_SIZE_FLAG) {
  92. if (table_flag & SHARED_TABLE_FLAG) {
  93. wasm_loader_set_error_buf(error_buf, error_buf_size,
  94. "tables cannot be shared", is_aot);
  95. }
  96. #if WASM_ENABLE_MEMORY64 == 0
  97. if (table_flag & TABLE64_FLAG) {
  98. wasm_loader_set_error_buf(error_buf, error_buf_size,
  99. "invalid limits flags(table64 flag was "
  100. "found, please enable memory64)",
  101. is_aot);
  102. return false;
  103. }
  104. #endif
  105. }
  106. if (table_flag > MAX_TABLE_SIZE_FLAG + TABLE64_FLAG) {
  107. wasm_loader_set_error_buf(error_buf, error_buf_size,
  108. "invalid limits flags", is_aot);
  109. return false;
  110. }
  111. return true;
  112. }
  113. /*
  114. * compare with a bigger type set in `wasm_value_type_size_internal()`,
  115. * this function will only cover global value type, function's param
  116. * value type and function's result value type.
  117. *
  118. * please feel free to add more if there are more requirements
  119. */
  120. bool
  121. is_valid_value_type(uint8 type)
  122. {
  123. if (/* I32/I64/F32/F64, 0x7C to 0x7F */
  124. (type >= VALUE_TYPE_F64 && type <= VALUE_TYPE_I32)
  125. #if WASM_ENABLE_GC != 0
  126. /* reference types, 0x65 to 0x70 */
  127. || wasm_is_type_reftype(type)
  128. #elif WASM_ENABLE_REF_TYPES != 0
  129. || (type == VALUE_TYPE_FUNCREF || type == VALUE_TYPE_EXTERNREF)
  130. #endif
  131. #if WASM_ENABLE_SIMD != 0
  132. || type == VALUE_TYPE_V128 /* 0x7B */
  133. #endif
  134. )
  135. return true;
  136. return false;
  137. }
  138. bool
  139. is_valid_value_type_for_interpreter(uint8 value_type)
  140. {
  141. #if (WASM_ENABLE_WAMR_COMPILER == 0) && (WASM_ENABLE_JIT == 0) \
  142. && (WASM_ENABLE_SIMDE == 0)
  143. /*
  144. * Note: regardless of WASM_ENABLE_SIMD, our classic interpreters don't
  145. * have SIMD implemented.
  146. *
  147. * WASM_ENABLE_SIMDE is used to control SIMD feaure in fast interpreter
  148. */
  149. if (value_type == VALUE_TYPE_V128)
  150. return false;
  151. #endif
  152. return is_valid_value_type(value_type);
  153. }
  154. bool
  155. is_valid_func_type(const WASMFuncType *func_type)
  156. {
  157. unsigned i;
  158. for (i = 0;
  159. i < (unsigned)(func_type->param_count + func_type->result_count);
  160. i++) {
  161. if (!is_valid_value_type(func_type->types[i]))
  162. return false;
  163. }
  164. return true;
  165. }
  166. bool
  167. is_valid_packed_type(uint8 packed_type)
  168. {
  169. return packed_type == PACKED_TYPE_I8 || packed_type == PACKED_TYPE_I16;
  170. }
  171. bool
  172. is_valid_field_type(uint8 field_type)
  173. {
  174. if (is_valid_value_type(field_type) || is_valid_packed_type(field_type))
  175. return true;
  176. return false;
  177. }
  178. /*
  179. * Indices are represented as a u32.
  180. */
  181. bool
  182. is_indices_overflow(uint32 import, uint32 other, char *error_buf,
  183. uint32 error_buf_size)
  184. {
  185. if (import > UINT32_MAX - other) {
  186. snprintf(error_buf, error_buf_size,
  187. "too many items in the index space(%" PRIu32 "+%" PRIu32 ").",
  188. import, other);
  189. return true;
  190. }
  191. return false;
  192. }
  193. bool
  194. read_leb(uint8 **p_buf, const uint8 *buf_end, uint32 maxbits, bool sign,
  195. uint64 *p_result, char *error_buf, uint32 error_buf_size)
  196. {
  197. size_t offset = 0;
  198. bh_leb_read_status_t status =
  199. bh_leb_read(*p_buf, buf_end, maxbits, sign, p_result, &offset);
  200. switch (status) {
  201. case BH_LEB_READ_SUCCESS:
  202. *p_buf += offset;
  203. return true;
  204. case BH_LEB_READ_TOO_LONG:
  205. wasm_loader_set_error_buf(error_buf, error_buf_size,
  206. "integer representation too long", false);
  207. return false;
  208. case BH_LEB_READ_OVERFLOW:
  209. wasm_loader_set_error_buf(error_buf, error_buf_size,
  210. "integer too large", false);
  211. return false;
  212. case BH_LEB_READ_UNEXPECTED_END:
  213. wasm_loader_set_error_buf(error_buf, error_buf_size,
  214. "unexpected end", false);
  215. return false;
  216. default:
  217. bh_assert(false);
  218. return false;
  219. }
  220. }
  221. #if WASM_ENABLE_EXTENDED_CONST_EXPR != 0
  222. void
  223. destroy_init_expr_recursive(InitializerExpression *expr)
  224. {
  225. if (expr == NULL) {
  226. return;
  227. }
  228. if (is_expr_binary_op(expr->init_expr_type)) {
  229. destroy_init_expr_recursive(expr->u.binary.l_expr);
  230. destroy_init_expr_recursive(expr->u.binary.r_expr);
  231. }
  232. wasm_runtime_free(expr);
  233. }
  234. #endif /* end of WASM_ENABLE_EXTENDED_CONST_EXPR != 0 */