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 {