changeset 180:6ebb93b409ba

Added library paths and --section-base
author lost
date Thu, 05 Mar 2009 02:23:25 +0000
parents 3711cd1c01e2
children 14878196ed5b
files ChangeLog lwlink/lwlink.c lwlink/lwlink.h lwlink/main.c lwlink/readfiles.c lwlink/script.c
diffstat 6 files changed, 139 insertions(+), 7 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog	Wed Mar 04 05:34:17 2009 +0000
+++ b/ChangeLog	Thu Mar 05 02:23:25 2009 +0000
@@ -10,6 +10,12 @@
 
 Also, the software affected may follow in [].
 
+Version 2.3
+
+[*] added library search path (-L) and library specification (-l) to LWLINK
+[*] added ability to specify section base addresses on the command line to
+    LWLINK (they get prepended to the built in link script)
+
 Version 2.2
 
 [*] created LWAR to manage library/archive files
--- a/lwlink/lwlink.c	Wed Mar 04 05:34:17 2009 +0000
+++ b/lwlink/lwlink.c	Thu Mar 05 02:23:25 2009 +0000
@@ -44,6 +44,12 @@
 fileinfo_t **inputfiles = NULL;
 int ninputfiles = 0;
 
+int nlibdirs = 0;
+char **libdirs = NULL;
+
+int nscriptls = 0;
+char **scriptls = NULL;
+
 void add_input_file(char *fn)
 {
 	inputfiles = lw_realloc(inputfiles, sizeof(fileinfo_t *) * (ninputfiles + 1));
@@ -52,3 +58,48 @@
 	inputfiles[ninputfiles++] -> filename = lw_strdup(fn);
 }
 
+void add_input_library(char *libname)
+{
+	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] -> islib = 1;
+	inputfiles[ninputfiles++] -> filename = lw_strdup(libname);	
+}
+
+void add_library_search(char *libdir)
+{
+	libdirs = lw_realloc(libdirs, sizeof(char*) * (nlibdirs + 1));
+	libdirs[nlibdirs] = lw_strdup(libdir);
+	nlibdirs++;
+}
+
+void add_section_base(char *sectspec)
+{
+	char *base;
+	int baseaddr;
+	char *t;
+	int l;
+	
+	base = strchr(sectspec, '=');
+	if (!base)
+	{
+		l = strlen(sectspec);
+		baseaddr = 0;
+	}
+	else
+	{
+		baseaddr = strtol(base + 1, NULL, 16);
+		l = base - sectspec;
+		*base = '\0';
+	}
+	baseaddr = baseaddr & 0xffff;
+	
+	t = lw_malloc(l + 25);
+	sprintf(t, "section %s load %04X", sectspec, baseaddr);
+	if (base)
+		*base = '=';
+	
+	scriptls = lw_realloc(scriptls, sizeof(char *) * (nscriptls + 1));
+	scriptls[nscriptls++] = t;
+}
--- a/lwlink/lwlink.h	Wed Mar 04 05:34:17 2009 +0000
+++ b/lwlink/lwlink.h	Thu Mar 05 02:23:25 2009 +0000
@@ -73,6 +73,7 @@
 	long filesize;
 	section_t *sections;
 	int nsections;
+	int islib;				// set to true if the file is a "-l" option
 
 	// "sub" files (like in archives or libraries)
 	int nsubs;
@@ -101,12 +102,21 @@
 extern fileinfo_t **inputfiles;
 extern char *scriptfile;
 
+extern int nlibdirs;
+extern char **libdirs;
+
+extern int nscriptls;
+extern char **scriptls;
+
 #define __lwlink_E__ extern
 #else
 #define __lwlink_E__
 #endif // __lwlink_c_seen__
 
 __lwlink_E__ void add_input_file(char *fn);
+__lwlink_E__ void add_input_library(char *fn);
+__lwlink_E__ void add_library_search(char *fn);
+__lwlink_E__ void add_section_base(char *fn);
 
 #undef __lwlink_E__
 
