Mercurial > hg-old > index.cgi
annotate lwasm/section.c @ 426:652eee8f0c82
Fixed lw_expr_destroy() to not crash on NULL
author | lost@l-w.ca |
---|---|
date | Sun, 19 Sep 2010 10:40:37 -0600 |
parents | 35a0b086bf4a |
children |
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 | |
387
a741d2e4869f
Various bugfixes; fixed lwobjdump to display symbols with unprintable characters more sensibly; start of a (nonfunctional for now) testing framework
lost@l-w.ca
parents:
385
diff
changeset
|
51 l -> len = 0; |
a741d2e4869f
Various bugfixes; fixed lwobjdump to display symbols with unprintable characters more sensibly; start of a (nonfunctional for now) testing framework
lost@l-w.ca
parents:
385
diff
changeset
|
52 |
353 | 53 if (as -> csect) |
54 { | |
55 lw_expr_destroy(as -> csect -> offset); | |
412
35a0b086bf4a
Added dummy .bank pseudo and fixed segfault in output for object target (on imported symbol)
lost@l-w.ca
parents:
387
diff
changeset
|
56 as -> csect -> offset = lw_expr_copy(l -> addr); |
353 | 57 as -> csect = NULL; |
58 } | |
59 | |
60 for (p2 = *p; *p2 && *p2 != ',' && !isspace(*p2); p2++) | |
61 /* do nothing */ ; | |
62 | |
63 sn = lw_strndup(*p, p2 - *p); | |
64 *p = p2; | |
65 | |
66 if (**p == ',') | |
67 { | |
68 // have opts | |
69 (*p)++; | |
70 | |
71 for (p2 = *p; *p2 && !isspace(*p2); p2++) | |
72 /* do nothing */ ; | |
73 | |
74 opts = lw_strndup(*p, p2 - *p); | |
75 *p = p2; | |
76 } | |
77 | |
78 for (s = as -> sections; s; s = s -> next) | |
79 { | |
80 if (!strcmp(s -> name, sn)) | |
81 break; | |
82 } | |
83 if (s && opts) | |
84 { | |
85 lwasm_register_warning(as, l, "Section flags can only be specified the first time; ignoring duplicate definition"); | |
86 } | |
87 if (!s) | |
88 { | |
89 // create section data structure | |
90 s = lw_alloc(sizeof(sectiontab_t)); | |
387
a741d2e4869f
Various bugfixes; fixed lwobjdump to display symbols with unprintable characters more sensibly; start of a (nonfunctional for now) testing framework
lost@l-w.ca
parents:
385
diff
changeset
|
91 s -> oblen = 0; |
a741d2e4869f
Various bugfixes; fixed lwobjdump to display symbols with unprintable characters more sensibly; start of a (nonfunctional for now) testing framework
lost@l-w.ca
parents:
385
diff
changeset
|
92 s -> obsize = 0; |
a741d2e4869f
Various bugfixes; fixed lwobjdump to display symbols with unprintable characters more sensibly; start of a (nonfunctional for now) testing framework
lost@l-w.ca
parents:
385
diff
changeset
|
93 s -> obytes = NULL; |
353 | 94 s -> name = lw_strdup(sn); |
367 | 95 s -> offset = lw_expr_build(lw_expr_type_special, lwasm_expr_secbase, s); |
353 | 96 s -> flags = section_flag_none; |
387
a741d2e4869f
Various bugfixes; fixed lwobjdump to display symbols with unprintable characters more sensibly; start of a (nonfunctional for now) testing framework
lost@l-w.ca
parents:
385
diff
changeset
|
97 s -> reloctab = NULL; |
353 | 98 if (!strcasecmp(sn, "bss") || !strcasecmp(sn, ".bss")) |
99 { | |
100 s -> flags |= section_flag_bss; | |
101 } | |
102 // parse options | |
103 if (opts) | |
104 { | |
105 // only one option ("bss" or "!bss") | |
106 if (!strcasecmp(opts, "bss")) | |
107 { | |
108 s -> flags |= section_flag_bss; | |
109 } | |
110 else if (!strcasecmp(opts, "!bss")) | |
111 { | |
112 s -> flags &= ~section_flag_bss; | |
113 } | |
114 else | |
115 { | |
116 lwasm_register_error(as, l, "Unrecognized section flag"); | |
117 lw_free(sn); | |
118 lw_free(opts); | |
119 lw_free(s -> name); | |
120 lw_expr_destroy(s -> offset); | |
121 lw_free(s); | |
122 return; | |
123 } | |
124 } | |
125 s -> next = as -> sections; | |
126 as -> sections = s; | |
127 } | |
128 | |
129 lw_expr_destroy(l -> addr); | |
130 l -> addr = lw_expr_copy(s -> offset); | |
131 | |
132 as -> csect = s; | |
133 as -> context = lwasm_next_context(as); | |
134 | |
135 l -> len = 0; | |
136 | |
137 lw_free(opts); | |
138 lw_free(sn); | |
139 } | |
140 | |
141 PARSEFUNC(pseudo_parse_endsection) | |
142 { | |
143 if (as -> output_format != OUTPUT_OBJ) | |
144 { | |
145 lwasm_register_error(as, l, "Cannot use sections unless using the object target"); | |
146 return; | |
147 } | |
148 | |
387
a741d2e4869f
Various bugfixes; fixed lwobjdump to display symbols with unprintable characters more sensibly; start of a (nonfunctional for now) testing framework
lost@l-w.ca
parents:
385
diff
changeset
|
149 l -> len = 0; |
a741d2e4869f
Various bugfixes; fixed lwobjdump to display symbols with unprintable characters more sensibly; start of a (nonfunctional for now) testing framework
lost@l-w.ca
parents:
385
diff
changeset
|
150 |
353 | 151 if (!(as -> csect)) |
152 { | |
153 lwasm_register_error(as, l, "ENDSECTION without SECTION"); | |
154 return; | |
155 } | |
156 | |
157 // save offset in case another instance of the section appears | |
158 lw_expr_destroy(as -> csect -> offset); | |
159 as -> csect -> offset = l -> addr; | |
160 | |
161 // reset address to 0 | |
162 l -> addr = lw_expr_build(lw_expr_type_int, 0); | |
163 as -> csect = NULL; | |
164 | |
165 // end of section is a context break | |
166 as -> context = lwasm_next_context(as); | |
167 | |
168 skip_operand(p); | |
169 } | |
356 | 170 |
171 PARSEFUNC(pseudo_parse_export) | |
172 { | |
173 int after = 0; | |
174 char *sym = NULL; | |
175 exportlist_t *e; | |
176 | |
177 if (as -> output_format != OUTPUT_OBJ) | |
178 { | |
179 lwasm_register_error(as, l, "EXPORT only supported for object target"); | |
180 return; | |
181 } | |
387
a741d2e4869f
Various bugfixes; fixed lwobjdump to display symbols with unprintable characters more sensibly; start of a (nonfunctional for now) testing framework
lost@l-w.ca
parents:
385
diff
changeset
|
182 |
a741d2e4869f
Various bugfixes; fixed lwobjdump to display symbols with unprintable characters more sensibly; start of a (nonfunctional for now) testing framework
lost@l-w.ca
parents:
385
diff
changeset
|
183 l -> len = 0; |
356 | 184 |
185 if (l -> sym) | |
385 | 186 { |
356 | 187 sym = lw_strdup(l -> sym); |
385 | 188 l -> symset = 1; |
189 } | |
356 | 190 |
191 if (l -> sym) | |
192 { | |
193 skip_operand(p); | |
194 } | |
195 | |
196 again: | |
197 if (after || !sym) | |
198 { | |
199 char *p2; | |
200 | |
201 after = 1; | |
202 for (p2 = *p; *p2 && *p2 != ',' && !isspace(*p2); p2++) | |
203 /* do nothing */ ; | |
204 | |
205 sym = lw_strndup(*p, p2 - *p); | |
385 | 206 *p = p2; |
356 | 207 } |
208 if (!sym) | |
209 { | |
210 lwasm_register_error(as, l, "No symbol for EXPORT"); | |
211 return; | |
212 } | |
213 | |
214 // add the symbol to the "export" list (which will be resolved | |
215 // after the parse pass is complete | |
216 e = lw_alloc(sizeof(exportlist_t)); | |
217 e -> next = as -> exportlist; | |
218 e -> symbol = lw_strdup(sym); | |
363
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
356
diff
changeset
|
219 e -> line = l; |
374 | 220 e -> se = NULL; |
356 | 221 as -> exportlist = e; |
222 lw_free(sym); | |
223 | |
224 if (after && **p == ',') | |
225 { | |
226 (*p)++; | |
227 for (; **p && isspace(**p); (*p)++) | |
228 /* do nothing */ ; | |
229 goto again; | |
230 } | |
231 } | |
232 | |
233 PARSEFUNC(pseudo_parse_extern) | |
234 { | |
235 int after = 0; | |
236 char *sym = NULL; | |
237 importlist_t *e; | |
238 | |
239 if (as -> output_format != OUTPUT_OBJ) | |
240 { | |
241 lwasm_register_error(as, l, "IMPORT only supported for object target"); | |
242 return; | |
243 } | |
244 | |
387
a741d2e4869f
Various bugfixes; fixed lwobjdump to display symbols with unprintable characters more sensibly; start of a (nonfunctional for now) testing framework
lost@l-w.ca
parents:
385
diff
changeset
|
245 l -> len = 0; |
a741d2e4869f
Various bugfixes; fixed lwobjdump to display symbols with unprintable characters more sensibly; start of a (nonfunctional for now) testing framework
lost@l-w.ca
parents:
385
diff
changeset
|
246 |
356 | 247 if (l -> sym) |
385 | 248 { |
356 | 249 sym = lw_strdup(l -> sym); |
385 | 250 l -> symset = 1; |
251 } | |
356 | 252 |
253 if (l -> sym) | |
254 { | |
255 skip_operand(p); | |
256 } | |
257 | |
258 again: | |
259 if (after || !sym) | |
260 { | |
261 char *p2; | |
262 | |
263 after = 1; | |
264 for (p2 = *p; *p2 && *p2 != ',' && !isspace(*p2); p2++) | |
265 /* do nothing */ ; | |
266 | |
267 sym = lw_strndup(*p, p2 - *p); | |
385 | 268 *p = p2; |
356 | 269 } |
270 if (!sym) | |
271 { | |
272 lwasm_register_error(as, l, "No symbol for IMPORT"); | |
273 return; | |
274 } | |
275 | |
276 // add the symbol to the "export" list (which will be resolved | |
277 // after the parse pass is complete | |
278 e = lw_alloc(sizeof(importlist_t)); | |
279 e -> next = as -> importlist; | |
280 e -> symbol = lw_strdup(sym); | |
281 as -> importlist = e; | |
282 lw_free(sym); | |
283 | |
284 if (after && **p == ',') | |
285 { | |
286 (*p)++; | |
287 for (; **p && isspace(**p); (*p)++) | |
288 /* do nothing */ ; | |
289 goto again; | |
290 } | |
291 } | |
380 | 292 |
293 PARSEFUNC(pseudo_parse_extdep) | |
294 { | |
295 int after = 0; | |
296 char *sym = NULL; | |
297 importlist_t *e; | |
298 | |
299 if (as -> output_format != OUTPUT_OBJ) | |
300 { | |
301 lwasm_register_error(as, l, "EXTDEP only supported for object target"); | |
302 return; | |
303 } | |
304 | |
305 if (!as -> csect) | |
306 { | |
307 lwasm_register_error(as, l, "EXTDEP must be within a section"); | |
308 return; | |
309 } | |
310 | |
387
a741d2e4869f
Various bugfixes; fixed lwobjdump to display symbols with unprintable characters more sensibly; start of a (nonfunctional for now) testing framework
lost@l-w.ca
parents:
385
diff
changeset
|
311 l -> len = 0; |
a741d2e4869f
Various bugfixes; fixed lwobjdump to display symbols with unprintable characters more sensibly; start of a (nonfunctional for now) testing framework
lost@l-w.ca
parents:
385
diff
changeset
|
312 |
380 | 313 if (l -> sym) |
314 sym = lw_strdup(l -> sym); | |
315 | |
316 if (l -> sym) | |
317 { | |
318 skip_operand(p); | |
319 } | |
320 | |
321 again: | |
322 if (after || !sym) | |
323 { | |
324 char *p2; | |
325 | |
326 after = 1; | |
327 for (p2 = *p; *p2 && *p2 != ',' && !isspace(*p2); p2++) | |
328 /* do nothing */ ; | |
329 | |
330 sym = lw_strndup(*p, p2 - *p); | |
331 } | |
332 if (!sym) | |
333 { | |
334 lwasm_register_error(as, l, "No symbol for EXTDEP"); | |
335 return; | |
336 } | |
337 | |
338 // create a zero-width dependency | |
339 { | |
340 lw_expr_t e; | |
341 e = lw_expr_build(lw_expr_type_int, 0); | |
342 lwasm_emitexpr(l, e, 0); | |
343 lw_expr_destroy(e); | |
344 } | |
345 | |
346 if (after && **p == ',') | |
347 { | |
348 (*p)++; | |
349 for (; **p && isspace(**p); (*p)++) | |
350 /* do nothing */ ; | |
351 goto again; | |
352 } | |
353 } |