diff src/pseudo.c @ 74:c8c772ef5df9

Checkpointing object target implementation
author lost
date Thu, 08 Jan 2009 01:18:40 +0000
parents 31d8e85706e7
children 121bf4a588ea
line wrap: on
line diff
--- 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);
+}