--- a/lwlink/main.c	Wed Mar 04 05:34:17 2009 +0000
+++ b/lwlink/main.c	Thu Mar 05 02:23:25 2009 +0000
@@ -84,6 +84,18 @@
 			outfile = "a.out";
 		break;
 	
+	case 'l':
+		add_input_library(arg);
+		break;
+	
+	case 'L':
+		add_library_search(arg);
+		break;
+	
+	case 0x100:
+		add_section_base(arg);
+		break;
+		
 	case ARGP_KEY_ARG:
 		add_input_file(arg);
 		break;
@@ -107,7 +119,13 @@
 	{ "raw",		'r',	0,		0,
 				"Generate raw binary format output, equivalent of --format=raw"},
 	{ "script",		's',	"FILE",		0,
-				"Specify the linking script (overrides the build in defaults)"},
+				"Specify the linking script (overrides the built in defaults)"},
+	{ "library",	'l',	"LIBSPEC",	0,
+				"Read library libLIBSPEC.a from the search path" },
+	{ "library-path", 'L',	"DIR",		0,
+				"Add DIR to the library search path" },
+	{ "section-base", 0x100,	"SECT=BASE",	0,
+				"Load section SECT at BASE" },
 	{ 0 }
 };
 
--- a/lwlink/readfiles.c	Wed Mar 04 05:34:17 2009 +0000
+++ b/lwlink/readfiles.c	Thu Mar 05 02:23:25 2009 +0000
@@ -70,12 +70,42 @@
 	long bread;
 	for (i = 0; i < ninputfiles; i++)
 	{
-		f = fopen(inputfiles[i] -> filename, "rb");
-		if (!f)
+		if (inputfiles[i] -> islib)
 		{
-			fprintf(stderr, "Can't open file %s:", inputfiles[i] -> filename);
-			perror("");
-			exit(1);
+			char *tf;
+			int s;
+			int j;
+			
+			f = NULL;
+			
+			for (j = 0; j < nlibdirs; j++)
+			{
+				s = strlen(libdirs[j]) + 7 + strlen(inputfiles[i] -> filename);
+				tf = lw_malloc(s + 1);
+				sprintf(tf, "%s/lib%s.a", libdirs[j], inputfiles[i] -> filename);
+				f = fopen(tf, "rb");
+				if (!f)
+				{
+					free(tf);
+					continue;
+				}
+				free(tf);
+			}
+			if (!f)
+			{
+				fprintf(stderr, "Can't open library: -l%s\n", inputfiles[i] -> filename);
+				exit(1);
+			}
+		}
+		else
+		{
+			f = fopen(inputfiles[i] -> filename, "rb");
+			if (!f)
+			{
+				fprintf(stderr, "Can't open file %s:", inputfiles[i] -> filename);
+				perror("");
+				exit(1);
+			}
 		}
 		fseek(f, 0, SEEK_END);
 		size = ftell(f);
--- a/lwlink/script.c	Wed Mar 04 05:34:17 2009 +0000
+++ b/lwlink/script.c	Thu Mar 05 02:23:25 2009 +0000
@@ -113,6 +113,23 @@
 		}
 		
 		size = strlen(script);
+		if (nscriptls)
+		{
+			char *rscript;
+			int i;
+			// prepend the "extra" script lines
+			for (i = 0; i < nscriptls; i++)
+				size += strlen(scriptls[i]) + 1;
+			
+			rscript = lw_malloc(size + 1);
+			oscript = rscript;
+			for (i = 0; i < nscriptls; i++)
+			{
+				oscript += sprintf(oscript, "%s\n", scriptls[i]);
+			}
+			strcpy(oscript, script);
+			script = rscript;
+		}
 	}
 
 	oscript = script;
@@ -252,6 +269,6 @@
 		lw_free(line);
 	}
 	
-	if (scriptfile)
+	if (scriptfile || nscriptls)
 		lw_free(oscript);
 }