Now that structs are not size 0, fix accessing their fields:
need to map field reads to byte offsets, not struct field index!
... | ... |
@@ -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 |
} |