Mercurial > hg > index.cgi
comparison lwlink/link.c @ 234:d389adbcc4ab
Added section base and length symbols to lwlink
Added the ability for a link script to define section base and section
length symbols when linking. These symbols are searched for when an external
reference is resolved before looking up any symbols in the various objects
being linked. Also documented the new link script directives and added such
directives to all default link scripts.
author | William Astle <lost@l-w.ca> |
---|---|
date | Fri, 10 Aug 2012 23:47:56 -0600 |
parents | 4682460aed00 |
children | e3741cf53e00 |
comparison
equal
deleted
inserted
replaced
233:7887a48b74df | 234:d389adbcc4ab |
---|---|
24 #include <stdio.h> | 24 #include <stdio.h> |
25 #include <stdlib.h> | 25 #include <stdlib.h> |
26 #include <string.h> | 26 #include <string.h> |
27 | 27 |
28 #include <lw_alloc.h> | 28 #include <lw_alloc.h> |
29 #include <lw_string.h> | |
29 | 30 |
30 #include "expr.h" | 31 #include "expr.h" |
31 #include "lwlink.h" | 32 #include "lwlink.h" |
32 | 33 |
33 void check_os9(void); | 34 void check_os9(void); |
34 | 35 |
35 struct section_list *sectlist = NULL; | 36 struct section_list *sectlist = NULL; |
36 int nsects = 0; | 37 int nsects = 0; |
37 static int nforced = 0; | 38 static int nforced = 0; |
38 static int resolveonly = 0; | 39 static int resolveonly = 0; |
40 | |
41 symlist_t *symlist = NULL; | |
39 | 42 |
40 void check_section_name(char *name, int *base, fileinfo_t *fn) | 43 void check_section_name(char *name, int *base, fileinfo_t *fn) |
41 { | 44 { |
42 int sn; | 45 int sn; |
43 | 46 |
213 } | 216 } |
214 | 217 |
215 // theoretically, all the base addresses are set now | 218 // theoretically, all the base addresses are set now |
216 } | 219 } |
217 | 220 |
221 /* run through all sections and generate any synthetic symbols */ | |
222 void generate_symbols(void) | |
223 { | |
224 int sn; | |
225 char *lastsect = NULL; | |
226 char sym[256]; | |
227 int len; | |
228 symlist_t *se; | |
229 fprintf(stderr, "Generating symbols\n"); | |
230 for (sn = 0; sn < nsects; sn++) | |
231 { | |
232 fprintf(stderr, "Section %s (%s)\n", sectlist[sn].ptr -> name, lastsect); | |
233 if (!lastsect || strcmp(lastsect, (char *)(sectlist[sn].ptr -> name))) | |
234 { | |
235 if (lastsect && linkscript.lensympat) | |
236 { | |
237 /* handle length symbol */ | |
238 se = lw_alloc(sizeof(symlist_t)); | |
239 se -> val = len; | |
240 snprintf(sym, 255, linkscript.lensympat, lastsect); | |
241 se -> sym = lw_strdup(sym); | |
242 se -> next = symlist; | |
243 symlist = se; | |
244 } | |
245 lastsect = (char *)(sectlist[sn].ptr -> name); | |
246 len = 0; | |
247 /* handle base symbol */ | |
248 if (lastsect && linkscript.basesympat) | |
249 { | |
250 se = lw_alloc(sizeof(symlist_t)); | |
251 se -> val = sectlist[sn].ptr -> loadaddress; | |
252 snprintf(sym, 255, linkscript.basesympat, lastsect); | |
253 se -> sym = lw_strdup(sym); | |
254 se -> next = symlist; | |
255 symlist = se; | |
256 } | |
257 } | |
258 len += sectlist[sn].ptr -> codesize; | |
259 } | |
260 if (lastsect && linkscript.lensympat) | |
261 { | |
262 /* handle length symbol */ | |
263 se = lw_alloc(sizeof(symlist_t)); | |
264 se -> val = len; | |
265 snprintf(sym, 255, linkscript.lensympat, lastsect); | |
266 se -> sym = lw_strdup(sym); | |
267 se -> next = symlist; | |
268 symlist = se; | |
269 } | |
270 | |
271 } | |
272 | |
218 lw_expr_stack_t *find_external_sym_recurse(char *sym, fileinfo_t *fn) | 273 lw_expr_stack_t *find_external_sym_recurse(char *sym, fileinfo_t *fn) |
219 { | 274 { |
220 int sn; | 275 int sn; |
221 lw_expr_stack_t *r; | 276 lw_expr_stack_t *r; |
222 lw_expr_term_t *term; | 277 lw_expr_term_t *term; |
348 fprintf(stderr, "Local symbol %s not found in %s:%s\n", sanitize_symbol(sym), sect -> file -> filename, sect -> name); | 403 fprintf(stderr, "Local symbol %s not found in %s:%s\n", sanitize_symbol(sym), sect -> file -> filename, sect -> name); |
349 goto outerr; | 404 goto outerr; |
350 } | 405 } |
351 else | 406 else |
352 { | 407 { |
408 symlist_t *se; | |
409 | |
353 // external symbol | 410 // external symbol |
411 // first look up synthesized symbols | |
412 for (se = symlist; se; se = se -> next) | |
413 { | |
414 if (!strcmp(se -> sym, sym)) | |
415 { | |
416 val = se -> val; | |
417 goto out; | |
418 } | |
419 } | |
420 | |
354 // read all files in order until found (or not found) | 421 // read all files in order until found (or not found) |
355 if (sect) | 422 if (sect) |
356 { | 423 { |
357 for (fp = sect -> file; fp; fp = fp -> parent) | 424 for (fp = sect -> file; fp; fp = fp -> parent) |
358 { | 425 { |