comparison lwasm/output.c @ 376:91c0fe026940

Output incomplete references in object target
author lost@starbug
date Mon, 26 Apr 2010 17:59:30 -0600
parents 3498b2d88376
children 55ed7d06b136
comparison
equal deleted inserted replaced
375:3498b2d88376 376:91c0fe026940
228 } 228 }
229 s -> obytes[s -> oblen] = b; 229 s -> obytes[s -> oblen] = b;
230 s -> oblen += 1; 230 s -> oblen += 1;
231 } 231 }
232 232
233
234 int write_code_obj_expraux(lw_expr_t e, void *of)
235 {
236 int tt;
237 int v;
238 unsigned char buf[16];
239
240 tt = lw_expr_type(e);
241
242 switch (tt)
243 {
244 case lw_expr_type_oper:
245 buf[0] = 0x04;
246 switch (lw_expr_intval(e))
247 {
248 case lw_expr_oper_plus:
249 buf[1] = 0x01;
250 break;
251
252 case lw_expr_oper_minus:
253 buf[1] = 0x02;
254 break;
255
256 case lw_expr_oper_times:
257 buf[1] = 0x03;
258 break;
259
260 case lw_expr_oper_divide:
261 buf[1] = 0x04;
262 break;
263
264 case lw_expr_oper_mod:
265 buf[1] = 0x05;
266 break;
267
268 case lw_expr_oper_intdiv:
269 buf[1] = 0x06;
270 break;
271
272 case lw_expr_oper_bwand:
273 buf[1] = 0x07;
274 break;
275
276 case lw_expr_oper_bwor:
277 buf[1] = 0x08;
278 break;
279
280 case lw_expr_oper_bwxor:
281 buf[1] = 0x09;
282 break;
283
284 case lw_expr_oper_and:
285 buf[1] = 0x0A;
286 break;
287
288 case lw_expr_oper_or:
289 buf[1] = 0x0B;
290 break;
291
292 case lw_expr_oper_neg:
293 buf[1] = 0x0C;
294 break;
295
296 case lw_expr_oper_com:
297 buf[1] = 0x0D;
298 break;
299
300 default:
301 buf[1] = 0xff;
302 }
303 writebytes(buf, 2, 1, of);
304 break;
305
306 case lw_expr_type_int:
307 v = lw_expr_intval(e);
308 buf[0] = 0x01;
309 buf[1] = (v >> 8) & 0xff;
310 buf[2] = v & 0xff;
311 writebytes(buf, 3, 1, of);
312 break;
313
314 case lw_expr_type_special:
315 v = lw_expr_specint(e);
316 switch (v)
317 {
318 case lwasm_expr_secbase:
319 writebytes("\x05", 1, 1, of);
320 break;
321
322 case lwasm_expr_import:
323 {
324 importlist_t *ie;
325 ie = lw_expr_specptr(e);
326 buf[0] = 0x02;
327 writebytes(buf, 1, 1, of);
328 writebytes(ie -> symbol, strlen(ie -> symbol) + 1, 1, of);
329 break;
330 }
331 case lwasm_expr_syment:
332 {
333 struct symtabe *se;
334 se = lw_expr_specptr(e);
335 buf[0] = 0x03;
336 writebytes(buf, 1, 1, of);
337 writebytes(se -> symbol, strlen(se -> symbol), 1, of);
338 if (se -> context != -1)
339 {
340 sprintf(buf, "\x01%d", se -> context);
341 writebytes(buf, strlen(buf), 1, of);
342 }
343 writebytes("", 1, 1, of);
344 break;
345 }
346 break;
347 }
348
349 default:
350 // unrecognized term type - replace with integer 0
351 buf[0] = 0x01;
352 buf[1] = 0x00;
353 buf[2] = 0x00;
354 writebytes(buf, 3, 1, of);
355 break;
356 }
357 return 0;
358 }
359
360
233 void write_code_obj(asmstate_t *as, FILE *of) 361 void write_code_obj(asmstate_t *as, FILE *of)
234 { 362 {
235 line_t *l; 363 line_t *l;
236 sectiontab_t *s; 364 sectiontab_t *s;
237 reloctab_t *re; 365 reloctab_t *re;
357 485
358 // flag end of exported symbols - "" is NOT an error 486 // flag end of exported symbols - "" is NOT an error
359 writebytes("", 1, 1, of); 487 writebytes("", 1, 1, of);
360 488
361 // FIXME - relocation table 489 // FIXME - relocation table
362 /* for (re = s -> rl; re; re = re -> next) 490 for (re = s -> reloctab; re; re = re -> next)
363 { 491 {
492 int offset;
493 lw_expr_t te;
494 line_t tl;
495
496 tl.as = as;
497 as -> cl = &tl;
498 as -> csect = s;
499 as -> exportcheck = 1;
500
364 if (re -> expr == NULL) 501 if (re -> expr == NULL)
365 { 502 {
366 // this is an error but we'll simply ignore it 503 // this is an error but we'll simply ignore it
367 // and not output this expression 504 // and not output this expression
368 continue; 505 continue;
369 } 506 }
370 507
371 // work through each term in the expression and output 508 // work through each term in the expression and output
372 // the proper equivalent to the object file 509 // the proper equivalent to the object file
373 if (re -> relocsize == 1) 510 if (re -> size == 1)
374 { 511 {
375 // flag an 8 bit relocation (low 8 bits will be used) 512 // flag an 8 bit relocation (low 8 bits will be used)
376 buf[0] = 0xFF; 513 buf[0] = 0xFF;
377 buf[1] = 0x01; 514 buf[1] = 0x01;
378 writebytes(buf, 2, 1, of); 515 writebytes(buf, 2, 1, of);
379 } 516 }
380 for (sn = re -> expr -> head; sn; sn = sn -> next) 517
381 { 518 te = lw_expr_copy(ex -> se -> value);
382 switch (sn -> term -> term_type) 519 lwasm_reduce_expr(as, te);
383 { 520 if (!lw_expr_istype(te, lw_expr_type_int))
384 case LWASM_TERM_OPER: 521 {
385 buf[0] = 0x04; 522 lw_expr_destroy(te);
386 buf[1] = sn -> term -> value; 523 continue;
387 writebytes(buf, 2, 1, of); 524 }
388 break; 525 offset = lw_expr_intval(te);
389 526 lw_expr_destroy(te);
390 case LWASM_TERM_INT: 527
391 buf[0] = 0x01; 528 // output expression
392 buf[1] = (sn -> term -> value >> 8) & 0xff; 529 lw_expr_testterms(re -> expr, write_code_obj_expraux, of);
393 buf[2] = sn -> term -> value & 0xff;
394 writebytes(buf, 3, 1, of);
395 break;
396
397 case LWASM_TERM_SECBASE:
398 writebytes("\x05", 1, 1, of);
399 break;
400
401 case LWASM_TERM_SYM:
402 // now for the ugly part - resolve a symbol reference
403 // and determine whether it's internal, external, or
404 // a section base
405 se = lwasm_find_symbol(as, sn -> term -> symbol, re -> context);
406 if (!se)
407 se = lwasm_find_symbol(as, sn -> term -> symbol, -1);
408 if (!se || se -> flags & SYMBOL_EXTERN)
409 {
410 // not found - assume external reference
411 // found but flagged external - handle it
412 writebytes("\x02", 1, 1, of);
413 writebytes(se -> sym, strlen(se -> sym) + 1, 1, of);
414 break;
415 }
416 // a local symbol reference here
417 writebytes("\x03", 1, 1, of);
418 writebytes(se -> sym, strlen(se -> sym), 1, of);
419 if (se -> context >= 0)
420 {
421 writebytes("\x01", 1, 1, of);
422 sprintf(buf, "%d", se -> context);
423 writebytes(buf, strlen(buf), 1, of);
424 }
425 writebytes("", 1, 1, of);
426 break;
427
428 default:
429 // unrecognized term type - replace with integer 0
430 buf[0] = 0x01;
431 buf[1] = 0x00;
432 buf[2] = 0x00;
433 writebytes(buf, 3, 1, of);
434 break;
435 }
436 }
437 530
438 // flag end of expressions 531 // flag end of expressions
439 writebytes("", 1, 1, of); 532 writebytes("", 1, 1, of);
440 533
441 // write the offset 534 // write the offset
442 buf[0] = (re -> offset >> 8) & 0xff; 535 buf[0] = (offset >> 8) & 0xff;
443 buf[1] = re -> offset & 0xff; 536 buf[1] = offset & 0xff;
444 writebytes(buf, 2, 1, of); 537 writebytes(buf, 2, 1, of);
445 } 538 }
446 */ 539
447 // flag end of incomplete references list 540 // flag end of incomplete references list
448 writebytes("", 1, 1, of); 541 writebytes("", 1, 1, of);
449 542
450 // now blast out the code 543 // now blast out the code
451 544