Mercurial > hg-old > index.cgi
annotate lwasm/lwasm.c @ 170:bf69160da467
Added ability to use 0x and 0X as prefixes for hexadecimal numbers
author | lost |
---|---|
date | Sun, 01 Mar 2009 00:53:21 +0000 |
parents | 427e268e876b |
children | bae1e3ecdce1 |
rev | line source |
---|---|
0 | 1 /* |
4
34568fab6058
Fixed package to include all required files; also added copyright preamble to all source files
lost
parents:
0
diff
changeset
|
2 lwasm.c |
55 | 3 Copyright © 2009 William Astle |
4
34568fab6058
Fixed package to include all required files; also added copyright preamble to all source files
lost
parents:
0
diff
changeset
|
4 |
34568fab6058
Fixed package to include all required files; also added copyright preamble to all source files
lost
parents:
0
diff
changeset
|
5 This file is part of LWASM. |
34568fab6058
Fixed package to include all required files; also added copyright preamble to all source files
lost
parents:
0
diff
changeset
|
6 |
34568fab6058
Fixed package to include all required files; also added copyright preamble to all source files
lost
parents:
0
diff
changeset
|
7 LWASM is free software: you can redistribute it and/or modify it under the |
34568fab6058
Fixed package to include all required files; also added copyright preamble to all source files
lost
parents:
0
diff
changeset
|
8 terms of the GNU General Public License as published by the Free Software |
34568fab6058
Fixed package to include all required files; also added copyright preamble to all source files
lost
parents:
0
diff
changeset
|
9 Foundation, either version 3 of the License, or (at your option) any later |
34568fab6058
Fixed package to include all required files; also added copyright preamble to all source files
lost
parents:
0
diff
changeset
|
10 version. |
34568fab6058
Fixed package to include all required files; also added copyright preamble to all source files
lost
parents:
0
diff
changeset
|
11 |
34568fab6058
Fixed package to include all required files; also added copyright preamble to all source files
lost
parents:
0
diff
changeset
|
12 This program is distributed in the hope that it will be useful, but WITHOUT |
34568fab6058
Fixed package to include all required files; also added copyright preamble to all source files
lost
parents:
0
diff
changeset
|
13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
34568fab6058
Fixed package to include all required files; also added copyright preamble to all source files
lost
parents:
0
diff
changeset
|
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for |
34568fab6058
Fixed package to include all required files; also added copyright preamble to all source files
lost
parents:
0
diff
changeset
|
15 more details. |
34568fab6058
Fixed package to include all required files; also added copyright preamble to all source files
lost
parents:
0
diff
changeset
|
16 |
34568fab6058
Fixed package to include all required files; also added copyright preamble to all source files
lost
parents:
0
diff
changeset
|
17 You should have received a copy of the GNU General Public License along with |
34568fab6058
Fixed package to include all required files; also added copyright preamble to all source files
lost
parents:
0
diff
changeset
|
18 this program. If not, see <http://www.gnu.org/licenses/>. |
34568fab6058
Fixed package to include all required files; also added copyright preamble to all source files
lost
parents:
0
diff
changeset
|
19 |
26 | 20 |
21 Contains random functions used by the assembler | |
4
34568fab6058
Fixed package to include all required files; also added copyright preamble to all source files
lost
parents:
0
diff
changeset
|
22 */ |
0 | 23 |
26 | 24 #define __lwasm_c_seen__ |
25 | |
26 #include <stdarg.h> | |
0 | 27 #include <stdlib.h> |
26 | 28 #include <stdio.h> |
29 | |
0 | 30 #include "lwasm.h" |
26 | 31 #include "util.h" |
37
538e15927776
Added symbol handling to expression subsystem; adpated instruction handlers to the new scheme; misc fixes
lost
parents:
32
diff
changeset
|
32 #include "expr.h" |
0 | 33 |
38 | 34 int debug_level = 0; |
35 | |
26 | 36 int register_error(asmstate_t *as, lwasm_line_t *l, int pass, const char *fmt, ...) |
0 | 37 { |
26 | 38 lwasm_error_t *e; |
39 va_list args; | |
40 char errbuff[1024]; | |
41 int r; | |
0 | 42 |
143
0ee5f65bccf9
Added pragma to allow all undefined symbols to be considered external and also added a --pragma command line option
lost
parents:
101
diff
changeset
|
43 if (!l) |
0ee5f65bccf9
Added pragma to allow all undefined symbols to be considered external and also added a --pragma command line option
lost
parents:
101
diff
changeset
|
44 return; |
0ee5f65bccf9
Added pragma to allow all undefined symbols to be considered external and also added a --pragma command line option
lost
parents:
101
diff
changeset
|
45 |
26 | 46 if (as -> passnum != pass) |
47 return; | |
48 | |
49 va_start(args, fmt); | |
0 | 50 |
26 | 51 e = lwasm_alloc(sizeof(lwasm_error_t)); |
52 | |
53 e -> next = l -> err; | |
54 l -> err = e; | |
0 | 55 |
56 as -> errorcount++; | |
57 | |
26 | 58 r = vsnprintf(errbuff, 1024, fmt, args); |
59 e -> mess = lwasm_strdup(errbuff); | |
0 | 60 |
26 | 61 va_end(args); |
0 | 62 |
26 | 63 return r; |
0 | 64 } |
27
f736579569b4
Added handlers for inherent and register to register instructions
lost
parents:
26
diff
changeset
|
65 |
f736579569b4
Added handlers for inherent and register to register instructions
lost
parents:
26
diff
changeset
|
66 void lwasm_emit(asmstate_t *as, lwasm_line_t *l, int b) |
f736579569b4
Added handlers for inherent and register to register instructions
lost
parents:
26
diff
changeset
|
67 { |
f736579569b4
Added handlers for inherent and register to register instructions
lost
parents:
26
diff
changeset
|
68 as -> addr += 1; |
58 | 69 as -> addr &= 0xffff; |
70 | |
74 | 71 if (as -> outformat == OUTPUT_OBJ && !(as -> csect)) |
72 { | |
73 register_error(as, l, 1, "Output not allowed outside sections with obj target"); | |
74 return; | |
75 } | |
76 if (as -> outformat == OUTPUT_OBJ && as -> csect -> flags & SECTION_BSS) | |
77 { | |
78 register_error(as, l, 1, "Output not allowed inside BSS sections"); | |
79 return; | |
80 } | |
27
f736579569b4
Added handlers for inherent and register to register instructions
lost
parents:
26
diff
changeset
|
81 if (as -> passnum == 1) |
f736579569b4
Added handlers for inherent and register to register instructions
lost
parents:
26
diff
changeset
|
82 return; |
f736579569b4
Added handlers for inherent and register to register instructions
lost
parents:
26
diff
changeset
|
83 |
42 | 84 |
85 if (l -> codelen >= l -> codesize) | |
86 { | |
87 l -> bytes = realloc(l -> bytes, l -> codesize + 16); | |
88 l -> codesize += 16; | |
89 } | |
90 l -> bytes[l -> codelen] = b & 0xff; | |
91 l -> codelen += 1; | |
27
f736579569b4
Added handlers for inherent and register to register instructions
lost
parents:
26
diff
changeset
|
92 } |
f736579569b4
Added handlers for inherent and register to register instructions
lost
parents:
26
diff
changeset
|
93 |
f736579569b4
Added handlers for inherent and register to register instructions
lost
parents:
26
diff
changeset
|
94 void lwasm_emitop(asmstate_t *as, lwasm_line_t *l, int o) |
f736579569b4
Added handlers for inherent and register to register instructions
lost
parents:
26
diff
changeset
|
95 { |
f736579569b4
Added handlers for inherent and register to register instructions
lost
parents:
26
diff
changeset
|
96 if (o >= 0x100) |
f736579569b4
Added handlers for inherent and register to register instructions
lost
parents:
26
diff
changeset
|
97 lwasm_emit(as, l, o >> 8); |
f736579569b4
Added handlers for inherent and register to register instructions
lost
parents:
26
diff
changeset
|
98 lwasm_emit(as, l, o & 0xff); |
f736579569b4
Added handlers for inherent and register to register instructions
lost
parents:
26
diff
changeset
|
99 } |
f736579569b4
Added handlers for inherent and register to register instructions
lost
parents:
26
diff
changeset
|
100 |
f736579569b4
Added handlers for inherent and register to register instructions
lost
parents:
26
diff
changeset
|
101 int lwasm_lookupreg2(const char *reglist, char **str) |
f736579569b4
Added handlers for inherent and register to register instructions
lost
parents:
26
diff
changeset
|
102 { |
f736579569b4
Added handlers for inherent and register to register instructions
lost
parents:
26
diff
changeset
|
103 int rval = 0; |
f736579569b4
Added handlers for inherent and register to register instructions
lost
parents:
26
diff
changeset
|
104 |
f736579569b4
Added handlers for inherent and register to register instructions
lost
parents:
26
diff
changeset
|
105 while (*reglist) |
f736579569b4
Added handlers for inherent and register to register instructions
lost
parents:
26
diff
changeset
|
106 { |
f736579569b4
Added handlers for inherent and register to register instructions
lost
parents:
26
diff
changeset
|
107 if (toupper(**str) == *reglist) |
f736579569b4
Added handlers for inherent and register to register instructions
lost
parents:
26
diff
changeset
|
108 { |
f736579569b4
Added handlers for inherent and register to register instructions
lost
parents:
26
diff
changeset
|
109 // first char matches |
f736579569b4
Added handlers for inherent and register to register instructions
lost
parents:
26
diff
changeset
|
110 if (reglist[1] == ' ' && !isalpha(*(*str + 1))) |
f736579569b4
Added handlers for inherent and register to register instructions
lost
parents:
26
diff
changeset
|
111 break; |
f736579569b4
Added handlers for inherent and register to register instructions
lost
parents:
26
diff
changeset
|
112 if (toupper(*(*str + 1)) == reglist[1]) |
f736579569b4
Added handlers for inherent and register to register instructions
lost
parents:
26
diff
changeset
|
113 break; |
f736579569b4
Added handlers for inherent and register to register instructions
lost
parents:
26
diff
changeset
|
114 } |
f736579569b4
Added handlers for inherent and register to register instructions
lost
parents:
26
diff
changeset
|
115 reglist += 2; |
f736579569b4
Added handlers for inherent and register to register instructions
lost
parents:
26
diff
changeset
|
116 rval++; |
f736579569b4
Added handlers for inherent and register to register instructions
lost
parents:
26
diff
changeset
|
117 } |
f736579569b4
Added handlers for inherent and register to register instructions
lost
parents:
26
diff
changeset
|
118 if (!*reglist) |
f736579569b4
Added handlers for inherent and register to register instructions
lost
parents:
26
diff
changeset
|
119 return -1; |
f736579569b4
Added handlers for inherent and register to register instructions
lost
parents:
26
diff
changeset
|
120 if (reglist[1] == ' ') |
f736579569b4
Added handlers for inherent and register to register instructions
lost
parents:
26
diff
changeset
|
121 (*str)++; |
f736579569b4
Added handlers for inherent and register to register instructions
lost
parents:
26
diff
changeset
|
122 else |
f736579569b4
Added handlers for inherent and register to register instructions
lost
parents:
26
diff
changeset
|
123 (*str) += 2; |
f736579569b4
Added handlers for inherent and register to register instructions
lost
parents:
26
diff
changeset
|
124 return rval; |
f736579569b4
Added handlers for inherent and register to register instructions
lost
parents:
26
diff
changeset
|
125 } |
32 | 126 |
127 int lwasm_lookupreg3(const char *rlist, const char **str) | |
128 { | |
129 int rval = 0; | |
130 int f = 0; | |
131 const char *reglist = rlist; | |
132 | |
133 while (*reglist) | |
134 { | |
135 if (toupper(**str) == *reglist) | |
136 { | |
137 // first char matches | |
138 if (reglist[1] == ' ') | |
139 { | |
140 f = 1; | |
141 break; | |
142 } | |
143 if (toupper(*(*str + 1)) == reglist[1]) | |
144 { | |
145 // second char matches | |
146 if (reglist[2] == ' ') | |
147 { | |
148 f = 1; | |
149 break; | |
150 } | |
151 if (toupper(*(*str + 2)) == reglist[2]) | |
152 { | |
153 f = 1; | |
154 break; | |
155 } | |
156 } | |
157 } | |
158 reglist += 3; | |
159 rval++; | |
160 } | |
161 if (f == 0) | |
162 return -1; | |
163 | |
164 | |
165 reglist = rval * 3 + rlist; | |
166 if (reglist[1] == ' ') | |
167 (*str) += 1; | |
168 else if (reglist[2] == ' ') | |
169 (*str) += 2; | |
170 else | |
171 (*str)+=3; | |
172 return rval; | |
173 } | |
37
538e15927776
Added symbol handling to expression subsystem; adpated instruction handlers to the new scheme; misc fixes
lost
parents:
32
diff
changeset
|
174 |
538e15927776
Added symbol handling to expression subsystem; adpated instruction handlers to the new scheme; misc fixes
lost
parents:
32
diff
changeset
|
175 struct symstateinfo |
538e15927776
Added symbol handling to expression subsystem; adpated instruction handlers to the new scheme; misc fixes
lost
parents:
32
diff
changeset
|
176 { |
538e15927776
Added symbol handling to expression subsystem; adpated instruction handlers to the new scheme; misc fixes
lost
parents:
32
diff
changeset
|
177 asmstate_t *as; |
538e15927776
Added symbol handling to expression subsystem; adpated instruction handlers to the new scheme; misc fixes
lost
parents:
32
diff
changeset
|
178 lwasm_line_t *l; |
101
f59c0916753d
Fixed relative branches and PCR addressing to handle constant intra-section references properly
lost
parents:
98
diff
changeset
|
179 int flags; |
37
538e15927776
Added symbol handling to expression subsystem; adpated instruction handlers to the new scheme; misc fixes
lost
parents:
32
diff
changeset
|
180 }; |
538e15927776
Added symbol handling to expression subsystem; adpated instruction handlers to the new scheme; misc fixes
lost
parents:
32
diff
changeset
|
181 |
76 | 182 lwasm_expr_stack_t *lwasm_expr_lookup_symbol(char *sym, void *state) |
37
538e15927776
Added symbol handling to expression subsystem; adpated instruction handlers to the new scheme; misc fixes
lost
parents:
32
diff
changeset
|
183 { |
538e15927776
Added symbol handling to expression subsystem; adpated instruction handlers to the new scheme; misc fixes
lost
parents:
32
diff
changeset
|
184 lwasm_symbol_ent_t *se; |
538e15927776
Added symbol handling to expression subsystem; adpated instruction handlers to the new scheme; misc fixes
lost
parents:
32
diff
changeset
|
185 struct symstateinfo *st; |
76 | 186 lwasm_expr_stack_t *rs; |
187 lwasm_expr_term_t *t; | |
188 lwasm_expr_stack_node_t *n; | |
189 | |
190 int val; | |
37
538e15927776
Added symbol handling to expression subsystem; adpated instruction handlers to the new scheme; misc fixes
lost
parents:
32
diff
changeset
|
191 |
538e15927776
Added symbol handling to expression subsystem; adpated instruction handlers to the new scheme; misc fixes
lost
parents:
32
diff
changeset
|
192 st = state; |
52 | 193 debug_message(3, "lwasm_expr_lookup_symbol(): find '%s' (context=%d)", sym, st -> as -> context); |
194 | |
60 | 195 // check for special symbols first... |
196 if (sym[1] == '\0') | |
197 { | |
198 switch (sym[0]) | |
199 { | |
200 // current line address | |
201 case '*': | |
202 case '.': | |
76 | 203 val = st -> l -> codeaddr; |
204 goto retconst; | |
60 | 205 |
206 case '<': | |
207 // previous branch point | |
208 // not implemented | |
209 break; | |
210 case '>': | |
211 // next branch point | |
212 // not implemented | |
213 break; | |
214 } | |
215 } | |
216 | |
37
538e15927776
Added symbol handling to expression subsystem; adpated instruction handlers to the new scheme; misc fixes
lost
parents:
32
diff
changeset
|
217 // look for local symbol first then global symbol |
538e15927776
Added symbol handling to expression subsystem; adpated instruction handlers to the new scheme; misc fixes
lost
parents:
32
diff
changeset
|
218 se = lwasm_find_symbol(st -> as, sym, st -> as -> context); |
538e15927776
Added symbol handling to expression subsystem; adpated instruction handlers to the new scheme; misc fixes
lost
parents:
32
diff
changeset
|
219 if (!se) |
538e15927776
Added symbol handling to expression subsystem; adpated instruction handlers to the new scheme; misc fixes
lost
parents:
32
diff
changeset
|
220 se = lwasm_find_symbol(st -> as, sym, -1); |
52 | 221 debug_message(3, "lwasm_expr_lookup_symbol(): got '%p'", se); |
37
538e15927776
Added symbol handling to expression subsystem; adpated instruction handlers to the new scheme; misc fixes
lost
parents:
32
diff
changeset
|
222 if (!se) |
77 | 223 { |
224 register_error(st -> as, st -> l, 2, "Undefined symbol '%s'", sym); | |
76 | 225 return NULL; |
77 | 226 } |
92
ea2cfebef5d0
Make external symbols remain unresolved in expressions and also flag them in the symbol list
lost
parents:
84
diff
changeset
|
227 // external reference - can not resolve it |
ea2cfebef5d0
Make external symbols remain unresolved in expressions and also flag them in the symbol list
lost
parents:
84
diff
changeset
|
228 if (se -> flags & SYMBOL_EXTERN) |
ea2cfebef5d0
Make external symbols remain unresolved in expressions and also flag them in the symbol list
lost
parents:
84
diff
changeset
|
229 { |
ea2cfebef5d0
Make external symbols remain unresolved in expressions and also flag them in the symbol list
lost
parents:
84
diff
changeset
|
230 return NULL; |
ea2cfebef5d0
Make external symbols remain unresolved in expressions and also flag them in the symbol list
lost
parents:
84
diff
changeset
|
231 } |
101
f59c0916753d
Fixed relative branches and PCR addressing to handle constant intra-section references properly
lost
parents:
98
diff
changeset
|
232 if (st -> flags & EXPR_SECTCONST) |
f59c0916753d
Fixed relative branches and PCR addressing to handle constant intra-section references properly
lost
parents:
98
diff
changeset
|
233 { |
f59c0916753d
Fixed relative branches and PCR addressing to handle constant intra-section references properly
lost
parents:
98
diff
changeset
|
234 if (se -> sect == st -> l -> sect) |
f59c0916753d
Fixed relative branches and PCR addressing to handle constant intra-section references properly
lost
parents:
98
diff
changeset
|
235 { |
f59c0916753d
Fixed relative branches and PCR addressing to handle constant intra-section references properly
lost
parents:
98
diff
changeset
|
236 if (se -> expr) |
f59c0916753d
Fixed relative branches and PCR addressing to handle constant intra-section references properly
lost
parents:
98
diff
changeset
|
237 goto retsym; |
f59c0916753d
Fixed relative branches and PCR addressing to handle constant intra-section references properly
lost
parents:
98
diff
changeset
|
238 val = se -> value; |
f59c0916753d
Fixed relative branches and PCR addressing to handle constant intra-section references properly
lost
parents:
98
diff
changeset
|
239 goto retconst; |
f59c0916753d
Fixed relative branches and PCR addressing to handle constant intra-section references properly
lost
parents:
98
diff
changeset
|
240 } |
f59c0916753d
Fixed relative branches and PCR addressing to handle constant intra-section references properly
lost
parents:
98
diff
changeset
|
241 } |
93
34ca1c6e9550
Fixed symbol resolution to not resolve intra-section references to constants by default
lost
parents:
92
diff
changeset
|
242 if (st -> as -> outformat == OUTPUT_OBJ && se -> sect != NULL) |
34ca1c6e9550
Fixed symbol resolution to not resolve intra-section references to constants by default
lost
parents:
92
diff
changeset
|
243 { |
34ca1c6e9550
Fixed symbol resolution to not resolve intra-section references to constants by default
lost
parents:
92
diff
changeset
|
244 return NULL; |
34ca1c6e9550
Fixed symbol resolution to not resolve intra-section references to constants by default
lost
parents:
92
diff
changeset
|
245 } |
34ca1c6e9550
Fixed symbol resolution to not resolve intra-section references to constants by default
lost
parents:
92
diff
changeset
|
246 if (st -> as -> outformat != OUTPUT_OBJ || se -> sect == NULL) |
76 | 247 { |
248 // global symbol, intrasegment reference, or not an object target | |
249 val = se -> value; | |
250 goto retconst; | |
251 } | |
101
f59c0916753d
Fixed relative branches and PCR addressing to handle constant intra-section references properly
lost
parents:
98
diff
changeset
|
252 |
76 | 253 // an intersegment reference will return as NULL (to be resolved at output/link time) |
254 // if se -> expr is NULL, it has to be an intersegment reference here | |
255 if (se -> expr == NULL) | |
256 { | |
257 return NULL; | |
258 } | |
259 | |
101
f59c0916753d
Fixed relative branches and PCR addressing to handle constant intra-section references properly
lost
parents:
98
diff
changeset
|
260 retsym: |
76 | 261 // duplicate the expression for return |
262 rs = lwasm_expr_stack_create(); | |
263 for (n = se -> expr -> head; n; n = n -> next) | |
264 { | |
265 lwasm_expr_stack_push(rs, n -> term); | |
266 } | |
267 return rs; | |
268 | |
269 retconst: | |
270 rs = lwasm_expr_stack_create(); | |
271 t = lwasm_expr_term_create_int(val); | |
272 lwasm_expr_stack_push(rs, t); | |
273 lwasm_expr_term_free(t); | |
274 return rs; | |
37
538e15927776
Added symbol handling to expression subsystem; adpated instruction handlers to the new scheme; misc fixes
lost
parents:
32
diff
changeset
|
275 } |
538e15927776
Added symbol handling to expression subsystem; adpated instruction handlers to the new scheme; misc fixes
lost
parents:
32
diff
changeset
|
276 |
101
f59c0916753d
Fixed relative branches and PCR addressing to handle constant intra-section references properly
lost
parents:
98
diff
changeset
|
277 lwasm_expr_stack_t *lwasm_evaluate_expr(asmstate_t *as, lwasm_line_t *l, const char *inp, const char **outp, int flags) |
37
538e15927776
Added symbol handling to expression subsystem; adpated instruction handlers to the new scheme; misc fixes
lost
parents:
32
diff
changeset
|
278 { |
538e15927776
Added symbol handling to expression subsystem; adpated instruction handlers to the new scheme; misc fixes
lost
parents:
32
diff
changeset
|
279 struct symstateinfo st; |
538e15927776
Added symbol handling to expression subsystem; adpated instruction handlers to the new scheme; misc fixes
lost
parents:
32
diff
changeset
|
280 |
538e15927776
Added symbol handling to expression subsystem; adpated instruction handlers to the new scheme; misc fixes
lost
parents:
32
diff
changeset
|
281 st.as = as; |
538e15927776
Added symbol handling to expression subsystem; adpated instruction handlers to the new scheme; misc fixes
lost
parents:
32
diff
changeset
|
282 st.l = l; |
101
f59c0916753d
Fixed relative branches and PCR addressing to handle constant intra-section references properly
lost
parents:
98
diff
changeset
|
283 st.flags = flags; |
37
538e15927776
Added symbol handling to expression subsystem; adpated instruction handlers to the new scheme; misc fixes
lost
parents:
32
diff
changeset
|
284 |
38 | 285 debug_message(2, "Evaluate expression: %s", inp); |
286 | |
37
538e15927776
Added symbol handling to expression subsystem; adpated instruction handlers to the new scheme; misc fixes
lost
parents:
32
diff
changeset
|
287 return(lwasm_expr_eval(inp, outp, lwasm_expr_lookup_symbol, &st)); |
538e15927776
Added symbol handling to expression subsystem; adpated instruction handlers to the new scheme; misc fixes
lost
parents:
32
diff
changeset
|
288 } |
38 | 289 |
77 | 290 |
101
f59c0916753d
Fixed relative branches and PCR addressing to handle constant intra-section references properly
lost
parents:
98
diff
changeset
|
291 int lwasm_reevaluate_expr(asmstate_t *as, lwasm_line_t *l, lwasm_expr_stack_t *s, int flags) |
77 | 292 { |
293 struct symstateinfo st; | |
294 | |
295 st.as = as; | |
296 st.l = l; | |
101
f59c0916753d
Fixed relative branches and PCR addressing to handle constant intra-section references properly
lost
parents:
98
diff
changeset
|
297 st.flags = flags; |
77 | 298 return(lwasm_expr_reval(s, lwasm_expr_lookup_symbol, &st)); |
299 } | |
300 | |
76 | 301 // return 1 if no undefined symbols (externals and incompletes are okay) |
302 // return 0 if there are undefined symbols | |
303 int lwasm_expr_result_ckconst(asmstate_t *as, lwasm_expr_stack_t *s) | |
304 { | |
305 lwasm_expr_stack_node_t *n; | |
306 lwasm_symbol_ent_t *se; | |
307 | |
77 | 308 if (as -> outformat != OUTPUT_OBJ) |
309 { | |
310 if (lwasm_expr_is_constant(s)) | |
311 return 1; | |
312 else | |
313 return 0; | |
314 } | |
315 | |
76 | 316 for (n = s -> head; n; n = n -> next) |
317 { | |
318 if (n -> term -> term_type == LWASM_TERM_SYM) | |
319 { | |
320 se = lwasm_find_symbol(as, n -> term -> symbol, as -> context); | |
321 if (!se) | |
322 se = lwasm_find_symbol(as, n -> term -> symbol, -1); | |
323 if (!se) | |
324 return 0; | |
325 } | |
326 } | |
327 return 1; | |
328 } | |
329 | |
330 /* | |
331 Evaluate an expression according to the flag value. Return 0 if a constant result was | |
332 obtained, 1 if an incomplete result was obtained, and -1 if an error was flagged. | |
333 | |
77 | 334 */ |
335 int lwasm_expr_result2(asmstate_t *as, lwasm_line_t *l, char **inp, int flag, int *val, int slot) | |
336 { | |
79
d0ce3f5f6797
Checkpointing deployment of non-constant expression handling
lost
parents:
78
diff
changeset
|
337 lwasm_expr_stack_t *s = NULL; |
77 | 338 const char *ep; |
339 int rval; | |
340 | |
101
f59c0916753d
Fixed relative branches and PCR addressing to handle constant intra-section references properly
lost
parents:
98
diff
changeset
|
341 if ((as -> passnum == 1 && !(flag & EXPR_REEVAL)) || slot < 0) |
77 | 342 { |
101
f59c0916753d
Fixed relative branches and PCR addressing to handle constant intra-section references properly
lost
parents:
98
diff
changeset
|
343 s = lwasm_evaluate_expr(as, l, *inp, &ep, flag); |
79
d0ce3f5f6797
Checkpointing deployment of non-constant expression handling
lost
parents:
78
diff
changeset
|
344 if (slot >= 0) |
d0ce3f5f6797
Checkpointing deployment of non-constant expression handling
lost
parents:
78
diff
changeset
|
345 l -> exprs[slot] = s; |
77 | 346 if (!s) |
347 { | |
348 register_error(as, l, 1, "Bad expression"); | |
349 *val = 0; | |
350 return -1; | |
351 } | |
352 *inp = (char *)ep; | |
79
d0ce3f5f6797
Checkpointing deployment of non-constant expression handling
lost
parents:
78
diff
changeset
|
353 if (slot >= 0) |
d0ce3f5f6797
Checkpointing deployment of non-constant expression handling
lost
parents:
78
diff
changeset
|
354 { |
94
83ba34ed11b3
Fixed problem with constant expressions evaluating to 0 when they shouldn't
lost
parents:
93
diff
changeset
|
355 l -> exprends[slot] = (char *)ep; |
79
d0ce3f5f6797
Checkpointing deployment of non-constant expression handling
lost
parents:
78
diff
changeset
|
356 l -> exprvals[slot] = lwasm_expr_get_value(s); |
d0ce3f5f6797
Checkpointing deployment of non-constant expression handling
lost
parents:
78
diff
changeset
|
357 } |
77 | 358 } |
359 else if (l -> exprs[slot]) | |
360 { | |
361 s = l -> exprs[slot]; | |
101
f59c0916753d
Fixed relative branches and PCR addressing to handle constant intra-section references properly
lost
parents:
98
diff
changeset
|
362 lwasm_reevaluate_expr(as, l, s, flag); |
77 | 363 l -> exprvals[slot] = lwasm_expr_get_value(s); |
364 } | |
84
e12edcfbebd5
Fixed problem with expression evaluation infrastructure not advancing input pointer on pass 2
lost
parents:
79
diff
changeset
|
365 if (as -> passnum == 2 && slot >= 0) |
e12edcfbebd5
Fixed problem with expression evaluation infrastructure not advancing input pointer on pass 2
lost
parents:
79
diff
changeset
|
366 *inp = l -> exprends[slot]; |
77 | 367 |
368 if (s && lwasm_expr_is_constant(s)) | |
369 { | |
94
83ba34ed11b3
Fixed problem with constant expressions evaluating to 0 when they shouldn't
lost
parents:
93
diff
changeset
|
370 *val = lwasm_expr_get_value(s); |
77 | 371 lwasm_expr_stack_free(s); |
372 l -> exprs[slot] = NULL; | |
373 s = NULL; | |
94
83ba34ed11b3
Fixed problem with constant expressions evaluating to 0 when they shouldn't
lost
parents:
93
diff
changeset
|
374 return 0; |
77 | 375 } |
376 | |
79
d0ce3f5f6797
Checkpointing deployment of non-constant expression handling
lost
parents:
78
diff
changeset
|
377 if (!s && slot >= 0) |
77 | 378 { |
379 *val = l -> exprvals[slot]; | |
380 return 0; | |
381 } | |
79
d0ce3f5f6797
Checkpointing deployment of non-constant expression handling
lost
parents:
78
diff
changeset
|
382 else if (!s) |
d0ce3f5f6797
Checkpointing deployment of non-constant expression handling
lost
parents:
78
diff
changeset
|
383 { |
d0ce3f5f6797
Checkpointing deployment of non-constant expression handling
lost
parents:
78
diff
changeset
|
384 *val = 0; |
d0ce3f5f6797
Checkpointing deployment of non-constant expression handling
lost
parents:
78
diff
changeset
|
385 return 0; |
d0ce3f5f6797
Checkpointing deployment of non-constant expression handling
lost
parents:
78
diff
changeset
|
386 } |
78
121bf4a588ea
Checkpointing deployment of non-constant expression handling
lost
parents:
77
diff
changeset
|
387 |
121bf4a588ea
Checkpointing deployment of non-constant expression handling
lost
parents:
77
diff
changeset
|
388 // was a constant result on pass 1 requested? |
121bf4a588ea
Checkpointing deployment of non-constant expression handling
lost
parents:
77
diff
changeset
|
389 // that means we must have a constant on either pass |
121bf4a588ea
Checkpointing deployment of non-constant expression handling
lost
parents:
77
diff
changeset
|
390 if (flag & EXPR_PASS1CONST) |
121bf4a588ea
Checkpointing deployment of non-constant expression handling
lost
parents:
77
diff
changeset
|
391 { |
121bf4a588ea
Checkpointing deployment of non-constant expression handling
lost
parents:
77
diff
changeset
|
392 *val = 0; |
79
d0ce3f5f6797
Checkpointing deployment of non-constant expression handling
lost
parents:
78
diff
changeset
|
393 if (slot >= 0) |
d0ce3f5f6797
Checkpointing deployment of non-constant expression handling
lost
parents:
78
diff
changeset
|
394 l -> exprvals[slot] = 0; |
78
121bf4a588ea
Checkpointing deployment of non-constant expression handling
lost
parents:
77
diff
changeset
|
395 register_error(as, l, 1, "Illegal forward, external, or inter-section reference"); |
121bf4a588ea
Checkpointing deployment of non-constant expression handling
lost
parents:
77
diff
changeset
|
396 lwasm_expr_stack_free(s); |
79
d0ce3f5f6797
Checkpointing deployment of non-constant expression handling
lost
parents:
78
diff
changeset
|
397 if (slot >= 0) |
d0ce3f5f6797
Checkpointing deployment of non-constant expression handling
lost
parents:
78
diff
changeset
|
398 l -> exprs[slot] = NULL; |
78
121bf4a588ea
Checkpointing deployment of non-constant expression handling
lost
parents:
77
diff
changeset
|
399 return -1; |
121bf4a588ea
Checkpointing deployment of non-constant expression handling
lost
parents:
77
diff
changeset
|
400 } |
77 | 401 |
402 return 1; | |
403 } | |
55 | 404 |
38 | 405 void debug_message(int level, const char *fmt, ...) |
406 { | |
407 va_list args; | |
408 | |
409 va_start(args, fmt); | |
410 if (debug_level >= level) | |
411 { | |
39 | 412 if (level > 0) |
413 fprintf(stderr, "DEBUG %d: ", level); | |
38 | 414 vfprintf(stderr, fmt, args); |
415 fputc('\n', stderr); | |
416 } | |
417 va_end(args); | |
418 } | |
57 | 419 |
420 int lwasm_next_context(asmstate_t *as) | |
421 { | |
58 | 422 int r; |
423 r = as -> nextcontext; | |
424 as -> nextcontext += 1; | |
425 debug_message(3, "lwasm_next_context(): %d (%d) pass %d", r, as -> nextcontext, as -> passnum); | |
426 return r; | |
57 | 427 } |
428 |