changeset 74:c8c772ef5df9

Checkpointing object target implementation
author lost
date Thu, 08 Jan 2009 01:18:40 +0000
parents 4b37f17624a7
children 92eb93bffa28
files src/Makefile.am src/lwasm.c src/lwasm.h src/main.c src/pass2.c src/pseudo.c
diffstat 6 files changed, 153 insertions(+), 3 deletions(-) [+]
line wrap: on
line diff
--- a/src/Makefile.am	Thu Jan 08 01:18:09 2009 +0000
+++ b/src/Makefile.am	Thu Jan 08 01:18:40 2009 +0000
@@ -1,3 +1,3 @@
 bin_PROGRAMS = lwasm
-lwasm_SOURCES = main.c expr.c pass1.c pass2.c util.c instab.c parse.c lwasm.c insn_inh.c insn_rtor.c insn_rlist.c insn_rel.c insn_tfm.c insn_bitbit.c insn_indexed.c insn_gen.c insn_logicmem.c list.c symbol.c output.c pseudo.c macro.c
+lwasm_SOURCES = main.c expr.c pass1.c pass2.c util.c instab.c parse.c lwasm.c insn_inh.c insn_rtor.c insn_rlist.c insn_rel.c insn_tfm.c insn_bitbit.c insn_indexed.c insn_gen.c insn_logicmem.c list.c symbol.c output.c pseudo.c macro.c pragma.c
 EXTRA_DIST = instab.h lwasm.h expr.h util.h
--- a/src/lwasm.c	Thu Jan 08 01:18:09 2009 +0000
+++ b/src/lwasm.c	Thu Jan 08 01:18:40 2009 +0000
@@ -65,6 +65,16 @@
 	as -> addr += 1;
 	as -> addr &= 0xffff;
 	
+	if (as -> outformat == OUTPUT_OBJ && !(as -> csect))
+	{
+		register_error(as, l, 1, "Output not allowed outside sections with obj target");
+		return;
+	}
+	if (as -> outformat == OUTPUT_OBJ && as -> csect -> flags & SECTION_BSS)
+	{
+		register_error(as, l, 1, "Output not allowed inside BSS sections");
+		return;
+	}
 	if (as -> passnum == 1)
 		return;
 
--- a/src/lwasm.h	Thu Jan 08 01:18:09 2009 +0000
+++ b/src/lwasm.h	Thu Jan 08 01:18:40 2009 +0000
@@ -32,6 +32,17 @@
 #define OUTPUT_OBJ		2	// proprietary object file format
 #define OUTPUT_RAWREL	3	// raw bytes where ORG causes a SEEK in the file
 
+// structure for tracking sections
+#define SECTION_BSS		1	// the section contains no actual code - just uninit vars
+typedef struct sectiontab_s sectiontab_t;
+struct sectiontab_s
+{
+	char *name;				// name of the section
+	int offset;				// current offset in the section
+	int flags;				// section flags
+	sectiontab_t *next;		// next section
+};
+
 // structure for tracking macros
 typedef struct macrotab_s macrotab_t;
 struct macrotab_s
@@ -69,6 +80,12 @@
 	int addrset;		// set if this instruction sets the assembly address
 	int symaddr;		// set if this instruction sets a symbol addr with EQU or the like
 	int badop;			// bad operation - ignore it
+	
+	// the following are used for obj format - for external references, inter-section
+	// references, and intrasection relocations
+	int relocoff;		// offset into insn where relocation value goes
+	// the incomplete reference expression
+	struct lwasm_expr_strack_t *expr;
 };
 
 // for keeping track of symbols
@@ -118,6 +135,10 @@
 	int macroex;				// current depth of macro expansion
 	int nextcontext;			// next context number
 	int skiplines;				// number of lines to skip
+	
+	// items used only for the "object" target
+	sectiontab_t *sections;		// pointer to section table
+	sectiontab_t *csect;		// current section - NULL if not in one
 } asmstate_t;
 
 #define PRAGMA_NOINDEX0TONONE	1
--- a/src/main.c	Thu Jan 08 01:18:09 2009 +0000
+++ b/src/main.c	Thu Jan 08 01:18:40 2009 +0000
@@ -132,7 +132,7 @@
 				"Generate DECB .bin format output, equivalent of --format=decb"},
 	{ "raw",		'r',	0,		0,
 				"Generate raw binary format output, equivalent of --format=raw"},
