Mercurial > hg-old > index.cgi
diff src/link.c @ 301:376cc55361c7
section order and address resolution done
author | lost |
---|---|
date | Wed, 21 Jan 2009 05:45:25 +0000 |
parents | |
children | eff969272fb9 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/link.c Wed Jan 21 05:45:25 2009 +0000 @@ -0,0 +1,142 @@ +/* +link.c +Copyright © 2009 William Astle + +This file is part of LWLINK. + +LWLINK is free software: you can redistribute it and/or modify it under the +terms of the GNU General Public License as published by the Free Software +Foundation, either version 3 of the License, or (at your option) any later +version. + +This program is distributed in the hope that it will be useful, but WITHOUT +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +more details. + +You should have received a copy of the GNU General Public License along with +this program. If not, see <http://www.gnu.org/licenses/>. + + +Resolve section and symbol addresses; handle incomplete references +*/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <stdlib.h> + +#include "lwlink.h" +#include "util.h" + +struct section_list +{ + section_t *ptr; // ptr to section structure + int forceaddr; // was this force to an address by the link script? +}; + +static struct section_list *sectlist = NULL; +static int nsects = 0; + +// work out section load order and resolve base addresses for each section +// make a list of sections to load in order +void resolve_sections(void) +{ + int laddr = 0; + int ln, sn, fn; + + for (ln = 0; ln < linkscript.nlines; ln++) + { + if (linkscript.lines[ln].sectname) + { + int f = 0; + // named section + // look for all instances of a section by the specified name + // and resolve base addresses and add to the list + for (fn = 0; fn < ninputfiles; fn++) + { + for (sn = 0; sn < inputfiles[fn] -> nsections; sn++) + { + if (!strcmp(linkscript.lines[ln].sectname, inputfiles[fn] -> sections[sn].name)) + { + // we have a match + sectlist = lw_realloc(sectlist, sizeof(struct section_list) * (nsects + 1)); + sectlist[nsects].ptr = &(inputfiles[fn] -> sections[sn]); + + inputfiles[fn] -> sections[sn].processed = 1; + if (!f && linkscript.lines[ln].loadat >= 0) + { + f = 1; + sectlist[nsects].forceaddr = 1; + laddr = linkscript.lines[ln].loadat; + } + else + { + sectlist[nsects].forceaddr = 0; + } + inputfiles[fn] -> sections[sn].loadaddress = laddr; + nsects++; + } + } + } + } + else + { + // wildcard section + // look for all sections not yet processed that match flags + + int f = 0; + int fn0, sn0; + char *sname; + + // named section + // look for all instances of a section by the specified name + // and resolve base addresses and add to the list + for (fn0 = 0; fn0 < ninputfiles; fn0++) + { + for (sn0 = 0; sn0 < inputfiles[fn0] -> nsections; sn0++) + { + // ignore if the "no flags" bit says to + if (linkscript.lines[ln].noflags && (inputfiles[fn0] -> sections[sn0].flags & linkscript.lines[ln].noflags)) + continue; + // ignore unless the yes flags tell us not to + if (linkscript.lines[ln].yesflags && (inputfiles[fn0] -> sections[sn0].flags & linkscript.lines[ln].yesflags == 0)) + continue; + if (inputfiles[fn0] -> sections[sn0].processed == 0) + { + sname = inputfiles[fn0] -> sections[sn0].name; + for (fn = 0; fn < ninputfiles; fn++) + { + for (sn = 0; sn < inputfiles[fn] -> nsections; sn++) + { + if (!strcmp(sname, inputfiles[fn] -> sections[sn].name)) + { + // we have a match + sectlist = lw_realloc(sectlist, sizeof(struct section_list) * (nsects + 1)); + sectlist[nsects].ptr = &(inputfiles[fn] -> sections[sn]); + + inputfiles[fn] -> sections[sn].processed = 1; + if (!f && linkscript.lines[ln].loadat >= 0) + { + f = 1; + sectlist[nsects].forceaddr = 1; + laddr = linkscript.lines[ln].loadat; + } + else + { + sectlist[nsects].forceaddr = 0; + } + inputfiles[fn] -> sections[sn].loadaddress = laddr; + nsects++; + } + } + } + } + } + } + } + } + + // theoretically, all the base addresses are set now +}