# HG changeset patch # User lost # Date 1232082889 0 # Node ID 918be0c02239d331e6401a36c15f9a01683ed488 # Parent e12edcfbebd5a34a7c4aa9b56daa604d2aaedfbf Started adding object target output diff -r e12edcfbebd5 -r 918be0c02239 src/lwasm.h --- a/src/lwasm.h Wed Jan 14 07:04:45 2009 +0000 +++ b/src/lwasm.h Fri Jan 16 05:14:49 2009 +0000 @@ -41,6 +41,9 @@ int offset; // current offset in the section int flags; // section flags sectiontab_t *next; // next section + unsigned char *obytes; // output bytes + int oblen; // how many bytes output so far? + int obsize; // how big is output buffer so far? }; // structure for tracking macros @@ -91,6 +94,8 @@ lwasm_expr_stack_t *exprs[4]; // non-constant expression values int exprvals[4]; // constant expression values char *exprends[4]; // pointer to character after end of expression + + sectiontab_t *sect; // which section is the line in? }; // for keeping track of symbols diff -r e12edcfbebd5 -r 918be0c02239 src/macro.c --- a/src/macro.c Wed Jan 14 07:04:45 2009 +0000 +++ b/src/macro.c Fri Jan 16 05:14:49 2009 +0000 @@ -249,6 +249,7 @@ nl -> addrset = 0; nl -> symaddr = -1; nl -> badop = 0; + nl -> relocoff = -1; if (as -> linestail) as -> linestail -> next = nl; as -> linestail = nl; diff -r e12edcfbebd5 -r 918be0c02239 src/output.c --- a/src/output.c Wed Jan 14 07:04:45 2009 +0000 +++ b/src/output.c Fri Jan 16 05:14:49 2009 +0000 @@ -30,10 +30,12 @@ #define __output_c_seen__ //#include "instab.h" #include "lwasm.h" +#include "util.h" void write_code_raw(asmstate_t *as, FILE *of); void write_code_decb(asmstate_t *as, FILE *of); void write_code_rawrel(asmstate_t *as, FILE *of); +void write_code_obj(asmstate_t *as, FILE *of); // this prevents warnings about not using the return value of fwrite() #define writebytes(s, l, c, f) do { int r; r = fwrite((s), (l), (c), (f)); } while (0) @@ -69,7 +71,11 @@ case OUTPUT_RAWREL: write_code_rawrel(as, of); break; - + + case OUTPUT_OBJ: + write_code_obj(as, of); + break; + default: fprintf(stderr, "BUG: unrecognized output format when generating output file\n"); fclose(of); @@ -180,3 +186,63 @@ outbuf[4] = (as -> execaddr) & 0xFF; writebytes(outbuf, 5, 1, of); } + +void write_code_obj_sbadd(sectiontab_t *s, unsigned char b) +{ + if (s -> oblen >= s -> obsize) + { + s -> obytes = lwasm_realloc(s -> obytes, s -> obsize + 128); + s -> obsize += 128; + } + s -> obytes[s -> oblen] = b; + s -> oblen += 1; +} + +void write_code_obj(asmstate_t *as, FILE *of) +{ + lwasm_line_t *l; + int i; + + // output the magic number and file header + writebytes("LWOBJ16\0", 8, 1, of); + + // run through the entire system and build the byte streams for each + // section; at the same time, generate a list of "local" symbols to + // output for each section + // NOTE: for "local" symbols, we will append \x01 and the ascii string + // of the context identifier (so sym in context 1 would be "sym\x011" + // we can do this because the linker can handle symbols with any + // character other than NUL. + // also we will generate a list of incomplete references for each + // section along with the actual definition that will be output + + // once all this information is generated, we will output each section + // to the file + + // NOTE: we build everything in memory then output it because the + // assembler accepts multiple instances of the same section but the + // linker expects only one instance of each section in the object file + // so we need to collect all the various pieces of a section together + // (also, the assembler treated multiple instances of the same section + // as continuations of previous sections so we would need to collect + // them together anyway. + + for (l = as -> lineshead; l; l = l -> next) + { + if (l -> sect) + { + // we're in a section - need to output some bytes + for (i = 0; i < l -> codelen; i++) + write_code_obj_sbadd(l -> sect, l -> bytes[i]); + for (i = 0; i < l -> nocodelen; i++) + write_code_obj_sbadd(l -> sect, 0); + + // do we have a "relocation"? If so, add a reference to the + // relocation table + if (l -> relocoff >= 0) + { + + } + } + } +} diff -r e12edcfbebd5 -r 918be0c02239 src/parse.c --- a/src/parse.c Wed Jan 14 07:04:45 2009 +0000 +++ b/src/parse.c Fri Jan 16 05:14:49 2009 +0000 @@ -186,6 +186,8 @@ } } + l -> sect = as -> csect; + lwasm_free(opc); if (sym) lwasm_free(sym); diff -r e12edcfbebd5 -r 918be0c02239 src/pass1.c --- a/src/pass1.c Wed Jan 14 07:04:45 2009 +0000 +++ b/src/pass1.c Fri Jan 16 05:14:49 2009 +0000 @@ -143,6 +143,7 @@ nl -> addrset = 0; nl -> symaddr = -1; nl -> badop = 0; + nl -> relocoff = -1; if (as -> linestail) as -> linestail -> next = nl; as -> linestail = nl; diff -r e12edcfbebd5 -r 918be0c02239 src/pseudo.c --- a/src/pseudo.c Wed Jan 14 07:04:45 2009 +0000 +++ b/src/pseudo.c Fri Jan 16 05:14:49 2009 +0000 @@ -717,6 +717,9 @@ s -> name = sn; s -> offset = 0; s -> flags = 0; + s -> obytes = NULL; + s -> oblen = 0; + s -> obsize = 0; // parse options; only one "bss" if (opts && as -> passnum == 1)