# HG changeset patch # User lost # Date 1233192731 0 # Node ID 0ee5f65bccf931e93111a113e526b7a92bfebff3 # Parent 36ca3fa755e09aa3e736e9a113e344a3b4ded041 Added pragma to allow all undefined symbols to be considered external and also added a --pragma command line option diff -r 36ca3fa755e0 -r 0ee5f65bccf9 src/lwasm.c --- a/src/lwasm.c Wed Jan 28 06:06:05 2009 +0000 +++ b/src/lwasm.c Thu Jan 29 01:32:11 2009 +0000 @@ -40,6 +40,9 @@ char errbuff[1024]; int r; + if (!l) + return; + if (as -> passnum != pass) return; diff -r 36ca3fa755e0 -r 0ee5f65bccf9 src/lwasm.h --- a/src/lwasm.h Wed Jan 28 06:06:05 2009 +0000 +++ b/src/lwasm.h Thu Jan 29 01:32:11 2009 +0000 @@ -178,7 +178,10 @@ sectiontab_t *csect; // current section - NULL if not in one } asmstate_t; +// do not rewrite XXX,r to ,r if XXX evaluates to 0 #define PRAGMA_NOINDEX0TONONE 1 +// any undefined symbols are considered external +#define PRAGMA_UNDEFEXTERN 2 #ifndef __lwasm_c_seen__ #define __lwasm_E__ extern diff -r 36ca3fa755e0 -r 0ee5f65bccf9 src/main.c --- a/src/main.c Wed Jan 28 06:06:05 2009 +0000 +++ b/src/main.c Thu Jan 29 01:32:11 2009 +0000 @@ -38,6 +38,7 @@ extern void lwasm_pass2(asmstate_t *as); extern void lwasm_list(asmstate_t *as); extern void lwasm_output(asmstate_t *as); +extern void pseudo_pragma_real(asmstate_t *as, lwasm_line_t *cl, char **optr, int error); // command line option handling const char *argp_program_version = "LWASM from " PACKAGE_STRING; @@ -46,6 +47,7 @@ static error_t parse_opts(int key, char *arg, struct argp_state *state) { asmstate_t *as = state -> input; + char *p; switch (key) { @@ -99,6 +101,18 @@ exit(1); } break; + + case 'p': + // pragmas + p = arg; + pseudo_pragma_real(as, NULL, &p, 2); + if (!p) + { + fprintf(stderr, "Invalid pragma string: %s\n", arg); + exit(1); + } + break; + case ARGP_KEY_END: // done; sanity check if (!as -> outfile) @@ -134,6 +148,8 @@ "Generate raw binary format output, equivalent of --format=raw"}, { "obj", 0x100, 0, 0, "Generate proprietary object file format for later linking, equivalent of --format=obj" }, + { "pragma", 'p', "PRAGMA", 0, + "Set an assembler pragma to any value understood by the \"pragma\" pseudo op"}, { 0 } }; diff -r 36ca3fa755e0 -r 0ee5f65bccf9 src/pragma.c --- a/src/pragma.c Wed Jan 28 06:06:05 2009 +0000 +++ b/src/pragma.c Thu Jan 29 01:32:11 2009 +0000 @@ -76,6 +76,10 @@ { register_error(as, cl, 1, "Unrecognized pragma"); } + if (error == 2) + { + *optr = NULL; + } return; } pragma[c] = 0; @@ -87,11 +91,23 @@ { as -> pragmas &= ~PRAGMA_NOINDEX0TONONE; } + else if (!strcmp(pragma, "undefextern")) + { + as -> pragmas |= PRAGMA_UNDEFEXTERN; + } + else if (!strcmp(pragma, "noundefextern")) + { + as -> pragmas &= ~PRAGMA_UNDEFEXTERN; + } else { if (error) { register_error(as, cl, 1, "Unrecognized pragma"); + if (error == 2) + { + *optr = NULL; + } } } } diff -r 36ca3fa755e0 -r 0ee5f65bccf9 src/symbol.c --- a/src/symbol.c Wed Jan 28 06:06:05 2009 +0000 +++ b/src/symbol.c Thu Jan 29 01:32:11 2009 +0000 @@ -138,7 +138,12 @@ se -> expr = l -> exprs[0]; se -> sym = lwasm_strdup(sym); se -> context = scontext; - se -> sect = as -> csect; + + if (!(flags & SYMBOL_EXTERN)) + se -> sect = as -> csect; + else + se -> sect = NULL; + se -> expr = NULL; se -> flags = flags; se -> externalname = NULL; @@ -149,6 +154,7 @@ lwasm_symbol_ent_t *lwasm_find_symbol(asmstate_t *as, char *sym, int scontext) { lwasm_symbol_ent_t *se; + static int st = 0; for (se = as -> symhead; se; se = se -> next) { @@ -157,6 +163,29 @@ return se; } } + if (as -> passnum == 2 && st == 0 && scontext == -1 && as -> outformat == OUTPUT_OBJ && as -> pragmas & PRAGMA_UNDEFEXTERN) + { + // we want undefined symbols to be considered external + // we didn't find it on a lookup so register it as external + // but we only do so when looking up in global context + st = 1; + if (lwasm_register_symbol(as, NULL, sym, 0, SYMBOL_EXTERN)) + { + st = 0; + return NULL; + } + st = 0; + + // find the newly registered symbol and return it + for (se = as -> symhead; se; se = se -> next) + { + if (scontext == se -> context && !strcmp(sym, se -> sym)) + { + return se; + } + } + } + return NULL; }