diff lwlink/link.c @ 205:42df94f30d82

checkpoint
author lost
date Sun, 19 Apr 2009 17:44:46 +0000
parents 048ebb85f6ef
children 299c5d793aca
line wrap: on
line diff
--- a/lwlink/link.c	Sun Mar 29 14:52:28 2009 +0000
+++ b/lwlink/link.c	Sun Apr 19 17:44:46 2009 +0000
@@ -34,10 +34,15 @@
 
 struct section_list *sectlist = NULL;
 int nsects = 0;
+static int nforced = 0;
 
 void check_section_name(char *name, int *base, fileinfo_t *fn)
 {
 	int sn;
+
+	if (fn -> forced == 0)
+		return;
+
 	for (sn = 0; sn < fn -> nsections; sn++)
 	{
 		if (!strcmp(name, fn -> sections[sn].name))
@@ -62,6 +67,10 @@
 void check_section_flags(int yesflags, int noflags, int *base, fileinfo_t *fn)
 {
 	int sn;
+
+	if (fn -> forced == 0)
+		return;
+
 	for (sn = 0; sn < fn -> nsections; sn++)
 	{
 		// ignore if the noflags tell us to
@@ -204,6 +213,11 @@
 		{
 			if (!strcmp(sym, se -> sym))
 			{
+				if (!(fn -> forced))
+				{
+					fn -> forced = 1;
+					nforced = 1;
+				}
 				val = se -> offset + fn -> sections[sn].loadaddress;
 				r = lw_expr_stack_create();
 				term = lw_expr_term_create_int(val & 0xffff);
@@ -218,7 +232,14 @@
 	{
 		r = find_external_sym_recurse(sym, fn -> subs[sn]);
 		if (r)
+		{
+			if (!(fn -> forced))
+			{
+				nforced = 1;
+				fn -> forced = 1;
+			}
 			return r;
+		}
 	}
 	return NULL;
 }
@@ -372,3 +393,61 @@
 	if (symerr)
 		exit(1);
 }
+
+/*
+This is just a pared down version of the algo for resolving references.
+*/
+void resolve_files(void)
+{
+	int sn;
+	int fn;
+	reloc_t *rl;
+	int rval;
+
+	// resolve entry point if required
+	// this must resolve to an *exported* symbol and will resolve to the
+	// first instance of that symbol
+	if (linkscript.execsym)
+	{
+		lw_expr_stack_t *s;
+		
+		s = resolve_sym(linkscript.execsym, 0, NULL);
+		if (!s)
+		{
+			fprintf(stderr, "Cannot resolve exec address '%s'\n", linkscript.execsym);
+			symerr = 1;
+		}
+	}
+	
+	do
+	{
+		nforced = 0;
+		for (fn = 0; fn < ninputfiles; fn++)
+		{
+			if (inputfiles[fn] -> forced == 0)
+				continue;
+	
+			for (sn = 0; sn < inputfiles[fn] -> nsections; sn++)
+			{
+				for (rl = inputfiles[fn] -> sections[sn].incompletes; rl; rl = rl -> next)
+				{
+					// do a "simplify" on the expression
+					rval = lw_expr_reval(rl -> expr, resolve_sym, &(inputfiles[fn] -> sections[sn]));
+
+					// is it constant? error out if not
+					if (rval != 0 || !lw_expr_is_constant(rl -> expr))
+					{
+						fprintf(stderr, "Incomplete reference at %s:%s+%02X\n", inputfiles[fn] -> filename, inputfiles[fn] -> sections[sn].name, rl -> offset);
+						symerr = 1;
+					}
+				}
+			}
+		}
+	}
+	while (nforced == 1);
+
+	if (symerr)
+		exit(1);
+	
+	// theoretically, all files referenced by other files now have "forced" set to 1
+}