changeset 85:918be0c02239

Started adding object target output
author lost
date Fri, 16 Jan 2009 05:14:49 +0000
parents e12edcfbebd5
children 033a328a10ae
files src/lwasm.h src/macro.c src/output.c src/parse.c src/pass1.c src/pseudo.c
diffstat 6 files changed, 79 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- 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
--- 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;
--- 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)
+			{
+			
+			}
+		}
+	}
+}
--- 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);
--- 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;
--- 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)