# HG changeset patch # User lost # Date 1231377520 0 # Node ID c8c772ef5df90ce378d8b3a5b19ed9ca29ab9489 # Parent 4b37f17624a7b097ddc7ac242cbababfb474c7bf Checkpointing object target implementation diff -r 4b37f17624a7 -r c8c772ef5df9 src/Makefile.am --- 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 diff -r 4b37f17624a7 -r c8c772ef5df9 src/lwasm.c --- 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; diff -r 4b37f17624a7 -r c8c772ef5df9 src/lwasm.h --- 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 diff -r 4b37f17624a7 -r c8c772ef5df9 src/main.c --- 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 } }; diff -r 4b37f17624a7 -r c8c772ef5df9 src/pass2.c --- 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) { diff -r 4b37f17624a7 -r c8c772ef5df9 src/pseudo.c --- 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); +}