R_API int r_reg_set_pack(RReg *reg, RRegItem *item, int packidx, int packbits, ut64 val) { int off, packbytes, packmod; if (!reg || !item) { eprintf ("r_reg_set_value: item is NULL\n"); return false; } if (packbits < 1) { packbits = item->packed_size; } off = item->offset; packbytes = packbits / 8; packmod = packbits % 8; if (packidx * packbits > item->size) { eprintf ("Packed index is beyond the register size\n"); return false; } if (packmod) { eprintf ("Invalid bit size for packet register\n"); return false; } if (reg->regset[item->arena].arena->size - BITS2BYTES (off) - BITS2BYTES (packbytes) >= 0) { ut8 *dst = reg->regset[item->arena].arena->bytes + BITS2BYTES (off); r_mem_copybits (dst, (ut8 *)&val, packbytes); return true; } eprintf ("r_reg_set_value: Cannot set %s to 0x%" PFMT64x "\n", item->name, val); return false; }
R_API int r_reg_set_double(RReg *reg, RRegItem *item, long double value) { long double vld = 0.0f; ut8 *src; if (!item) { eprintf ("r_reg_set_value: item is NULL\n"); return R_FALSE; } switch (item->size) { case 80: r_mem_copyendian ( (ut8*)&vld, (ut8*)&value, 10, !reg->big_endian); src = (ut8*)&vld; break; default: eprintf ("r_reg_set_double : Bit size %d not supported\n", item->size); return R_FALSE; } if (reg->regset[item->type].arena->size - BITS2BYTES (item->offset) - BITS2BYTES(item->size)>=0) { r_mem_copybits (reg->regset[item->type].arena->bytes+ BITS2BYTES (item->offset), src, item->size); return R_TRUE; } eprintf ("r_reg_set_value: Cannot set %s to %Lf\n", item->name, value); return R_FALSE; }
// TODO: cleanup this ugly code R_API int r_reg_set_value(RReg *reg, RRegItem *item, ut64 value) { ut64 v64; ut32 v32; ut16 v16; ut8 v8, *src; if (!item) return R_FALSE; switch (item->size) { case 64: v64 = (ut64)value; src = (ut8*)&v64; break; case 32: v32 = (ut32)value; src = (ut8*)&v32; break; case 16: v16 = (ut16)value; src = (ut8*)&v16; break; case 8: v8 = (ut8)value; src = (ut8*)&v8; break; case 1: if (value) { ut8 * buf = reg->regset[item->type].arena->bytes + (item->offset/8); int bit = (item->offset%8); ut8 mask = (1<<bit); buf[0] = (buf[0] &(0xff^mask)) | mask; } else { ut8 * buf = reg->regset[item->type].arena->bytes + (item->offset/8); int bit = (item->offset%8); ut8 mask = 0xff^(1<<bit); buf[0] = (buf[0] & mask) | 0; } return R_TRUE; default: eprintf ("r_reg_set_value: Bit size %d not supported\n", item->size); return R_FALSE; } r_mem_copybits (reg->regset[item->type].arena->bytes+ BITS2BYTES (item->offset), src, item->size); return R_TRUE; }
R_API bool r_reg_set_longdouble(RReg *reg, RRegItem *item, long double value) { ut8 *src; if (!item) { eprintf ("r_reg_set_value: item is NULL\n"); return false; } switch (item->size) { case 80: case 96: case 128: // FIXME: endian src = (ut8 *)&value; break; default: eprintf ("r_reg_set_longdouble: Bit size %d not supported\n", item->size); return false; } if (reg->regset[item->arena].arena->size - BITS2BYTES (item->offset) - BITS2BYTES (item->size) >= 0) { r_mem_copybits (reg->regset[item->arena].arena->bytes + BITS2BYTES (item->offset), src, item->size); return true; } eprintf ("r_reg_set_value: Cannot set %s to %Lf\n", item->name, value); return false; }
// TODO: this method is ugly as shit. R_API void r_mem_copybits_delta(ut8 *dst, int doff, const ut8 *src, int soff, int bits) { int nbits = bits; #if 0 int dofb, sofb; int bdoff = (doff / 8); int bsoff = (soff / 8); int nbits = 0; ut8 mask; int sdelta = soff - doff; /* apply delta offsets */ src = src + bsoff; dst = dst + bdoff; dofb = doff % 8; sofb = soff % 8; if (sofb || dofb) { // TODO : this algorithm is not implemented int mask = (1 << sofb); int nmask = 0xff ^ mask; int s = src[0] << sofb; int d = dst[0] << dofb; if (soff == doff && bits == 1) { mask = 0xff ^ (1 << dofb); dst[0] = ((src[0] & mask) | (dst[0] & mask)); } else { printf ("TODO: Oops. not supported method of bitcopy\n"); } /* 1) shift algin src i dst 2) copy (8-dofb) bits from dst to src 3) dst[0] = dst[0]&^(0x1<<nbits) | (src&(1<<nbits)) */ src++; dst++; } /* doff v dst |__________|___________| soff v src |__________|_________| */ #endif r_mem_copybits (dst, src, nbits); }
// TODO: cleanup this ugly code R_API int r_reg_set_value(RReg *reg, RRegItem *item, ut64 value) { ut64 v64; ut32 v32; ut16 v16; ut8 v8, *src; if (!item) { eprintf ("r_reg_set_value: item is NULL\n"); return R_FALSE; } switch (item->size) { case 64: r_mem_copyendian ( (ut8*)&v64, (ut8*)&value, 8, !reg->big_endian); src = (ut8*)&v64; break; case 32: r_mem_copyendian ( (ut8*)&v32, (ut8*)&value, 4, !reg->big_endian); src = (ut8*)&v32; break; case 16: r_mem_copyendian ( (ut8*)&v16, (ut8*)&value, 2, !reg->big_endian); src = (ut8*)&v16; break; case 8: v8 = (ut8)value; src = (ut8*)&v8; break; case 1: if (value) { ut8 * buf = reg->regset[item->type].arena->bytes + (item->offset/8); int bit = (item->offset%8); ut8 mask = (1<<bit); buf[0] = (buf[0] &(0xff^mask)) | mask; } else { ut8 * buf = reg->regset[item->type].arena->bytes + (item->offset/8); int bit = (item->offset%8); ut8 mask = 0xff^(1<<bit); buf[0] = (buf[0] & mask) | 0; } return R_TRUE; default: eprintf ("r_reg_set_value: Bit size %d not supported\n", item->size); return R_FALSE; } if (reg->regset[item->type].arena->size - BITS2BYTES (item->offset) - BITS2BYTES(item->size)>=0) { r_mem_copybits (reg->regset[item->type].arena->bytes+ BITS2BYTES (item->offset), src, item->size); return R_TRUE; } eprintf ("r_reg_set_value: Cannot set %s to 0x%"PFMT64x"\n", item->name, value); return R_FALSE; }
R_API bool r_reg_set_value(RReg *reg, RRegItem *item, ut64 value) { int fits_in_arena; ut8 bytes[12]; ut8 *src = bytes; if (!item) { eprintf ("r_reg_set_value: item is NULL\n"); return false; } switch (item->size) { case 80: case 96: // long floating value r_reg_set_longdouble (reg, item, (long double)value); break; case 64: if (reg->big_endian) { r_write_be64 (src, value); } else { r_write_le64 (src, value); } break; case 32: if (reg->big_endian) { r_write_be32 (src, value); } else { r_write_le32 (src, value); } break; case 16: if (reg->big_endian) { r_write_be16 (src, value); } else { r_write_le16 (src, value); } break; case 8: r_write_ble8 (src, (ut8)(value & UT8_MAX)); break; case 1: if (value) { ut8 *buf = reg->regset[item->arena].arena->bytes + (item->offset / 8); int bit = (item->offset % 8); ut8 mask = (1 << bit); buf[0] = (buf[0] & (0xff ^ mask)) | mask; } else { int idx = item->offset / 8; RRegArena *arena = reg->regset[item->arena].arena; if (idx + item->size > arena->size) { eprintf ("RRegSetOverflow %d vs %d\n", idx + item->size, arena->size); return false; } ut8 *buf = arena->bytes + idx; int bit = item->offset % 8; ut8 mask = 0xff ^ (1 << bit); buf[0] = (buf[0] & mask) | 0; } return true; default: eprintf ("r_reg_set_value: Bit size %d not supported\n", item->size); return false; } fits_in_arena = (reg->regset[item->arena].arena->size - BITS2BYTES (item->offset) - BITS2BYTES (item->size)) >= 0; if (src && fits_in_arena) { r_mem_copybits (reg->regset[item->arena].arena->bytes + BITS2BYTES (item->offset), src, item->size); return true; } eprintf ("r_reg_set_value: Cannot set %s to 0x%" PFMT64x "\n", item->name, value); return false; }