Browse Source

fix sgx compile and link error, preserve space for locals before set/tee opcode (#214)

Co-authored-by: Xu Jun <jun1.xu@intel.com>
Xu Jun 5 years ago
parent
commit
75009a2421

+ 2 - 1
.gitignore

@@ -3,4 +3,5 @@
 core/deps/lv_drivers
 core/deps/llvm
 core/deps/lvgl
-core/shared/mem-alloc/tlsf
+core/shared/mem-alloc/tlsf
+

+ 178 - 124
core/iwasm/interpreter/wasm_loader.c

@@ -1620,9 +1620,9 @@ load_from_sections(WASMModule *module, WASMSection *sections,
 
                 if (llvm_data_end_global && llvm_heap_base_global) {
                     if ((data_end_global_index == heap_base_global_index + 1
-                         && data_end_global_index > 0)
+                         && (int32)data_end_global_index > 1)
                         || (heap_base_global_index == data_end_global_index + 1
-                            && heap_base_global_index > 0)) {
+                            && (int32)heap_base_global_index > 1)) {
                         global_index =
                             data_end_global_index < heap_base_global_index
                             ? data_end_global_index - 1 : heap_base_global_index - 1;
@@ -2716,6 +2716,128 @@ wasm_loader_check_br(WASMLoaderContext *ctx, uint32 depth,
 }
 
 #if WASM_ENABLE_FAST_INTERP != 0
+
+#if WASM_ENABLE_ABS_LABEL_ADDR != 0
+
+#define emit_label(opcode) do {                                     \
+    wasm_loader_emit_ptr(loader_ctx, handle_table[opcode]);         \
+    LOG_OP("\nemit_op [%02x]\t", opcode);                           \
+  } while (0)
+
+#define skip_label() do {                                           \
+    wasm_loader_emit_backspace(loader_ctx, sizeof(void *));         \
+    LOG_OP("\ndelete last op\n");                                   \
+  } while (0)
+
+#else
+
+#define emit_label(opcode) do {                                     \
+    int32 offset = (int32)(handle_table[opcode] - handle_table[0]); \
+    if (!(offset >= INT16_MIN && offset < INT16_MAX)) {             \
+        set_error_buf(error_buf, error_buf_size,                    \
+                      "WASM module load failed: "                   \
+                      "pre-compiled label offset out of range");    \
+        goto fail;                                                  \
+    }                                                               \
+    wasm_loader_emit_int16(loader_ctx, offset);                     \
+    LOG_OP("\nemit_op [%02x]\t", opcode);                           \
+  } while (0)
+
+// drop local.get / const / block / loop / end
+#define skip_label() do {                                           \
+    wasm_loader_emit_backspace(loader_ctx, sizeof(int16));          \
+    LOG_OP("\ndelete last op\n");                                   \
+  } while (0)
+
+#endif /* WASM_ENABLE_ABS_LABEL_ADDR */
+
+#define emit_empty_label_addr_and_frame_ip(type) do {               \
+    if (!add_label_patch_to_list(loader_ctx->frame_csp - 1, type,   \
+                                 loader_ctx->p_code_compiled,       \
+                                 error_buf, error_buf_size))        \
+        goto fail;                                                  \
+    /* label address, to be patched */                              \
+    wasm_loader_emit_ptr(loader_ctx, NULL);                         \
+  } while (0)
+
+#define emit_br_info(frame_csp) do {                                \
+    if (!wasm_loader_emit_br_info(loader_ctx, frame_csp,            \
+                                  error_buf, error_buf_size))       \
+        goto fail;                                                  \
+  } while (0)
+
+#define LAST_OP_OUTPUT_I32() (last_op >= WASM_OP_I32_EQZ                \
+                                && last_op <= WASM_OP_I32_ROTR)         \
+                            || (last_op == WASM_OP_I32_LOAD             \
+                                || last_op == WASM_OP_F32_LOAD)         \
+                            || (last_op >= WASM_OP_I32_LOAD8_S          \
+                                && last_op <= WASM_OP_I32_LOAD16_U)     \
+                            || (last_op >= WASM_OP_F32_ABS              \
+                                && last_op <= WASM_OP_F32_COPYSIGN)     \
+                            || (last_op >= WASM_OP_I32_WRAP_I64         \
+                                && last_op <= WASM_OP_I32_TRUNC_U_F64)  \
+                            || (last_op >= WASM_OP_F32_CONVERT_S_I32    \
+                                && last_op <= WASM_OP_F32_DEMOTE_F64)   \
+                            || (last_op == WASM_OP_I32_REINTERPRET_F32) \
+                            || (last_op == WASM_OP_F32_REINTERPRET_I32) \
+                            || (last_op == EXT_OP_COPY_STACK_TOP)
+
+#define LAST_OP_OUTPUT_I64() (last_op >= WASM_OP_I64_CLZ                \
+                                && last_op <= WASM_OP_I64_ROTR)         \
+                            || (last_op >= WASM_OP_F64_ABS              \
+                                && last_op <= WASM_OP_F64_COPYSIGN)     \
+                            || (last_op == WASM_OP_I64_LOAD             \
+                                || last_op == WASM_OP_F64_LOAD)         \
+                            || (last_op >= WASM_OP_I64_LOAD8_S          \
+                                && last_op <= WASM_OP_I64_LOAD32_U)     \
+                            || (last_op >= WASM_OP_I64_EXTEND_S_I32     \
+                                && last_op <= WASM_OP_I64_TRUNC_U_F64)  \
+                            || (last_op >= WASM_OP_F64_CONVERT_S_I32    \
+                                && last_op <= WASM_OP_F64_PROMOTE_F32)  \
+                            || (last_op == WASM_OP_I64_REINTERPRET_F64) \
+                            || (last_op == WASM_OP_F64_REINTERPRET_I64) \
+                            || (last_op == EXT_OP_COPY_STACK_TOP_I64)
+
+#define GET_CONST_OFFSET(type, val) do {                                \
+    if (!(wasm_loader_get_const_offset(loader_ctx, type,                \
+                                       val, 0, 0, &operand_offset,      \
+                                       error_buf, error_buf_size)))     \
+        goto fail;                                                      \
+  } while (0)
+
+#define GET_CONST_F32_OFFSET(type, fval) do {                           \
+    if (!(wasm_loader_get_const_offset(loader_ctx, type,                \
+                                       0, fval, 0, &operand_offset,     \
+                                       error_buf, error_buf_size)))     \
+        goto fail;                                                      \
+  } while (0)
+
+#define GET_CONST_F64_OFFSET(type, fval) do {                           \
+    if (!(wasm_loader_get_const_offset(loader_ctx, type,                \
+                                       0, 0, fval, &operand_offset,     \
+                                       error_buf, error_buf_size)))     \
+        goto fail;                                                      \
+  } while (0)
+
+#define emit_operand(ctx, offset) do {                              \
+    wasm_loader_emit_int16(ctx, offset);                            \
+    LOG_OP("%d\t", offset);                                         \
+  } while (0)
+
+#define emit_byte(ctx, byte) do {                                   \
+    wasm_loader_emit_uint8(ctx, byte);                              \
+    LOG_OP("%d\t", byte);                                           \
+  } while (0)
+
+#define emit_leb() do {                                             \
+    wasm_loader_emit_leb(loader_ctx, p_org, p);                     \
+  } while (0)
+
+#define emit_const(value) do {                                      \
+    GET_CONST_OFFSET(VALUE_TYPE_I32, value);                        \
+    emit_operand(loader_ctx, operand_offset);                       \
+  } while (0)
+
 static bool
 wasm_loader_ctx_reinit(WASMLoaderContext *ctx)
 {
@@ -2803,6 +2925,47 @@ wasm_loader_emit_leb(WASMLoaderContext *ctx, uint8* start, uint8* end)
 
 }
 
