Mercurial > hg-old > index.cgi
comparison lwlink/link.c @ 171:d610b8aef91b
Added LWAR skeleton
author | lost |
---|---|
date | Sun, 01 Mar 2009 19:37:03 +0000 |
parents | 106c2fe3c9d9 |
children | 0395e6fd67e9 |
comparison
equal
deleted
inserted
replaced
170:bf69160da467 | 171:d610b8aef91b |
---|---|
33 #include "util.h" | 33 #include "util.h" |
34 | 34 |
35 struct section_list *sectlist = NULL; | 35 struct section_list *sectlist = NULL; |
36 int nsects = 0; | 36 int nsects = 0; |
37 | 37 |
38 void check_section_name(char *name, int *base, fileinfo_t *fn) | |
39 { | |
40 int sn; | |
41 for (sn = 0; sn < fn -> nsections; sn++) | |
42 { | |
43 if (!strcmp(name, fn -> sections[sn].name)) | |
44 { | |
45 // we have a match | |
46 sectlist = lw_realloc(sectlist, sizeof(struct section_list) * (nsects + 1)); | |
47 sectlist[nsects].ptr = &(fn -> sections[sn]); | |
48 | |
49 fn -> sections[sn].processed = 1; | |
50 fn -> sections[sn].loadaddress = *base; | |
51 *base += fn -> sections[sn].codesize; | |
52 nsects++; | |
53 } | |
54 } | |
55 for (sn = 0; sn < fn -> nsubs; fn++) | |
56 { | |
57 check_section_name(name, base, fn -> subs[sn]); | |
58 } | |
59 } | |
60 | |
61 void add_matching_sections(char *name, int yesflags, int noflags, int *base); | |
62 void check_section_flags(int yesflags, int noflags, int *base, fileinfo_t *fn) | |
63 { | |
64 int sn; | |
65 for (sn = 0; sn < fn -> nsections; sn++) | |
66 { | |
67 // ignore if the noflags tell us to | |
68 if (noflags && (fn -> sections[sn].flags & noflags)) | |
69 continue; | |
70 // ignore unless the yesflags tell us not to | |
71 if (yesflags && (fn -> sections[sn].flags & yesflags == 0)) | |
72 continue; | |
73 // ignore it if already processed | |
74 if (fn -> sections[sn].processed) | |
75 continue; | |
76 | |
77 // we have a match - now collect *all* sections of the same name! | |
78 add_matching_sections(fn -> sections[sn].name, 0, 0, base); | |
79 | |
80 // and then continue looking for sections | |
81 } | |
82 for (sn = 0; sn < fn -> nsubs; fn++) | |
83 { | |
84 check_section_flags(yesflags, noflags, base, fn -> subs[sn]); | |
85 } | |
86 } | |
87 | |
88 | |
89 | |
90 void add_matching_sections(char *name, int yesflags, int noflags, int *base) | |
91 { | |
92 int fn; | |
93 if (name) | |
94 { | |
95 // named section | |
96 // look for all instances of a section by the specified name | |
97 // and resolve base addresses and add to the list | |
98 for (fn = 0; fn < ninputfiles; fn++) | |
99 { | |
100 check_section_name(name, base, inputfiles[fn]); | |
101 } | |
102 } | |
103 else | |
104 { | |
105 // wildcard section | |
106 // named section | |
107 // look for all instances of a section by the specified name | |
108 // and resolve base addresses and add to the list | |
109 for (fn = 0; fn < ninputfiles; fn++) | |
110 { | |
111 check_section_flags(yesflags, noflags, base, inputfiles[fn]); | |
112 } | |
113 } | |
114 } | |
115 | |
38 // work out section load order and resolve base addresses for each section | 116 // work out section load order and resolve base addresses for each section |
39 // make a list of sections to load in order | 117 // make a list of sections to load in order |
40 void resolve_sections(void) | 118 void resolve_sections(void) |
41 { | 119 { |
42 int laddr = 0; | 120 int laddr = 0; |
43 int ln, sn, fn; | 121 int ln, sn, fn; |
44 | 122 |
45 for (ln = 0; ln < linkscript.nlines; ln++) | 123 for (ln = 0; ln < linkscript.nlines; ln++) |
46 { | 124 { |
47 // printf("Linker script line %d: '%s', %04X, %d, %d\n", ln, linkscript.lines[ln].sectname, linkscript.lines[ln].loadat, linkscript.lines[ln].yesflags, linkscript.lines[ln].noflags); | 125 if (linkscript.lines[ln].loadat >= 0) |
126 laddr = linkscript.lines[ln].loadat; | |
127 add_matching_sections(linkscript.lines[ln].sectname, linkscript.lines[ln].yesflags, linkscript.lines[ln].noflags, &laddr); | |
128 | |
48 if (linkscript.lines[ln].sectname) | 129 if (linkscript.lines[ln].sectname) |
49 { | 130 { |
50 int f = 0; | |
51 // named section | |
52 // look for all instances of a section by the specified name | |
53 // and resolve base addresses and add to the list | |
54 for (fn = 0; fn < ninputfiles; fn++) | |
55 { | |
56 for (sn = 0; sn < inputfiles[fn] -> nsections; sn++) | |
57 { | |
58 // printf(" Considering %s:%s\n", inputfiles[fn]->filename, inputfiles[fn]->sections[sn].name); | |
59 if (!strcmp(linkscript.lines[ln].sectname, inputfiles[fn] -> sections[sn].name)) | |
60 { | |
61 // we have a match | |
62 sectlist = lw_realloc(sectlist, sizeof(struct section_list) * (nsects + 1)); | |
63 sectlist[nsects].ptr = &(inputfiles[fn] -> sections[sn]); | |
64 | |
65 inputfiles[fn] -> sections[sn].processed = 1; | |
66 if (!f && linkscript.lines[ln].loadat >= 0) | |
67 { | |
68 f = 1; | |
69 sectlist[nsects].forceaddr = 1; | |
70 laddr = linkscript.lines[ln].loadat; | |
71 } | |
72 else | |
73 { | |
74 sectlist[nsects].forceaddr = 0; | |
75 } | |
76 inputfiles[fn] -> sections[sn].loadaddress = laddr; | |
77 laddr += inputfiles[fn] -> sections[sn].codesize; | |
78 nsects++; | |
79 } | |
80 } | |
81 } | |
82 } | 131 } |
83 else | 132 else |
84 { | 133 { |
85 // wildcard section | 134 // wildcard section |
86 // look for all sections not yet processed that match flags | 135 // look for all sections not yet processed that match flags |
139 } | 188 } |
140 | 189 |
141 // theoretically, all the base addresses are set now | 190 // theoretically, all the base addresses are set now |
142 } | 191 } |
143 | 192 |
193 lw_expr_stack_t *find_external_sym_recurse(char *sym, fileinfo_t *fn) | |
194 { | |
195 int sn; | |
196 lw_expr_stack_t *r; | |
197 lw_expr_term_t *term; | |
198 symtab_t *se; | |
199 int val; | |
200 | |
201 for (sn = 0; sn < fn -> nsections; sn++) | |
202 { | |
203 for (se = fn -> sections[sn].exportedsyms; se; se = se -> next) | |
204 { | |
205 if (!strcmp(sym, se -> sym)) | |
206 { | |
207 val = se -> offset + fn -> sections[sn].loadaddress; | |
208 r = lw_expr_stack_create(); | |
209 term = lw_expr_term_create_int(val & 0xffff); | |
210 lw_expr_stack_push(r, term); | |
211 lw_expr_term_free(term); | |
212 return r; | |
213 } | |
214 } | |
215 } | |
216 | |
217 for (sn = 0; sn < fn -> nsubs; sn++) | |
218 { | |
219 r = find_external_sym_recurse(sym, fn -> subs[sn]); | |
220 if (r) | |
221 return r; | |
222 } | |
223 return NULL; | |
224 } | |
225 | |
144 // resolve all incomplete references now | 226 // resolve all incomplete references now |
145 // anything that is unresolvable at this stage will throw an error | 227 // anything that is unresolvable at this stage will throw an error |
146 // because we know the load address of every section now | 228 // because we know the load address of every section now |
147 lw_expr_stack_t *resolve_sym(char *sym, int symtype, void *state) | 229 lw_expr_stack_t *resolve_sym(char *sym, int symtype, void *state) |
148 { | 230 { |
149 section_t *sect = state; | 231 section_t *sect = state; |
150 lw_expr_term_t *term; | 232 lw_expr_term_t *term; |
151 int val = 0, i, fn; | 233 int val = 0, i, fn; |
152 lw_expr_stack_t *s; | 234 lw_expr_stack_t *s; |
153 symtab_t *se; | 235 symtab_t *se; |
154 | 236 fileinfo_t *fp; |
237 | |
155 if (symtype == 1) | 238 if (symtype == 1) |
156 { | 239 { |
157 // local symbol | 240 // local symbol |
158 if (!sym) | 241 if (!sym) |
159 { | 242 { |
188 } | 271 } |
189 else | 272 else |
190 { | 273 { |
191 // external symbol | 274 // external symbol |
192 // read all files in order until found (or not found) | 275 // read all files in order until found (or not found) |
276 for (fp = sect -> file; fp; fp = fp -> parent) | |
277 { | |
278 s = find_external_sym_recurse(sym, fp); | |
279 if (s) | |
280 return s; | |
281 } | |
282 | |
193 for (fn = 0; fn < ninputfiles; fn++) | 283 for (fn = 0; fn < ninputfiles; fn++) |
194 { | 284 { |
195 for (i = 0; i < inputfiles[fn] -> nsections; i++) | 285 s = find_external_sym_recurse(sym, inputfiles[fn]); |
196 { | 286 if (s) |
197 for (se = inputfiles[fn] -> sections[i].exportedsyms; se; se = se -> next) | 287 return s; |
198 { | |
199 if (!strcmp(sym, se -> sym)) | |
200 { | |
201 val = se -> offset + inputfiles[fn] -> sections[i].loadaddress; | |
202 goto out; | |
203 } | |
204 } | |
205 } | |
206 } | 288 } |
207 if (sect) | 289 if (sect) |
208 { | 290 { |
209 fprintf(stderr, "External symbol %s not found in %s:%s\n", sym, sect -> file -> filename, sect -> name); | 291 fprintf(stderr, "External symbol %s not found in %s:%s\n", sym, sect -> file -> filename, sect -> name); |
210 } | 292 } |