Mercurial > hg-old > index.cgi
comparison 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 |
comparison
equal
deleted
inserted
replaced
300:48945dac8178 | 301:376cc55361c7 |
---|---|
1 /* | |
2 link.c | |
3 Copyright © 2009 William Astle | |
4 | |
5 This file is part of LWLINK. | |
6 | |
7 LWLINK is free software: you can redistribute it and/or modify it under the | |
8 terms of the GNU General Public License as published by the Free Software | |
9 Foundation, either version 3 of the License, or (at your option) any later | |
10 version. | |
11 | |
12 This program is distributed in the hope that it will be useful, but WITHOUT | |
13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | |
15 more details. | |
16 | |
17 You should have received a copy of the GNU General Public License along with | |
18 this program. If not, see <http://www.gnu.org/licenses/>. | |
19 | |
20 | |
21 Resolve section and symbol addresses; handle incomplete references | |
22 */ | |
23 | |
24 #ifdef HAVE_CONFIG_H | |
25 #include "config.h" | |
26 #endif | |
27 | |
28 #include <stdlib.h> | |
29 | |
30 #include "lwlink.h" | |
31 #include "util.h" | |
32 | |
33 struct section_list | |
34 { | |
35 section_t *ptr; // ptr to section structure | |
36 int forceaddr; // was this force to an address by the link script? | |
37 }; | |
38 | |
39 static struct section_list *sectlist = NULL; | |
40 static int nsects = 0; | |
41 | |
42 // work out section load order and resolve base addresses for each section | |
43 // make a list of sections to load in order | |
44 void resolve_sections(void) | |
45 { | |
46 int laddr = 0; | |
47 int ln, sn, fn; | |
48 | |
49 for (ln = 0; ln < linkscript.nlines; ln++) | |
50 { | |
51 if (linkscript.lines[ln].sectname) | |
52 { | |
53 int f = 0; | |
54 // named section | |
55 // look for all instances of a section by the specified name | |
56 // and resolve base addresses and add to the list | |
57 for (fn = 0; fn < ninputfiles; fn++) | |
58 { | |
59 for (sn = 0; sn < inputfiles[fn] -> nsections; sn++) | |
60 { | |
61 if (!strcmp(linkscript.lines[ln].sectname, inputfiles[fn] -> sections[sn].name)) | |
62 { | |
63 // we have a match | |
64 sectlist = lw_realloc(sectlist, sizeof(struct section_list) * (nsects + 1)); | |
65 sectlist[nsects].ptr = &(inputfiles[fn] -> sections[sn]); | |
66 | |
67 inputfiles[fn] -> sections[sn].processed = 1; | |
68 if (!f && linkscript.lines[ln].loadat >= 0) | |
69 { | |
70 f = 1; | |
71 sectlist[nsects].forceaddr = 1; | |
72 laddr = linkscript.lines[ln].loadat; | |
73 } | |
74 else | |
75 { | |
76 sectlist[nsects].forceaddr = 0; | |
77 } | |
78 inputfiles[fn] -> sections[sn].loadaddress = laddr; | |
79 nsects++; | |
80 } | |
81 } | |
82 } | |
83 } | |
84 else | |
85 { | |
86 // wildcard section | |
87 // look for all sections not yet processed that match flags | |
88 | |
89 int f = 0; | |
90 int fn0, sn0; | |
91 char *sname; | |
92 | |
93 // named section | |
94 // look for all instances of a section by the specified name | |
95 // and resolve base addresses and add to the list | |
96 for (fn0 = 0; fn0 < ninputfiles; fn0++) | |
97 { | |
98 for (sn0 = 0; sn0 < inputfiles[fn0] -> nsections; sn0++) | |
99 { | |
100 // ignore if the "no flags" bit says to | |
101 if (linkscript.lines[ln].noflags && (inputfiles[fn0] -> sections[sn0].flags & linkscript.lines[ln].noflags)) | |
102 continue; | |
103 // ignore unless the yes flags tell us not to | |
104 if (linkscript.lines[ln].yesflags && (inputfiles[fn0] -> sections[sn0].flags & linkscript.lines[ln].yesflags == 0)) | |
105 continue; | |
106 if (inputfiles[fn0] -> sections[sn0].processed == 0) | |
107 { | |
108 sname = inputfiles[fn0] -> sections[sn0].name; | |
109 for (fn = 0; fn < ninputfiles; fn++) | |
110 { | |
111 for (sn = 0; sn < inputfiles[fn] -> nsections; sn++) | |
112 { | |
113 if (!strcmp(sname, inputfiles[fn] -> sections[sn].name)) | |
114 { | |
115 // we have a match | |
116 sectlist = lw_realloc(sectlist, sizeof(struct section_list) * (nsects + 1)); | |
117 sectlist[nsects].ptr = &(inputfiles[fn] -> sections[sn]); | |
118 | |
119 inputfiles[fn] -> sections[sn].processed = 1; | |
120 if (!f && linkscript.lines[ln].loadat >= 0) | |
121 { | |
122 f = 1; | |
123 sectlist[nsects].forceaddr = 1; | |
124 laddr = linkscript.lines[ln].loadat; | |
125 } | |
126 else | |
127 { | |
128 sectlist[nsects].forceaddr = 0; | |
129 } | |
130 inputfiles[fn] -> sections[sn].loadaddress = laddr; | |
131 nsects++; | |
132 } | |
133 } | |
134 } | |
135 } | |
136 } | |
137 } | |
138 } | |
139 } | |
140 | |
141 // theoretically, all the base addresses are set now | |
142 } |