changeset 376:91c0fe026940

Output incomplete references in object target
author lost@starbug
date Mon, 26 Apr 2010 17:59:30 -0600
parents 3498b2d88376
children 55ed7d06b136
files lwasm/lwasm.c lwasm/lwasm.h lwasm/output.c lwlib/lw_expr.c lwlib/lw_expr.h
diffstat 5 files changed, 173 insertions(+), 64 deletions(-) [+]
line wrap: on
line diff
--- a/lwasm/lwasm.c	Mon Apr 26 17:14:04 2010 -0600
+++ b/lwasm/lwasm.c	Mon Apr 26 17:59:30 2010 -0600
@@ -629,13 +629,16 @@
 		if (l -> as -> output_format == OUTPUT_OBJ)
 		{
 			reloctab_t *re;
+			lw_expr_t te;
 			
 			// add "expression" record to section table
-			v = lw_expr_intval(l -> addr) + l -> outputl;
 			re = lw_alloc(sizeof(reloctab_t));
 			re -> next = l -> csect -> reloctab;
 			l -> csect -> reloctab = re;
-			re -> offset = v;
+			te = lw_expr_build(lw_expr_type_int, l -> outputl);
+			re -> offset = lw_expr_build(lw_expr_type_oper, lw_expr_oper_plus, l -> addr, te);
+			lw_expr_destroy(te);
+			lwasm_reduce_expr(l -> as, re -> offset);
 			re -> size = size;
 			re -> expr = lw_expr_copy(expr);
 			
--- a/lwasm/lwasm.h	Mon Apr 26 17:14:04 2010 -0600
+++ b/lwasm/lwasm.h	Mon Apr 26 17:59:30 2010 -0600
@@ -87,9 +87,9 @@
 typedef struct reloctab_s reloctab_t;
 struct reloctab_s
 {
-	int offset;							// offset of relocation
+	lw_expr_t offset;					// offset of relocation
 	int size;							// size of relocation
-	lw_expr_t *expr;					// relocation expression
+	lw_expr_t expr;						// relocation expression
 	reloctab_t *next;
 };
 
--- a/lwasm/output.c	Mon Apr 26 17:14:04 2010 -0600
+++ b/lwasm/output.c	Mon Apr 26 17:59:30 2010 -0600
@@ -230,6 +230,134 @@
 	s -> oblen += 1;
 }
 
