Skip to content

Commit 84ce666

Browse files
committed
Output relocation for table index
* Add relocation types: * R_WASM_MEMORY_ADDR_SLEB * R_WASM_TABLE_NUMBER_LEB * Relocation type for `i32.const` is `sleb` * Handle multiple output for same function (`main`)
1 parent 5900aa3 commit 84ce666

13 files changed

Lines changed: 238 additions & 117 deletions

File tree

src/_debug/wcc-ld.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
static void init(void) {
1414
functypes = new_vector();
1515
tags = new_vector();
16+
tables = new_vector();
1617
table_init(&indirect_function_table);
1718
}
1819

src/util/util.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -538,6 +538,16 @@ void data_string(DataStorage *data, const void *str, size_t len) {
538538
data_append(data, (const unsigned char*)str, len);
539539
}
540540

541+
void data_varint32(DataStorage *data, ssize_t pos, int64_t val) {
542+
unsigned char buf[5], *p = buf;
543+
for (int i = 0; i < 4; ++i) {
544+
*p++ = (val & 0x7f) | 0x80;
545+
val >>= 7;
546+
}
547+
*p++ = val & 0x7f;
548+
data_insert(data, pos, buf, p - buf);
549+
}
550+
541551
void data_varuint32(DataStorage *data, ssize_t pos, uint64_t val) {
542552
unsigned char buf[5], *p = buf;
543553
for (int i = 0; i < 4; ++i) {

src/util/util.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,7 @@ void data_uleb128(DataStorage *data, ssize_t pos, uint64_t val);
9898
void data_string(DataStorage *data, const void *str, size_t len);
9999
void data_open_chunk(DataStorage *data);
100100
void data_close_chunk(DataStorage *data, ssize_t num);
101+
void data_varint32(DataStorage *data, ssize_t pos, int64_t val);
101102
void data_varuint32(DataStorage *data, ssize_t pos, uint64_t val);
102103

103104
// StringBuffer

src/wcc/emit_wasm.c

Lines changed: 25 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -264,15 +264,17 @@ static void emit_import_section(EmitWasm *ew) {
264264
data_uleb128(&imports_section, -1, 0); // size
265265
++imports_count;
266266
}
267-
if (indirect_function_table.count > 0 || (compile_unit_flag & CUF_INDIRECT_CALL)) {
268-
static const char kTableName[] = "__indirect_function_table";
269-
data_string(&imports_section, env_module_name, sizeof(env_module_name) - 1); // import module name
270-
data_string(&imports_section, kTableName, sizeof(kTableName) - 1); // import name
271-
data_push(&imports_section, IMPORT_TABLE); // import kind
272-
data_push(&imports_section, WT_FUNCREF);
273-
data_push(&imports_section, 0x00); // limits: flags
274-
data_leb128(&imports_section, -1, INDIRECT_FUNCTION_TABLE_START_INDEX); // initial
275-
++imports_count;
267+
if (tables->len > 0) {
268+
for (int i = 0; i < tables->len; ++i) {
269+
TableInfo *t = tables->data[i];
270+
data_string(&imports_section, env_module_name, sizeof(env_module_name) - 1); // import module name
271+
data_string(&imports_section, t->name->chars, t->name->bytes); // import name
272+
data_push(&imports_section, IMPORT_TABLE); // import kind
273+
data_push(&imports_section, t->type);
274+
data_push(&imports_section, 0x00); // limits: flags
275+
data_leb128(&imports_section, -1, INDIRECT_FUNCTION_TABLE_START_INDEX); // initial
276+
++imports_count;
277+
}
276278
}
277279

278280
{
@@ -655,6 +657,16 @@ static void emit_linking_section(EmitWasm *ew) {
655657
++count;
656658
}
657659
}
660+
if (tables->len > 0) { // Table
661+
for (int i = 0, len = tables->len; i < len; ++i) {
662+
TableInfo *ti = tables->data[i];
663+
int flags = WASM_SYM_UNDEFINED | WASM_SYM_EXPORTED | WASM_SYM_NO_STRIP;
664+
data_push(&linking_section, SIK_SYMTAB_TABLE); // kind
665+
data_uleb128(&linking_section, -1, flags);
666+
data_uleb128(&linking_section, -1, ti->index);
667+
++count;
668+
}
669+
}
658670
if (tags->len > 0) { // Tag
659671
for (int i = 0, len = tags->len; i < len; ++i) {
660672
TagInfo *ti = tags->data[i];
@@ -739,13 +751,15 @@ static void emit_reloc_section(EmitWasm *ew, int section_index, Vector *relocs,
739751
data_uleb128(&ds, -1, reloc->index);
740752
switch (reloc->type) {
741753
case R_WASM_MEMORY_ADDR_LEB:
742-
case R_WASM_MEMORY_ADDR_SLEB:
743754
case R_WASM_MEMORY_ADDR_I32:
744755
case R_WASM_MEMORY_ADDR_LEB64:
745-
case R_WASM_MEMORY_ADDR_SLEB64:
746756
case R_WASM_MEMORY_ADDR_I64:
747757
case R_WASM_FUNCTION_OFFSET_I32:
748758
case R_WASM_SECTION_OFFSET_I32:
759+
data_uleb128(&ds, -1, reloc->addend);
760+
break;
761+
case R_WASM_MEMORY_ADDR_SLEB:
762+
case R_WASM_MEMORY_ADDR_SLEB64:
749763
data_leb128(&ds, -1, reloc->addend);
750764
break;
751765
default: break;

src/wcc/gen_wasm.c

Lines changed: 24 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727

2828
#define ADD_LEB128(x) data_leb128(CODE, -1, x)
2929
#define ADD_ULEB128(x) data_uleb128(CODE, -1, x)
30+
#define ADD_VARINT32(x) data_varint32(CODE, -1, x)
3031
#define ADD_VARUINT32(x) data_varuint32(CODE, -1, x)
3132

3233
// TODO: Endian.
@@ -389,19 +390,29 @@ static void gen_funcall(Expr *expr) {
389390
gen_funcall_by_name(func->var.name);
390391
} else {
391392
gen_expr(func, true);
392-
int index = get_func_type_index(functype);
393-
assert(index >= 0);
394393
ADD_CODE(OP_CALL_INDIRECT);
394+
395395
FuncExtra *extra = curfunc->extra;
396396
DataStorage *code = extra->code;
397-
RelocInfo *ri = calloc_or_die(sizeof(*ri));
398-
ri->type = R_WASM_TYPE_INDEX_LEB;
399-
ri->index = index;
400-
ri->offset = code->len;
401-
vec_push(extra->reloc_code, ri);
402-
403-
ADD_VARUINT32(index);
404-
ADD_ULEB128(0); // table index
397+
{
398+
int index = get_func_type_index(functype);
399+
assert(index >= 0);
400+
RelocInfo *ri = calloc_or_die(sizeof(*ri));
401+
ri->type = R_WASM_TYPE_INDEX_LEB;
402+
ri->index = index;
403+
ri->offset = code->len;
404+
vec_push(extra->reloc_code, ri);
405+
ADD_VARUINT32(index);
406+
}
407+
{
408+
TableInfo *ti = getsert_indirect_function_table();
409+
RelocInfo *ri = calloc_or_die(sizeof(*ri));
410+
ri->type = R_WASM_TABLE_NUMBER_LEB;
411+
ri->index = ti->symbol_index;
412+
ri->offset = code->len;
413+
vec_push(extra->reloc_code, ri);
414+
ADD_VARUINT32(ti->index); // table index
415+
}
405416
}
406417
}
407418

@@ -459,21 +470,21 @@ static void gen_ref_sub(Expr *expr) {
459470
ri->index = info->index; // Assume that symtab index is same as function index.
460471
vec_push(extra->reloc_code, ri);
461472

462-
ADD_VARUINT32(info->indirect_index);
473+
ADD_VARINT32(info->indirect_index);
463474
} else {
464475
GVarInfo *info = get_gvar_info(expr);
465476
assert(info != NULL);
466477
ADD_CODE(OP_I32_CONST);
467478
FuncExtra *extra = curfunc->extra;
468479
DataStorage *code = extra->code;
469480
RelocInfo *ri = calloc_or_die(sizeof(*ri));
470-
ri->type = R_WASM_MEMORY_ADDR_LEB;
481+
ri->type = R_WASM_MEMORY_ADDR_SLEB;
471482
ri->offset = code->len;
472483
ri->addend = 0;
473484
ri->index = info->symbol_index;
474485
vec_push(extra->reloc_code, ri);
475486

476-
ADD_VARUINT32(info->non_prim.address);
487+
ADD_VARINT32(info->non_prim.address);
477488
}
478489
} else {
479490
VReg *vreg = varinfo->local.vreg;

src/wcc/traverse.c

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,7 @@ static uint32_t register_indirect_function(const Name *name) {
130130
info = register_func_info(name, NULL, NULL, FF_INDIRECT | FF_REFERRED);
131131
uint32_t index = indirect_function_table.count;
132132
table_put(&indirect_function_table, name, info);
133+
getsert_indirect_function_table();
133134
return index;
134135
}
135136

@@ -208,7 +209,7 @@ static void traverse_func_expr(Expr **pexpr) {
208209
assert(type != NULL && type->kind == TY_FUNC);
209210
getsert_func_type_index(type, true);
210211
traverse_expr(pexpr, true);
211-
compile_unit_flag |= CUF_INDIRECT_CALL;
212+
getsert_indirect_function_table();
212213
}
213214
}
214215

@@ -958,6 +959,12 @@ void traverse_ast(Vector *decls) {
958959
}
959960
}
960961

962+
// Table
963+
for (int i = 0, len = tables->len; i < len; ++i) {
964+
TableInfo *ti = tables->data[i];
965+
ti->symbol_index = symbol_index++;
966+
}
967+
961968
// Tag
962969
for (int i = 0, len = tags->len; i < len; ++i) {
963970
TagInfo *ti = tags->data[i];

0 commit comments

Comments
 (0)