Mercurial > hg > index.cgi
diff 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 |
line wrap: on
line diff
--- a/lwlink/link.c Thu Jul 19 13:17:30 2012 -0600 +++ b/lwlink/link.c Fri Aug 10 23:47:56 2012 -0600 @@ -26,6 +26,7 @@ #include <string.h> #include <lw_alloc.h> +#include <lw_string.h> #include "expr.h" #include "lwlink.h" @@ -37,6 +38,8 @@ static int nforced = 0; static int resolveonly = 0; +symlist_t *symlist = NULL; + void check_section_name(char *name, int *base, fileinfo_t *fn) { int sn; @@ -215,6 +218,58 @@ // theoretically, all the base addresses are set now } +/* run through all sections and generate any synthetic symbols */ +void generate_symbols(void) +{ + int sn; + char *lastsect = NULL; + char sym[256]; + int len; + symlist_t *se; +fprintf(stderr, "Generating symbols\n"); + for (sn = 0; sn < nsects; sn++) + { + fprintf(stderr, "Section %s (%s)\n", sectlist[sn].ptr -> name, lastsect); + if (!lastsect || strcmp(lastsect, (char *)(sectlist[sn].ptr -> name))) + { + if (lastsect && linkscript.lensympat) + { + /* handle length symbol */ + se = lw_alloc(sizeof(symlist_t)); + se -> val = len; + snprintf(sym, 255, linkscript.lensympat, lastsect); + se -> sym = lw_strdup(sym); + se -> next = symlist; + symlist = se; + } + lastsect = (char *)(sectlist[sn].ptr -> name); + len = 0; + /* handle base symbol */ + if (lastsect && linkscript.basesympat) + { + se = lw_alloc(sizeof(symlist_t)); + se -> val = sectlist[sn].ptr -> loadaddress; + snprintf(sym, 255, linkscript.basesympat, lastsect); + se -> sym = lw_strdup(sym); + se -> next = symlist; + symlist = se; + } + } + len += sectlist[sn].ptr -> codesize; + } + if (lastsect && linkscript.lensympat) + { + /* handle length symbol */ + se = lw_alloc(sizeof(symlist_t)); + se -> val = len; + snprintf(sym, 255, linkscript.lensympat, lastsect); + se -> sym = lw_strdup(sym); + se -> next = symlist; + symlist = se; + } + +} + lw_expr_stack_t *find_external_sym_recurse(char *sym, fileinfo_t *fn) { int sn; @@ -350,7 +405,19 @@ } else { + symlist_t *se; + // external symbol + // first look up synthesized symbols + for (se = symlist; se; se = se -> next) + { + if (!strcmp(se -> sym, sym)) + { + val = se -> val; + goto out; + } + } + // read all files in order until found (or not found) if (sect) {