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 }