# HG changeset patch # User William Astle # Date 1433297338 21600 # Node ID 3f8abaac214ca8518a768ae8ccf402ac8f448754 # Parent 44270b66df3ca30a9883f356d74471a0d249452a Add map file output and option to suppress local symbols in listings Add --map option to generate a symbol map in a regular format that can be used as an import for other tools. Also add --symbols-nolocals to suppress output of local symbols in the symbol listing. In other words, only global symbols are listed. Thanks to Erik G for the patch. diff -r 44270b66df3c -r 3f8abaac214c lwasm/lwasm.h --- a/lwasm/lwasm.h Mon Jun 01 19:55:11 2015 -0600 +++ b/lwasm/lwasm.h Tue Jun 02 20:08:58 2015 -0600 @@ -76,6 +76,8 @@ FLAG_SYMBOLS = 0x004, FLAG_DEPENDNOERR = 0x0008, FLAG_UNICORNS = 0x0010, + FLAG_MAP = 0x0020, + FLAG_SYMBOLS_NOLOCALS = 0x0040, FLAG_NONE = 0 }; @@ -306,6 +308,7 @@ exportlist_t *exportlist; // list of exported symbols importlist_t *importlist; // list of imported symbols char *list_file; // name of file to list to + char *map_file; // name of map file char *output_file; // output file name lw_stringlist_t input_files; // files to assemble void *input_data; // opaque data used by the input system diff -r 44270b66df3c -r 3f8abaac214c lwasm/main.c --- a/lwasm/main.c Mon Jun 01 19:55:11 2015 -0600 +++ b/lwasm/main.c Tue Jun 02 20:08:58 2015 -0600 @@ -47,6 +47,8 @@ { "format", 'f', "TYPE", 0, "Select output format: decb, raw, obj, os9"}, { "list", 'l', "FILE", lw_cmdline_opt_optional, "Generate list [to FILE]"}, { "symbols", 's', 0, lw_cmdline_opt_optional, "Generate symbol list in listing, no effect without --list"}, + { "symbols-nolocals", 0x103, 0, lw_cmdline_opt_optional, "Same as --symbols but with local labels ignored"}, + { "map", 'm', "FILE", lw_cmdline_opt_optional, "Generate map [to FILE]"}, { "decb", 'b', 0, 0, "Generate DECB .bin format output, equivalent of --format=decb"}, { "raw", 'r', 0, 0, "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" }, @@ -122,10 +124,24 @@ as -> flags |= FLAG_LIST; break; + case 'm': + if (as -> map_file) + lw_free(as -> map_file); + if (!arg) + as -> map_file = lw_strdup("-"); + else + as -> map_file = lw_strdup(arg); + as -> flags |= FLAG_MAP; + break; + case 's': as -> flags |= FLAG_SYMBOLS; break; - + + case 0x103: + as -> flags |= FLAG_SYMBOLS | FLAG_SYMBOLS_NOLOCALS; + break; + case 'b': as -> output_format = OUTPUT_DECB; break; @@ -236,6 +252,7 @@ extern void do_pass7(asmstate_t *as); extern void do_output(asmstate_t *as); extern void do_list(asmstate_t *as); +extern void do_map(asmstate_t *as); extern lw_expr_t lwasm_evaluate_special(int t, void *ptr, void *priv); extern lw_expr_t lwasm_evaluate_var(char *var, void *priv); extern lw_expr_t lwasm_parse_term(char **p, void *priv); @@ -343,5 +360,6 @@ lwasm_do_unicorns(&asmstate); } do_list(&asmstate); + do_map(&asmstate); exit(0); } diff -r 44270b66df3c -r 3f8abaac214c lwasm/symbol.c --- a/lwasm/symbol.c Mon Jun 01 19:55:11 2015 -0600 +++ b/lwasm/symbol.c Tue Jun 02 20:08:58 2015 -0600 @@ -341,6 +341,10 @@ { if (s -> flags & symbol_flag_nolist) continue; + + if ((as -> flags & FLAG_SYMBOLS_NOLOCALS) && (s -> context >= 0)) + continue; + lwasm_reduce_expr(as, s -> value); fputc('[', of); if (s -> flags & symbol_flag_set) @@ -400,3 +404,77 @@ fprintf(of, "\nSymbol Table:\n"); list_symbols_aux(as, of, as -> symtab.head); } + +void map_symbols(asmstate_t *as, FILE *of, struct symtabe *se) +{ + struct symtabe *s; + lw_expr_t te; + struct listinfo li; + + li.as = as; + + if (!se) + return; + + map_symbols(as, of, se -> left); + + for (s = se; s; s = s -> nextver) + { + if (s -> flags & symbol_flag_nolist) + continue; + lwasm_reduce_expr(as, s -> value); + + te = lw_expr_copy(s -> value); + li.complex = 0; + li.sect = NULL; + lw_expr_testterms(te, list_symbols_test, &li); + if (li.sect) + { + as -> exportcheck = 1; + as -> csect = li.sect; + lwasm_reduce_expr(as, te); + as -> exportcheck = 0; + } + + if (lw_expr_istype(te, lw_expr_type_int)) + { + fprintf(of, "Symbol: %s", s -> symbol); + if (s -> context != -1) + fprintf(of, "_%04X", lw_expr_intval(te)); + fprintf(of, " (%s) = %04X\n", as -> output_file, lw_expr_intval(te)); + + } + lw_expr_destroy(te); + } + + map_symbols(as, of, se -> right); +} + +void do_map(asmstate_t *as) +{ + FILE *of = NULL; + + if (!(as -> flags & FLAG_MAP)) + return; + + if (as -> map_file) + { + if (strcmp(as -> map_file, "-") == 0) + { + of = stdout; + } + else + of = fopen(as -> map_file, "w"); + } + else + of = stdout; + if (!of) + { + fprintf(stderr, "Cannot open map file '%s' for output\n", as -> map_file); + return; + } + + map_symbols(as, of, as -> symtab.head); + + fclose(of); +}