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 }