Mercurial > hg-old > index.cgi
comparison lwlink/link.c @ 248:e8d70b95ec41 2.x
Fixed various problems with determining which files to include in the output and also fixed problem identifying which files actually resolved symbols
author | lost |
---|---|
date | Sun, 22 Nov 2009 05:46:31 +0000 |
parents | eb499c146c0d |
children |
comparison
equal
deleted
inserted
replaced
247:d8b5ff5c4ef9 | 248:e8d70b95ec41 |
---|---|
31 #include "util.h" | 31 #include "util.h" |
32 | 32 |
33 struct section_list *sectlist = NULL; | 33 struct section_list *sectlist = NULL; |
34 int nsects = 0; | 34 int nsects = 0; |
35 static int nforced = 0; | 35 static int nforced = 0; |
36 static fileinfo_t *lookingfrom; | |
36 | 37 |
37 void check_section_name(char *name, int *base, fileinfo_t *fn) | 38 void check_section_name(char *name, int *base, fileinfo_t *fn) |
38 { | 39 { |
39 int sn; | 40 int sn; |
40 | 41 |
41 if (fn -> forced == 0) | 42 if (fn -> forced != 0) |
42 return; | 43 { |
43 | 44 for (sn = 0; sn < fn -> nsections; sn++) |
44 for (sn = 0; sn < fn -> nsections; sn++) | 45 { |
45 { | 46 if (!strcmp(name, fn -> sections[sn].name)) |
46 if (!strcmp(name, fn -> sections[sn].name)) | 47 { |
47 { | 48 // we have a match |
48 // we have a match | 49 sectlist = lw_realloc(sectlist, sizeof(struct section_list) * (nsects + 1)); |
49 sectlist = lw_realloc(sectlist, sizeof(struct section_list) * (nsects + 1)); | 50 sectlist[nsects].ptr = &(fn -> sections[sn]); |
50 sectlist[nsects].ptr = &(fn -> sections[sn]); | |
51 | 51 |
52 fn -> sections[sn].processed = 1; | 52 fn -> sections[sn].processed = 1; |
53 fn -> sections[sn].loadaddress = *base; | 53 fn -> sections[sn].loadaddress = *base; |
54 *base += fn -> sections[sn].codesize; | 54 *base += fn -> sections[sn].codesize; |
55 nsects++; | 55 nsects++; |
56 } | |
56 } | 57 } |
57 } | 58 } |
58 for (sn = 0; sn < fn -> nsubs; sn++) | 59 for (sn = 0; sn < fn -> nsubs; sn++) |
59 { | 60 { |
60 check_section_name(name, base, fn -> subs[sn]); | 61 check_section_name(name, base, fn -> subs[sn]); |
64 void add_matching_sections(char *name, int yesflags, int noflags, int *base); | 65 void add_matching_sections(char *name, int yesflags, int noflags, int *base); |
65 void check_section_flags(int yesflags, int noflags, int *base, fileinfo_t *fn) | 66 void check_section_flags(int yesflags, int noflags, int *base, fileinfo_t *fn) |
66 { | 67 { |
67 int sn; | 68 int sn; |
68 | 69 |
69 if (fn -> forced == 0) | 70 if (fn -> forced != 0) |
70 return; | 71 { |
71 | 72 for (sn = 0; sn < fn -> nsections; sn++) |
72 for (sn = 0; sn < fn -> nsections; sn++) | 73 { |
73 { | 74 // ignore if the noflags tell us to |
74 // ignore if the noflags tell us to | 75 if (noflags && (fn -> sections[sn].flags & noflags)) |
75 if (noflags && (fn -> sections[sn].flags & noflags)) | 76 continue; |
76 continue; | 77 // ignore unless the yesflags tell us not to |
77 // ignore unless the yesflags tell us not to | 78 if (yesflags && (fn -> sections[sn].flags & yesflags == 0)) |
78 if (yesflags && (fn -> sections[sn].flags & yesflags == 0)) | 79 continue; |
79 continue; | 80 // ignore it if already processed |
80 // ignore it if already processed | 81 if (fn -> sections[sn].processed) |
81 if (fn -> sections[sn].processed) | 82 continue; |
82 continue; | 83 |
83 | 84 // we have a match - now collect *all* sections of the same name! |
84 // we have a match - now collect *all* sections of the same name! | 85 add_matching_sections(fn -> sections[sn].name, 0, 0, base); |
85 add_matching_sections(fn -> sections[sn].name, 0, 0, base); | 86 |
86 | 87 // and then continue looking for sections |
87 // and then continue looking for sections | 88 } |
88 } | 89 } |
89 for (sn = 0; sn < fn -> nsubs; sn++) | 90 for (sn = 0; sn < fn -> nsubs; sn++) |
90 { | 91 { |
91 check_section_flags(yesflags, noflags, base, fn -> subs[sn]); | 92 check_section_flags(yesflags, noflags, base, fn -> subs[sn]); |
92 } | 93 } |
211 { | 212 { |
212 if (!strcmp(sym, se -> sym)) | 213 if (!strcmp(sym, se -> sym)) |
213 { | 214 { |
214 if (!(fn -> forced)) | 215 if (!(fn -> forced)) |
215 { | 216 { |
216 // fprintf(stderr, "Forced inclusion of %s due to symbol reference\n", fn -> filename); | 217 // we if this isn't a true external reference, don't force inclusion |
218 // (without an external reference, internal references don't matter) | |
219 if (fn == lookingfrom) | |
220 continue; | |
221 // fprintf(stderr, "Forced inclusion of %s due to symbol reference (%s) from (%s)\n", fn -> filename, sym, lookingfrom ? lookingfrom -> filename : "<none>"); | |
217 fn -> forced = 1; | 222 fn -> forced = 1; |
218 nforced = 1; | 223 nforced = 1; |
219 } | 224 } |
225 fn -> resolves = 1; | |
220 val = se -> offset + fn -> sections[sn].loadaddress; | 226 val = se -> offset + fn -> sections[sn].loadaddress; |
221 r = lw_expr_stack_create(); | 227 r = lw_expr_stack_create(); |
222 term = lw_expr_term_create_int(val & 0xffff); | 228 term = lw_expr_term_create_int(val & 0xffff); |
223 lw_expr_stack_push(r, term); | 229 lw_expr_stack_push(r, term); |
224 lw_expr_term_free(term); | 230 lw_expr_term_free(term); |
230 for (sn = 0; sn < fn -> nsubs; sn++) | 236 for (sn = 0; sn < fn -> nsubs; sn++) |
231 { | 237 { |
232 r = find_external_sym_recurse(sym, fn -> subs[sn]); | 238 r = find_external_sym_recurse(sym, fn -> subs[sn]); |
233 if (r) | 239 if (r) |
234 { | 240 { |
235 if (!(fn -> forced)) | 241 // don't do this when recursing - the sub file will already be set if needed |
236 { | 242 // if (!(fn -> forced)) |
237 nforced = 1; | 243 // { |
238 fn -> forced = 1; | 244 // fprintf(stderr, "Forced inclusion of %s due to symbol reference (%s)\n", fn -> filename, sym); |
239 } | 245 // nforced = 1; |
246 // fn -> forced = 1; | |
247 // } | |
248 if (r) | |
249 fn -> resolves = 1; | |
240 return r; | 250 return r; |
241 } | 251 } |
242 } | 252 } |
243 return NULL; | 253 return NULL; |
244 } | 254 } |
344 // first instance of that symbol | 354 // first instance of that symbol |
345 if (linkscript.execsym) | 355 if (linkscript.execsym) |
346 { | 356 { |
347 lw_expr_stack_t *s; | 357 lw_expr_stack_t *s; |
348 | 358 |
359 lookingfrom = NULL; | |
349 s = resolve_sym(linkscript.execsym, 0, NULL); | 360 s = resolve_sym(linkscript.execsym, 0, NULL); |
350 if (!s) | 361 if (!s) |
351 { | 362 { |
352 fprintf(stderr, "Cannot resolve exec address '%s'\n", linkscript.execsym); | 363 fprintf(stderr, "Cannot resolve exec address '%s'\n", linkscript.execsym); |
353 symerr = 1; | 364 symerr = 1; |
361 | 372 |
362 for (sn = 0; sn < nsects; sn++) | 373 for (sn = 0; sn < nsects; sn++) |
363 { | 374 { |
364 for (rl = sectlist[sn].ptr -> incompletes; rl; rl = rl -> next) | 375 for (rl = sectlist[sn].ptr -> incompletes; rl; rl = rl -> next) |
365 { | 376 { |
377 lookingfrom = sectlist[sn].ptr -> file; | |
366 // do a "simplify" on the expression | 378 // do a "simplify" on the expression |
367 rval = lw_expr_reval(rl -> expr, resolve_sym, sectlist[sn].ptr); | 379 rval = lw_expr_reval(rl -> expr, resolve_sym, sectlist[sn].ptr); |
368 | 380 |
369 // is it constant? error out if not | 381 // is it constant? error out if not |
370 if (rval != 0 || !lw_expr_is_constant(rl -> expr)) | 382 if (rval != 0 || !lw_expr_is_constant(rl -> expr)) |
407 lw_expr_stack_t *te; | 419 lw_expr_stack_t *te; |
408 reloc_t *rl; | 420 reloc_t *rl; |
409 | 421 |
410 if (fn -> forced != 0) | 422 if (fn -> forced != 0) |
411 { | 423 { |
424 lookingfrom = fn; | |
412 for (sn = 0; sn < fn -> nsections; sn++) | 425 for (sn = 0; sn < fn -> nsections; sn++) |
413 { | 426 { |
414 for (rl = fn -> sections[sn].incompletes; rl; rl = rl -> next) | 427 for (rl = fn -> sections[sn].incompletes; rl; rl = rl -> next) |
415 { | 428 { |
416 // do a "simplify" on the expression | 429 // do a "simplify" on the expression |
436 { | 449 { |
437 int sn; | 450 int sn; |
438 int fn; | 451 int fn; |
439 reloc_t *rl; | 452 reloc_t *rl; |
440 lw_expr_stack_t *te; | 453 lw_expr_stack_t *te; |
441 int c = 0; | 454 // int c = 0; |
442 | 455 |
443 int rval; | 456 int rval; |
444 | 457 |
445 // resolve entry point if required | 458 // resolve entry point if required |
446 // this must resolve to an *exported* symbol and will resolve to the | 459 // this must resolve to an *exported* symbol and will resolve to the |
447 // first instance of that symbol | 460 // first instance of that symbol |
448 if (linkscript.execsym) | 461 if (linkscript.execsym) |
449 { | 462 { |
450 lw_expr_stack_t *s; | 463 lw_expr_stack_t *s; |
451 | 464 |
465 lookingfrom = NULL; | |
452 s = resolve_sym(linkscript.execsym, 0, NULL); | 466 s = resolve_sym(linkscript.execsym, 0, NULL); |
453 if (!s) | 467 if (!s) |
454 { | 468 { |
455 fprintf(stderr, "Cannot resolve exec address '%s'\n", linkscript.execsym); | 469 fprintf(stderr, "Cannot resolve exec address '%s'\n", linkscript.execsym); |
456 symerr = 1; | 470 symerr = 1; |
460 do | 474 do |
461 { | 475 { |
462 nforced = 0; | 476 nforced = 0; |
463 for (fn = 0; fn < ninputfiles; fn++) | 477 for (fn = 0; fn < ninputfiles; fn++) |
464 { | 478 { |
465 if (inputfiles[fn] -> forced == 0) | |
466 continue; | |
467 | |
468 resolve_files_aux(inputfiles[fn]); | 479 resolve_files_aux(inputfiles[fn]); |
469 } | 480 } |
470 // fprintf(stderr, "File resolution pass %d, nforced = %d\n", ++c, nforced); | 481 // fprintf(stderr, "File resolution pass %d, nforced = %d\n", ++c, nforced); |
471 } | 482 } |
472 while (nforced == 1); | 483 while (nforced == 1); |
475 exit(1); | 486 exit(1); |
476 | 487 |
477 // theoretically, all files referenced by other files now have "forced" set to 1 | 488 // theoretically, all files referenced by other files now have "forced" set to 1 |
478 for (fn = 0; fn < ninputfiles; fn++) | 489 for (fn = 0; fn < ninputfiles; fn++) |
479 { | 490 { |
480 if (inputfiles[fn] -> forced == 1) | 491 if (inputfiles[fn] -> forced == 1 || inputfiles[fn] -> resolves == 1) |
481 continue; | 492 continue; |
482 | 493 |
483 fprintf(stderr, "Warning: %s (%d) does not resolve any symbols\n", inputfiles[fn] -> filename, fn); | 494 fprintf(stderr, "Warning: %s (%d) does not resolve any symbols\n", inputfiles[fn] -> filename, fn); |
484 } | 495 } |
485 } | 496 } |