Mercurial > hg-old > index.cgi
view 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 source
/* 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 }