Mercurial > hg-old > index.cgi
diff lwlink/link.c @ 205:42df94f30d82
checkpoint
author | lost |
---|---|
date | Sun, 19 Apr 2009 17:44:46 +0000 |
parents | 048ebb85f6ef |
children | 299c5d793aca |
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 +}