changeset 187:857cb407229e

Added LWEX0 (LWOS simple binary) target to lwlink
author lost
date Sun, 22 Mar 2009 04:24:39 +0000
parents bc2fae9438eb
children bb2665c7005c
files ChangeLog lwlink/link.c lwlink/lwlink.h lwlink/main.c lwlink/output.c lwlink/script.c
diffstat 6 files changed, 109 insertions(+), 6 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog	Sat Mar 21 19:49:01 2009 +0000
+++ b/ChangeLog	Sun Mar 22 04:24:39 2009 +0000
@@ -13,10 +13,11 @@
 
 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
+[+] 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)
-[*] added ability to output a "linkmap" to lwlink (--map, -m)
+[+] added ability to output a "linkmap" to lwlink (--map, -m)
+[+] added LWEX0 (LWOS simple binary) target to LWLINK
 [b] arranged for output files for lwasm/lwlink to be removed if the assembly
     or linking fails
 [ ] DECB output of LWLINK now collapses contiguous output blocks into single
--- a/lwlink/link.c	Sat Mar 21 19:49:01 2009 +0000
+++ b/lwlink/link.c	Sun Mar 22 04:24:39 2009 +0000
@@ -327,8 +327,16 @@
 		lw_expr_stack_t *s;
 		
 		s = resolve_sym(linkscript.execsym, 0, NULL);
-		linkscript.execaddr = lw_expr_get_value(s);
-		lw_expr_stack_free(s);
+		if (!s)
+		{
+			fprintf(stderr, "Cannot resolve exec address '%s'\n", linkscript.execsym);
+			symerr = 1;
+		}
+		else
+		{
+			linkscript.execaddr = lw_expr_get_value(s);
+			lw_expr_stack_free(s);
+		}
 	}
 	
 	for (sn = 0; sn < nsects; sn++)
--- a/lwlink/lwlink.h	Sat Mar 21 19:49:01 2009 +0000
+++ b/lwlink/lwlink.h	Sun Mar 22 04:24:39 2009 +0000
@@ -28,6 +28,7 @@
 
 #define OUTPUT_DECB		0	// DECB multirecord format
 #define OUTPUT_RAW		1	// raw sequence of bytes
+#define OUTPUT_LWEX0	2	// LWOS LWEX binary version 0
 
 typedef struct symtab_s symtab_t;
 struct symtab_s
@@ -139,6 +140,7 @@
 	int padsize;				// the size to pad to, -1 for none
 	char *execsym;				// entry point symbol
 	int execaddr;				// execution address (entry point)
+	int stacksize;				// stack size
 } linkscript_t;
 
 #ifndef __script_c_seen__
--- a/lwlink/main.c	Sat Mar 21 19:49:01 2009 +0000
+++ b/lwlink/main.c	Sun Mar 22 04:24:39 2009 +0000
@@ -73,6 +73,8 @@
 			outformat = OUTPUT_DECB;
 		else if (!strcasecmp(arg, "raw"))
 			outformat = OUTPUT_RAW;
+		else if (!strcasecmp(arg, "lwex0") || !strcasecmp(arg, "lwex"))
+			outformat = OUTPUT_LWEX0;
 		else
 		{
 			fprintf(stderr, "Invalid output format: %s\n", arg);
@@ -118,7 +120,7 @@
 	{ "debug",		'd',	0,		0,
 				"Set debug mode"},
 	{ "format",		'f',	"TYPE",	0,
-				"Select output format: decb, raw"},
+				"Select output format: decb, raw, lwex"},
 	{ "decb",		'b',	0,		0,
 				"Generate DECB .bin format output, equivalent of --format=decb"},
 	{ "raw",		'r',	0,		0,
--- a/lwlink/output.c	Sat Mar 21 19:49:01 2009 +0000
+++ b/lwlink/output.c	Sun Mar 22 04:24:39 2009 +0000
@@ -27,6 +27,7 @@
 
 #include <stdio.h>
 #include <stdlib.h>
+#include <string.h>
 
 #include "lwlink.h"
 
@@ -37,6 +38,7 @@
 
 void do_output_decb(FILE *of);
 void do_output_raw(FILE *of);
+void do_output_lwex0(FILE *of);
 
 void do_output(void)
 {
@@ -59,6 +61,10 @@
 	case OUTPUT_RAW:
 		do_output_raw(of);
 		break;
+
+	case OUTPUT_LWEX0:
+		do_output_lwex0(of);
+		break;
 	
 	default:
 		fprintf(stderr, "Unknown output format doing output!\n");
@@ -152,3 +158,62 @@
 		writebytes(sectlist[sn].ptr -> code, 1, sectlist[sn].ptr -> codesize, of);
 	}
 }
