style: formatting
This commit is contained in:
parent
bce3e3bf25
commit
906b2d03e3
469
wai.c
469
wai.c
|
@ -3,8 +3,8 @@
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: GPL-3.0
|
* SPDX-License-Identifier: GPL-3.0
|
||||||
*
|
*
|
||||||
* This program, named WAI, is a WebAssembly Interpreter.
|
* This program, named WAI, is a WebAssembly Interpreter.
|
||||||
* Compile using make.
|
* Compile using make.
|
||||||
* Usage: wai [FILE.wasm]
|
* Usage: wai [FILE.wasm]
|
||||||
*
|
*
|
||||||
* Copyright (C) 2025 orangrot <me@orangerot.dev>
|
* Copyright (C) 2025 orangrot <me@orangerot.dev>
|
||||||
|
@ -24,12 +24,12 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <endian.h>
|
#include <endian.h>
|
||||||
|
#include <inttypes.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <inttypes.h>
|
|
||||||
|
|
||||||
enum section {
|
enum section {
|
||||||
Section_Custom,
|
Section_Custom,
|
||||||
|
@ -94,42 +94,40 @@ enum INSTRUCTION {
|
||||||
INSTR_F64_SUB = 0xa1,
|
INSTR_F64_SUB = 0xa1,
|
||||||
INSTR_IF = 0x04,
|
INSTR_IF = 0x04,
|
||||||
INSTR_LOCAL_GET = 0x20,
|
INSTR_LOCAL_GET = 0x20,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum TYPE {
|
enum TYPE {
|
||||||
TYPE_I32 = 0x7F,
|
TYPE_I32 = 0x7F,
|
||||||
TYPE_I64 = 0x7E,
|
TYPE_I64 = 0x7E,
|
||||||
TYPE_F32 = 0x7D,
|
TYPE_F32 = 0x7D,
|
||||||
TYPE_F64 = 0x7C,
|
TYPE_F64 = 0x7C,
|
||||||
TYPE_V128= 0x7B,
|
TYPE_V128 = 0x7B,
|
||||||
TYPE_FUNCREF = 0x70,
|
TYPE_FUNCREF = 0x70,
|
||||||
TYPE_EXTERNREF = 0x6F
|
TYPE_EXTERNREF = 0x6F
|
||||||
};
|
};
|
||||||
|
|
||||||
static const int TYPE_SIZE[] = {
|
static const int TYPE_SIZE[] = {
|
||||||
[TYPE_I32] = 4,
|
[TYPE_I32] = 4, [TYPE_I64] = 8, [TYPE_F32] = 4, [TYPE_F64] = 8,
|
||||||
[TYPE_I64] = 8,
|
[TYPE_V128] = 16, [TYPE_FUNCREF] = 16, [TYPE_EXTERNREF] = 16};
|
||||||
[TYPE_F32] = 4,
|
|
||||||
[TYPE_F64] = 8,
|
|
||||||
[TYPE_V128] = 16,
|
|
||||||
[TYPE_FUNCREF] = 16,
|
|
||||||
[TYPE_EXTERNREF] = 16
|
|
||||||
};
|
|
||||||
|
|
||||||
struct value_t {
|
struct value_t {
|
||||||
enum TYPE type;
|
enum TYPE type;
|
||||||
union {
|
union {
|
||||||
int32_t i32;
|
int32_t i32;
|
||||||
int64_t i64;
|
int64_t i64;
|
||||||
float f32;
|
float f32;
|
||||||
double f64;
|
double f64;
|
||||||
__int128 v128;
|
__int128 v128;
|
||||||
int64_t funcref;
|
int64_t funcref;
|
||||||
int64_t extref;
|
int64_t extref;
|
||||||
} value;
|
} value;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define incr(i, len) i++; if (i >= len) {return -1;}
|
#define incr(i, len) \
|
||||||
|
i++; \
|
||||||
|
if (i >= len) { \
|
||||||
|
return -1; \
|
||||||
|
}
|
||||||
|
|
||||||
void stack_push(struct stack *s, const struct value_t *value) {
|
void stack_push(struct stack *s, const struct value_t *value) {
|
||||||
size_t type_size = TYPE_SIZE[value->type];
|
size_t type_size = TYPE_SIZE[value->type];
|
||||||
|
@ -144,37 +142,38 @@ void stack_push(struct stack *s, const struct value_t *value) {
|
||||||
void *value = &s->items[i - type_size];
|
void *value = &s->items[i - type_size];
|
||||||
|
|
||||||
switch (t) {
|
switch (t) {
|
||||||
case TYPE_I32:
|
case TYPE_I32:
|
||||||
printf("%d (I32)", *(int32_t*)value);
|
printf("%d (I32)", *(int32_t *)value);
|
||||||
break;
|
break;
|
||||||
case TYPE_I64:
|
case TYPE_I64:
|
||||||
printf("%ld (I32)", *(int64_t*)value);
|
printf("%ld (I32)", *(int64_t *)value);
|
||||||
break;
|
break;
|
||||||
case TYPE_F32:
|
case TYPE_F32:
|
||||||
printf("%f (F32)", *(float*)value);
|
printf("%f (F32)", *(float *)value);
|
||||||
break;
|
break;
|
||||||
case TYPE_F64:
|
case TYPE_F64:
|
||||||
printf("%f (F64)", *(double*)value);
|
printf("%f (F64)", *(double *)value);
|
||||||
break;
|
break;
|
||||||
case TYPE_V128:
|
case TYPE_V128:
|
||||||
printf("%ld (V128)", *(__int128*)value);
|
printf("%ld (V128)", *(__int128 *)value);
|
||||||
break;
|
break;
|
||||||
case TYPE_FUNCREF:
|
case TYPE_FUNCREF:
|
||||||
printf("%ld (EREF)", *(int64_t*)value);
|
printf("%ld (EREF)", *(int64_t *)value);
|
||||||
break;
|
break;
|
||||||
case TYPE_EXTERNREF:
|
case TYPE_EXTERNREF:
|
||||||
printf("%ld (EREF)", *(int64_t*)value);
|
printf("%ld (EREF)", *(int64_t *)value);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
printf(", ");
|
printf(", ");
|
||||||
}
|
}
|
||||||
printf("\n");
|
printf("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
void stack_top(struct stack *s, struct value_t *value) {
|
void stack_top(struct stack *s, struct value_t *value) {
|
||||||
value->type = s->items[s->bytes-1];
|
value->type = s->items[s->bytes - 1];
|
||||||
memcpy(&value->value, &(s->items[s->bytes - 1 - TYPE_SIZE[value->type]]), TYPE_SIZE[value->type]);
|
memcpy(&value->value, &(s->items[s->bytes - 1 - TYPE_SIZE[value->type]]),
|
||||||
}
|
TYPE_SIZE[value->type]);
|
||||||
|
}
|
||||||
|
|
||||||
void stack_pop(struct stack *s, struct value_t *value) {
|
void stack_pop(struct stack *s, struct value_t *value) {
|
||||||
stack_top(s, value);
|
stack_top(s, value);
|
||||||
|
@ -187,24 +186,26 @@ int parse_type(u_char *binary, int len) {
|
||||||
printf("type %x\n", param);
|
printf("type %x\n", param);
|
||||||
incr(i, len);
|
incr(i, len);
|
||||||
switch (param) {
|
switch (param) {
|
||||||
case TYPE_I32:
|
case TYPE_I32:
|
||||||
case TYPE_I64:
|
case TYPE_I64:
|
||||||
case TYPE_F32:
|
case TYPE_F32:
|
||||||
case TYPE_F64:
|
case TYPE_F64:
|
||||||
case TYPE_V128:
|
case TYPE_V128:
|
||||||
case TYPE_FUNCREF:
|
case TYPE_FUNCREF:
|
||||||
case TYPE_EXTERNREF:
|
case TYPE_EXTERNREF:
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
|
||||||
int parse_function(struct module *module, u_char *binary, double param, int len);
|
int parse_function(struct module *module, u_char *binary, double param,
|
||||||
int parse_instruction(struct module *module, u_char *binary, double param, int len) {
|
int len);
|
||||||
|
int parse_instruction(struct module *module, u_char *binary, double param,
|
||||||
|
int len) {
|
||||||
int i = 0;
|
int i = 0;
|
||||||
enum INSTRUCTION instr = (u_char) binary[i];
|
enum INSTRUCTION instr = (u_char)binary[i];
|
||||||
u_char *instr_addr = &binary[i];
|
u_char *instr_addr = &binary[i];
|
||||||
struct value_t a = {0};
|
struct value_t a = {0};
|
||||||
struct value_t b = {0};
|
struct value_t b = {0};
|
||||||
|
@ -213,94 +214,97 @@ int parse_instruction(struct module *module, u_char *binary, double param, int l
|
||||||
incr(i, len);
|
incr(i, len);
|
||||||
|
|
||||||
switch (instr) {
|
switch (instr) {
|
||||||
case INSTR_CALL: {
|
case INSTR_CALL: {
|
||||||
int func_index = binary[i];
|
int func_index = binary[i];
|
||||||
incr(i, len);
|
incr(i, len);
|
||||||
stack_pop(&module->stack, &a);
|
stack_pop(&module->stack, &a);
|
||||||
parse_function(module, module->funcs[func_index], a.value.f64, len);
|
parse_function(module, module->funcs[func_index], a.value.f64, len);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case INSTR_ELSE:
|
case INSTR_ELSE:
|
||||||
printf("reached else instruction: impossible!\n");
|
printf("reached else instruction: impossible!\n");
|
||||||
case INSTR_END:
|
case INSTR_END:
|
||||||
break;
|
break;
|
||||||
case INSTR_F64_CONST:
|
case INSTR_F64_CONST:
|
||||||
result.type = TYPE_F64;
|
result.type = TYPE_F64;
|
||||||
result.value.f64 = *(double*)&binary[i];
|
result.value.f64 = *(double *)&binary[i];
|
||||||
i += 8;
|
i += 8;
|
||||||
stack_push(&module->stack, &result);
|
stack_push(&module->stack, &result);
|
||||||
break;
|
break;
|
||||||
case INSTR_F64_LT: {
|
case INSTR_F64_LT: {
|
||||||
stack_pop(&module->stack, &a);
|
stack_pop(&module->stack, &a);
|
||||||
stack_pop(&module->stack, &b);
|
stack_pop(&module->stack, &b);
|
||||||
if (a.type != TYPE_F64 || b.type != TYPE_F64)
|
if (a.type != TYPE_F64 || b.type != TYPE_F64)
|
||||||
printf("Wrong types!\n");
|
printf("Wrong types!\n");
|
||||||
result.type = TYPE_F64;
|
result.type = TYPE_F64;
|
||||||
result.value.f64 = b.value.f64 < a.value.f64;
|
result.value.f64 = b.value.f64 < a.value.f64;
|
||||||
stack_push(&module->stack, &result);
|
stack_push(&module->stack, &result);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case INSTR_F64_MUL: {
|
case INSTR_F64_MUL: {
|
||||||
stack_pop(&module->stack, &a);
|
stack_pop(&module->stack, &a);
|
||||||
stack_pop(&module->stack, &b);
|
stack_pop(&module->stack, &b);
|
||||||
if (a.type != TYPE_F64 || b.type != TYPE_F64)
|
if (a.type != TYPE_F64 || b.type != TYPE_F64)
|
||||||
printf("Wrong types!\n");
|
printf("Wrong types!\n");
|
||||||
result.type = TYPE_F64;
|
result.type = TYPE_F64;
|
||||||
result.value.f64 = a.value.f64 * b.value.f64;
|
result.value.f64 = a.value.f64 * b.value.f64;
|
||||||
stack_push(&module->stack, &result);
|
stack_push(&module->stack, &result);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case INSTR_F64_SUB: {
|
case INSTR_F64_SUB: {
|
||||||
stack_pop(&module->stack, &a);
|
stack_pop(&module->stack, &a);
|
||||||
stack_pop(&module->stack, &b);
|
stack_pop(&module->stack, &b);
|
||||||
if (a.type != TYPE_F64 || b.type != TYPE_F64)
|
if (a.type != TYPE_F64 || b.type != TYPE_F64)
|
||||||
printf("Wrong types!\n");
|
printf("Wrong types!\n");
|
||||||
result.type = TYPE_F64;
|
result.type = TYPE_F64;
|
||||||
result.value.f64 = b.value.f64 - a.value.f64;
|
result.value.f64 = b.value.f64 - a.value.f64;
|
||||||
stack_push(&module->stack, &result);
|
stack_push(&module->stack, &result);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case INSTR_IF: {
|
case INSTR_IF: {
|
||||||
stack_pop(&module->stack, &a);
|
stack_pop(&module->stack, &a);
|
||||||
enum TYPE condition_type = binary[i];
|
enum TYPE condition_type = binary[i];
|
||||||
incr(i, len);
|
incr(i, len);
|
||||||
if (a.type != condition_type)
|
if (a.type != condition_type)
|
||||||
printf("Wrong types!\n");
|
printf("Wrong types!\n");
|
||||||
|
|
||||||
while (binary[i] != INSTR_ELSE) {
|
while (binary[i] != INSTR_ELSE) {
|
||||||
// TODO test condition with correct type.
|
// TODO test condition with correct type.
|
||||||
// This might not matter since all types are false with 0x0
|
// This might not matter since all types are false with 0x0
|
||||||
if (a.value.i64) {
|
if (a.value.i64) {
|
||||||
i += parse_instruction(module, &binary[i], param, len);
|
i += parse_instruction(module, &binary[i], param, len);
|
||||||
} else {
|
} else {
|
||||||
incr(i, len);
|
incr(i, len);
|
||||||
}
|
|
||||||
}
|
|
||||||
incr(i, len);
|
|
||||||
while (binary[i] != INSTR_END) {
|
|
||||||
if (a.value.i64) {
|
|
||||||
incr(i, len);
|
|
||||||
} else {
|
|
||||||
i += parse_instruction(module, &binary[i], param, len);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
incr(i, len);
|
}
|
||||||
break;
|
incr(i, len);
|
||||||
|
while (binary[i] != INSTR_END) {
|
||||||
|
if (a.value.i64) {
|
||||||
|
incr(i, len);
|
||||||
|
} else {
|
||||||
|
i += parse_instruction(module, &binary[i], param, len);
|
||||||
}
|
}
|
||||||
case INSTR_LOCAL_GET: {
|
}
|
||||||
int local_index = binary[i];
|
incr(i, len);
|
||||||
incr(i, len);
|
break;
|
||||||
stack_push(&module->stack, &(struct value_t) {.value.f64 = param, .type = TYPE_F64});
|
}
|
||||||
break;
|
case INSTR_LOCAL_GET: {
|
||||||
}
|
int local_index = binary[i];
|
||||||
default:
|
incr(i, len);
|
||||||
printf("unknown instruction! %x at %lx\n", instr, instr_addr - module->binary);
|
stack_push(&module->stack,
|
||||||
exit(1);
|
&(struct value_t){.value.f64 = param, .type = TYPE_F64});
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
printf("unknown instruction! %x at %lx\n", instr,
|
||||||
|
instr_addr - module->binary);
|
||||||
|
exit(1);
|
||||||
}
|
}
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
|
||||||
int parse_function(struct module *module, u_char *binary, double param, int len) {
|
int parse_function(struct module *module, u_char *binary, double param,
|
||||||
|
int len) {
|
||||||
int i = 0;
|
int i = 0;
|
||||||
int body_size = binary[i];
|
int body_size = binary[i];
|
||||||
incr(i, len);
|
incr(i, len);
|
||||||
|
@ -322,98 +326,102 @@ int parse_section(struct module *module, u_char *binary, int len) {
|
||||||
incr(i, len);
|
incr(i, len);
|
||||||
printf("section %x with size %d\n", type, size);
|
printf("section %x with size %d\n", type, size);
|
||||||
|
|
||||||
switch ((enum section) type) {
|
switch ((enum section)type) {
|
||||||
case Section_Custom:
|
case Section_Custom:
|
||||||
break;
|
break;
|
||||||
case Section_Type:
|
case Section_Type:
|
||||||
printf("section: type\n");
|
printf("section: type\n");
|
||||||
int num_types = binary[i];
|
int num_types = binary[i];
|
||||||
incr(i, len);
|
incr(i, len);
|
||||||
for (int type_i = 0; type_i < num_types; type_i++) {
|
for (int type_i = 0; type_i < num_types; type_i++) {
|
||||||
if (binary[i] != 0x60) {
|
if (binary[i] != 0x60) {
|
||||||
printf("expected function type, found %x\n", binary[i]);
|
printf("expected function type, found %x\n", binary[i]);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
|
||||||
incr(i, len);
|
|
||||||
int num_params = binary[i];
|
|
||||||
incr(i, len);
|
|
||||||
for (int params_i = 0; params_i < num_params; params_i++) {
|
|
||||||
i += (parse_type(&binary[i], len));
|
|
||||||
}
|
|
||||||
int num_results = binary[i];
|
|
||||||
incr(i, len);
|
|
||||||
for (int results_i = 0; results_i < num_results; results_i++) {
|
|
||||||
i += (parse_type(&binary[i], len));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case Section_Import:
|
|
||||||
break;
|
|
||||||
case Section_Function:
|
|
||||||
printf("section: function\n");
|
|
||||||
int num_functions = binary[i];
|
|
||||||
incr(i, len);
|
|
||||||
for (int function_i = 0; function_i < num_functions; function_i++) {
|
|
||||||
incr(i, len);
|
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
case Section_Table:
|
|
||||||
break;
|
|
||||||
case Section_Memory:
|
|
||||||
break;
|
|
||||||
case Section_Global:
|
|
||||||
break;
|
|
||||||
case Section_Export:
|
|
||||||
printf("section: exports\n");
|
|
||||||
int num_exports = binary[i];
|
|
||||||
|
|
||||||
if(num_exports > MAX_FUNCTIONS) {
|
|
||||||
printf("Number of exports exceeds maximum number of functions in a module (%d)", MAX_FUNCTIONS);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
incr(i, len);
|
incr(i, len);
|
||||||
for (int exports_i = 0; exports_i < num_exports; exports_i++) {
|
int num_params = binary[i];
|
||||||
struct export_t *export = &module->exports[i];
|
incr(i, len);
|
||||||
|
for (int params_i = 0; params_i < num_params; params_i++) {
|
||||||
|
i += (parse_type(&binary[i], len));
|
||||||
|
}
|
||||||
|
int num_results = binary[i];
|
||||||
|
incr(i, len);
|
||||||
|
for (int results_i = 0; results_i < num_results; results_i++) {
|
||||||
|
i += (parse_type(&binary[i], len));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case Section_Import:
|
||||||
|
break;
|
||||||
|
case Section_Function:
|
||||||
|
printf("section: function\n");
|
||||||
|
int num_functions = binary[i];
|
||||||
|
incr(i, len);
|
||||||
|
for (int function_i = 0; function_i < num_functions; function_i++) {
|
||||||
|
incr(i, len);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case Section_Table:
|
||||||
|
break;
|
||||||
|
case Section_Memory:
|
||||||
|
break;
|
||||||
|
case Section_Global:
|
||||||
|
break;
|
||||||
|
case Section_Export:
|
||||||
|
printf("section: exports\n");
|
||||||
|
int num_exports = binary[i];
|
||||||
|
|
||||||
export->name_length = binary[i];
|
if (num_exports > MAX_FUNCTIONS) {
|
||||||
incr(i, len);
|
printf("Number of exports exceeds maximum number of functions in a "
|
||||||
|
"module (%d)",
|
||||||
for (int si = 0; si < export->name_length; si++) {
|
MAX_FUNCTIONS);
|
||||||
export->name[si] = binary[i];
|
return -1;
|
||||||
incr(i, len);
|
}
|
||||||
}
|
|
||||||
export->description = (int) binary[i];
|
incr(i, len);
|
||||||
incr(i, len);
|
for (int exports_i = 0; exports_i < num_exports; exports_i++) {
|
||||||
export->index = (uint32_t) binary[i];
|
struct export_t *export = &module->exports[i];
|
||||||
printf("export name: %s of type %d\n", export->name, export->description);
|
|
||||||
incr(i, len);
|
export->name_length = binary[i];
|
||||||
}
|
|
||||||
break;
|
|
||||||
case Section_Start:
|
|
||||||
break;
|
|
||||||
case Section_Element:
|
|
||||||
break;
|
|
||||||
case Section_Code:
|
|
||||||
printf("section: code\n");
|
|
||||||
int num_functions2 = binary[i];
|
|
||||||
incr(i, len);
|
incr(i, len);
|
||||||
for (int function_i = 0; function_i < num_functions2; function_i++) {
|
|
||||||
module->funcs[function_i] = &binary[i];
|
for (size_t si = 0; si < export->name_length; si++) {
|
||||||
i += parse_function(module, &binary[i], 4, len);
|
export->name[si] = binary[i];
|
||||||
|
incr(i, len);
|
||||||
}
|
}
|
||||||
// printf("result: %f\n", module->stack.items[0]);
|
export->description = (int)binary[i];
|
||||||
break;
|
incr(i, len);
|
||||||
case Section_Data:
|
export->index = (uint32_t)binary[i];
|
||||||
break;
|
printf("export name: %s of type %d\n", export->name, export->description);
|
||||||
case Section_Data_Count:
|
incr(i, len);
|
||||||
break;
|
}
|
||||||
default:
|
break;
|
||||||
fprintf(stderr, "expectet section\n");
|
case Section_Start:
|
||||||
exit(1);
|
break;
|
||||||
|
case Section_Element:
|
||||||
|
break;
|
||||||
|
case Section_Code:
|
||||||
|
printf("section: code\n");
|
||||||
|
int num_functions2 = binary[i];
|
||||||
|
incr(i, len);
|
||||||
|
for (int function_i = 0; function_i < num_functions2; function_i++) {
|
||||||
|
module->funcs[function_i] = &binary[i];
|
||||||
|
i += parse_function(module, &binary[i], 4, len);
|
||||||
|
}
|
||||||
|
// printf("result: %f\n", module->stack.items[0]);
|
||||||
|
break;
|
||||||
|
case Section_Data:
|
||||||
|
break;
|
||||||
|
case Section_Data_Count:
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
fprintf(stderr, "expectet section\n");
|
||||||
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (size == 0x0) {incr(i, len);}
|
if (size == 0x0) {
|
||||||
|
incr(i, len);
|
||||||
|
}
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -421,14 +429,14 @@ int parse_module(u_char *binary, size_t len) {
|
||||||
int i = 0;
|
int i = 0;
|
||||||
char *magic = "\0asm";
|
char *magic = "\0asm";
|
||||||
while (i < 4) {
|
while (i < 4) {
|
||||||
if ((char) binary[i] != magic[i]) {
|
if ((char)binary[i] != magic[i]) {
|
||||||
fprintf(stderr, "no wasm magic\n");
|
fprintf(stderr, "no wasm magic\n");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
incr(i, len);
|
incr(i, len);
|
||||||
}
|
}
|
||||||
printf("magic found\n");
|
printf("magic found\n");
|
||||||
printf("wasm version: %d\n", le32toh(*(int*)&binary[i]));
|
printf("wasm version: %d\n", le32toh(*(int *)&binary[i]));
|
||||||
i += 4;
|
i += 4;
|
||||||
printf("addr %d\n", i);
|
printf("addr %d\n", i);
|
||||||
|
|
||||||
|
@ -442,7 +450,7 @@ int parse_module(u_char *binary, size_t len) {
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char **argv) {
|
int main(int argc, char **argv) {
|
||||||
|
|
||||||
if (argc != 2) {
|
if (argc != 2) {
|
||||||
fprintf(stderr, "Usage: %s [file]\n", argv[0]);
|
fprintf(stderr, "Usage: %s [file]\n", argv[0]);
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -456,16 +464,15 @@ int main(int argc, char **argv) {
|
||||||
struct stat st;
|
struct stat st;
|
||||||
stat(argv[1], &st);
|
stat(argv[1], &st);
|
||||||
printf("size: %ld\n", st.st_size);
|
printf("size: %ld\n", st.st_size);
|
||||||
|
|
||||||
u_char *binary = malloc(st.st_size);
|
u_char *binary = malloc(st.st_size);
|
||||||
fread(binary, st.st_size, 1, file);
|
fread(binary, st.st_size, 1, file);
|
||||||
|
|
||||||
if (parse_module(binary, st.st_size) == -1) {
|
if (parse_module(binary, st.st_size) == -1) {
|
||||||
printf("error :(\n");
|
printf("error :(\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
free(binary);
|
free(binary);
|
||||||
fclose(file);
|
fclose(file);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue