# HG changeset patch # User lost # Date 1240163086 0 # Node ID 42df94f30d8200f4074cb5ad04a8cbcf67a49c74 # Parent 048ebb85f6ef8f2d989938abc993b85e237d3b2e checkpoint diff -r 048ebb85f6ef -r 42df94f30d82 lwlink/link.c --- 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 +} diff -r 048ebb85f6ef -r 42df94f30d82 lwlink/lwlink.c --- 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); } diff -r 048ebb85f6ef -r 42df94f30d82 lwlink/lwlink.h --- 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; diff -r 048ebb85f6ef -r 42df94f30d82 lwlink/main.c --- 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(); diff -r 048ebb85f6ef -r 42df94f30d82 lwlink/readfiles.c --- 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)