Mercurial > hg-old > index.cgi
annotate lwasm/section.c @ 385:cf8c92d70eb1
Various bugfixes
author | lost@starbug |
---|---|
date | Sun, 16 May 2010 11:50:00 -0600 |
parents | cc154dc614fe |
children | a741d2e4869f |
rev | line source |
---|---|
353 | 1 /* |
2 section.c | |
3 | |
4 Copyright © 2010 William Astle | |
5 | |
6 This file is part of LWTOOLS. | |
7 | |
8 LWTOOLS is free software: you can redistribute it and/or modify it under the | |
9 terms of the GNU General Public License as published by the Free Software | |
10 Foundation, either version 3 of the License, or (at your option) any later | |
11 version. | |
12 | |
13 This program is distributed in the hope that it will be useful, but WITHOUT | |
14 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | |
16 more details. | |
17 | |
18 You should have received a copy of the GNU General Public License along with | |
19 this program. If not, see <http://www.gnu.org/licenses/>. | |
20 */ | |
21 | |
22 #include <config.h> | |
23 | |
24 #include <string.h> | |
25 | |
26 #include <lw_string.h> | |
27 #include <lw_alloc.h> | |
28 | |
29 #include "lwasm.h" | |
30 #include "instab.h" | |
31 | |
32 PARSEFUNC(pseudo_parse_section) | |
33 { | |
34 char *p2; | |
35 char *sn; | |
36 char *opts = NULL; | |
37 sectiontab_t *s; | |
38 | |
39 if (as -> output_format != OUTPUT_OBJ) | |
40 { | |
41 lwasm_register_error(as, l, "Cannot use sections unless using the object target"); | |
42 return; | |
43 } | |
44 | |
45 if (!**p) | |
46 { | |
47 lwasm_register_error(as, l, "Need section name"); | |
48 return; | |
49 } | |
50 | |
51 if (as -> csect) | |
52 { | |
53 lw_expr_destroy(as -> csect -> offset); | |
54 as -> csect -> offset = l -> addr; | |
55 as -> csect = NULL; | |
56 } | |
57 | |
58 for (p2 = *p; *p2 && *p2 != ',' && !isspace(*p2); p2++) | |
59 /* do nothing */ ; | |
60 | |
61 sn = lw_strndup(*p, p2 - *p); | |
62 *p = p2; | |
63 | |
64 if (**p == ',') | |
65 { | |
66 // have opts | |
67 (*p)++; | |
68 | |
69 for (p2 = *p; *p2 && !isspace(*p2); p2++) | |
70 /* do nothing */ ; | |
71 | |
72 opts = lw_strndup(*p, p2 - *p); | |
73 *p = p2; | |
74 } | |
75 | |
76 for (s = as -> sections; s; s = s -> next) | |
77 { | |
78 if (!strcmp(s -> name, sn)) | |
79 break; | |
80 } | |
81 if (s && opts) | |
82 { | |
83 lwasm_register_warning(as, l, "Section flags can only be specified the first time; ignoring duplicate definition"); | |
84 } | |
85 if (!s) | |
86 { | |
87 // create section data structure | |
88 s = lw_alloc(sizeof(sectiontab_t)); | |
89 s -> name = lw_strdup(sn); | |
367 | 90 s -> offset = lw_expr_build(lw_expr_type_special, lwasm_expr_secbase, s); |
353 | 91 s -> flags = section_flag_none; |
92 if (!strcasecmp(sn, "bss") || !strcasecmp(sn, ".bss")) | |
93 { | |
94 s -> flags |= section_flag_bss; | |
95 } | |
96 // parse options | |
97 if (opts) | |
98 { | |
99 // only one option ("bss" or "!bss") | |
100 if (!strcasecmp(opts, "bss")) | |
101 { | |
102 s -> flags |= section_flag_bss; | |
103 } | |
104 else if (!strcasecmp(opts, "!bss")) | |
105 { | |
106 s -> flags &= ~section_flag_bss; | |
107 } | |
108 else | |
109 { | |
110 lwasm_register_error(as, l, "Unrecognized section flag"); | |
111 lw_free(sn); | |
112 lw_free(opts); | |
113 lw_free(s -> name); | |
114 lw_expr_destroy(s -> offset); | |
115 lw_free(s); | |
116 return; | |
117 } | |
118 } | |
119 s -> next = as -> sections; | |
120 as -> sections = s; | |
121 } | |
122 | |
123 lw_expr_destroy(l -> addr); | |
124 l -> addr = lw_expr_copy(s -> offset); | |
125 | |
126 as -> csect = s; | |
127 as -> context = lwasm_next_context(as); | |
128 | |
129 l -> len = 0; | |
130 | |
131 lw_free(opts); | |
132 lw_free(sn); | |
133 } | |
134 | |
135 PARSEFUNC(pseudo_parse_endsection) | |
136 { | |
137 if (as -> output_format != OUTPUT_OBJ) | |
138 { | |
139 lwasm_register_error(as, l, "Cannot use sections unless using the object target"); | |
140 return; | |
141 } | |
142 | |
143 if (!(as -> csect)) | |
144 { | |
145 lwasm_register_error(as, l, "ENDSECTION without SECTION"); | |
146 return; | |
147 } | |
148 | |
149 // save offset in case another instance of the section appears | |
150 lw_expr_destroy(as -> csect -> offset); | |
151 as -> csect -> offset = l -> addr; | |
152 | |
153 // reset address to 0 | |
154 l -> addr = lw_expr_build(lw_expr_type_int, 0); | |
155 as -> csect = NULL; | |
156 | |
157 // end of section is a context break | |
158 as -> context = lwasm_next_context(as); | |
159 | |
160 skip_operand(p); | |
161 } | |
356 | 162 |
163 PARSEFUNC(pseudo_parse_export) | |
164 { | |
165 int after = 0; | |
166 char *sym = NULL; | |
167 exportlist_t *e; | |
168 | |
169 if (as -> output_format != OUTPUT_OBJ) | |
170 { | |
171 lwasm_register_error(as, l, "EXPORT only supported for object target"); | |
172 return; | |
173 } | |
174 | |
175 if (l -> sym) | |
385 | 176 { |
356 | 177 sym = lw_strdup(l -> sym); |
385 | 178 l -> symset = 1; |
179 } | |
356 | 180 |
181 if (l -> sym) | |
182 { | |
183 skip_operand(p); | |
184 } | |
185 | |
186 again: | |
187 if (after || !sym) | |
188 { | |
189 char *p2; | |
190 | |
191 after = 1; | |
192 for (p2 = *p; *p2 && *p2 != ',' && !isspace(*p2); p2++) | |
193 /* do nothing */ ; | |
194 | |
195 sym = lw_strndup(*p, p2 - *p); | |
385 | 196 *p = p2; |
356 | 197 } |
198 if (!sym) | |
199 { | |
200 lwasm_register_error(as, l, "No symbol for EXPORT"); | |
201 return; | |
202 } | |
203 | |
204 // add the symbol to the "export" list (which will be resolved | |
205 // after the parse pass is complete | |
206 e = lw_alloc(sizeof(exportlist_t)); | |
207 e -> next = as -> exportlist; | |
208 e -> symbol = lw_strdup(sym); | |
363
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
356
diff
changeset
|
209 e -> line = l; |
374 | 210 e -> se = NULL; |
356 | 211 as -> exportlist = e; |
212 lw_free(sym); | |
213 | |
214 if (after && **p == ',') | |
215 { | |
216 (*p)++; | |
217 for (; **p && isspace(**p); (*p)++) | |
218 /* do nothing */ ; | |
219 goto again; | |
220 } | |
221 } | |
222 | |
223 PARSEFUNC(pseudo_parse_extern) | |
224 { | |
225 int after = 0; | |
226 char *sym = NULL; | |
227 importlist_t *e; | |
228 | |
229 if (as -> output_format != OUTPUT_OBJ) | |
230 { | |
231 lwasm_register_error(as, l, "IMPORT only supported for object target"); | |
232 return; | |
233 } | |
234 | |
235 if (l -> sym) | |
385 | 236 { |
356 | 237 sym = lw_strdup(l -> sym); |
385 | 238 l -> symset = 1; |
239 } | |
356 | 240 |
241 if (l -> sym) | |
242 { | |
243 skip_operand(p); | |
244 } | |
245 | |
246 again: | |
247 if (after || !sym) | |
248 { | |
249 char *p2; | |
250 | |
251 after = 1; | |
252 for (p2 = *p; *p2 && *p2 != ',' && !isspace(*p2); p2++) | |
253 /* do nothing */ ; | |
254 | |
255 sym = lw_strndup(*p, p2 - *p); | |
385 | 256 *p = p2; |
356 | 257 } |
258 if (!sym) | |
259 { | |
260 lwasm_register_error(as, l, "No symbol for IMPORT"); | |
261 return; | |
262 } | |
263 | |
264 // add the symbol to the "export" list (which will be resolved | |
265 // after the parse pass is complete | |
266 e = lw_alloc(sizeof(importlist_t)); | |
267 e -> next = as -> importlist; | |
268 e -> symbol = lw_strdup(sym); | |
269 as -> importlist = e; | |
270 lw_free(sym); | |
271 | |
272 if (after && **p == ',') | |
273 { | |
274 (*p)++; | |
275 for (; **p && isspace(**p); (*p)++) | |
276 /* do nothing */ ; | |
277 goto again; | |
278 } | |
279 } | |
380 | 280 |
281 PARSEFUNC(pseudo_parse_extdep) | |
282 { | |
283 int after = 0; | |
284 char *sym = NULL; | |
285 importlist_t *e; | |
286 | |
287 if (as -> output_format != OUTPUT_OBJ) | |
288 { | |
289 lwasm_register_error(as, l, "EXTDEP only supported for object target"); | |
290 return; | |
291 } | |
292 | |
293 if (!as -> csect) | |
294 { | |
295 lwasm_register_error(as, l, "EXTDEP must be within a section"); | |
296 return; | |
297 } | |
298 | |
299 if (l -> sym) | |
300 sym = lw_strdup(l -> sym); | |
301 | |
302 if (l -> sym) | |
303 { | |
304 skip_operand(p); | |
305 } | |
306 | |
307 again: | |
308 if (after || !sym) | |
309 { | |
310 char *p2; | |
311 | |
312 after = 1; | |
313 for (p2 = *p; *p2 && *p2 != ',' && !isspace(*p2); p2++) | |
314 /* do nothing */ ; | |
315 | |
316 sym = lw_strndup(*p, p2 - *p); | |
317 } | |
318 if (!sym) | |
319 { | |
320 lwasm_register_error(as, l, "No symbol for EXTDEP"); | |
321 return; | |
322 } | |
323 | |
324 // create a zero-width dependency | |
325 { | |
326 lw_expr_t e; | |
327 e = lw_expr_build(lw_expr_type_int, 0); | |
328 lwasm_emitexpr(l, e, 0); | |
329 lw_expr_destroy(e); | |
330 } | |
331 | |
332 if (after && **p == ',') | |
333 { | |
334 (*p)++; | |
335 for (; **p && isspace(**p); (*p)++) | |
336 /* do nothing */ ; | |
337 goto again; | |
338 } | |
339 } |