Skip to content

Commit

Permalink
Harmonize memory64/table64 limit checking and types
Browse files Browse the repository at this point in the history
  • Loading branch information
keithw committed Nov 11, 2024
1 parent 765b47d commit 2ece28b
Show file tree
Hide file tree
Showing 9 changed files with 239 additions and 288 deletions.
75 changes: 33 additions & 42 deletions src/prebuilt/wasm2c_source_declarations.cc
Original file line number Diff line number Diff line change
Expand Up @@ -165,15 +165,28 @@ R"w2c_template( (CHECK_CALL_INDIRECT(table, ft, x), \
R"w2c_template( DO_CALL_INDIRECT(table, t, x, __VA_ARGS__))
)w2c_template"
R"w2c_template(
#ifdef SUPPORT_MEMORY64
#if __has_builtin(__builtin_add_overflow)
)w2c_template"
R"w2c_template(#define RANGE_CHECK(mem, offset, len) \
R"w2c_template(#define add_overflow(a, b, resptr) __builtin_add_overflow(a, b, resptr)
)w2c_template"
R"w2c_template(#else /* MSVC */
)w2c_template"
R"w2c_template(static inline bool add_overflow(uint64_t a, uint64_t b, uint64_t* resptr) {
)w2c_template"
R"w2c_template( return _addcarry_u64(0, a, b, resptr);
)w2c_template"
R"w2c_template(}
)w2c_template"
R"w2c_template(#endif
)w2c_template"
R"w2c_template(
#define RANGE_CHECK(mem, offset, len) \
)w2c_template"
R"w2c_template( do { \
)w2c_template"
R"w2c_template( uint64_t res; \
)w2c_template"
R"w2c_template( if (__builtin_add_overflow(offset, len, &res)) \
R"w2c_template( if (UNLIKELY(add_overflow(offset, len, &res))) \
)w2c_template"
R"w2c_template( TRAP(OOB); \
)w2c_template"
Expand All @@ -183,16 +196,6 @@ R"w2c_template( TRAP(OOB); \
)w2c_template"
R"w2c_template( } while (0);
)w2c_template"
R"w2c_template(#else
)w2c_template"
R"w2c_template(#define RANGE_CHECK(mem, offset, len) \
)w2c_template"
R"w2c_template( if (UNLIKELY(offset + (uint64_t)len > mem->size)) \
)w2c_template"
R"w2c_template( TRAP(OOB);
)w2c_template"
R"w2c_template(#endif
)w2c_template"
R"w2c_template(
#if WASM_RT_USE_SEGUE_FOR_THIS_MODULE && WASM_RT_SANITY_CHECKS
)w2c_template"
Expand Down Expand Up @@ -976,7 +979,7 @@ R"w2c_template( return sqrtf(x);
R"w2c_template(}
)w2c_template"
R"w2c_template(
static inline void memory_fill(wasm_rt_memory_t* mem, u32 d, u32 val, u32 n) {
static inline void memory_fill(wasm_rt_memory_t* mem, u64 d, u32 val, u64 n) {
)w2c_template"
R"w2c_template( RANGE_CHECK(mem, d, n);
)w2c_template"
Expand All @@ -989,11 +992,11 @@ static inline void memory_copy(wasm_rt_memory_t* dest,
)w2c_template"
R"w2c_template( const wasm_rt_memory_t* src,
)w2c_template"
R"w2c_template( u32 dest_addr,
R"w2c_template( u64 dest_addr,
)w2c_template"
R"w2c_template( u32 src_addr,
R"w2c_template( u64 src_addr,
)w2c_template"
R"w2c_template( u32 n) {
R"w2c_template( u64 n) {
)w2c_template"
R"w2c_template( RANGE_CHECK(dest, dest_addr, n);
)w2c_template"
Expand All @@ -1010,7 +1013,7 @@ R"w2c_template( const u8* src,
)w2c_template"
R"w2c_template( u32 src_size,
)w2c_template"
R"w2c_template( u32 dest_addr,
R"w2c_template( u64 dest_addr,
)w2c_template"
R"w2c_template( u32 src_addr,
)w2c_template"
Expand Down Expand Up @@ -1046,7 +1049,7 @@ R"w2c_template( const wasm_elem_segment_exp
)w2c_template"
R"w2c_template( u32 src_size,
)w2c_template"
R"w2c_template( u32 dest_addr,
R"w2c_template( u64 dest_addr,
)w2c_template"
R"w2c_template( u32 src_addr,
)w2c_template"
Expand All @@ -1058,9 +1061,7 @@ R"w2c_template( if (UNLIKELY(src_addr + (uint64_t)n > src_size))
)w2c_template"
R"w2c_template( TRAP(OOB);
)w2c_template"
R"w2c_template( if (UNLIKELY(dest_addr + (uint64_t)n > dest->size))
)w2c_template"
R"w2c_template( TRAP(OOB);
R"w2c_template( RANGE_CHECK(dest, dest_addr, n);
)w2c_template"
R"w2c_template( for (u32 i = 0; i < n; i++) {
)w2c_template"
Expand Down Expand Up @@ -1107,7 +1108,7 @@ R"w2c_template(static inline void externref_table_init(wasm_rt_externref_table_t
)w2c_template"
R"w2c_template( u32 src_size,
)w2c_template"
R"w2c_template( u32 dest_addr,
R"w2c_template( u64 dest_addr,
)w2c_template"
R"w2c_template( u32 src_addr,
)w2c_template"
Expand All @@ -1117,9 +1118,7 @@ R"w2c_template( if (UNLIKELY(src_addr + (uint64_t)n > src_size))
)w2c_template"
R"w2c_template( TRAP(OOB);
)w2c_template"
R"w2c_template( if (UNLIKELY(dest_addr + (uint64_t)n > dest->size))
)w2c_template"
R"w2c_template( TRAP(OOB);
R"w2c_template( RANGE_CHECK(dest, dest_addr, n);
)w2c_template"
R"w2c_template( for (u32 i = 0; i < n; i++) {
)w2c_template"
Expand All @@ -1136,17 +1135,11 @@ R"w2c_template( static inline void type##_table_copy(wasm_rt_##type##_table_t*
)w2c_template"
R"w2c_template( const wasm_rt_##type##_table_t* src, \
)w2c_template"
R"w2c_template( u32 dest_addr, u32 src_addr, u32 n) { \
)w2c_template"
R"w2c_template( if (UNLIKELY(dest_addr + (uint64_t)n > dest->size)) \
R"w2c_template( u64 dest_addr, u64 src_addr, u64 n) { \
)w2c_template"
R"w2c_template( TRAP(OOB); \
R"w2c_template( RANGE_CHECK(dest, dest_addr, n); \
)w2c_template"
R"w2c_template( if (UNLIKELY(src_addr + (uint64_t)n > src->size)) \
)w2c_template"
R"w2c_template( TRAP(OOB); \
)w2c_template"
R"w2c_template( \
R"w2c_template( RANGE_CHECK(src, src_addr, n); \
)w2c_template"
R"w2c_template( memmove(dest->data + dest_addr, src->data + src_addr, \
)w2c_template"
Expand All @@ -1164,7 +1157,7 @@ R"w2c_template(
)w2c_template"
R"w2c_template( static inline wasm_rt_##type##_t type##_table_get( \
)w2c_template"
R"w2c_template( const wasm_rt_##type##_table_t* table, u32 i) { \
R"w2c_template( const wasm_rt_##type##_table_t* table, u64 i) { \
)w2c_template"
R"w2c_template( if (UNLIKELY(i >= table->size)) \
)w2c_template"
Expand All @@ -1184,7 +1177,7 @@ R"w2c_template(
)w2c_template"
R"w2c_template( static inline void type##_table_set(const wasm_rt_##type##_table_t* table, \
)w2c_template"
R"w2c_template( u32 i, const wasm_rt_##type##_t val) { \
R"w2c_template( u64 i, const wasm_rt_##type##_t val) { \
)w2c_template"
R"w2c_template( if (UNLIKELY(i >= table->size)) \
)w2c_template"
Expand All @@ -1204,13 +1197,11 @@ R"w2c_template(
)w2c_template"
R"w2c_template( static inline void type##_table_fill(const wasm_rt_##type##_table_t* table, \
)w2c_template"
R"w2c_template( u32 d, const wasm_rt_##type##_t val, \
)w2c_template"
R"w2c_template( u32 n) { \
R"w2c_template( u64 d, const wasm_rt_##type##_t val, \
)w2c_template"
R"w2c_template( if (UNLIKELY((uint64_t)d + n > table->size)) \
R"w2c_template( u64 n) { \
)w2c_template"
R"w2c_template( TRAP(OOB); \
R"w2c_template( RANGE_CHECK(table, d, n); \
)w2c_template"
R"w2c_template( for (uint32_t i = d; i < d + n; i++) { \
)w2c_template"
Expand Down
56 changes: 26 additions & 30 deletions src/template/wasm2c.declarations.c
Original file line number Diff line number Diff line change
Expand Up @@ -89,20 +89,22 @@ static inline bool func_types_eq(const wasm_rt_func_type_t a,
(CHECK_CALL_INDIRECT(table, ft, x), \
DO_CALL_INDIRECT(table, t, x, __VA_ARGS__))

#ifdef SUPPORT_MEMORY64
#if __has_builtin(__builtin_add_overflow)
#define add_overflow(a, b, resptr) __builtin_add_overflow(a, b, resptr)
#else /* MSVC */
static inline bool add_overflow(uint64_t a, uint64_t b, uint64_t* resptr) {
return _addcarry_u64(0, a, b, resptr);
}
#endif

#define RANGE_CHECK(mem, offset, len) \
do { \
uint64_t res; \
if (__builtin_add_overflow(offset, len, &res)) \
if (UNLIKELY(add_overflow(offset, len, &res))) \
TRAP(OOB); \
if (UNLIKELY(res > mem->size)) \
TRAP(OOB); \
} while (0);
#else
#define RANGE_CHECK(mem, offset, len) \
if (UNLIKELY(offset + (uint64_t)len > mem->size)) \
TRAP(OOB);
#endif

#if WASM_RT_USE_SEGUE_FOR_THIS_MODULE && WASM_RT_SANITY_CHECKS
#include <stdio.h>
Expand Down Expand Up @@ -523,16 +525,16 @@ static float wasm_sqrtf(float x) {
return sqrtf(x);
}

static inline void memory_fill(wasm_rt_memory_t* mem, u32 d, u32 val, u32 n) {
static inline void memory_fill(wasm_rt_memory_t* mem, u64 d, u32 val, u64 n) {
RANGE_CHECK(mem, d, n);
memset(MEM_ADDR(mem, d, n), val, n);
}

static inline void memory_copy(wasm_rt_memory_t* dest,
const wasm_rt_memory_t* src,
u32 dest_addr,
u32 src_addr,
u32 n) {
u64 dest_addr,
u64 src_addr,
u64 n) {
RANGE_CHECK(dest, dest_addr, n);
RANGE_CHECK(src, src_addr, n);
memmove(MEM_ADDR(dest, dest_addr, n), MEM_ADDR(src, src_addr, n), n);
Expand All @@ -541,7 +543,7 @@ static inline void memory_copy(wasm_rt_memory_t* dest,
static inline void memory_init(wasm_rt_memory_t* dest,
const u8* src,
u32 src_size,
u32 dest_addr,
u64 dest_addr,
u32 src_addr,
u32 n) {
if (UNLIKELY(src_addr + (uint64_t)n > src_size))
Expand All @@ -560,14 +562,13 @@ typedef struct {
static inline void funcref_table_init(wasm_rt_funcref_table_t* dest,
const wasm_elem_segment_expr_t* src,
u32 src_size,
u32 dest_addr,
u64 dest_addr,
u32 src_addr,
u32 n,
void* module_instance) {
if (UNLIKELY(src_addr + (uint64_t)n > src_size))
TRAP(OOB);
if (UNLIKELY(dest_addr + (uint64_t)n > dest->size))
TRAP(OOB);
RANGE_CHECK(dest, dest_addr, n);
for (u32 i = 0; i < n; i++) {
const wasm_elem_segment_expr_t* const src_expr = &src[src_addr + i];
wasm_rt_funcref_t* const dest_val = &(dest->data[dest_addr + i]);
Expand All @@ -591,13 +592,12 @@ static inline void funcref_table_init(wasm_rt_funcref_table_t* dest,
// Currently wasm2c only supports initializing externref tables with ref.null.
static inline void externref_table_init(wasm_rt_externref_table_t* dest,
u32 src_size,
u32 dest_addr,
u64 dest_addr,
u32 src_addr,
u32 n) {
if (UNLIKELY(src_addr + (uint64_t)n > src_size))
TRAP(OOB);
if (UNLIKELY(dest_addr + (uint64_t)n > dest->size))
TRAP(OOB);
RANGE_CHECK(dest, dest_addr, n);
for (u32 i = 0; i < n; i++) {
dest->data[dest_addr + i] = wasm_rt_externref_null_value;
}
Expand All @@ -606,12 +606,9 @@ static inline void externref_table_init(wasm_rt_externref_table_t* dest,
#define DEFINE_TABLE_COPY(type) \
static inline void type##_table_copy(wasm_rt_##type##_table_t* dest, \
const wasm_rt_##type##_table_t* src, \
u32 dest_addr, u32 src_addr, u32 n) { \
if (UNLIKELY(dest_addr + (uint64_t)n > dest->size)) \
TRAP(OOB); \
if (UNLIKELY(src_addr + (uint64_t)n > src->size)) \
TRAP(OOB); \
\
u64 dest_addr, u64 src_addr, u64 n) { \
RANGE_CHECK(dest, dest_addr, n); \
RANGE_CHECK(src, src_addr, n); \
memmove(dest->data + dest_addr, src->data + src_addr, \
n * sizeof(wasm_rt_##type##_t)); \
}
Expand All @@ -621,7 +618,7 @@ DEFINE_TABLE_COPY(externref)

#define DEFINE_TABLE_GET(type) \
static inline wasm_rt_##type##_t type##_table_get( \
const wasm_rt_##type##_table_t* table, u32 i) { \
const wasm_rt_##type##_table_t* table, u64 i) { \
if (UNLIKELY(i >= table->size)) \
TRAP(OOB); \
return table->data[i]; \
Expand All @@ -632,7 +629,7 @@ DEFINE_TABLE_GET(externref)

#define DEFINE_TABLE_SET(type) \
static inline void type##_table_set(const wasm_rt_##type##_table_t* table, \
u32 i, const wasm_rt_##type##_t val) { \
u64 i, const wasm_rt_##type##_t val) { \
if (UNLIKELY(i >= table->size)) \
TRAP(OOB); \
table->data[i] = val; \
Expand All @@ -643,10 +640,9 @@ DEFINE_TABLE_SET(externref)

#define DEFINE_TABLE_FILL(type) \
static inline void type##_table_fill(const wasm_rt_##type##_table_t* table, \
u32 d, const wasm_rt_##type##_t val, \
u32 n) { \
if (UNLIKELY((uint64_t)d + n > table->size)) \
TRAP(OOB); \
u64 d, const wasm_rt_##type##_t val, \
u64 n) { \
RANGE_CHECK(table, d, n); \
for (uint32_t i = d; i < d + n; i++) { \
table->data[i] = val; \
} \
Expand Down
Loading

0 comments on commit 2ece28b

Please sign in to comment.