Browse code

Fix another interpreter bug accessing structs.

Now that structs are not size 0, fix accessing their fields:
need to map field reads to byte offsets, not struct field index!

Török Edvin authored on 2010/07/29 19:45:14
Showing 1 changed files
... ...
@@ -1699,9 +1699,42 @@ static inline int get_geptypesize(const struct cli_bc *bc, uint16_t tid)
1699 1699
   return typesize(bc, ty->containedTypes[0]);
1700 1700
 }
1701 1701
 
1702
+static int calc_gepz(struct cli_bc *bc, struct cli_bc_func *func, uint16_t tid, operand_t op)
1703
+{
1704
+    unsigned off = 0, i;
1705
+    uint64_t *gepoff;
1706
+    const struct cli_bc_type *ty;
1707
+    if (tid >= bc->num_types + 65) {
1708
+	cli_errmsg("bytecode: typeid out of range %u >= %u\n", tid, bc->num_types);
1709
+	return -1;
1710
+    }
1711
+    if (tid <= 65) {
1712
+	cli_errmsg("bytecode: invalid type for gep (%u)\n", tid);
1713
+	return -1;
1714
+    }
1715
+    ty = &bc->types[tid - 65];
1716
+    if (ty->kind != DPointerType || ty->containedTypes[0] < 65) {
1717
+	cli_errmsg("bytecode: invalid gep type, must be pointer to nonint: %u\n", tid);
1718
+	return -1;
1719
+    }
1720
+    ty = &bc->types[ty->containedTypes[0] - 65];
1721
+    if (ty->kind != DStructType && ty->kind != DPackedStructType)
1722
+	return 0;
1723
+    gepoff = &func->constants[op - func->numValues];
1724
+    if (*gepoff >= ty->numElements) {
1725
+	cli_errmsg("bytecode: gep offset out of range: %d >= %d\n",*gepoff, ty->numElements);
1726
+	return -1;
1727
+    }
1728
+    for (i=0;i<*gepoff;i++) {
1729
+	off += typesize(bc, ty->containedTypes[i]);
1730
+    }
1731
+    *gepoff = off;
1732
+    return 1;
1733
+}
1734
+
1702 1735
 static int cli_bytecode_prepare_interpreter(struct cli_bc *bc)
1703 1736
 {
1704
-    unsigned i, j, k;
1737
+    unsigned i, j, k, rc;
1705 1738
     uint64_t *gmap;
1706 1739
     unsigned bcglobalid = cli_apicall_maxglobal - _FIRST_GLOBAL+2;
1707 1740
     bc->numGlobalBytes = 0;
... ...
@@ -1795,6 +1828,7 @@ static int cli_bytecode_prepare_interpreter(struct cli_bc *bc)
1795 1795
 	    map[j] = bcfunc->numBytes;
1796 1796
 	    /* printf("%d -> %d, %u\n", j, map[j], typesize(bc, ty)); */
1797 1797
 	    bcfunc->numBytes += typesize(bc, ty);
1798
+	    /* TODO: don't allow size 0, it is always a bug! */
1798 1799
 	}
1799 1800
 	bcfunc->numBytes = (bcfunc->numBytes + 7)&~7;
1800 1801
 	for (j=0;j<bcfunc->numConstants;j++) {
... ...
@@ -1912,11 +1946,13 @@ static int cli_bytecode_prepare_interpreter(struct cli_bc *bc)
1912 1912
 		    else
1913 1913
 			inst->interp_op = 5*(inst->interp_op/5)+3;
1914 1914
 		    MAP(inst->u.three[1]);
1915
+		    if (calc_gepz(bc, bcfunc, inst->u.three[0], inst->u.three[2]) == -1)
1916
+			return CL_EBYTECODE;
1915 1917
 		    MAP(inst->u.three[2]);
1916 1918
 		    break;
1917
-		case OP_BC_GEPN:
1918
-		    /*TODO */
1919
-		    break;
1919
+/*		case OP_BC_GEPN:
1920
+		    *TODO 
1921
+		    break;*/
1920 1922
 		case OP_BC_MEMSET:
1921 1923
 		case OP_BC_MEMCPY:
1922 1924
 		case OP_BC_MEMMOVE:
... ...
@@ -1943,7 +1979,7 @@ static int cli_bytecode_prepare_interpreter(struct cli_bc *bc)
1943 1943
 		    MAPPTR(inst->u.unaryop);
1944 1944
 		    break;
1945 1945
 		default:
1946
-		    cli_dbgmsg("Unhandled opcode: %d\n", inst->opcode);
1946
+		    cli_warnmsg("Bytecode: unhandled opcode: %d\n", inst->opcode);
1947 1947
 		    return CL_EBYTECODE;
1948 1948
 	    }
1949 1949
 	}