+static bool
+preserve_referenced_local(WASMLoaderContext *loader_ctx, uint8 opcode,
+                          uint32 local_index, uint32 local_type, bool *preserved,
+                          char *error_buf, uint32 error_buf_size)
+{
+    int16 preserved_offset = (int16)local_index;
+    *preserved = false;
+    for (uint32 i = 0; i < loader_ctx->stack_cell_num; i++) {
+        /* move previous local into dynamic space before a set/tee_local opcode */
+        if (loader_ctx->frame_offset_bottom[i] == (int16)local_index) {
+            if (preserved_offset == (int16)local_index) {
+                *preserved = true;
+                skip_label();
+                if (local_type == VALUE_TYPE_I32
+                    || local_type == VALUE_TYPE_F32) {
+                    preserved_offset = loader_ctx->dynamic_offset++;
+                    emit_label(EXT_OP_COPY_STACK_TOP);
+                }
+                else {
+                    preserved_offset = loader_ctx->dynamic_offset;
+                    loader_ctx->dynamic_offset += 2;
+                    emit_label(EXT_OP_COPY_STACK_TOP_I64);
+                }
+                emit_operand(loader_ctx, local_index);
+                emit_operand(loader_ctx, preserved_offset);
+                emit_label(opcode);
+                if (loader_ctx->dynamic_offset > loader_ctx->max_dynamic_offset)
+                    loader_ctx->max_dynamic_offset = loader_ctx->dynamic_offset;
+            }
+            loader_ctx->frame_offset_bottom[i] = preserved_offset;
+        }
+    }
+
+    return true;
+
+#if WASM_ENABLE_ABS_LABEL_ADDR == 0
+fail:
+    return false;
+#endif
+}
+
 static bool
 add_label_patch_to_list(BranchBlock *frame_csp,
                         uint8 patch_type, uint8 *p_code_compiled,
@@ -2858,25 +3021,6 @@ apply_label_patch(WASMLoaderContext *ctx, uint8 depth,
     }
 }
 
