diff src/output.c @ 85:918be0c02239

Started adding object target output
author lost
date Fri, 16 Jan 2009 05:14:49 +0000
parents 6de358e7903f
children 033a328a10ae
line wrap: on
line diff
--- 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)
+			{
+			
+			}
+		}
+	}
+}