diff src/pseudo.c @ 90:6097cb1486f8

Added EXPORT pseudo op
author lost
date Sat, 17 Jan 2009 05:07:45 +0000
parents 033a328a10ae
children 83ba34ed11b3
line wrap: on
line diff
--- a/src/pseudo.c	Sat Jan 17 04:38:32 2009 +0000
+++ b/src/pseudo.c	Sat Jan 17 05:07:45 2009 +0000
@@ -721,6 +721,7 @@
 		s -> oblen = 0;
 		s -> obsize = 0;
 		s -> rl = NULL;
+		s -> exports = NULL;
 		// parse options; only one "bss"
 		if (opts && as -> passnum == 1)
 		{
@@ -784,3 +785,65 @@
 	
 	lwasm_register_symbol(as, l, l -> sym, 0, SYMBOL_EXTERN);
 }
+
+OPFUNC(pseudo_export)
+{
+	lwasm_symbol_ent_t *se;
+	export_list_t *ex;
+	
+	if (as -> outformat != OUTPUT_OBJ)
+	{
+		register_error(as, l, 1, "Symbol exports only supported for obj target");
+		return;
+	}
+	
+	if (as -> passnum == 1)
+		return;
+
+	// the symbol better be defined at this point (pass 2)
+	// local symbols cannot be exported nor can "global" symbols
+	se = lwasm_find_symbol(as, l -> sym, -1);
+	if (!se)
+	{
+		register_error(as, l, 2, "Exported symbols must be fully defined within a section");
+		return;
+	}
+	if (se -> sect == NULL)
+	{
+		register_error(as, l, 2, "Only non-local symbols within a section can be exported");
+		return;
+	}
+
+	if (se -> flags & SYMBOL_SET)
+	{
+		register_error(as, l, 2, "You cannot export symbols defined with SET");
+		return;
+	}
+
+	// if the symbol is not already a simple value, re-evaluate it
+	// and see if it becomes simple
+	
+
+	if (se -> flags & SYMBOL_COMPLEX)
+	{
+		register_error(as, l, 2, "Exported symbols must be fully resolved on pass 2");
+		return;
+	}
+
+	// search for existing export
+	for (ex = se -> sect -> exports; ex; ex = ex -> next)
+		if (!strcmp(l -> sym, ex -> sym))
+			break;
+	if (ex)
+	{
+		register_error(as, l, 2, "Symbol %s already exported", l -> sym);
+		return;
+	}
+
+	// add an external reference
+	ex = lwasm_alloc(sizeof(export_list_t));
+	ex -> next = se -> sect -> exports;
+	se -> sect -> exports = ex;
+	ex -> offset = se -> value;
+	ex -> sym = lwasm_strdup(se -> sym);
+}