# HG changeset patch # User lost # Date 1237695879 0 # Node ID 857cb407229e4a7889fc804b1ba168d7f67ca143 # Parent bc2fae9438eb89039618be7c8079566844fbbaa8 Added LWEX0 (LWOS simple binary) target to lwlink diff -r bc2fae9438eb -r 857cb407229e ChangeLog --- 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 diff -r bc2fae9438eb -r 857cb407229e lwlink/link.c --- 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++) diff -r bc2fae9438eb -r 857cb407229e lwlink/lwlink.h --- 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__ diff -r bc2fae9438eb -r 857cb407229e lwlink/main.c --- 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, diff -r bc2fae9438eb -r 857cb407229e lwlink/output.c --- 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 #include +#include #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); + } +} diff -r bc2fae9438eb -r 857cb407229e lwlink/script.c --- 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;