changeset 205:42df94f30d82

checkpoint
author lost
date Sun, 19 Apr 2009 17:44:46 +0000
parents 048ebb85f6ef
children 299c5d793aca
files lwlink/link.c lwlink/lwlink.c lwlink/lwlink.h lwlink/main.c lwlink/readfiles.c
diffstat 5 files changed, 91 insertions(+), 1 deletions(-) [+]
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
+}
--- a/lwlink/lwlink.c	Sun Mar 29 14:52:28 2009 +0000
+++ b/lwlink/lwlink.c	Sun Apr 19 17:44:46 2009 +0000
@@ -57,6 +57,7 @@
 	inputfiles = lw_realloc(inputfiles, sizeof(fileinfo_t *) * (ninputfiles + 1));
 	inputfiles[ninputfiles] = lw_malloc(sizeof(fileinfo_t));
 	memset(inputfiles[ninputfiles], 0, sizeof(fileinfo_t));
+	inputfiles[ninputfiles] -> forced = 1;
 	inputfiles[ninputfiles++] -> filename = lw_strdup(fn);
 }
 
@@ -66,6 +67,7 @@
 	inputfiles[ninputfiles] = lw_malloc(sizeof(fileinfo_t));
 	memset(inputfiles[ninputfiles], 0, sizeof(fileinfo_t));
 	inputfiles[ninputfiles] -> islib = 1;
+	inputfiles[ninputfiles] -> forced = 0;
 	inputfiles[ninputfiles++] -> filename = lw_strdup(libname);	
 }
 
--- a/lwlink/lwlink.h	Sun Mar 29 14:52:28 2009 +0000
+++ b/lwlink/lwlink.h	Sun Apr 19 17:44:46 2009 +0000
@@ -79,6 +79,8 @@
 	int nsections;
 	int islib;				// set to true if the file is a "-l" option
 
+	int forced;				// set to true if the file is a "forced" include
+
 	// "sub" files (like in archives or libraries)
 	int nsubs;
 	fileinfo_t **subs;
--- a/lwlink/main.c	Sun Mar 29 14:52:28 2009 +0000
+++ b/lwlink/main.c	Sun Apr 19 17:44:46 2009 +0000
@@ -148,6 +148,7 @@
 
 extern void read_files(void);
 extern void setup_script(void);
+extern void resolve_files(void);
 extern void resolve_sections(void);
 extern void resolve_references(void);
 extern void do_output(void);
@@ -171,6 +172,10 @@
 
 	// read the input files
 	read_files();
+
+	// trace unresolved references and determine which non-forced
+	// objects must be included
+	resolve_files();
 	
 	// resolve section bases and section order
 	resolve_sections();
--- a/lwlink/readfiles.c	Sun Mar 29 14:52:28 2009 +0000
+++ b/lwlink/readfiles.c	Sun Apr 19 17:44:46 2009 +0000
@@ -279,7 +279,9 @@
 					// a flag specifier
 					tt = CURBYTE();
 					rp -> flags = tt;
+					NEXTBYTE();
 					term = NULL;
+					break;
 					
 				case 0x01:
 					// 16 bit integer
@@ -316,7 +318,7 @@
 					break;
 					
 				default:
-					fprintf(stderr, "%s (%s): bad relocation expression\n", fn -> filename, s -> name);
+					fprintf(stderr, "%s (%s): bad relocation expression (%02X)\n", fn -> filename, s -> name, tt);
 					exit(1);
 				}
 				if (term)