Mercurial > hg-old > index.cgi
comparison lwlink/link.c @ 205:42df94f30d82
checkpoint
author | lost |
---|---|
date | Sun, 19 Apr 2009 17:44:46 +0000 |
parents | 048ebb85f6ef |
children | 299c5d793aca |
comparison
equal
deleted
inserted
replaced
204:048ebb85f6ef | 205:42df94f30d82 |
---|---|
32 #include "lwlink.h" | 32 #include "lwlink.h" |
33 #include "util.h" | 33 #include "util.h" |
34 | 34 |
35 struct section_list *sectlist = NULL; | 35 struct section_list *sectlist = NULL; |
36 int nsects = 0; | 36 int nsects = 0; |
37 static int nforced = 0; | |
37 | 38 |
38 void check_section_name(char *name, int *base, fileinfo_t *fn) | 39 void check_section_name(char *name, int *base, fileinfo_t *fn) |
39 { | 40 { |
40 int sn; | 41 int sn; |
42 | |
43 if (fn -> forced == 0) | |
44 return; | |
45 | |
41 for (sn = 0; sn < fn -> nsections; sn++) | 46 for (sn = 0; sn < fn -> nsections; sn++) |
42 { | 47 { |
43 if (!strcmp(name, fn -> sections[sn].name)) | 48 if (!strcmp(name, fn -> sections[sn].name)) |
44 { | 49 { |
45 // we have a match | 50 // we have a match |
60 | 65 |
61 void add_matching_sections(char *name, int yesflags, int noflags, int *base); | 66 void add_matching_sections(char *name, int yesflags, int noflags, int *base); |
62 void check_section_flags(int yesflags, int noflags, int *base, fileinfo_t *fn) | 67 void check_section_flags(int yesflags, int noflags, int *base, fileinfo_t *fn) |
63 { | 68 { |
64 int sn; | 69 int sn; |
70 | |
71 if (fn -> forced == 0) | |
72 return; | |
73 | |
65 for (sn = 0; sn < fn -> nsections; sn++) | 74 for (sn = 0; sn < fn -> nsections; sn++) |
66 { | 75 { |
67 // ignore if the noflags tell us to | 76 // ignore if the noflags tell us to |
68 if (noflags && (fn -> sections[sn].flags & noflags)) | 77 if (noflags && (fn -> sections[sn].flags & noflags)) |
69 continue; | 78 continue; |
202 { | 211 { |
203 for (se = fn -> sections[sn].exportedsyms; se; se = se -> next) | 212 for (se = fn -> sections[sn].exportedsyms; se; se = se -> next) |
204 { | 213 { |
205 if (!strcmp(sym, se -> sym)) | 214 if (!strcmp(sym, se -> sym)) |
206 { | 215 { |
216 if (!(fn -> forced)) | |
217 { | |
218 fn -> forced = 1; | |
219 nforced = 1; | |
220 } | |
207 val = se -> offset + fn -> sections[sn].loadaddress; | 221 val = se -> offset + fn -> sections[sn].loadaddress; |
208 r = lw_expr_stack_create(); | 222 r = lw_expr_stack_create(); |
209 term = lw_expr_term_create_int(val & 0xffff); | 223 term = lw_expr_term_create_int(val & 0xffff); |
210 lw_expr_stack_push(r, term); | 224 lw_expr_stack_push(r, term); |
211 lw_expr_term_free(term); | 225 lw_expr_term_free(term); |
216 | 230 |
217 for (sn = 0; sn < fn -> nsubs; sn++) | 231 for (sn = 0; sn < fn -> nsubs; sn++) |
218 { | 232 { |
219 r = find_external_sym_recurse(sym, fn -> subs[sn]); | 233 r = find_external_sym_recurse(sym, fn -> subs[sn]); |
220 if (r) | 234 if (r) |
235 { | |
236 if (!(fn -> forced)) | |
237 { | |
238 nforced = 1; | |
239 fn -> forced = 1; | |
240 } | |
221 return r; | 241 return r; |
242 } | |
222 } | 243 } |
223 return NULL; | 244 return NULL; |
224 } | 245 } |
225 | 246 |
226 // resolve all incomplete references now | 247 // resolve all incomplete references now |
370 } | 391 } |
371 | 392 |
372 if (symerr) | 393 if (symerr) |
373 exit(1); | 394 exit(1); |
374 } | 395 } |
396 | |
397 /* | |
398 This is just a pared down version of the algo for resolving references. | |
399 */ | |
400 void resolve_files(void) | |
401 { | |
402 int sn; | |
403 int fn; | |
404 reloc_t *rl; | |
405 int rval; | |
406 | |
407 // resolve entry point if required | |
408 // this must resolve to an *exported* symbol and will resolve to the | |
409 // first instance of that symbol | |
410 if (linkscript.execsym) | |
411 { | |
412 lw_expr_stack_t *s; | |
413 | |
414 s = resolve_sym(linkscript.execsym, 0, NULL); | |
415 if (!s) | |
416 { | |
417 fprintf(stderr, "Cannot resolve exec address '%s'\n", linkscript.execsym); | |
418 symerr = 1; | |
419 } | |
420 } | |
421 | |
422 do | |
423 { | |
424 nforced = 0; | |
425 for (fn = 0; fn < ninputfiles; fn++) | |
426 { | |
427 if (inputfiles[fn] -> forced == 0) | |
428 continue; | |
429 | |
430 for (sn = 0; sn < inputfiles[fn] -> nsections; sn++) | |
431 { | |
432 for (rl = inputfiles[fn] -> sections[sn].incompletes; rl; rl = rl -> next) | |
433 { | |
434 // do a "simplify" on the expression | |
435 rval = lw_expr_reval(rl -> expr, resolve_sym, &(inputfiles[fn] -> sections[sn])); | |
436 | |
437 // is it constant? error out if not | |
438 if (rval != 0 || !lw_expr_is_constant(rl -> expr)) | |
439 { | |
440 fprintf(stderr, "Incomplete reference at %s:%s+%02X\n", inputfiles[fn] -> filename, inputfiles[fn] -> sections[sn].name, rl -> offset); | |
441 symerr = 1; | |
442 } | |
443 } | |
444 } | |
445 } | |
446 } | |
447 while (nforced == 1); | |
448 | |
449 if (symerr) | |
450 exit(1); | |
451 | |
452 // theoretically, all files referenced by other files now have "forced" set to 1 | |
453 } |