changeset 90:6097cb1486f8

Added EXPORT pseudo op
author lost
date Sat, 17 Jan 2009 05:07:45 +0000
parents 11d38c9e5095
children 718998b673ee
files src/instab.c src/lwasm.h src/pseudo.c
diffstat 3 files changed, 76 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- a/src/instab.c	Sat Jan 17 04:38:32 2009 +0000
+++ b/src/instab.c	Sat Jan 17 05:07:45 2009 +0000
@@ -76,7 +76,8 @@
 extern OPFUNC(pseudo_pragma);
 extern OPFUNC(pseudo_starpragma);
 extern OPFUNC(pseudo_extern);
-\
+extern OPFUNC(pseudo_export);
+
 instab_t instab[] =
 {
 	{ "abx",	{	0x3a,	-0x1,	-0x1,	-0x1	},	insn_inh },
@@ -325,6 +326,8 @@
 	{ "=",		{ -1, -1, -1, -1 },	pseudo_equ,	0,	0,	1 },
 	{ "extern",	{ -1, -1, -1, -1 },	pseudo_extern,	0,	0,	1 },
 	{ "external",	{ -1, -1, -1, -1 },	pseudo_extern,	0,	0,	1 },
+	{ "import",	{ -1, -1, -1, -1 },	pseudo_extern,	0,	0,	1 },
+	{ "export",	{ -1, -1, -1, -1 },	pseudo_export,	0,	0,	1 },
 
 
 	{ "rmb", 	{ -1, -1, -1, -1 }, pseudo_rmb },
--- a/src/lwasm.h	Sat Jan 17 04:38:32 2009 +0000
+++ b/src/lwasm.h	Sat Jan 17 05:07:45 2009 +0000
@@ -41,6 +41,14 @@
 	section_reloc_list_t *next;		// next relocation
 };
 
+typedef struct export_list_s export_list_t;
+struct export_list_s
+{
+	int offset;						// offset of symbol
+	char *sym;						// name of symbol
+	export_list_t *next;			// next export	
+};
+
 #define SECTION_BSS		1	// the section contains no actual code - just uninit vars
 typedef struct sectiontab_s sectiontab_t;
 struct sectiontab_s
@@ -54,6 +62,7 @@
 	int oblen;				// how many bytes output so far?
 	int obsize;				// how big is output buffer so far?
 	section_reloc_list_t *rl;	// relocation list
+	export_list_t *exports;	// export list for the section
 };
 
 // structure for tracking macros
--- 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);
+}