Skip to content

Commit 649fc8a

Browse files
committed
Add option: allow-undefined
1 parent 91e3acf commit 649fc8a

5 files changed

Lines changed: 60 additions & 5 deletions

File tree

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,8 @@ Command line options:
114114
* `-nodefaultlibs`: Ignore libc
115115
* `-nostdlib`: Ignore libc and crt0
116116
* `--verbose`: Output debug information
117+
* `-Wl,...`: Linker option
118+
* `--allow-undefined`: Handles unresolved function symbols as imported on runtime
117119

118120
#### Run
119121

src/_debug/wcc-ld.c

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,16 +28,22 @@ int main(int argc, char *argv[]) {
2828
OPT_VERBOSE = 256,
2929
OPT_ENTRY_POINT,
3030
OPT_STACK_SIZE,
31+
OPT_ALLOW_UNDEFINED,
3132
};
3233
static const struct option kOptions[] = {
3334
{"o", required_argument}, // Specify output filename
3435
{"-verbose", no_argument, OPT_VERBOSE},
3536
{"-entry-point", required_argument, OPT_ENTRY_POINT},
3637
{"-stack-size", required_argument, OPT_STACK_SIZE},
38+
{"-allow-undefined", no_argument, OPT_ALLOW_UNDEFINED},
3739

3840
{NULL},
3941
};
4042

43+
WasmLinker linker_body;
44+
WasmLinker *linker = &linker_body;
45+
linker_init(linker);
46+
4147
int opt;
4248
while ((opt = optparse(argc, argv, kOptions)) != -1) {
4349
switch (opt) {
@@ -69,17 +75,16 @@ int main(int argc, char *argv[]) {
6975
stack_size = size;
7076
}
7177
break;
78+
case OPT_ALLOW_UNDEFINED:
79+
linker->options.allow_undefined = true;
80+
break;
7281
case '?':
7382
fprintf(stderr, "Warning: unknown option: %s\n", argv[optind - 1]);
7483
break;
7584
}
7685
}
7786
int iarg = optind;
7887

79-
WasmLinker linker_body;
80-
WasmLinker *linker = &linker_body;
81-
linker_init(linker);
82-
8388
bool result = true;
8489
for (int i = iarg; i < argc; ++i) {
8590
const char *src = argv[i];

src/wcc/wasm_linker.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -767,7 +767,8 @@ static bool resolve_symbols(WasmLinker *linker) {
767767
switch (sym->kind) {
768768
default: assert(false); // Fallthrough to suppress warning.
769769
case SIK_SYMTAB_FUNCTION:
770-
if (sym->module_name != NULL && equal_name(sym->module_name, wasi_module_name)) {
770+
if ((sym->module_name != NULL && equal_name(sym->module_name, wasi_module_name)) ||
771+
linker->options.allow_undefined) {
771772
sym->combined_index = unresolved_func_count++;
772773
break;
773774
}
@@ -1218,6 +1219,7 @@ static void out_import_section(WasmLinker *linker) {
12181219
const Name *name;
12191220
SymbolInfo *sym;
12201221
for (int it = 0; (it = table_iterate(&linker->unresolved, it, &name, (void**)&sym)) != -1; ) {
1222+
assert(sym != NULL);
12211223
if (sym->kind != SIK_SYMTAB_FUNCTION)
12221224
continue;
12231225
const Name *modname = sym->module_name;

src/wcc/wasm_linker.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,19 @@ typedef struct Vector Vector;
1111

1212
#define WASI_MODULE_NAME "wasi_snapshot_preview1"
1313

14+
typedef struct {
15+
bool allow_undefined;
16+
} WasmLinkerOptions;
17+
1418
typedef struct {
1519
Vector *files; // <File*>
1620
Table defined, unresolved; // <SymbolInfo*>
1721
Vector *indirect_functions; // public/static indirect functions, <SymbolInfo*>
1822
uint32_t unresolved_func_count;
1923
uint32_t address_bottom;
2024

25+
WasmLinkerOptions options;
26+
2127
const Name *sp_name;
2228
const Name *curbrk_name;
2329
const Name *indirect_function_table_name;

src/wcc/wcc.c

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,8 @@ typedef struct {
4545
enum SourceType src_type;
4646
uint32_t stack_size;
4747
bool nodefaultlibs, nostdlib, nostdinc;
48+
49+
WasmLinkerOptions linker_opts;
4850
} Options;
4951

5052
static Vector remove_on_exit;
@@ -232,6 +234,38 @@ int compile_csource(const char *src, const char *ofn, Vector *obj_files, Options
232234
return 0;
233235
}
234236

237+
static void parse_linker_options(const char *arg, WasmLinkerOptions *lopts) {
238+
const char *arg_bak = arg;
239+
if (*arg != '-')
240+
return;
241+
++arg;
242+
243+
enum {
244+
OPT_ALLOW_UNDEFINED,
245+
};
246+
static const struct option kOptions[] = {
247+
{"-allow-undefined", no_argument, OPT_ALLOW_UNDEFINED},
248+
249+
{NULL},
250+
};
251+
252+
for (int i = 0; ; ++i) {
253+
if (kOptions[i].name == NULL)
254+
break;
255+
if (strcmp(arg, kOptions[i].name) == 0) {
256+
switch (kOptions[i].val) {
257+
default: assert(false); break;
258+
case OPT_ALLOW_UNDEFINED:
259+
lopts->allow_undefined = true;
260+
break;
261+
}
262+
return;
263+
}
264+
}
265+
fprintf(stderr, "Warning: unknown option: %s\n", arg_bak);
266+
}
267+
268+
235269
static void parse_options(int argc, char *argv[], Options *opts) {
236270
enum {
237271
OPT_HELP = 128,
@@ -470,6 +504,11 @@ static void parse_options(int argc, char *argv[], Options *opts) {
470504
*p = true;
471505
break;
472506
}
507+
508+
const char *arg = argv[optind - 1];
509+
if (strncmp(arg, "-Wl,", 4) == 0) {
510+
parse_linker_options(arg + 4, &opts->linker_opts);
511+
}
473512
}
474513
// Fallthrough
475514
case OPT_WNO:
@@ -534,6 +573,7 @@ static int do_link(Vector *obj_files, Options *opts) {
534573
WasmLinker linker_body;
535574
WasmLinker *linker = &linker_body;
536575
linker_init(linker);
576+
linker->options = opts->linker_opts;
537577

538578
for (int i = 0; i < obj_files->len; ++i) {
539579
const char *objfn = obj_files->data[i];

0 commit comments

Comments
 (0)