Mercurial > hg-old > index.cgi
comparison src/lwasm.c @ 101:f59c0916753d
Fixed relative branches and PCR addressing to handle constant intra-section references properly
author | lost |
---|---|
date | Fri, 23 Jan 2009 03:36:27 +0000 |
parents | 81fc353d4d69 |
children | 0ee5f65bccf9 |
comparison
equal
deleted
inserted
replaced
100:579ac3697918 | 101:f59c0916753d |
---|---|
171 | 171 |
172 struct symstateinfo | 172 struct symstateinfo |
173 { | 173 { |
174 asmstate_t *as; | 174 asmstate_t *as; |
175 lwasm_line_t *l; | 175 lwasm_line_t *l; |
176 int flags; | |
176 }; | 177 }; |
177 | 178 |
178 lwasm_expr_stack_t *lwasm_expr_lookup_symbol(char *sym, void *state) | 179 lwasm_expr_stack_t *lwasm_expr_lookup_symbol(char *sym, void *state) |
179 { | 180 { |
180 lwasm_symbol_ent_t *se; | 181 lwasm_symbol_ent_t *se; |
223 // external reference - can not resolve it | 224 // external reference - can not resolve it |
224 if (se -> flags & SYMBOL_EXTERN) | 225 if (se -> flags & SYMBOL_EXTERN) |
225 { | 226 { |
226 return NULL; | 227 return NULL; |
227 } | 228 } |
229 if (st -> flags & EXPR_SECTCONST) | |
230 { | |
231 if (se -> sect == st -> l -> sect) | |
232 { | |
233 if (se -> expr) | |
234 goto retsym; | |
235 val = se -> value; | |
236 goto retconst; | |
237 } | |
238 } | |
228 if (st -> as -> outformat == OUTPUT_OBJ && se -> sect != NULL) | 239 if (st -> as -> outformat == OUTPUT_OBJ && se -> sect != NULL) |
229 { | 240 { |
230 // do not resolve any section symbols in object mode | |
231 return NULL; | 241 return NULL; |
232 } | 242 } |
233 if (st -> as -> outformat != OUTPUT_OBJ || se -> sect == NULL) | 243 if (st -> as -> outformat != OUTPUT_OBJ || se -> sect == NULL) |
234 { | 244 { |
235 // global symbol, intrasegment reference, or not an object target | 245 // global symbol, intrasegment reference, or not an object target |
236 val = se -> value; | 246 val = se -> value; |
237 goto retconst; | 247 goto retconst; |
238 } | 248 } |
249 | |
239 // an intersegment reference will return as NULL (to be resolved at output/link time) | 250 // an intersegment reference will return as NULL (to be resolved at output/link time) |
240 // if se -> expr is NULL, it has to be an intersegment reference here | 251 // if se -> expr is NULL, it has to be an intersegment reference here |
241 if (se -> expr == NULL) | 252 if (se -> expr == NULL) |
242 { | 253 { |
243 return NULL; | 254 return NULL; |
244 } | 255 } |
245 | 256 |
257 retsym: | |
246 // duplicate the expression for return | 258 // duplicate the expression for return |
247 rs = lwasm_expr_stack_create(); | 259 rs = lwasm_expr_stack_create(); |
248 for (n = se -> expr -> head; n; n = n -> next) | 260 for (n = se -> expr -> head; n; n = n -> next) |
249 { | 261 { |
250 lwasm_expr_stack_push(rs, n -> term); | 262 lwasm_expr_stack_push(rs, n -> term); |
257 lwasm_expr_stack_push(rs, t); | 269 lwasm_expr_stack_push(rs, t); |
258 lwasm_expr_term_free(t); | 270 lwasm_expr_term_free(t); |
259 return rs; | 271 return rs; |
260 } | 272 } |
261 | 273 |
262 lwasm_expr_stack_t *lwasm_evaluate_expr(asmstate_t *as, lwasm_line_t *l, const char *inp, const char **outp) | 274 lwasm_expr_stack_t *lwasm_evaluate_expr(asmstate_t *as, lwasm_line_t *l, const char *inp, const char **outp, int flags) |
263 { | 275 { |
264 struct symstateinfo st; | 276 struct symstateinfo st; |
265 | 277 |
266 st.as = as; | 278 st.as = as; |
267 st.l = l; | 279 st.l = l; |
280 st.flags = flags; | |
268 | 281 |
269 debug_message(2, "Evaluate expression: %s", inp); | 282 debug_message(2, "Evaluate expression: %s", inp); |
270 | 283 |
271 return(lwasm_expr_eval(inp, outp, lwasm_expr_lookup_symbol, &st)); | 284 return(lwasm_expr_eval(inp, outp, lwasm_expr_lookup_symbol, &st)); |
272 } | 285 } |
273 | 286 |
274 | 287 |
275 int lwasm_reevaluate_expr(asmstate_t *as, lwasm_line_t *l, lwasm_expr_stack_t *s) | 288 int lwasm_reevaluate_expr(asmstate_t *as, lwasm_line_t *l, lwasm_expr_stack_t *s, int flags) |
276 { | 289 { |
277 struct symstateinfo st; | 290 struct symstateinfo st; |
278 | 291 |
279 st.as = as; | 292 st.as = as; |
280 st.l = l; | 293 st.l = l; |
281 | 294 st.flags = flags; |
282 return(lwasm_expr_reval(s, lwasm_expr_lookup_symbol, &st)); | 295 return(lwasm_expr_reval(s, lwasm_expr_lookup_symbol, &st)); |
283 } | 296 } |
284 | 297 |
285 // return 1 if no undefined symbols (externals and incompletes are okay) | 298 // return 1 if no undefined symbols (externals and incompletes are okay) |
286 // return 0 if there are undefined symbols | 299 // return 0 if there are undefined symbols |
320 { | 333 { |
321 lwasm_expr_stack_t *s = NULL; | 334 lwasm_expr_stack_t *s = NULL; |
322 const char *ep; | 335 const char *ep; |
323 int rval; | 336 int rval; |
324 | 337 |
325 if (as -> passnum == 1 || slot < 0) | 338 if ((as -> passnum == 1 && !(flag & EXPR_REEVAL)) || slot < 0) |
326 { | 339 { |
327 s = lwasm_evaluate_expr(as, l, *inp, &ep); | 340 s = lwasm_evaluate_expr(as, l, *inp, &ep, flag); |
328 if (slot >= 0) | 341 if (slot >= 0) |
329 l -> exprs[slot] = s; | 342 l -> exprs[slot] = s; |
330 if (!s) | 343 if (!s) |
331 { | 344 { |
332 register_error(as, l, 1, "Bad expression"); | 345 register_error(as, l, 1, "Bad expression"); |
341 } | 354 } |
342 } | 355 } |
343 else if (l -> exprs[slot]) | 356 else if (l -> exprs[slot]) |
344 { | 357 { |
345 s = l -> exprs[slot]; | 358 s = l -> exprs[slot]; |
346 lwasm_reevaluate_expr(as, l, s); | 359 lwasm_reevaluate_expr(as, l, s, flag); |
347 l -> exprvals[slot] = lwasm_expr_get_value(s); | 360 l -> exprvals[slot] = lwasm_expr_get_value(s); |
348 } | 361 } |
349 if (as -> passnum == 2 && slot >= 0) | 362 if (as -> passnum == 2 && slot >= 0) |
350 *inp = l -> exprends[slot]; | 363 *inp = l -> exprends[slot]; |
351 | 364 |