-#define emit_operand(ctx, offset) do {                              \
-    wasm_loader_emit_int16(ctx, offset);                            \
-    LOG_OP("%d\t", offset);                                         \
-  } while (0)
-
-#define emit_byte(ctx, byte) do {                                   \
-    wasm_loader_emit_uint8(ctx, byte);                               \
-    LOG_OP("%d\t", byte);                                           \
-  } while (0)
-
-#define emit_leb() do {                                             \
-    wasm_loader_emit_leb(loader_ctx, p_org, p);                     \
-  } while (0)
-
-#define emit_const(value) do {                                      \
-    GET_CONST_OFFSET(VALUE_TYPE_I32, value);                        \
-    emit_operand(loader_ctx, operand_offset);                       \
-  } while (0)
-
 static bool
 wasm_loader_emit_br_info(WASMLoaderContext *ctx, BranchBlock *frame_csp,
                          char *error_buf, uint32 error_buf_size)
@@ -3270,107 +3414,7 @@ check_memory(WASMModule *module,
   } while (0)
 
 #if WASM_ENABLE_FAST_INTERP != 0
-#if WASM_ENABLE_ABS_LABEL_ADDR != 0
-
-#define emit_label(opcode) do {                                     \
-    wasm_loader_emit_ptr(loader_ctx, handle_table[opcode]);         \
-    LOG_OP("\nemit_op [%02x]\t", opcode);                           \
-  } while (0)
-
-#define skip_label() do {                                           \
-    wasm_loader_emit_backspace(loader_ctx, sizeof(void *));         \
-    LOG_OP("\ndelete last op\n");                                   \
-  } while (0)
-
-#else
-
-#define emit_label(opcode) do {                                     \
-    int32 offset = (int32)(handle_table[opcode] - handle_table[0]); \
-    if (!(offset >= INT16_MIN && offset < INT16_MAX)) {             \
-        set_error_buf(error_buf, error_buf_size,                    \
-                      "WASM module load failed: "                   \
-                      "pre-compiled label offset out of range");    \
-        goto fail;                                                  \
-    }                                                               \
-    wasm_loader_emit_int16(loader_ctx, offset);                     \
-    LOG_OP("\nemit_op [%02x]\t", opcode);                           \
-  } while (0)
-
-// drop local.get / const / block / loop / end
-#define skip_label() do {                                           \
-    wasm_loader_emit_backspace(loader_ctx, sizeof(int16));          \
-    LOG_OP("\ndelete last op\n");                                   \
-  } while (0)
-
-#endif /* WASM_ENABLE_ABS_LABEL_ADDR */
-
-#define emit_empty_label_addr_and_frame_ip(type) do {               \
-    if (!add_label_patch_to_list(loader_ctx->frame_csp - 1, type,   \
-                                 loader_ctx->p_code_compiled,       \
-                                 error_buf, error_buf_size))        \
-        goto fail;                                                  \
-    /* label address, to be patched */                              \
-    wasm_loader_emit_ptr(loader_ctx, NULL);                         \
-  } while (0)
 
