changeset 365:3f8abaac214c

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 <erik@6809.org> for the patch.
author William Astle <lost@l-w.ca>
date Tue, 02 Jun 2015 20:08:58 -0600
parents 44270b66df3c
children 433dbc18fb41
files lwasm/lwasm.h lwasm/main.c lwasm/symbol.c
diffstat 3 files changed, 100 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- 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
--- 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);
 }
--- 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);
+}