Rizin
unix-like reverse engineering framework and cli tools
io_cache.c
Go to the documentation of this file.
1 // SPDX-FileCopyrightText: 2008-2020 pancake <pancake@nopcode.org>
2 // SPDX-License-Identifier: LGPL-3.0-only
3 
4 #include <rz_io.h>
5 #include <rz_skyline.h>
6 
7 static void cache_item_free(RzIOCache *cache) {
8  if (!cache) {
9  return;
10  }
11  free(cache->data);
12  free(cache->odata);
13  free(cache);
14 }
15 
17  rz_return_val_if_fail(io, false);
19 }
20 
25  io->cached = 0;
26 }
27 
30  rz_pvector_fini(&io->cache);
32  io->cached = 0;
33 }
34 
36  void **iter;
37  RzIOCache *c;
40  rz_pvector_foreach (&io->cache, iter) {
41  // if (from <= c->to - 1 && c->from <= to - 1) {
42  c = *iter;
43  if (rz_itv_overlap(c->itv, range)) {
44  int cached = io->cached;
45  io->cached = 0;
46  if (rz_io_write_at(io, rz_itv_begin(c->itv), c->data, rz_itv_size(c->itv))) {
47  c->written = true;
48  } else {
49  eprintf("Error writing change at 0x%08" PFMT64x "\n", rz_itv_begin(c->itv));
50  }
51  io->cached = cached;
52  // break; // XXX old behavior, revisit this
53  }
54  }
55 }
56 
57 RZ_API void rz_io_cache_reset(RzIO *io, int set) {
59  io->cached = set;
60  rz_pvector_clear(&io->cache);
62 }
63 
65  rz_return_val_if_fail(io, 0);
66  int invalidated = 0;
67  void **iter;
68  RzIOCache *c;
71  c = *iter;
72  if (rz_itv_overlap(c->itv, range)) {
73  int cached = io->cached;
74  io->cached = 0;
75  rz_io_write_at(io, rz_itv_begin(c->itv), c->odata, rz_itv_size(c->itv));
76  io->cached = cached;
77  c->written = false;
79  free(c->data);
80  free(c->odata);
81  free(c);
82  invalidated++;
83  }
84  }
86  rz_pvector_foreach (&io->cache, iter) {
87  c = *iter;
88  rz_skyline_add(&io->cache_skyline, c->itv, c);
89  }
90  return invalidated;
91 }
92 
93 RZ_API bool rz_io_cache_write(RzIO *io, ut64 addr, const ut8 *buf, int len) {
94  rz_return_val_if_fail(io && buf, false);
96  if (!ch) {
97  return false;
98  }
99  if (UT64_ADD_OVFCHK(addr, len)) {
100  const ut64 first_len = UT64_MAX - addr;
101  rz_io_cache_write(io, 0, buf + first_len, len - first_len);
102  len = first_len;
103  }
104  ch->itv = (RzInterval){ addr, len };
105  ch->odata = (ut8 *)calloc(1, len + 1);
106  if (!ch->odata) {
107  free(ch);
108  return false;
109  }
110  ch->data = (ut8 *)calloc(1, len + 1);
111  if (!ch->data) {
112  free(ch->odata);
113  free(ch);
114  return false;
115  }
116  ch->written = false;
117  {
118  const bool cm = io->cachemode;
119  io->cachemode = false;
120  rz_io_read_at(io, addr, ch->odata, len);
121  io->cachemode = cm;
122  }
123  memcpy(ch->data, buf, len);
124  rz_pvector_push(&io->cache, ch);
125  rz_skyline_add(&io->cache_skyline, ch->itv, ch);
126  RzEventIOWrite iow = { addr, buf, len };
128  return true;
129 }
130 
132  rz_return_val_if_fail(io && buf, false);
133  RzSkyline *skyline = &io->cache_skyline;
134  if (!len) {
135  return true;
136  }
137  if (UT64_ADD_OVFCHK(addr, len)) {
138  const ut64 first_len = UT64_MAX - addr;
139  rz_io_cache_read(io, 0, buf + first_len, len - first_len);
140  len = first_len;
141  }
143  if (!iter) {
144  return false;
145  }
146  const RzSkylineItem *last = (RzSkylineItem *)skyline->v.a + skyline->v.len;
147  bool covered = false;
148  while (iter != last) {
149  const ut64 begin = rz_itv_begin(iter->itv);
150  const st64 addr_offset = begin - addr;
151  const ut64 buf_offset = addr_offset > 0 ? addr_offset : 0;
152  const ut64 cur_addr = addr + buf_offset;
153  const ut64 left = len - buf_offset;
154  if (begin > cur_addr + left) {
155  break;
156  }
157  RzIOCache *cache = iter->user;
158  const ut64 cache_shift = addr_offset < 0 ? -addr_offset : 0;
159  const ut64 cache_offset = begin - rz_itv_begin(cache->itv) + cache_shift;
160  const ut64 read = RZ_MIN(left, rz_itv_size(iter->itv) - cache_shift);
161  memcpy(buf + buf_offset, cache->data + cache_offset, read);
162  covered = true;
163  if (left - read <= 0) {
164  break;
165  }
166  iter++;
167  }
168  return covered;
169 }
size_t len
Definition: 6502dis.c:15
#define RZ_API
RZ_API void Ht_() free(HtName_(Ht) *ht)
Definition: ht_inc.c:130
RZ_API void rz_io_cache_init(RzIO *io)
Definition: io_cache.c:21
RZ_API int rz_io_cache_invalidate(RzIO *io, ut64 from, ut64 to)
Definition: io_cache.c:64
RZ_API bool rz_io_cache_at(RzIO *io, ut64 addr)
Definition: io_cache.c:16
RZ_API void rz_io_cache_reset(RzIO *io, int set)
Definition: io_cache.c:57
RZ_API bool rz_io_cache_read(RzIO *io, ut64 addr, ut8 *buf, int len)
Definition: io_cache.c:131
RZ_API bool rz_io_cache_write(RzIO *io, ut64 addr, const ut8 *buf, int len)
Definition: io_cache.c:93
RZ_API void rz_io_cache_fini(RzIO *io)
Definition: io_cache.c:28
static void cache_item_free(RzIOCache *cache)
Definition: io_cache.c:7
RZ_API void rz_io_cache_commit(RzIO *io, ut64 from, ut64 to)
Definition: io_cache.c:35
voidpf void * buf
Definition: ioapi.h:138
uint8_t ut8
Definition: lh5801.h:11
memcpy(mem, inblock.get(), min(CONTAINING_RECORD(inblock.get(), MEMBLOCK, data) ->size, size))
void * calloc(size_t number, size_t size)
Definition: malloc.c:102
while(len< limit &&buf1[len]==buf2[len])++len
#define eprintf(x, y...)
Definition: rlcc.c:7
#define rz_return_if_fail(expr)
Definition: rz_assert.h:100
#define rz_return_val_if_fail(expr, val)
Definition: rz_assert.h:108
RZ_API void rz_event_send(RzEvent *ev, int type, void *data)
Definition: event.c:115
@ RZ_EVENT_IO_WRITE
Definition: rz_event.h:42
RZ_API bool rz_io_read_at(RzIO *io, ut64 addr, ut8 *buf, int len)
Definition: io.c:300
RZ_API bool rz_io_write_at(RzIO *io, ut64 addr, const ut8 *buf, int len)
Definition: io.c:358
static ut64 rz_itv_begin(RzInterval itv)
Definition: rz_itv.h:34
struct rz_interval_t RzInterval
static bool rz_itv_overlap(RzInterval itv, RzInterval x)
Definition: rz_itv.h:64
static ut64 rz_itv_size(RzInterval itv)
Definition: rz_itv.h:38
static bool rz_skyline_contains(RzSkyline *skyline, ut64 addr)
Definition: rz_skyline.h:51
RZ_API const RzSkylineItem * rz_skyline_get_item_intersect(RzSkyline *skyline, ut64 addr, ut64 len)
Definition: skyline.c:60
static void rz_skyline_init(RzSkyline *skyline)
Definition: rz_skyline.h:19
static void rz_skyline_fini(RzSkyline *skyline)
Definition: rz_skyline.h:24
static void rz_skyline_clear(RzSkyline *skyline)
Definition: rz_skyline.h:29
RZ_API bool rz_skyline_add(RzSkyline *skyline, RzInterval itv, void *user)
Definition: skyline.c:12
#define RZ_NEW0(x)
Definition: rz_types.h:284
#define PFMT64x
Definition: rz_types.h:393
#define RZ_MIN(x, y)
#define st64
Definition: rz_types_base.h:10
#define UT64_MAX
Definition: rz_types_base.h:86
#define UT64_ADD_OVFCHK(x, y)
RZ_API void rz_pvector_remove_data(RzPVector *vec, void *x)
Definition: vector.c:362
RZ_API void rz_pvector_init(RzPVector *vec, RzPVectorFree free)
Definition: vector.c:298
RZ_API void rz_pvector_fini(RzPVector *vec)
Definition: vector.c:331
void(* RzPVectorFree)(void *e)
Definition: rz_vector.h:43
#define rz_pvector_foreach_prev(vec, it)
Definition: rz_vector.h:338
static void ** rz_pvector_push(RzPVector *vec, void *x)
Definition: rz_vector.h:300
RZ_API void rz_pvector_clear(RzPVector *vec)
Definition: vector.c:326
#define rz_pvector_foreach(vec, it)
Definition: rz_vector.h:334
static struct sockaddr static addrlen static backlog const void static flags void struct sockaddr from
Definition: sfsocketcall.h:123
static struct sockaddr static addrlen static backlog const void static flags void struct sockaddr socklen_t static fromlen const void const struct sockaddr to
Definition: sfsocketcall.h:125
#define c(i)
Definition: sha256.c:43
RzInterval itv
Definition: rz_io.h:163
int written
Definition: rz_io.h:166
ut8 * odata
Definition: rz_io.h:165
ut8 * data
Definition: rz_io.h:164
Definition: rz_io.h:59
bool cachemode
Definition: rz_io.h:70
RzEvent * event
Definition: rz_io.h:90
int cached
Definition: rz_io.h:69
RzSkyline cache_skyline
Definition: rz_io.h:77
RzPVector cache
Definition: rz_io.h:76
RzVector v
Definition: rz_skyline.h:13
void * a
Definition: rz_vector.h:46
size_t len
Definition: rz_vector.h:47
ut64(WINAPI *w32_GetEnabledXStateFeatures)()
static int addr
Definition: z80asm.c:58
int read(izstream &zs, T *x, Items items)
Definition: zstream.h:115