+
+int write_code_obj_expraux(lw_expr_t e, void *of)
+{
+	int tt;
+	int v;
+	unsigned char buf[16];
+	
+	tt = lw_expr_type(e);
+
+	switch (tt)
+	{
+	case lw_expr_type_oper:
+		buf[0] =  0x04;
+		switch (lw_expr_intval(e))
+		{
+		case lw_expr_oper_plus:
+			buf[1] = 0x01;
+			break;
+		
+		case lw_expr_oper_minus:
+			buf[1] = 0x02;
+			break;
+		
+		case lw_expr_oper_times:
+			buf[1] = 0x03;
+			break;
+		
+		case lw_expr_oper_divide:
+			buf[1] = 0x04;
+			break;
+		
+		case lw_expr_oper_mod:
+			buf[1] = 0x05;
+			break;
+		
+		case lw_expr_oper_intdiv:
+			buf[1] = 0x06;
+			break;
+		
+		case lw_expr_oper_bwand:
+			buf[1] = 0x07;
+			break;
+		
+		case lw_expr_oper_bwor:
+			buf[1] = 0x08;
+			break;
+		
+		case lw_expr_oper_bwxor:
+			buf[1] = 0x09;
+			break;
+		
+		case lw_expr_oper_and:
+			buf[1] = 0x0A;
+			break;
+		
+		case lw_expr_oper_or:
+			buf[1] = 0x0B;
+			break;
+		
+		case lw_expr_oper_neg:
+			buf[1] = 0x0C;
+			break;
+		
+		case lw_expr_oper_com:
+			buf[1] = 0x0D;
+			break;
+
+		default:
+			buf[1] = 0xff;
+		}
+		writebytes(buf, 2, 1, of);
+		break;
+
+	case lw_expr_type_int:
+		v = lw_expr_intval(e);
+		buf[0] = 0x01;
+		buf[1] = (v >> 8) & 0xff;
+		buf[2] = v & 0xff;
+		writebytes(buf, 3, 1, of);
+		break;
+		
+	case lw_expr_type_special:
+		v = lw_expr_specint(e);
+		switch (v)
+		{
+		case lwasm_expr_secbase:
+			writebytes("\x05", 1, 1, of);
+			break;
+		
+		case lwasm_expr_import:
+			{
+				importlist_t *ie;
+				ie = lw_expr_specptr(e);
+				buf[0] = 0x02;
+				writebytes(buf, 1, 1, of);
+				writebytes(ie -> symbol, strlen(ie -> symbol) + 1, 1, of);
+				break;
+			}
+		case lwasm_expr_syment:
+			{
+				struct symtabe *se;
+				se = lw_expr_specptr(e);
+				buf[0] = 0x03;
+				writebytes(buf, 1, 1, of);
+				writebytes(se -> symbol, strlen(se -> symbol), 1, of);
+				if (se -> context != -1)
+				{
+					sprintf(buf, "\x01%d", se -> context);
+					writebytes(buf, strlen(buf), 1, of);
+				}
+				writebytes("", 1, 1, of);
+				break;
+			}
+			break;
+		}
+			
+	default:
+		// unrecognized term type - replace with integer 0
+		buf[0] = 0x01;
+		buf[1] = 0x00;
+		buf[2] = 0x00;
+		writebytes(buf, 3, 1, of);
+		break;
+	}
+	return 0;
+}
+
+
 void write_code_obj(asmstate_t *as, FILE *of)
 {
 	line_t *l;
@@ -359,8 +487,17 @@
 		writebytes("", 1, 1, of);
 		
 		// FIXME - relocation table
-/*		for (re = s -> rl; re; re = re -> next)
+		for (re = s -> reloctab; re; re = re -> next)
 		{
+			int offset;
+			lw_expr_t te;
+			line_t tl;
+			
+			tl.as = as;
+			as -> cl = &tl;
+			as -> csect = s;
+			as -> exportcheck = 1;
+			
 			if (re -> expr == NULL)
 			{
 				// this is an error but we'll simply ignore it
@@ -370,80 +507,36 @@
 			
 			// work through each term in the expression and output
 			// the proper equivalent to the object file
-			if (re -> relocsize == 1)
+			if (re -> size == 1)
 			{
 				// flag an 8 bit relocation (low 8 bits will be used)
 				buf[0] = 0xFF;
 				buf[1] = 0x01;
 				writebytes(buf, 2, 1, of);
 			}
-			for (sn = re -> expr -> head; sn; sn = sn -> next)
+			
+			te = lw_expr_copy(ex -> se -> value);
+			lwasm_reduce_expr(as, te);
+			if (!lw_expr_istype(te, lw_expr_type_int))
 			{
-				switch (sn -> term -> term_type)
-				{
-				case LWASM_TERM_OPER:
-					buf[0] =  0x04;
-					buf[1] = sn -> term -> value;
-					writebytes(buf, 2, 1, of);
-					break;
-					
-				case LWASM_TERM_INT:
-					buf[0] = 0x01;
-					buf[1] = (sn -> term -> value >> 8) & 0xff;
-					buf[2] = sn -> term -> value & 0xff;
-					writebytes(buf, 3, 1, of);
-					break;
-				
-				case LWASM_TERM_SECBASE:
-					writebytes("\x05", 1, 1, of);
-					break;
-
-				case LWASM_TERM_SYM:
-					// now for the ugly part - resolve a symbol reference
-					// and determine whether it's internal, external, or
-					// a section base
-					se = lwasm_find_symbol(as, sn -> term -> symbol, re -> context);
-					if (!se)
-						se = lwasm_find_symbol(as, sn -> term -> symbol, -1);
-					if (!se || se -> flags & SYMBOL_EXTERN)
-					{
-						// not found - assume external reference
-						// found but flagged external - handle it
-						writebytes("\x02", 1, 1, of);
-						writebytes(se -> sym, strlen(se -> sym) + 1, 1, of);
-						break;
-					}
-					// a local symbol reference here
-					writebytes("\x03", 1, 1, of);
-					writebytes(se -> sym, strlen(se -> sym), 1, of);
-					if (se -> context >= 0)
-					{
-						writebytes("\x01", 1, 1, of);
-						sprintf(buf, "%d", se -> context);
-						writebytes(buf, strlen(buf), 1, of);
-					}
-					writebytes("", 1, 1, of);
-					break;
-
-				default:
-					// unrecognized term type - replace with integer 0
-					buf[0] = 0x01;
-					buf[1] = 0x00;
-					buf[2] = 0x00;
-					writebytes(buf, 3, 1, of);
-					break;
-				}
+				lw_expr_destroy(te);
+				continue;
 			}
+			offset = lw_expr_intval(te);
+			lw_expr_destroy(te);
+			
+			// output expression
+			lw_expr_testterms(re -> expr, write_code_obj_expraux, of);
 			
 			// flag end of expressions
 			writebytes("", 1, 1, of);
 			
 			// write the offset
-			buf[0] = (re -> offset >> 8) & 0xff;
-			buf[1] = re -> offset & 0xff;
+			buf[0] = (offset >> 8) & 0xff;
+			buf[1] = offset & 0xff;
 			writebytes(buf, 2, 1, of);
 		}
-*/
+
 		// flag end of incomplete references list
 		writebytes("", 1, 1, of);
 		
--- a/lwlib/lw_expr.c	Mon Apr 26 17:14:04 2010 -0600
+++ b/lwlib/lw_expr.c	Mon Apr 26 17:59:30 2010 -0600
@@ -1119,3 +1119,13 @@
 	}
 	return (fn)(e, priv);
 }
+
+int lw_expr_type(lw_expr_t e)
+{
+	return e -> type;
+}
+
+void *lw_expr_specptr(lw_expr_t e)
+{
+	return e -> value2;
+}
--- a/lwlib/lw_expr.h	Mon Apr 26 17:14:04 2010 -0600
+++ b/lwlib/lw_expr.h	Mon Apr 26 17:59:30 2010 -0600
@@ -98,6 +98,9 @@
 extern int lw_expr_istype(lw_expr_t e, int t);
 extern int lw_expr_intval(lw_expr_t e);
 extern int lw_expr_specint(lw_expr_t e);
+extern void *lw_expr_specptr(lw_expr_t e);
+
+extern int lw_expr_type(lw_expr_t e);
 
 typedef int lw_expr_testfn_t(lw_expr_t e, void *priv);