-#define emit_br_info(frame_csp) do {                                \
-    if (!wasm_loader_emit_br_info(loader_ctx, frame_csp,            \
-                                  error_buf, error_buf_size))       \
-        goto fail;                                                  \
-  } while (0)
-
-#define LAST_OP_OUTPUT_I32() (last_op >= WASM_OP_I32_EQZ                \
-                                && last_op <= WASM_OP_I32_ROTR)         \
-                            || (last_op == WASM_OP_I32_LOAD             \
-                                || last_op == WASM_OP_F32_LOAD)         \
-                            || (last_op >= WASM_OP_I32_LOAD8_S          \
-                                && last_op <= WASM_OP_I32_LOAD16_U)     \
-                            || (last_op >= WASM_OP_F32_ABS              \
-                                && last_op <= WASM_OP_F32_COPYSIGN)     \
-                            || (last_op >= WASM_OP_I32_WRAP_I64         \
-                                && last_op <= WASM_OP_I32_TRUNC_U_F64)  \
-                            || (last_op >= WASM_OP_F32_CONVERT_S_I32    \
-                                && last_op <= WASM_OP_F32_DEMOTE_F64)   \
-                            || (last_op == WASM_OP_I32_REINTERPRET_F32) \
-                            || (last_op == WASM_OP_F32_REINTERPRET_I32) \
-                            || (last_op == EXT_OP_COPY_STACK_TOP)
-
-#define LAST_OP_OUTPUT_I64() (last_op >= WASM_OP_I64_CLZ                \
-                                && last_op <= WASM_OP_I64_ROTR)         \
-                            || (last_op >= WASM_OP_F64_ABS              \
-                                && last_op <= WASM_OP_F64_COPYSIGN)     \
-                            || (last_op == WASM_OP_I64_LOAD             \
-                                || last_op == WASM_OP_F64_LOAD)         \
-                            || (last_op >= WASM_OP_I64_LOAD8_S          \
-                                && last_op <= WASM_OP_I64_LOAD32_U)     \
-                            || (last_op >= WASM_OP_I64_EXTEND_S_I32     \
-                                && last_op <= WASM_OP_I64_TRUNC_U_F64)  \
-                            || (last_op >= WASM_OP_F64_CONVERT_S_I32    \
-                                && last_op <= WASM_OP_F64_PROMOTE_F32)  \
-                            || (last_op == WASM_OP_I64_REINTERPRET_F64) \
-                            || (last_op == WASM_OP_F64_REINTERPRET_I64) \
-                            || (last_op == EXT_OP_COPY_STACK_TOP_I64)
-
-#define GET_CONST_OFFSET(type, val) do {                                \
-    if (!(wasm_loader_get_const_offset(loader_ctx, type,                \
-                                       val, 0, 0, &operand_offset,      \
-                                       error_buf, error_buf_size)))     \
-        goto fail;                                                      \
-  } while (0)
-
-#define GET_CONST_F32_OFFSET(type, fval) do {                           \
-    if (!(wasm_loader_get_const_offset(loader_ctx, type,                \
-                                       0, fval, 0, &operand_offset,     \
-                                       error_buf, error_buf_size)))     \
-        goto fail;                                                      \
-  } while (0)
-
-#define GET_CONST_F64_OFFSET(type, fval) do {                           \
-    if (!(wasm_loader_get_const_offset(loader_ctx, type,                \
-                                       0, 0, fval, &operand_offset,     \
-                                       error_buf, error_buf_size)))     \
-        goto fail;                                                      \
-  } while (0)
 
 #endif /* WASM_ENABLE_FAST_INTERP */
 