-	{ "obj",		0,		0,		0,
+	{ "obj",		0x100,		0,		0,
 				"Generate proprietary object file format for later linking, equivalent of --format=obj" },
 	{ 0 }
 };
--- a/src/pass2.c	Thu Jan 08 01:18:09 2009 +0000
+++ b/src/pass2.c	Thu Jan 08 01:18:40 2009 +0000
@@ -31,7 +31,8 @@
 void lwasm_pass2(asmstate_t *as)
 {
 	lwasm_line_t *l;
-
+	sectiontab_t *st;
+	
 	debug_message(1, "Entering pass 2");
 	as -> passnum = 2;
 	as -> addr = 0;
@@ -45,6 +46,10 @@
 	as -> skiplines = 0;
 	as -> dpval = 0;
 	
+	for (st = as -> sections; st; st = st -> next)
+		st -> offset = 0;
+	as -> csect = NULL;
+	
 	// iterate over all the lines and re-parse them
 	for (l = as -> lineshead; l && !(as -> endseen); l = l -> next)
 	{
--- a/src/pseudo.c	Thu Jan 08 01:18:09 2009 +0000
+++ b/src/pseudo.c	Thu Jan 08 01:18:40 2009 +0000
@@ -35,6 +35,12 @@
 	int rval;
 	lwasm_expr_stack_t *s;
 
+	if (as -> csect)
+	{
+		register_error(as, l, 1, "ORG not allowed within sections");
+		return;
+	}
+
 	if (as -> passnum != 1)
 	{
 		// org is not needed to be processed on pass 2
@@ -692,3 +698,111 @@
 	register_error(as, l, 1, "User error: %s", *p);
 }
 
+
+OPFUNC(pseudo_section)
+{
+	sectiontab_t *s;
+	char *p2;
+	char *sn;
+	char *opts;
+	
+	
+	if (as -> outformat != OUTPUT_OBJ)
+	{
+		register_error(as, l, 1, "Sections only supported for obj target");
+		return;
+	}
+	
+	if (as -> csect)
+	{
+		as -> csect -> offset = as -> addr;
+		as -> csect = NULL;
+	}
+	
+	if (!**p)
+	{
+		register_error(as, l, 1, "Need section name");
+		return;
+	}
+	
+	for (p2 = *p; *p2 && !isspace(*p2); p2++)
+		/* do nothing */ ;
+	
+	sn = lwasm_alloc(p2 - *p + 1);
+	memcpy(sn, *p, p2 - *p);
+	sn[p2 - *p] = '\0';
+	
+	*p = p2;
+	
+	opts = strchr(sn, ',');
+	if (opts)
+	{
+		*opts++ = '\0';
+	}
+	
+	// have we seen the section name already?
+	for (s = as -> sections; s; s = s -> next)
+	{
+		if (!strcmp(s -> name, sn))
+			break;
+	}
+	
+	if (s)
+	{
+		lwasm_free(sn);
+		if (opts)
+		{
+			register_error(as, l, 1, "Section options can only be specified the first time");
+			return;
+		}
+	}
+	else if (!s)
+	{
+		s = lwasm_alloc(sizeof(sectiontab_t));
+		s -> name = sn;
+		s -> offset = 0;
+		s -> flags = 0;
+		
+		// parse options; only one "bss"
+		if (opts && as -> passnum == 1)
+		{
+			if (!strcasecmp(opts, "bss"))
+			{
+				s -> flags = SECTION_BSS;
+			}
+			else
+			{
+				register_error(as, l, 1, "Unrecognized section option '%s'", opts);
+				lwasm_free(s -> name);
+				lwasm_free(s);
+				return;
+			}
+		}
+		
+		s -> next = as -> sections;
+		as -> sections = s;
+	}
+	as -> addr = s -> offset;
+	as -> csect = s;
+	as -> context = lwasm_next_context(as);
+}
+
+OPFUNC(pseudo_endsection)
+{
+	if (as -> outformat != OUTPUT_OBJ)
+	{
+		register_error(as, l, 1, "Sections only supported for obj target");
+		return;
+	}
+	
+	if (!(as -> csect))
+	{
+		register_error(as, l, 1, "ENDSECTION when not in a section");
+		return;
+	}
+	
+	as -> csect -> offset = as -> addr;
+	as -> addr = 0;
+	as -> csect = 0;
+	as -> context = lwasm_next_context(as);
+}