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