Mercurial > hg-old > index.cgi
annotate lwlink/link.c @ 245:eb499c146c0d 2.x
Fixed selection of objects for inclusion from within libraries to actually resolve references correctly
author | lost |
---|---|
date | Thu, 19 Nov 2009 00:51:31 +0000 |
parents | f9f01a499525 |
children | e8d70b95ec41 |
rev | line source |
---|---|
119 | 1 /* |
2 link.c | |
3 Copyright © 2009 William Astle | |
4 | |
5 This file is part of LWLINK. | |
6 | |
7 LWLINK is free software: you can redistribute it and/or modify it under the | |
8 terms of the GNU General Public License as published by the Free Software | |
9 Foundation, either version 3 of the License, or (at your option) any later | |
10 version. | |
11 | |
12 This program is distributed in the hope that it will be useful, but WITHOUT | |
13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | |
15 more details. | |
16 | |
17 You should have received a copy of the GNU General Public License along with | |
18 this program. If not, see <http://www.gnu.org/licenses/>. | |
19 | |
20 | |
21 Resolve section and symbol addresses; handle incomplete references | |
22 */ | |
23 | |
212 | 24 #include <config.h> |
119 | 25 |
120 | 26 #include <stdio.h> |
119 | 27 #include <stdlib.h> |
28 | |
120 | 29 #include "expr.h" |
119 | 30 #include "lwlink.h" |
31 #include "util.h" | |
32 | |
121 | 33 struct section_list *sectlist = NULL; |
34 int nsects = 0; | |
205 | 35 static int nforced = 0; |
119 | 36 |
171 | 37 void check_section_name(char *name, int *base, fileinfo_t *fn) |
38 { | |
39 int sn; | |
205 | 40 |
41 if (fn -> forced == 0) | |
42 return; | |
43 | |
171 | 44 for (sn = 0; sn < fn -> nsections; sn++) |
45 { | |
46 if (!strcmp(name, fn -> sections[sn].name)) | |
47 { | |
48 // we have a match | |
49 sectlist = lw_realloc(sectlist, sizeof(struct section_list) * (nsects + 1)); | |
50 sectlist[nsects].ptr = &(fn -> sections[sn]); | |
51 | |
52 fn -> sections[sn].processed = 1; | |
53 fn -> sections[sn].loadaddress = *base; | |
54 *base += fn -> sections[sn].codesize; | |
55 nsects++; | |
56 } | |
57 } | |
173 | 58 for (sn = 0; sn < fn -> nsubs; sn++) |
171 | 59 { |
60 check_section_name(name, base, fn -> subs[sn]); | |
61 } | |
62 } | |
63 | |
64 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 { | |
67 int sn; | |
205 | 68 |
69 if (fn -> forced == 0) | |
70 return; | |
71 | |
171 | 72 for (sn = 0; sn < fn -> nsections; sn++) |
73 { | |
74 // ignore if the noflags tell us to | |
75 if (noflags && (fn -> sections[sn].flags & noflags)) | |
76 continue; | |
77 // ignore unless the yesflags tell us not to | |
78 if (yesflags && (fn -> sections[sn].flags & yesflags == 0)) | |
79 continue; | |
80 // ignore it if already processed | |
81 if (fn -> sections[sn].processed) | |
82 continue; | |
83 | |
84 // we have a match - now collect *all* sections of the same name! | |
85 add_matching_sections(fn -> sections[sn].name, 0, 0, base); | |
86 | |
87 // and then continue looking for sections | |
88 } | |
173 | 89 for (sn = 0; sn < fn -> nsubs; sn++) |
171 | 90 { |
91 check_section_flags(yesflags, noflags, base, fn -> subs[sn]); | |
92 } | |
93 } | |
94 | |
95 | |
96 | |
97 void add_matching_sections(char *name, int yesflags, int noflags, int *base) | |
98 { | |
99 int fn; | |
100 if (name) | |
101 { | |
102 // named section | |
103 // look for all instances of a section by the specified name | |
104 // and resolve base addresses and add to the list | |
105 for (fn = 0; fn < ninputfiles; fn++) | |
106 { | |
107 check_section_name(name, base, inputfiles[fn]); | |
108 } | |
109 } | |
110 else | |
111 { | |
112 // wildcard section | |
113 // named section | |
114 // look for all instances of a section by the specified name | |
115 // and resolve base addresses and add to the list | |
116 for (fn = 0; fn < ninputfiles; fn++) | |
117 { | |
118 check_section_flags(yesflags, noflags, base, inputfiles[fn]); | |
119 } | |
120 } | |
121 } | |
122 | |
119 | 123 // work out section load order and resolve base addresses for each section |
124 // make a list of sections to load in order | |
125 void resolve_sections(void) | |
126 { | |
127 int laddr = 0; | |
128 int ln, sn, fn; | |
129 | |
130 for (ln = 0; ln < linkscript.nlines; ln++) | |
131 { | |
171 | 132 if (linkscript.lines[ln].loadat >= 0) |
133 laddr = linkscript.lines[ln].loadat; | |
134 add_matching_sections(linkscript.lines[ln].sectname, linkscript.lines[ln].yesflags, linkscript.lines[ln].noflags, &laddr); | |
135 | |
119 | 136 if (linkscript.lines[ln].sectname) |
137 { | |
138 } | |
139 else | |
140 { | |
141 // wildcard section | |
142 // look for all sections not yet processed that match flags | |
143 | |
144 int f = 0; | |
145 int fn0, sn0; | |
146 char *sname; | |
147 | |
148 // named section | |
149 // look for all instances of a section by the specified name | |
150 // and resolve base addresses and add to the list | |
151 for (fn0 = 0; fn0 < ninputfiles; fn0++) | |
152 { | |
153 for (sn0 = 0; sn0 < inputfiles[fn0] -> nsections; sn0++) | |
154 { | |
155 // ignore if the "no flags" bit says to | |
156 if (linkscript.lines[ln].noflags && (inputfiles[fn0] -> sections[sn0].flags & linkscript.lines[ln].noflags)) | |
157 continue; | |
158 // ignore unless the yes flags tell us not to | |
159 if (linkscript.lines[ln].yesflags && (inputfiles[fn0] -> sections[sn0].flags & linkscript.lines[ln].yesflags == 0)) | |
160 continue; | |
161 if (inputfiles[fn0] -> sections[sn0].processed == 0) | |
162 { | |
163 sname = inputfiles[fn0] -> sections[sn0].name; | |
164 for (fn = 0; fn < ninputfiles; fn++) | |
165 { | |
166 for (sn = 0; sn < inputfiles[fn] -> nsections; sn++) | |
167 { | |
168 if (!strcmp(sname, inputfiles[fn] -> sections[sn].name)) | |
169 { | |
170 // we have a match | |
171 sectlist = lw_realloc(sectlist, sizeof(struct section_list) * (nsects + 1)); | |
172 sectlist[nsects].ptr = &(inputfiles[fn] -> sections[sn]); | |
173 | |
174 inputfiles[fn] -> sections[sn].processed = 1; | |
175 if (!f && linkscript.lines[ln].loadat >= 0) | |
176 { | |
177 f = 1; | |
178 sectlist[nsects].forceaddr = 1; | |
179 laddr = linkscript.lines[ln].loadat; | |
180 } | |
181 else | |
182 { | |
183 sectlist[nsects].forceaddr = 0; | |
184 } | |
185 inputfiles[fn] -> sections[sn].loadaddress = laddr; | |
131
5276565799bd
Fixed load addresses of chained sections and subsections to actually increment
lost
parents:
130
diff
changeset
|
186 laddr += inputfiles[fn] -> sections[sn].codesize; |
119 | 187 nsects++; |
188 } | |
189 } | |
190 } | |
191 } | |
192 } | |
193 } | |
194 } | |
195 } | |
196 | |
197 // theoretically, all the base addresses are set now | |
198 } | |
120 | 199 |
171 | 200 lw_expr_stack_t *find_external_sym_recurse(char *sym, fileinfo_t *fn) |
201 { | |
202 int sn; | |
203 lw_expr_stack_t *r; | |
204 lw_expr_term_t *term; | |
205 symtab_t *se; | |
206 int val; | |
207 | |
208 for (sn = 0; sn < fn -> nsections; sn++) | |
209 { | |
210 for (se = fn -> sections[sn].exportedsyms; se; se = se -> next) | |
211 { | |
212 if (!strcmp(sym, se -> sym)) | |
213 { | |
205 | 214 if (!(fn -> forced)) |
215 { | |
245
eb499c146c0d
Fixed selection of objects for inclusion from within libraries to actually resolve references correctly
lost
parents:
243
diff
changeset
|
216 // fprintf(stderr, "Forced inclusion of %s due to symbol reference\n", fn -> filename); |
205 | 217 fn -> forced = 1; |
218 nforced = 1; | |
219 } | |
171 | 220 val = se -> offset + fn -> sections[sn].loadaddress; |
221 r = lw_expr_stack_create(); | |
222 term = lw_expr_term_create_int(val & 0xffff); | |
223 lw_expr_stack_push(r, term); | |
224 lw_expr_term_free(term); | |
225 return r; | |
226 } | |
227 } | |
228 } | |
229 | |
230 for (sn = 0; sn < fn -> nsubs; sn++) | |
231 { | |
232 r = find_external_sym_recurse(sym, fn -> subs[sn]); | |
233 if (r) | |
205 | 234 { |
235 if (!(fn -> forced)) | |
236 { | |
237 nforced = 1; | |
238 fn -> forced = 1; | |
239 } | |
171 | 240 return r; |
205 | 241 } |
171 | 242 } |
243 return NULL; | |
244 } | |
245 | |
120 | 246 // resolve all incomplete references now |
247 // anything that is unresolvable at this stage will throw an error | |
248 // because we know the load address of every section now | |
249 lw_expr_stack_t *resolve_sym(char *sym, int symtype, void *state) | |
250 { | |
251 section_t *sect = state; | |
252 lw_expr_term_t *term; | |
253 int val = 0, i, fn; | |
254 lw_expr_stack_t *s; | |
255 symtab_t *se; | |
171 | 256 fileinfo_t *fp; |
257 | |
120 | 258 if (symtype == 1) |
259 { | |
260 // local symbol | |
261 if (!sym) | |
262 { | |
263 val = sect -> loadaddress; | |
264 goto out; | |
265 } | |
266 | |
267 // start with this section | |
268 for (se = sect -> localsyms; se; se = se -> next) | |
269 { | |
270 if (!strcmp(se -> sym, sym)) | |
271 { | |
272 val = se -> offset + sect -> loadaddress; | |
273 goto out; | |
274 } | |
275 } | |
276 // not in this section - check all sections in this file | |
277 for (i = 0; i < sect -> file -> nsections; i++) | |
278 { | |
279 for (se = sect -> file -> sections[i].localsyms; se; se = se -> next) | |
280 { | |
281 if (!strcmp(se -> sym, sym)) | |
282 { | |
283 val = se -> offset + sect -> file -> sections[i].loadaddress; | |
284 goto out; | |
285 } | |
286 } | |
287 } | |
288 // not found | |
184
220a760ec654
Make lwlink display all undefined references instead of bailing after the first one
lost
parents:
173
diff
changeset
|
289 symerr = 1; |
120 | 290 fprintf(stderr, "Local symbol %s not found in %s:%s\n", sym, sect -> file -> filename, sect -> name); |
184
220a760ec654
Make lwlink display all undefined references instead of bailing after the first one
lost
parents:
173
diff
changeset
|
291 goto outerr; |
120 | 292 } |
293 else | |
294 { | |
295 // external symbol | |
296 // read all files in order until found (or not found) | |
173 | 297 if (sect) |
171 | 298 { |
173 | 299 for (fp = sect -> file; fp; fp = fp -> parent) |
300 { | |
301 s = find_external_sym_recurse(sym, fp); | |
302 if (s) | |
303 return s; | |
304 } | |
171 | 305 } |
306 | |
120 | 307 for (fn = 0; fn < ninputfiles; fn++) |
308 { | |
171 | 309 s = find_external_sym_recurse(sym, inputfiles[fn]); |
310 if (s) | |
311 return s; | |
120 | 312 } |
130 | 313 if (sect) |
314 { | |
315 fprintf(stderr, "External symbol %s not found in %s:%s\n", sym, sect -> file -> filename, sect -> name); | |
316 } | |
317 else | |
318 { | |
319 fprintf(stderr, "External symbol %s not found\n", sym); | |
320 } | |
184
220a760ec654
Make lwlink display all undefined references instead of bailing after the first one
lost
parents:
173
diff
changeset
|
321 symerr = 1; |
220a760ec654
Make lwlink display all undefined references instead of bailing after the first one
lost
parents:
173
diff
changeset
|
322 goto outerr; |
120 | 323 } |
324 fprintf(stderr, "Shouldn't ever get here!!!\n"); | |
325 exit(88); | |
326 out: | |
327 s = lw_expr_stack_create(); | |
328 term = lw_expr_term_create_int(val & 0xffff); | |
329 lw_expr_stack_push(s, term); | |
330 lw_expr_term_free(term); | |
331 return s; | |
184
220a760ec654
Make lwlink display all undefined references instead of bailing after the first one
lost
parents:
173
diff
changeset
|
332 outerr: |
220a760ec654
Make lwlink display all undefined references instead of bailing after the first one
lost
parents:
173
diff
changeset
|
333 return NULL; |
120 | 334 } |
335 | |
336 void resolve_references(void) | |
337 { | |
338 int sn; | |
339 reloc_t *rl; | |
340 int rval; | |
121 | 341 |
342 // resolve entry point if required | |
343 // this must resolve to an *exported* symbol and will resolve to the | |
344 // first instance of that symbol | |
345 if (linkscript.execsym) | |
346 { | |
347 lw_expr_stack_t *s; | |
348 | |
349 s = resolve_sym(linkscript.execsym, 0, NULL); | |
187 | 350 if (!s) |
351 { | |
352 fprintf(stderr, "Cannot resolve exec address '%s'\n", linkscript.execsym); | |
353 symerr = 1; | |
354 } | |
355 else | |
356 { | |
357 linkscript.execaddr = lw_expr_get_value(s); | |
358 lw_expr_stack_free(s); | |
359 } | |
121 | 360 } |
120 | 361 |
124 | 362 for (sn = 0; sn < nsects; sn++) |
120 | 363 { |
364 for (rl = sectlist[sn].ptr -> incompletes; rl; rl = rl -> next) | |
365 { | |
366 // do a "simplify" on the expression | |
367 rval = lw_expr_reval(rl -> expr, resolve_sym, sectlist[sn].ptr); | |
368 | |
369 // is it constant? error out if not | |
370 if (rval != 0 || !lw_expr_is_constant(rl -> expr)) | |
371 { | |
184
220a760ec654
Make lwlink display all undefined references instead of bailing after the first one
lost
parents:
173
diff
changeset
|
372 fprintf(stderr, "Incomplete reference at %s:%s+%02X\n", sectlist[sn].ptr -> file -> filename, sectlist[sn].ptr -> name, rl -> offset); |
220a760ec654
Make lwlink display all undefined references instead of bailing after the first one
lost
parents:
173
diff
changeset
|
373 symerr = 1; |
120 | 374 } |
184
220a760ec654
Make lwlink display all undefined references instead of bailing after the first one
lost
parents:
173
diff
changeset
|
375 else |
220a760ec654
Make lwlink display all undefined references instead of bailing after the first one
lost
parents:
173
diff
changeset
|
376 { |
243 | 377 // is it a zero-width link? |
378 if (rl -> flags & RELOC_0BIT) | |
379 continue; | |
184
220a760ec654
Make lwlink display all undefined references instead of bailing after the first one
lost
parents:
173
diff
changeset
|
380 // put the value into the relocation address |
220a760ec654
Make lwlink display all undefined references instead of bailing after the first one
lost
parents:
173
diff
changeset
|
381 rval = lw_expr_get_value(rl -> expr); |
204
048ebb85f6ef
Added 8 bit external references for base page addressing mode
lost
parents:
187
diff
changeset
|
382 if (rl -> flags & RELOC_8BIT) |
048ebb85f6ef
Added 8 bit external references for base page addressing mode
lost
parents:
187
diff
changeset
|
383 { |
048ebb85f6ef
Added 8 bit external references for base page addressing mode
lost
parents:
187
diff
changeset
|
384 sectlist[sn].ptr -> code[rl -> offset] = rval & 0xff; |
048ebb85f6ef
Added 8 bit external references for base page addressing mode
lost
parents:
187
diff
changeset
|
385 } |
048ebb85f6ef
Added 8 bit external references for base page addressing mode
lost
parents:
187
diff
changeset
|
386 else |
048ebb85f6ef
Added 8 bit external references for base page addressing mode
lost
parents:
187
diff
changeset
|
387 { |
048ebb85f6ef
Added 8 bit external references for base page addressing mode
lost
parents:
187
diff
changeset
|
388 sectlist[sn].ptr -> code[rl -> offset] = (rval >> 8) & 0xff; |
048ebb85f6ef
Added 8 bit external references for base page addressing mode
lost
parents:
187
diff
changeset
|
389 sectlist[sn].ptr -> code[rl -> offset + 1] = rval & 0xff; |
048ebb85f6ef
Added 8 bit external references for base page addressing mode
lost
parents:
187
diff
changeset
|
390 } |
184
220a760ec654
Make lwlink display all undefined references instead of bailing after the first one
lost
parents:
173
diff
changeset
|
391 } |
120 | 392 } |
393 } | |
184
220a760ec654
Make lwlink display all undefined references instead of bailing after the first one
lost
parents:
173
diff
changeset
|
394 |
220a760ec654
Make lwlink display all undefined references instead of bailing after the first one
lost
parents:
173
diff
changeset
|
395 if (symerr) |
220a760ec654
Make lwlink display all undefined references instead of bailing after the first one
lost
parents:
173
diff
changeset
|
396 exit(1); |
120 | 397 } |
205 | 398 |
399 /* | |
400 This is just a pared down version of the algo for resolving references. | |
401 */ | |
245
eb499c146c0d
Fixed selection of objects for inclusion from within libraries to actually resolve references correctly
lost
parents:
243
diff
changeset
|
402 void resolve_files_aux(fileinfo_t *fn) |
eb499c146c0d
Fixed selection of objects for inclusion from within libraries to actually resolve references correctly
lost
parents:
243
diff
changeset
|
403 { |
eb499c146c0d
Fixed selection of objects for inclusion from within libraries to actually resolve references correctly
lost
parents:
243
diff
changeset
|
404 int n; |
eb499c146c0d
Fixed selection of objects for inclusion from within libraries to actually resolve references correctly
lost
parents:
243
diff
changeset
|
405 int sn; |
eb499c146c0d
Fixed selection of objects for inclusion from within libraries to actually resolve references correctly
lost
parents:
243
diff
changeset
|
406 int rval; |
eb499c146c0d
Fixed selection of objects for inclusion from within libraries to actually resolve references correctly
lost
parents:
243
diff
changeset
|
407 lw_expr_stack_t *te; |
eb499c146c0d
Fixed selection of objects for inclusion from within libraries to actually resolve references correctly
lost
parents:
243
diff
changeset
|
408 reloc_t *rl; |
eb499c146c0d
Fixed selection of objects for inclusion from within libraries to actually resolve references correctly
lost
parents:
243
diff
changeset
|
409 |
eb499c146c0d
Fixed selection of objects for inclusion from within libraries to actually resolve references correctly
lost
parents:
243
diff
changeset
|
410 if (fn -> forced != 0) |
eb499c146c0d
Fixed selection of objects for inclusion from within libraries to actually resolve references correctly
lost
parents:
243
diff
changeset
|
411 { |
eb499c146c0d
Fixed selection of objects for inclusion from within libraries to actually resolve references correctly
lost
parents:
243
diff
changeset
|
412 for (sn = 0; sn < fn -> nsections; sn++) |
eb499c146c0d
Fixed selection of objects for inclusion from within libraries to actually resolve references correctly
lost
parents:
243
diff
changeset
|
413 { |
eb499c146c0d
Fixed selection of objects for inclusion from within libraries to actually resolve references correctly
lost
parents:
243
diff
changeset
|
414 for (rl = fn -> sections[sn].incompletes; rl; rl = rl -> next) |
eb499c146c0d
Fixed selection of objects for inclusion from within libraries to actually resolve references correctly
lost
parents:
243
diff
changeset
|
415 { |
eb499c146c0d
Fixed selection of objects for inclusion from within libraries to actually resolve references correctly
lost
parents:
243
diff
changeset
|
416 // do a "simplify" on the expression |
eb499c146c0d
Fixed selection of objects for inclusion from within libraries to actually resolve references correctly
lost
parents:
243
diff
changeset
|
417 te = lw_expr_stack_dup(rl -> expr); |
eb499c146c0d
Fixed selection of objects for inclusion from within libraries to actually resolve references correctly
lost
parents:
243
diff
changeset
|
418 rval = lw_expr_reval(te, resolve_sym, &(fn -> sections[sn])); |
eb499c146c0d
Fixed selection of objects for inclusion from within libraries to actually resolve references correctly
lost
parents:
243
diff
changeset
|
419 |
eb499c146c0d
Fixed selection of objects for inclusion from within libraries to actually resolve references correctly
lost
parents:
243
diff
changeset
|
420 // is it constant? error out if not |
eb499c146c0d
Fixed selection of objects for inclusion from within libraries to actually resolve references correctly
lost
parents:
243
diff
changeset
|
421 if (rval != 0 || !lw_expr_is_constant(te)) |
eb499c146c0d
Fixed selection of objects for inclusion from within libraries to actually resolve references correctly
lost
parents:
243
diff
changeset
|
422 { |
eb499c146c0d
Fixed selection of objects for inclusion from within libraries to actually resolve references correctly
lost
parents:
243
diff
changeset
|
423 fprintf(stderr, "Incomplete reference at %s:%s+%02X\n", fn -> filename, fn -> sections[sn].name, rl -> offset); |
eb499c146c0d
Fixed selection of objects for inclusion from within libraries to actually resolve references correctly
lost
parents:
243
diff
changeset
|
424 symerr = 1; |
eb499c146c0d
Fixed selection of objects for inclusion from within libraries to actually resolve references correctly
lost
parents:
243
diff
changeset
|
425 } |
eb499c146c0d
Fixed selection of objects for inclusion from within libraries to actually resolve references correctly
lost
parents:
243
diff
changeset
|
426 lw_expr_stack_free(te); |
eb499c146c0d
Fixed selection of objects for inclusion from within libraries to actually resolve references correctly
lost
parents:
243
diff
changeset
|
427 } |
eb499c146c0d
Fixed selection of objects for inclusion from within libraries to actually resolve references correctly
lost
parents:
243
diff
changeset
|
428 } |
eb499c146c0d
Fixed selection of objects for inclusion from within libraries to actually resolve references correctly
lost
parents:
243
diff
changeset
|
429 } |
eb499c146c0d
Fixed selection of objects for inclusion from within libraries to actually resolve references correctly
lost
parents:
243
diff
changeset
|
430 // handle sub files |
eb499c146c0d
Fixed selection of objects for inclusion from within libraries to actually resolve references correctly
lost
parents:
243
diff
changeset
|
431 for (n = 0; n < fn -> nsubs; n++) |
eb499c146c0d
Fixed selection of objects for inclusion from within libraries to actually resolve references correctly
lost
parents:
243
diff
changeset
|
432 resolve_files_aux(fn -> subs[n]); |
eb499c146c0d
Fixed selection of objects for inclusion from within libraries to actually resolve references correctly
lost
parents:
243
diff
changeset
|
433 } |
eb499c146c0d
Fixed selection of objects for inclusion from within libraries to actually resolve references correctly
lost
parents:
243
diff
changeset
|
434 |
205 | 435 void resolve_files(void) |
436 { | |
437 int sn; | |
438 int fn; | |
439 reloc_t *rl; | |
206
299c5d793aca
Made lwlink smarter about not included unneeded (unreferenced) members of a library file
lost
parents:
205
diff
changeset
|
440 lw_expr_stack_t *te; |
245
eb499c146c0d
Fixed selection of objects for inclusion from within libraries to actually resolve references correctly
lost
parents:
243
diff
changeset
|
441 int c = 0; |
206
299c5d793aca
Made lwlink smarter about not included unneeded (unreferenced) members of a library file
lost
parents:
205
diff
changeset
|
442 |
205 | 443 int rval; |
444 | |
445 // resolve entry point if required | |
446 // this must resolve to an *exported* symbol and will resolve to the | |
447 // first instance of that symbol | |
448 if (linkscript.execsym) | |
449 { | |
450 lw_expr_stack_t *s; | |
451 | |
452 s = resolve_sym(linkscript.execsym, 0, NULL); | |
453 if (!s) | |
454 { | |
455 fprintf(stderr, "Cannot resolve exec address '%s'\n", linkscript.execsym); | |
456 symerr = 1; | |
457 } | |
458 } | |
459 | |
460 do | |
461 { | |
462 nforced = 0; | |
463 for (fn = 0; fn < ninputfiles; fn++) | |
464 { | |
465 if (inputfiles[fn] -> forced == 0) | |
466 continue; | |
467 | |
245
eb499c146c0d
Fixed selection of objects for inclusion from within libraries to actually resolve references correctly
lost
parents:
243
diff
changeset
|
468 resolve_files_aux(inputfiles[fn]); |
205 | 469 } |
245
eb499c146c0d
Fixed selection of objects for inclusion from within libraries to actually resolve references correctly
lost
parents:
243
diff
changeset
|
470 // fprintf(stderr, "File resolution pass %d, nforced = %d\n", ++c, nforced); |
205 | 471 } |
472 while (nforced == 1); | |
473 | |
474 if (symerr) | |
475 exit(1); | |
476 | |
477 // theoretically, all files referenced by other files now have "forced" set to 1 | |
206
299c5d793aca
Made lwlink smarter about not included unneeded (unreferenced) members of a library file
lost
parents:
205
diff
changeset
|
478 for (fn = 0; fn < ninputfiles; fn++) |
299c5d793aca
Made lwlink smarter about not included unneeded (unreferenced) members of a library file
lost
parents:
205
diff
changeset
|
479 { |
299c5d793aca
Made lwlink smarter about not included unneeded (unreferenced) members of a library file
lost
parents:
205
diff
changeset
|
480 if (inputfiles[fn] -> forced == 1) |
299c5d793aca
Made lwlink smarter about not included unneeded (unreferenced) members of a library file
lost
parents:
205
diff
changeset
|
481 continue; |
299c5d793aca
Made lwlink smarter about not included unneeded (unreferenced) members of a library file
lost
parents:
205
diff
changeset
|
482 |
299c5d793aca
Made lwlink smarter about not included unneeded (unreferenced) members of a library file
lost
parents:
205
diff
changeset
|
483 fprintf(stderr, "Warning: %s (%d) does not resolve any symbols\n", inputfiles[fn] -> filename, fn); |
299c5d793aca
Made lwlink smarter about not included unneeded (unreferenced) members of a library file
lost
parents:
205
diff
changeset
|
484 } |
205 | 485 } |