diff src/lwasm.c @ 101:f59c0916753d

Fixed relative branches and PCR addressing to handle constant intra-section references properly
author lost
date Fri, 23 Jan 2009 03:36:27 +0000
parents 81fc353d4d69
children 0ee5f65bccf9
line wrap: on
line diff
--- a/src/lwasm.c	Sat Jan 17 07:35:18 2009 +0000
+++ b/src/lwasm.c	Fri Jan 23 03:36:27 2009 +0000
@@ -173,6 +173,7 @@
 {
 	asmstate_t *as;
 	lwasm_line_t *l;
+	int flags;
 };	
 
 lwasm_expr_stack_t *lwasm_expr_lookup_symbol(char *sym, void *state)
@@ -225,9 +226,18 @@
 	{
 		return NULL;
 	}
+	if (st -> flags & EXPR_SECTCONST)
+	{
+		if (se -> sect == st -> l -> sect)
+		{
+			if (se -> expr)
+				goto retsym;
+			val = se -> value;
+			goto retconst;
+		}
+	}
 	if (st -> as -> outformat == OUTPUT_OBJ && se -> sect != NULL)
 	{
-		// do not resolve any section symbols in object mode
 		return NULL;
 	}
 	if (st -> as -> outformat != OUTPUT_OBJ || se -> sect == NULL)
@@ -236,6 +246,7 @@
 		val = se -> value;
 		goto retconst;
 	}
+	
 	// an intersegment reference will return as NULL (to be resolved at output/link time)
 	// if se -> expr is NULL, it has to be an intersegment reference here
 	if (se -> expr == NULL)
@@ -243,6 +254,7 @@
 		return NULL;
 	}
 	
+retsym:
 	// duplicate the expression for return
 	rs = lwasm_expr_stack_create();
 	for (n = se -> expr -> head; n; n = n -> next)
@@ -259,12 +271,13 @@
 	return rs;
 }
 
-lwasm_expr_stack_t *lwasm_evaluate_expr(asmstate_t *as, lwasm_line_t *l, const char *inp, const char **outp)
+lwasm_expr_stack_t *lwasm_evaluate_expr(asmstate_t *as, lwasm_line_t *l, const char *inp, const char **outp, int flags)
 {
 	struct symstateinfo st;
 	
 	st.as = as;
 	st.l = l;
+	st.flags = flags;
 	
 	debug_message(2, "Evaluate expression: %s", inp);
 	
@@ -272,13 +285,13 @@
 }
 
 
-int lwasm_reevaluate_expr(asmstate_t *as, lwasm_line_t *l, lwasm_expr_stack_t *s)
+int lwasm_reevaluate_expr(asmstate_t *as, lwasm_line_t *l, lwasm_expr_stack_t *s, int flags)
 {
 	struct symstateinfo st;
 	
 	st.as = as;
 	st.l = l;
-	
+	st.flags = flags;
 	return(lwasm_expr_reval(s, lwasm_expr_lookup_symbol, &st));
 }
 
@@ -322,9 +335,9 @@
 	const char *ep;
 	int rval;
 
-	if (as -> passnum == 1 || slot < 0)
+	if ((as -> passnum == 1 && !(flag & EXPR_REEVAL)) || slot < 0)
 	{		
-		s = lwasm_evaluate_expr(as, l, *inp, &ep);
+		s = lwasm_evaluate_expr(as, l, *inp, &ep, flag);
 		if (slot >= 0)
 			l -> exprs[slot] = s;
 		if (!s)
@@ -343,7 +356,7 @@
 	else if (l -> exprs[slot])
 	{
 		s = l -> exprs[slot];
-		lwasm_reevaluate_expr(as, l, s);
+		lwasm_reevaluate_expr(as, l, s, flag);
 		l -> exprvals[slot] = lwasm_expr_get_value(s);
 	}
 	if (as -> passnum == 2 && slot >= 0)