diff lwlink/link.c @ 248:e8d70b95ec41 2.x

Fixed various problems with determining which files to include in the output and also fixed problem identifying which files actually resolved symbols
author lost
date Sun, 22 Nov 2009 05:46:31 +0000
parents eb499c146c0d
children
line wrap: on
line diff
--- a/lwlink/link.c	Thu Nov 19 02:48:36 2009 +0000
+++ b/lwlink/link.c	Sun Nov 22 05:46:31 2009 +0000
@@ -33,26 +33,27 @@
 struct section_list *sectlist = NULL;
 int nsects = 0;
 static int nforced = 0;
+static fileinfo_t *lookingfrom;
 
 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 (fn -> forced != 0)
 	{
-		if (!strcmp(name, fn -> sections[sn].name))
+		for (sn = 0; sn < fn -> nsections; sn++)
 		{
-			// we have a match
-			sectlist = lw_realloc(sectlist, sizeof(struct section_list) * (nsects + 1));
-			sectlist[nsects].ptr = &(fn -> sections[sn]);
+			if (!strcmp(name, fn -> sections[sn].name))
+			{
+				// we have a match
+				sectlist = lw_realloc(sectlist, sizeof(struct section_list) * (nsects + 1));
+				sectlist[nsects].ptr = &(fn -> sections[sn]);
 					
-			fn -> sections[sn].processed = 1;
-			fn -> sections[sn].loadaddress = *base;
-			*base += fn -> sections[sn].codesize;
-			nsects++;
+				fn -> sections[sn].processed = 1;
+				fn -> sections[sn].loadaddress = *base;
+				*base += fn -> sections[sn].codesize;
+				nsects++;
+			}
 		}
 	}
 	for (sn = 0; sn < fn -> nsubs; sn++)
@@ -66,25 +67,25 @@
 {
 	int sn;
 
-	if (fn -> forced == 0)
-		return;
-
-	for (sn = 0; sn < fn -> nsections; sn++)
+	if (fn -> forced != 0)
 	{
-		// ignore if the noflags tell us to
-		if (noflags && (fn -> sections[sn].flags & noflags))
-			continue;
-		// ignore unless the yesflags tell us not to
-		if (yesflags && (fn -> sections[sn].flags & yesflags == 0))
-			continue;
-		// ignore it if already processed
-		if (fn -> sections[sn].processed)
-			continue;
+		for (sn = 0; sn < fn -> nsections; sn++)
+		{
+			// ignore if the noflags tell us to
+			if (noflags && (fn -> sections[sn].flags & noflags))
+				continue;
+			// ignore unless the yesflags tell us not to
+			if (yesflags && (fn -> sections[sn].flags & yesflags == 0))
+				continue;
+			// ignore it if already processed
+			if (fn -> sections[sn].processed)
+				continue;
 
-		// we have a match - now collect *all* sections of the same name!
-		add_matching_sections(fn -> sections[sn].name, 0, 0, base);
+			// we have a match - now collect *all* sections of the same name!
+			add_matching_sections(fn -> sections[sn].name, 0, 0, base);
 		
-		// and then continue looking for sections
+			// and then continue looking for sections
+		}
 	}
 	for (sn = 0; sn < fn -> nsubs; sn++)
 	{
@@ -213,10 +214,15 @@
 			{
 				if (!(fn -> forced))
 				{
-//					fprintf(stderr, "Forced inclusion of %s due to symbol reference\n", fn -> filename);
+					// we if this isn't a true external reference, don't force inclusion
+					// (without an external reference, internal references don't matter)
+					if (fn == lookingfrom)
+						continue;
+//					fprintf(stderr, "Forced inclusion of %s due to symbol reference (%s) from (%s)\n", fn -> filename, sym, lookingfrom ? lookingfrom -> filename : "<none>");
 					fn -> forced = 1;
 					nforced = 1;
 				}
+				fn -> resolves = 1;
 				val = se -> offset + fn -> sections[sn].loadaddress;
 				r = lw_expr_stack_create();
 				term = lw_expr_term_create_int(val & 0xffff);
@@ -232,11 +238,15 @@
 		r = find_external_sym_recurse(sym, fn -> subs[sn]);
 		if (r)
 		{
-			if (!(fn -> forced))
-			{
-				nforced = 1;
-				fn -> forced = 1;
-			}
+// don't do this when recursing - the sub file will already be set if needed
+//			if (!(fn -> forced))
+//			{
+//				fprintf(stderr, "Forced inclusion of %s due to symbol reference (%s)\n", fn -> filename, sym);
+//				nforced = 1;
+//				fn -> forced = 1;
+//			}
+			if (r)
+				fn -> resolves = 1;
 			return r;
 		}
 	}
@@ -346,6 +356,7 @@
 	{
 		lw_expr_stack_t *s;
 		
+		lookingfrom = NULL;
 		s = resolve_sym(linkscript.execsym, 0, NULL);
 		if (!s)
 		{
@@ -363,6 +374,7 @@
 	{
 		for (rl = sectlist[sn].ptr -> incompletes; rl; rl = rl -> next)
 		{
+			lookingfrom = sectlist[sn].ptr -> file;
 			// do a "simplify" on the expression
 			rval = lw_expr_reval(rl -> expr, resolve_sym, sectlist[sn].ptr);
 
@@ -409,6 +421,7 @@
 	
 	if (fn -> forced != 0)
 	{
+		lookingfrom = fn;
 		for (sn = 0; sn < fn -> nsections; sn++)
 		{
 			for (rl = fn -> sections[sn].incompletes; rl; rl = rl -> next)
@@ -438,7 +451,7 @@
 	int fn;
 	reloc_t *rl;
 	lw_expr_stack_t *te;
-	int c = 0;
+//	int c = 0;
 	
 	int rval;
 
@@ -449,6 +462,7 @@
 	{
 		lw_expr_stack_t *s;
 		
+		lookingfrom = NULL;
 		s = resolve_sym(linkscript.execsym, 0, NULL);
 		if (!s)
 		{
@@ -462,9 +476,6 @@
 		nforced = 0;
 		for (fn = 0; fn < ninputfiles; fn++)
 		{
-			if (inputfiles[fn] -> forced == 0)
-				continue;
-	
 			resolve_files_aux(inputfiles[fn]);
 		}
 //		fprintf(stderr, "File resolution pass %d, nforced = %d\n", ++c, nforced);
@@ -477,7 +488,7 @@
 	// theoretically, all files referenced by other files now have "forced" set to 1
 	for (fn = 0; fn < ninputfiles; fn++)
 	{
-		if (inputfiles[fn] -> forced == 1)
+		if (inputfiles[fn] -> forced == 1 || inputfiles[fn] -> resolves == 1)
 			continue;
 		
 		fprintf(stderr, "Warning: %s (%d) does not resolve any symbols\n", inputfiles[fn] -> filename, fn);