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 }