R_API ut64 r_io_seek(RIO *io, ut64 offset, int whence) { int posix_whence = SEEK_SET; ut64 ret = UT64_MAX; if (io->buffer_enabled) { io->off = offset; return offset; } switch (whence) { case R_IO_SEEK_SET: posix_whence = SEEK_SET; ret = offset; break; case R_IO_SEEK_CUR: // offset += io->off; posix_whence = SEEK_CUR; ret = offset+io->off; break; case R_IO_SEEK_END: //offset = UT64_MAX; // XXX: depending on io bits? ret = UT64_MAX; posix_whence = SEEK_END; break; } if (io == NULL) return ret; // XXX: list_empty trick must be done in r_io_set_va(); //eprintf ("-(seek)-> 0x%08llx\n", offset); if (!io->debug && io->va && !r_list_empty (io->sections)) { ut64 o = r_io_section_vaddr_to_offset (io, offset); if (o != UT64_MAX) offset = o; // eprintf ("-(vadd)-> 0x%08llx\n", offset); } // if resolution fails... just return as invalid address if (offset==UT64_MAX) return UT64_MAX; if (io->fd != NULL) { if (io->plugin && io->plugin->lseek) ret = io->plugin->lseek (io, io->fd, offset, whence); // XXX can be problematic on w32..so no 64 bit offset? else ret = (ut64)lseek (io->fd->fd, offset, posix_whence); if (ret != UT64_MAX) { io->off = ret; // XXX this can be tricky.. better not to use this .. must be deprecated // r_io_sundo_push (io); ret = (!io->debug && io->va && !r_list_empty (io->sections))? r_io_section_offset_to_vaddr (io, io->off) : io->off; } //else eprintf ("r_io_seek: cannot seek to %"PFMT64x"\n", offset); } //else { eprintf ("r_io_seek: null fd\n"); } return ret; }
R_API int r_io_read_at(RIO *io, ut64 addr, ut8 *buf, int len) { ut64 paddr, last, last2; int ms, ret, l, olen = len, w = 0; io->off = addr; memset (buf, 0xff, len); // probably unnecessary if (io->buffer_enabled) return r_io_buffer_read (io, addr, buf, len); while (len>0) { last = r_io_section_next (io, addr+w); last2 = r_io_map_next (io, addr+w); // XXX: must use physical address if (last == (addr+w)) last = last2; //else if (last2<last) last = last2; l = (len > (last-addr+w))? (last-addr+w): len; if (l<1) l = len; { paddr = w? r_io_section_vaddr_to_offset (io, addr+w): addr; if (len>0 && l>len) l = len; addr = paddr-w; if (r_io_seek (io, paddr, R_IO_SEEK_SET)==UT64_MAX) { memset (buf+w, 0xff, l); } } #if 0 if (io->zeromap) if (!r_io_map_get (io, addr+w)) { if (addr==0||r_io_section_getv (io, addr+w)) { memset (buf+w, 0xff, l); eprintf ("RETRERET\n"); return -1; } } #endif // XXX is this necessary? ms = r_io_map_select (io, addr+w); ret = r_io_read_internal (io, buf+w, l); //eprintf ("READ %d = %02x %02x %02x\n", ret, buf[w], buf[w+1], buf[w+2]); if (ret<1) { memset (buf+w, 0xff, l); // reading out of file ret = 1; } else if (ret<l) { l = ret; } #if USE_CACHE if (io->cached) { r_io_cache_read (io, addr+w, buf+w, len-w); } else if (r_list_length (io->maps) >1) { if (!io->debug && ms>0) { //eprintf ("FAIL MS=%d l=%d d=%d\n", ms, l, d); /* check if address is vaddred in sections */ ut64 o = r_io_section_offset_to_vaddr (io, addr+w); if (o == UT64_MAX) { ut64 o = r_io_section_vaddr_to_offset (io, addr+w); if (o == UT64_MAX) memset (buf+w, 0xff, l); } break; } } #endif w += l; len -= l; } return olen; }
R_API int r_io_read_at(RIO *io, ut64 addr, ut8 *buf, int len) { int ret, l, olen = len; int w = 0; #if 0 // HACK?: if io->va == 0 -> call seek+read without checking sections ? if (!io->va) { // r_io_seek (io, addr, R_IO_SEEK_SET); r_io_map_select (io, addr); ret = r_io_read_internal (io, buf, len); if (io->cached) { r_io_cache_read (io, addr, buf, len); } return ret; } #endif // XXX: this is buggy! while (len>0) { int ms; ut64 last = r_io_section_next (io, addr); l = (len > (last-addr))? (last-addr): len; if (l<1) l = len; // ignore seek errors // eprintf ("0x%llx %llx\n", addr+w, //r_io_seek (io, addr+w, R_IO_SEEK_SET); if (r_io_seek (io, addr+w, R_IO_SEEK_SET)==UT64_MAX) { memset (buf+w, 0xff, l); return -1; } ms = r_io_map_select (io, addr+w); ret = r_io_read_internal (io, buf+w, l); if (ret<1) { memset (buf+w, 0xff, l); // reading out of file ret = 1; } else if (ret<l) { // eprintf ("FOUND EOF AT %llx\n", addr+ret); l = ret; } if (io->cached) { r_io_cache_read (io, addr+w, buf+w, l); /* * XXX: The 'else' below is fixing the io.cache * with resized files. That may be wrong */ } else // hide non-mapped files here // do not allow reading on real addresses if mapped != 0 if (!io->debug && ms>0) { //eprintf ("FAIL MS=%d l=%d d=%d\n", ms, l, d); /* check if address is vaddred in sections */ ut64 o = r_io_section_offset_to_vaddr (io, addr); if (o == UT64_MAX) { ut64 o = r_io_section_vaddr_to_offset (io, addr); if (o == UT64_MAX) memset (buf+w, 0xff, l); } break; } w += l; len -= l; } return olen; }