@@ -3395,7 +3439,7 @@ wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func,
     uint8 *func_const_end, *func_const;
     int16 operand_offset;
     uint8 last_op = 0;
-    bool disable_emit;
+    bool disable_emit, preserve_local = false;
     float32 f32;
     float64 f64;
 
@@ -3997,15 +4041,20 @@ handle_next_reachable_block:
                 POP_TYPE(local_type);
 
 #if WASM_ENABLE_FAST_INTERP != 0
+                if (!(preserve_referenced_local(loader_ctx, opcode, local_offset,
+                                                local_type, &preserve_local,
+                                                error_buf, error_buf_size)))
+                    goto fail;
+
                 if (local_offset < 256) {
                     skip_label();
-                    if (LAST_OP_OUTPUT_I32()) {
+                    if ((!preserve_local) && (LAST_OP_OUTPUT_I32())) {
                         if (loader_ctx->p_code_compiled)
                             *(int16*)(loader_ctx->p_code_compiled - 2) = local_offset;
                         loader_ctx->frame_offset --;
                         loader_ctx->dynamic_offset --;
                     }
-                    else if (LAST_OP_OUTPUT_I64()) {
+                    else if ((!preserve_local) && (LAST_OP_OUTPUT_I64())) {
                         if (loader_ctx->p_code_compiled)
                             *(int16*)(loader_ctx->p_code_compiled - 2) = local_offset;
                         loader_ctx->frame_offset -= 2;
@@ -4054,6 +4103,11 @@ handle_next_reachable_block:
                 PUSH_TYPE(local_type);
 
 #if WASM_ENABLE_FAST_INTERP != 0
+                if (!(preserve_referenced_local(loader_ctx, opcode, local_offset,
+                                                local_type, &preserve_local,
+                                                error_buf, error_buf_size)))
+                    goto fail;
+
                 if (local_offset < 256) {
                     skip_label();
                     if (local_type == VALUE_TYPE_I32

+ 13 - 8
core/shared/platform/linux-sgx/sgx_thread.c

@@ -24,21 +24,26 @@ int os_mutex_destroy(korp_mutex *mutex)
     return BHT_OK;
 }
 
-/* Returned error (EINVAL, EAGAIN and EDEADLK) from
- locking the mutex indicates some logic error present in
- the program somewhere.
- Don't try to recover error for an existing unknown error.*/
 void os_mutex_lock(korp_mutex *mutex)
 {
     sgx_thread_mutex_lock(mutex);
 }
 
-/* Returned error (EINVAL, EAGAIN and EPERM) from
- unlocking the mutex indicates some logic error present
- in the program somewhere.
- Don't try to recover error for an existing unknown error.*/
 void os_mutex_unlock(korp_mutex *mutex)
 {
     sgx_thread_mutex_unlock(mutex);
 }
 
+int os_cond_init(korp_cond *cond)
+{
+    sgx_thread_cond_t c = SGX_THREAD_COND_INITIALIZER;
+    *cond = c;
+    return BHT_OK;
+}
+
+int os_cond_destroy(korp_cond *cond)
+{
+    sgx_thread_cond_destroy(cond);
+    return BHT_OK;
+}
+

+ 2 - 2
core/shared/utils/bh_log.c

@@ -71,8 +71,8 @@ bh_print_time(const char *prompt)
 
     total_time_ms += curr_time_ms - last_time_ms;
 
-    printf("%-48s time of last stage: %u ms, total time: %u ms\n",
-           prompt, curr_time_ms - last_time_ms, total_time_ms);
+    os_printf("%-48s time of last stage: %u ms, total time: %u ms\n",
+              prompt, curr_time_ms - last_time_ms, total_time_ms);
 
     last_time_ms = curr_time_ms;
 }

+ 1 - 1
core/shared/utils/runtime_timer.c

@@ -230,7 +230,7 @@ timer_ctx_t create_timer_ctx(timer_callback_f timer_handler,
 
     return ctx;
 
-    cleanup:
+cleanup:
 
     if (ctx) {
         release_timer_list(&ctx->free_timers);