Skip to content

Commit

Permalink
Merge branch 'feature/wasm-linker'
Browse files Browse the repository at this point in the history
  • Loading branch information
tyfkda committed Feb 28, 2024
2 parents 82c19c2 + b2c60e3 commit ac55b9d
Show file tree
Hide file tree
Showing 17 changed files with 1,592 additions and 24 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ libsrc/_wasm/libc.c

*.wasm
/wcc
/wcc-ld
/cc.wasm
/gen3cc.wasm
/tests/*.wasm
Expand Down
13 changes: 11 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ test-libs: all
clean:
rm -rf $(EXES) $(OBJ_DIR) a.out gen2* gen3* tmp.s \
dump_expr* dump_ir* dump_type* \
wcc cc.wasm a.wasm public release $(WCC_LIBS)
wcc wcc-ld cc.wasm a.wasm public release $(WCC_LIBS)
@$(MAKE) -C libsrc clean
@$(MAKE) -C tests clean

Expand Down Expand Up @@ -201,14 +201,23 @@ WCC_LIBS:=$(LIBSRC_DIR)/_wasm/crt0.c $(LIBSRC_DIR)/_wasm/libc.c
wcc: $(PARENT_DEPS) $(WCC_OBJS) $(WCC_LIBS)
$(CC) -o $@ $(WCC_OBJS) $(LDFLAGS)

WCCLD_SRCS:=$(DEBUG_DIR)/wcc-ld.c $(WCC_DIR)/wasm_linker.c \
$(WCC_DIR)/wcc_util.c $(WCC_DIR)/emit_wasm.c $(WCC_DIR)/traverse.c $(WCC_DIR)/traverse_setjmp.c \
$(wildcard $(CC1_FE_DIR)/*.c) \
$(UTIL_DIR)/util.c $(UTIL_DIR)/table.c
WCCLD_OBJS:=$(addprefix $(WCC_OBJ_DIR)/,$(notdir $(WCCLD_SRCS:.c=.o)))

wcc-ld: $(WCCLD_OBJS)
$(CC) -o $@ $(WCCLD_OBJS) $(LDFLAGS)

-include $(WCC_OBJ_DIR)/*.d

define DEFINE_WCCOBJ_TARGET
$(WCC_OBJ_DIR)/%.o: $(1)/%.c $(PARENT_DEPS)
@mkdir -p $(WCC_OBJ_DIR)
$(CC) $(WCC_CFLAGS) -DXCC_TARGET_ARCH=XCC_ARCH_WASM -c -o $$@ $$<
endef
WCC_SRC_DIRS:=$(WCC_DIR) $(CC1_FE_DIR) $(CC1_BE_DIR) $(CC1_DIR) $(CPP_DIR) $(UTIL_DIR)
WCC_SRC_DIRS:=$(WCC_DIR) $(DEBUG_DIR) $(CC1_FE_DIR) $(CC1_BE_DIR) $(CC1_DIR) $(CPP_DIR) $(UTIL_DIR)
$(foreach D, $(WCC_SRC_DIRS), $(eval $(call DEFINE_WCCOBJ_TARGET,$(D))))

WCC_CRT0_SRCS:=$(wildcard $(LIBSRC_DIR)/_wasm/crt0/*.c)
Expand Down
2 changes: 1 addition & 1 deletion libsrc/_wasm/unistd/clock_gettime.c
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#include "time.h"

#include "stddef.h" // NULL
#include "stdint.h"
#include "../wasi.h"

int clock_gettime(clockid_t clk_id, struct timespec *tp) {
if (tp == NULL)
Expand Down
1 change: 1 addition & 0 deletions libsrc/_wasm/unistd/lseek.c
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#include "unistd.h"
#include "../wasi.h"

off_t lseek(int fd, off_t offset, int whence) {
size_t size;
Expand Down
1 change: 1 addition & 0 deletions libsrc/_wasm/unistd/time.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#include "time.h"
#include "stddef.h" // NULL
#include "stdint.h"
#include "../wasi.h"

time_t time(time_t *timer) {
uint64_t t;
Expand Down
1 change: 1 addition & 0 deletions libsrc/_wasm/unistd/unlink.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#include "unistd.h"
#include "errno.h"
#include "string.h"
#include "../wasi.h"

extern int max_preopen_fd;
Expand Down
96 changes: 96 additions & 0 deletions src/_debug/wcc-ld.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
#include "../config.h"

#include <assert.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h> // atoi

#include "../wcc/wasm.h"
#include "../wcc/wasm_linker.h"
#include "../wcc/wcc.h"
#include "table.h"
#include "util.h"

static void init(void) {
out_type = OutExecutable;
functypes = new_vector();
tags = new_vector();
table_init(&indirect_function_table);
}

int main(int argc, char *argv[]) {
const char *ofn = "a.wasm";
const char *entry_point = "_start";
uint32_t stack_size = DEFAULT_STACK_SIZE;

init();

enum {
OPT_VERBOSE = 256,
OPT_ENTRY_POINT,
OPT_STACK_SIZE,
};
static const struct option options[] = {
{"o", required_argument}, // Specify output filename
{"-verbose", no_argument, OPT_VERBOSE},
{"-entry-point", required_argument, OPT_ENTRY_POINT},
{"-stack-size", required_argument, OPT_STACK_SIZE},

{NULL},
};

int opt;
while ((opt = optparse(argc, argv, options)) != -1) {
switch (opt) {
default: assert(false); break;
case 'o':
ofn = optarg;
break;
case OPT_VERBOSE:
verbose = true;
break;
case OPT_ENTRY_POINT:
entry_point = optarg;
break;
case OPT_STACK_SIZE:
{
int size = atoi(optarg);
if (size <= 0) {
error("stack-size must be positive");
}
stack_size = size;
}
break;
case '?':
fprintf(stderr, "Warning: unknown option: %s\n", argv[optind - 1]);
break;
}
}
int iarg = optind;

WasmLinker linker_body;
WasmLinker *linker = &linker_body;
linker_init(linker);

bool result = true;
for (int i = iarg; i < argc; ++i) {
const char *src = argv[i];
if (!read_wasm_obj(linker, src)) {
fprintf(stderr, "error: failed to read wasm object file: %s\n", src);
result = false;
break;
}
}
if (!result)
return 1;

Vector *exports = new_vector();
if (*entry_point != '\0')
vec_push(exports, alloc_name(entry_point, NULL, false));

if (!link_wasm_objs(linker, exports, stack_size) ||
!linker_emit_wasm(linker, ofn, exports))
return 1;

return 0;
}
20 changes: 10 additions & 10 deletions src/wcc/emit_wasm.c
Original file line number Diff line number Diff line change
Expand Up @@ -310,14 +310,14 @@ static void emit_import_section(EmitWasm *ew) {
const char *module_name = ew->import_module_name;
size_t module_name_len = strlen(module_name);

for (int i = 0, len = global_scope->vars->len; i < len; ++i) {
VarInfo *varinfo = global_scope->vars->data[i];
if (varinfo->storage & VS_ENUM_MEMBER || varinfo->type->kind == TY_FUNC)
continue;
if (is_global_datsec_var(varinfo, global_scope))
const Name *name;
GVarInfo *info;
for (int it = 0; (it = table_iterate(&gvar_info_table, it, &name, (void**)&info)) != -1; ) {
if (!(info->flag & GVF_UNRESOLVED))
continue;
GVarInfo *info = get_gvar_info_from_name(varinfo->name);
if (info == NULL || !(info->flag & GVF_UNRESOLVED))
VarInfo *varinfo = info->varinfo;
if (varinfo->storage & VS_ENUM_MEMBER || varinfo->type->kind == TY_FUNC ||
is_global_datsec_var(varinfo, global_scope))
continue;

const Name *name = varinfo->name;
Expand Down Expand Up @@ -729,10 +729,10 @@ static void emit_linking_section(EmitWasm *ew) {
if (tags->len > 0) { // Tag
for (int i = 0, len = tags->len; i < len; ++i) {
TagInfo *ti = tags->data[i];
int flags = 0;
int flags = WASM_SYM_BINDING_WEAK;
data_push(&linking_section, SIK_SYMTAB_EVENT); // kind
data_uleb128(&linking_section, -1, flags);
data_uleb128(&linking_section, -1, i);
data_uleb128(&linking_section, -1, ti->typeindex);
data_string(&linking_section, ti->name->chars, ti->name->bytes);
++count;
}
Expand Down Expand Up @@ -790,7 +790,7 @@ static void emit_reloc_section(EmitWasm *ew, int section_index, Vector *relocs,
case R_WASM_MEMORY_ADDR_I64:
case R_WASM_FUNCTION_OFFSET_I32:
case R_WASM_SECTION_OFFSET_I32:
data_uleb128(&ds, -1, reloc->addend);
data_leb128(&ds, -1, reloc->addend);
break;
default: break;
}
Expand Down
2 changes: 1 addition & 1 deletion src/wcc/gen_wasm.c
Original file line number Diff line number Diff line change
Expand Up @@ -482,7 +482,7 @@ static void gen_ref_sub(Expr *expr) {
RelocInfo *ri = calloc_or_die(sizeof(*ri));
ri->type = R_WASM_TABLE_INDEX_SLEB;
ri->offset = code->len;
ri->index = info->index;
ri->index = info->index; // Assume that symtab index is same as function index.
vec_push(extra->reloc_code, ri);

ADD_VARUINT32(info->indirect_index);
Expand Down
4 changes: 2 additions & 2 deletions src/wcc/traverse.c
Original file line number Diff line number Diff line change
Expand Up @@ -579,9 +579,9 @@ static void traverse_vardecl(Stmt *stmt) {
register_func_info(decl->ident, NULL, varinfo, 0);
} else if (varinfo->storage & VS_EXTERN) {
assert(!is_global_scope(curscope));
if (out_type < OutExecutable) {
if (out_type < OutExecutable && scope_find(global_scope, decl->ident, NULL) == NULL) {
// Register into global to output linking information.
GVarInfo *info = register_gvar_info(decl->ident, varinfo); // TODO: Confirm.
GVarInfo *info = register_gvar_info(decl->ident, varinfo);
info->flag |= GVF_UNRESOLVED;
}
}
Expand Down
Loading

0 comments on commit ac55b9d

Please sign in to comment.