# HG changeset patch # User lost@starbug # Date 1272333370 21600 # Node ID 1624a36f12a346e011aaf9f9d14f40a66f4fd6d8 # Parent cc154dc614fe698084f3b232639c9c9aef5655a8 Properly support 32 bit relocations diff -r cc154dc614fe -r 1624a36f12a3 lwasm/lwasm.c --- a/lwasm/lwasm.c Mon Apr 26 19:44:44 2010 -0600 +++ b/lwasm/lwasm.c Mon Apr 26 19:56:10 2010 -0600 @@ -631,17 +631,52 @@ reloctab_t *re; lw_expr_t te; - // add "expression" record to section table - re = lw_alloc(sizeof(reloctab_t)); - re -> next = l -> csect -> reloctab; - l -> csect -> reloctab = re; - 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); - + if (size == 4) + { + // create a two part reference because lwlink doesn't + // support 32 bit references + lw_expr_t te2; + te = lw_expr_build(lw_expr_type_int, 0x10000); + te2 = lw_expr_build(lw_expr_type_oper, lw_expr_oper_divide, expr, te); + lw_expr_destroy(te); + + re = lw_alloc(sizeof(reloctab_t)); + re -> next = l -> csect -> reloctab; + l -> csect -> reloctab = re; + 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 -> expr = te2; + re -> size = 2; + + te = lw_expr_build(lw_expr_type_int, 0xFFFF); + te2 = lw_expr_build(lw_expr_type_oper, lw_expr_oper_bwand, expr, te); + lw_expr_destroy(te); + + re = lw_alloc(sizeof(reloctab_t)); + re -> next = l -> csect -> reloctab; + l -> csect -> reloctab = re; + te = lw_expr_build(lw_expr_type_int, l -> outputl + 2); + 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 -> expr = te2; + re -> size = 2; + } + else + { + // add "expression" record to section table + re = lw_alloc(sizeof(reloctab_t)); + re -> next = l -> csect -> reloctab; + l -> csect -> reloctab = re; + 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); + } for (v = 0; v < size; v++) lwasm_emit(l, 0); return 0;