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