# HG changeset patch # User lost@starbug # Date 1272326370 21600 # Node ID 91c0fe0269408ea867f474a57f9f06a825f8b9dd # Parent 3498b2d88376ed768035def8ba89a79e9f46376f Output incomplete references in object target diff -r 3498b2d88376 -r 91c0fe026940 lwasm/lwasm.c --- a/lwasm/lwasm.c Mon Apr 26 17:14:04 2010 -0600 +++ b/lwasm/lwasm.c Mon Apr 26 17:59:30 2010 -0600 @@ -629,13 +629,16 @@ if (l -> as -> output_format == OUTPUT_OBJ) { reloctab_t *re; + lw_expr_t te; // add "expression" record to section table - v = lw_expr_intval(l -> addr) + l -> outputl; re = lw_alloc(sizeof(reloctab_t)); re -> next = l -> csect -> reloctab; l -> csect -> reloctab = re; - re -> offset = v; + te = lw_expr_build(lw_expr_type_int, l -> outputl); + re -> offset = lw_expr_build(lw_expr_type_oper, lw_expr_oper_plus, l -> addr, te); + lw_expr_destroy(te); + lwasm_reduce_expr(l -> as, re -> offset); re -> size = size; re -> expr = lw_expr_copy(expr); diff -r 3498b2d88376 -r 91c0fe026940 lwasm/lwasm.h --- a/lwasm/lwasm.h Mon Apr 26 17:14:04 2010 -0600 +++ b/lwasm/lwasm.h Mon Apr 26 17:59:30 2010 -0600 @@ -87,9 +87,9 @@ typedef struct reloctab_s reloctab_t; struct reloctab_s { - int offset; // offset of relocation + lw_expr_t offset; // offset of relocation int size; // size of relocation - lw_expr_t *expr; // relocation expression + lw_expr_t expr; // relocation expression reloctab_t *next; }; diff -r 3498b2d88376 -r 91c0fe026940 lwasm/output.c --- a/lwasm/output.c Mon Apr 26 17:14:04 2010 -0600 +++ b/lwasm/output.c Mon Apr 26 17:59:30 2010 -0600 @@ -230,6 +230,134 @@ s -> oblen += 1; } + +int write_code_obj_expraux(lw_expr_t e, void *of) +{ + int tt; + int v; + unsigned char buf[16]; + + tt = lw_expr_type(e); + + switch (tt) + { + case lw_expr_type_oper: + buf[0] = 0x04; + switch (lw_expr_intval(e)) + { + case lw_expr_oper_plus: + buf[1] = 0x01; + break; + + case lw_expr_oper_minus: + buf[1] = 0x02; + break; + + case lw_expr_oper_times: + buf[1] = 0x03; + break; + + case lw_expr_oper_divide: + buf[1] = 0x04; + break; + + case lw_expr_oper_mod: + buf[1] = 0x05; + break; + + case lw_expr_oper_intdiv: + buf[1] = 0x06; + break; + + case lw_expr_oper_bwand: + buf[1] = 0x07; + break; + + case lw_expr_oper_bwor: + buf[1] = 0x08; + break; + + case lw_expr_oper_bwxor: + buf[1] = 0x09; + break; + + case lw_expr_oper_and: + buf[1] = 0x0A; + break; + + case lw_expr_oper_or: + buf[1] = 0x0B; + break; + + case lw_expr_oper_neg: + buf[1] = 0x0C; + break; + + case lw_expr_oper_com: + buf[1] = 0x0D; + break; + + default: + buf[1] = 0xff; + } + writebytes(buf, 2, 1, of); + break; + + case lw_expr_type_int: + v = lw_expr_intval(e); + buf[0] = 0x01; + buf[1] = (v >> 8) & 0xff; + buf[2] = v & 0xff; + writebytes(buf, 3, 1, of); + break; + + case lw_expr_type_special: + v = lw_expr_specint(e); + switch (v) + { + case lwasm_expr_secbase: + writebytes("\x05", 1, 1, of); + break; + + case lwasm_expr_import: + { + importlist_t *ie; + ie = lw_expr_specptr(e); + buf[0] = 0x02; + writebytes(buf, 1, 1, of); + writebytes(ie -> symbol, strlen(ie -> symbol) + 1, 1, of); + break; + } + case lwasm_expr_syment: + { + struct symtabe *se; + se = lw_expr_specptr(e); + buf[0] = 0x03; + writebytes(buf, 1, 1, of); + writebytes(se -> symbol, strlen(se -> symbol), 1, of); + if (se -> context != -1) + { + sprintf(buf, "\x01%d", se -> context); + writebytes(buf, strlen(buf), 1, of); + } + writebytes("", 1, 1, of); + break; + } + break; + } + + default: + // unrecognized term type - replace with integer 0 + buf[0] = 0x01; + buf[1] = 0x00; + buf[2] = 0x00; + writebytes(buf, 3, 1, of); + break; + } + return 0; +} + + void write_code_obj(asmstate_t *as, FILE *of) { line_t *l; @@ -359,8 +487,17 @@ writebytes("", 1, 1, of); // FIXME - relocation table -/* for (re = s -> rl; re; re = re -> next) + for (re = s -> reloctab; re; re = re -> next) { + int offset; + lw_expr_t te; + line_t tl; + + tl.as = as; + as -> cl = &tl; + as -> csect = s; + as -> exportcheck = 1; + if (re -> expr == NULL) { // this is an error but we'll simply ignore it @@ -370,80 +507,36 @@ // work through each term in the expression and output // the proper equivalent to the object file - if (re -> relocsize == 1) + if (re -> size == 1) { // flag an 8 bit relocation (low 8 bits will be used) buf[0] = 0xFF; buf[1] = 0x01; writebytes(buf, 2, 1, of); } - for (sn = re -> expr -> head; sn; sn = sn -> next) + + te = lw_expr_copy(ex -> se -> value); + lwasm_reduce_expr(as, te); + if (!lw_expr_istype(te, lw_expr_type_int)) { - switch (sn -> term -> term_type) - { - case LWASM_TERM_OPER: - buf[0] = 0x04; - buf[1] = sn -> term -> value; - writebytes(buf, 2, 1, of); - break; - - case LWASM_TERM_INT: - buf[0] = 0x01; - buf[1] = (sn -> term -> value >> 8) & 0xff; - buf[2] = sn -> term -> value & 0xff; - writebytes(buf, 3, 1, of); - break; - - case LWASM_TERM_SECBASE: - writebytes("\x05", 1, 1, of); - break; - - case LWASM_TERM_SYM: - // now for the ugly part - resolve a symbol reference - // and determine whether it's internal, external, or - // a section base - se = lwasm_find_symbol(as, sn -> term -> symbol, re -> context); - if (!se) - se = lwasm_find_symbol(as, sn -> term -> symbol, -1); - if (!se || se -> flags & SYMBOL_EXTERN) - { - // not found - assume external reference - // found but flagged external - handle it - writebytes("\x02", 1, 1, of); - writebytes(se -> sym, strlen(se -> sym) + 1, 1, of); - break; - } - // a local symbol reference here - writebytes("\x03", 1, 1, of); - writebytes(se -> sym, strlen(se -> sym), 1, of); - if (se -> context >= 0) - { - writebytes("\x01", 1, 1, of); - sprintf(buf, "%d", se -> context); - writebytes(buf, strlen(buf), 1, of); - } - writebytes("", 1, 1, of); - break; - - default: - // unrecognized term type - replace with integer 0 - buf[0] = 0x01; - buf[1] = 0x00; - buf[2] = 0x00; - writebytes(buf, 3, 1, of); - break; - } + lw_expr_destroy(te); + continue; } + offset = lw_expr_intval(te); + lw_expr_destroy(te); + + // output expression + lw_expr_testterms(re -> expr, write_code_obj_expraux, of); // flag end of expressions writebytes("", 1, 1, of); // write the offset - buf[0] = (re -> offset >> 8) & 0xff; - buf[1] = re -> offset & 0xff; + buf[0] = (offset >> 8) & 0xff; + buf[1] = offset & 0xff; writebytes(buf, 2, 1, of); } -*/ + // flag end of incomplete references list writebytes("", 1, 1, of); diff -r 3498b2d88376 -r 91c0fe026940 lwlib/lw_expr.c --- a/lwlib/lw_expr.c Mon Apr 26 17:14:04 2010 -0600 +++ b/lwlib/lw_expr.c Mon Apr 26 17:59:30 2010 -0600 @@ -1119,3 +1119,13 @@ } return (fn)(e, priv); } + +int lw_expr_type(lw_expr_t e) +{ + return e -> type; +} + +void *lw_expr_specptr(lw_expr_t e) +{ + return e -> value2; +} diff -r 3498b2d88376 -r 91c0fe026940 lwlib/lw_expr.h --- a/lwlib/lw_expr.h Mon Apr 26 17:14:04 2010 -0600 +++ b/lwlib/lw_expr.h Mon Apr 26 17:59:30 2010 -0600 @@ -98,6 +98,9 @@ extern int lw_expr_istype(lw_expr_t e, int t); extern int lw_expr_intval(lw_expr_t e); extern int lw_expr_specint(lw_expr_t e); +extern void *lw_expr_specptr(lw_expr_t e); + +extern int lw_expr_type(lw_expr_t e); typedef int lw_expr_testfn_t(lw_expr_t e, void *priv);