+
+void do_output_lwex0(FILE *of)
+{
+	int nskips = 0;		// used to output blanks for BSS inline
+	int sn;
+	int codedatasize = 0;
+	unsigned char buf[32];
+	
+	// calculate items for the file header
+	for (sn = 0; sn < nsects; sn++)
+	{
+		if (sectlist[sn].ptr -> flags & SECTION_BSS)
+		{
+			// no output for a BSS section
+			nskips += sectlist[sn].ptr -> codesize;
+			continue;
+		}
+		codedatasize += nskips;
+		nskips = 0;
+		codedatasize += sectlist[sn].ptr -> codesize;
+	}
+
+	// output the file header
+	buf[0] = 'L';
+	buf[1] = 'W';
+	buf[2] = 'E';
+	buf[3] = 'X';
+	buf[4] = 0;		// version 0
+	buf[5] = 0;		// low stack
+	buf[6] = linkscript.stacksize / 256;
+	buf[7] = linkscript.stacksize & 0xff;
+	buf[8] = nskips / 256;
+	buf[9] = nskips & 0xff;
+	buf[10] = codedatasize / 256;
+	buf[11] = codedatasize & 0xff;
+	buf[12] = linkscript.execaddr / 256;
+	buf[13] = linkscript.execaddr & 0xff;
+	memset(buf + 14, 0, 18);
+	
+	writebytes(buf, 1, 32, of);
+	// output the data
+	// NOTE: disjoint load addresses will not work correctly!!!!!
+	for (sn = 0; sn < nsects; sn++)
+	{
+		if (sectlist[sn].ptr -> flags & SECTION_BSS)
+		{
+			// no output for a BSS section
+			nskips += sectlist[sn].ptr -> codesize;
+			continue;
+		}
+		while (nskips > 0)
+		{
+			// the "" is not an error - it turns into a single NUL byte!
+			writebytes("", 1, 1, of);
+			nskips--;
+		}
+		writebytes(sectlist[sn].ptr -> code, 1, sectlist[sn].ptr -> codesize, of);
+	}
+}
--- a/lwlink/script.c	Sat Mar 21 19:49:01 2009 +0000
+++ b/lwlink/script.c	Sun Mar 22 04:24:39 2009 +0000
@@ -50,6 +50,16 @@
 	"section *,bss\n"
 	;
 
+static char *lwex0_script =
+	"section init load 0100\n"
+	"section .text\n"
+	"section .data\n"
+	"section *,!bss\n"
+	"section *,bss\n"
+	"entry _start\n"
+	"stacksize 0100\n"		// default 256 byte stack
+	;
+
 // the "simple" script
 static char *simple_script = 
 	"section *,!bss\n"
@@ -107,6 +117,10 @@
 			script = decb_script;
 			break;
 		
+		case OUTPUT_LWEX0:
+			script = lwex0_script;
+			break;
+			
 		default:
 			script = simple_script;
 			break;
@@ -132,6 +146,9 @@
 		}
 	}
 
+	if (outformat == OUTPUT_LWEX0)
+		linkscript.stacksize = 0x100;
+
 	oscript = script;
 	// now parse the script file
 	while (*script)
@@ -177,6 +194,14 @@
 			if (linkscript.padsize < 0)
 				linkscript.padsize = 0;
 		}
+		else if (!strcmp(line, "stacksize"))
+		{
+			// stack size for targets that support it
+			// parse the hex number and stow it
+			linkscript.padsize = strtol(ptr, NULL, 16);
+			if (linkscript.stacksize < 0)
+				linkscript.stacksize = 0x100;
+		}
 		else if (!strcmp(line, "entry"))
 		{
 			int eaddr;