changeset 448:5cccf90bf838 3.0 tip

Fixed bug with complex external references generating invalid relocations in the object file
author lost@l-w.ca
date Fri, 05 Nov 2010 22:27:00 -0600
parents 00924eeb2ec8
children
files ChangeLog lwasm/output.c lwlib/lw_expr.c lwlib/lw_expr.h
diffstat 4 files changed, 24 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog	Thu Nov 04 23:25:18 2010 -0600
+++ b/ChangeLog	Fri Nov 05 22:27:00 2010 -0600
@@ -16,6 +16,8 @@
 Version 3.0.2
 
 [ ] Listings now assume an 8 space tab and convert tabs to spaces
+[b] Fixed problem with complex external references, usually those referring
+    to multiple symbols, in the object target output generation
 
 Version 3.0.1
 
--- a/lwasm/output.c	Thu Nov 04 23:25:18 2010 -0600
+++ b/lwasm/output.c	Fri Nov 05 22:27:00 2010 -0600
@@ -235,6 +235,7 @@
 {
 	int tt;
 	int v;
+	int count = 1;
 	unsigned char buf[16];
 	
 	tt = lw_expr_type(e);
@@ -243,10 +244,12 @@
 	{
 	case lw_expr_type_oper:
 		buf[0] =  0x04;
+		
 		switch (lw_expr_whichop(e))
 		{
 		case lw_expr_oper_plus:
 			buf[1] = 0x01;
+			count = lw_expr_operandcount(e) - 1;
 			break;
 		
 		case lw_expr_oper_minus:
@@ -255,6 +258,7 @@
 		
 		case lw_expr_oper_times:
 			buf[1] = 0x03;
+			count = lw_expr_operandcount(e) - 1;
 			break;
 		
 		case lw_expr_oper_divide:
@@ -300,7 +304,8 @@
 		default:
 			buf[1] = 0xff;
 		}
-		writebytes(buf, 2, 1, of);
+		while (count--)
+			writebytes(buf, 2, 1, of);
 		return 0;
 
 	case lw_expr_type_int:
--- a/lwlib/lw_expr.c	Thu Nov 04 23:25:18 2010 -0600
+++ b/lwlib/lw_expr.c	Fri Nov 05 22:27:00 2010 -0600
@@ -1273,3 +1273,17 @@
 {
 	return e -> value2;
 }
+
+int lw_expr_operandcount(lw_expr_t e)
+{
+	int count = 0;
+	struct lw_expr_opers *o;
+	
+	if (e -> type != lw_expr_type_oper)
+		return 0;
+	
+	for (o = e -> operands; o; o = o -> next)
+		count++;
+	
+	return count;
+}
--- a/lwlib/lw_expr.h	Thu Nov 04 23:25:18 2010 -0600
+++ b/lwlib/lw_expr.h	Fri Nov 05 22:27:00 2010 -0600
@@ -105,6 +105,8 @@
 
 typedef int lw_expr_testfn_t(lw_expr_t e, void *priv);
 
+extern int lw_expr_operandcount(lw_expr_t e);
+
 // run a function on all terms in an expression; if the function
 // returns non-zero for any term, return non-zero, else return
 // zero