static float updateAddr(const ut8 *buf, int i, int endian, ut64 *addr, ut64 *addr64) { float f; // assert sizeof (float) == sizeof (ut32)) ut32 tmpaddr; r_mem_swaporcopy ((ut8*)&f, buf + i, sizeof (float), endian); if (addr) { tmpaddr = r_read_ble32 (buf + i, endian); *addr = (ut64)tmpaddr; } if (addr64) { *addr64 = r_read_ble64 (buf + i, endian); } return f; }
static ut64 get_buf_val(ut8 *buf, int endian, int width) { return (width == 8)? r_read_ble64 (buf, endian) : (ut64) r_read_ble32 (buf,endian); }
static int r_buf_fcpy_at (RBuffer *b, ut64 addr, ut8 *buf, const char *fmt, int n, int write) { ut64 len, check_len; int i, j, k, tsize, bigendian, m = 1; if (!b || b->empty) return 0; if (b->fd != -1) { eprintf ("r_buf_fcpy_at not supported yet for r_buf_new_file\n"); return 0; } if (addr == R_BUF_CUR) addr = b->cur; else addr -= b->base; if (addr == UT64_MAX || addr > b->length) return -1; tsize = 2; for (i = len = 0; i < n; i++) for (j = 0; fmt[j]; j++) { switch (fmt[j]) { #ifdef _MSC_VER case'0':case'1':case'2':case'3':case'4':case'5':case'6':case'7':case'8':case'9': #else case '0'...'9': #endif if (m == 1) m = r_num_get (NULL, &fmt[j]); continue; case 's': tsize = 2; bigendian = 0; break; case 'S': tsize = 2; bigendian = 1; break; case 'i': tsize = 4; bigendian = 0; break; case 'I': tsize = 4; bigendian = 1; break; case 'l': tsize = 8; bigendian = 0; break; case 'L': tsize = 8; bigendian = 1; break; case 'c': tsize = 1; bigendian = 0; break; default: return -1; } /* Avoid read/write out of bound. tsize and m are not user controled, then don't need to check possible overflow. */ if (!UT64_ADD (&check_len, len, tsize*m)) return -1; if (!UT64_ADD (&check_len, check_len, addr)) return -1; if (check_len > b->length) { return check_len; // return -1; } for (k = 0; k < m; k++) { ut8* src1 = &b->buf[len+(k*tsize)]; ut8* src2 = &b->buf[addr+len+(k*tsize)]; void* dest1 = &buf[addr+len+(k*tsize)]; void* dest2 = &buf[len+(k*tsize)]; ut8* dest1_8 = (ut8*)dest1; ut16* dest1_16 = (ut16*)dest1; ut32* dest1_32 = (ut32*)dest1; ut64* dest1_64 = (ut64*)dest1; ut8* dest2_8 = (ut8*)dest2; ut16* dest2_16 = (ut16*)dest2; ut32* dest2_32 = (ut32*)dest2; ut64* dest2_64 = (ut64*)dest2; if (write) { switch (tsize) { case 1: *dest1_8 = r_read_ble8 (src1); break; case 2: *dest1_16 = r_read_ble16 (src1, bigendian); break; case 4: *dest1_32 = r_read_ble32 (src1, bigendian); break; case 8: *dest1_64 = r_read_ble64 (src1, bigendian); break; } } else { switch (tsize) { case 1: *dest2_8 = r_read_ble8 (src2); break; case 2: *dest2_16 = r_read_ble16 (src2, bigendian); break; case 4: *dest2_32 = r_read_ble32 (src2, bigendian); break; case 8: *dest2_64 = r_read_ble64 (src2, bigendian); break; } } } len += tsize * m; m = 1; } b->cur = addr + len; return len; }
R_API ut64 r_reg_get_value(RReg *reg, RRegItem *item) { RRegSet *regset; int off; ut64 ret = 0LL; if (!reg || !item) { return 0LL; } off = BITS2BYTES (item->offset); regset = ®->regset[item->arena]; switch (item->size) { case 1: { int offset = item->offset / 8; if (offset + item->size >= regset->arena->size) { break; } ret = (regset->arena->bytes[offset] & (1 << (item->offset % 8))) ? 1 : 0; } break; case 4: if (regset->arena->size - off - 1 >= 0) { ret = (r_read_at_ble8 (regset->arena->bytes, off)) & 0xF; } break; case 8: if (regset->arena->size - off - 1 >= 0) { ret = r_read_at_ble8 (regset->arena->bytes, off); } break; case 16: if (regset->arena->size - off - 2 >= 0) { ret = r_read_ble16 (regset->arena->bytes + off, reg->big_endian); } break; case 27: if (off + 3 < regset->arena->size) { ret = r_read_me27 (regset->arena->bytes + off, 0); } break; case 32: if (off + 4 <= regset->arena->size) { ret = r_read_ble32 (regset->arena->bytes + off, reg->big_endian); } else { eprintf ("r_reg_get_value: 32bit oob read %d\n", off); } break; case 64: if (regset->arena->bytes && (off + 8 <= regset->arena->size)) { ret = r_read_ble64 (regset->arena->bytes + off, reg->big_endian); } else { eprintf ("r_reg_get_value: null or oob arena for current regset\n"); } break; case 80: // long double case 96: // long floating value // FIXME: It is a precision loss, please implement me properly! ret = (ut64)r_reg_get_longdouble (reg, item); break; default: eprintf ("r_reg_get_value: Bit size %d not supported\n", item->size); break; } return ret; }