# HG changeset patch # User lost # Date 1232168865 0 # Node ID 6097cb1486f83032c5c81114247ee9fcc31a4cf9 # Parent 11d38c9e5095a6f37342660384ba6e4e691e66f7 Added EXPORT pseudo op diff -r 11d38c9e5095 -r 6097cb1486f8 src/instab.c --- 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 }, diff -r 11d38c9e5095 -r 6097cb1486f8 src/lwasm.h --- 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 diff -r 11d38c9e5095 -r 6097cb1486f8 src/pseudo.c --- 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); +}