Rizin
unix-like reverse engineering framework and cli tools
p_cache.c File Reference
#include <rz_io.h>
#include <rz_types.h>
#include <string.h>

Go to the source code of this file.

Functions

static void pcache_kv_free (HtUPKv *kv)
 
RZ_API bool rz_io_desc_cache_init (RzIODesc *desc)
 
RZ_API int rz_io_desc_cache_write (RzIODesc *desc, ut64 paddr, const ut8 *buf, int len)
 
RZ_API int rz_io_desc_cache_read (RzIODesc *desc, ut64 paddr, ut8 *buf, int len)
 
static void __riocache_free (void *user)
 
static bool __desc_cache_list_cb (void *user, const ut64 k, const void *v)
 
RZ_API RzListrz_io_desc_cache_list (RzIODesc *desc)
 
static bool __desc_cache_commit_cb (void *user, const ut64 k, const void *v)
 
RZ_API bool rz_io_desc_cache_commit (RzIODesc *desc)
 
static bool __desc_cache_cleanup_cb (void *user, const ut64 k, const void *v)
 
RZ_API void rz_io_desc_cache_cleanup (RzIODesc *desc)
 
static bool __desc_fini_cb (void *user, void *data, ut32 id)
 
RZ_API void rz_io_desc_cache_fini (RzIODesc *desc)
 
RZ_API void rz_io_desc_cache_fini_all (RzIO *io)
 

Variables

const ut64 cleanup_masks []
 

Function Documentation

◆ __desc_cache_cleanup_cb()

static bool __desc_cache_cleanup_cb ( void *  user,
const ut64  k,
const void *  v 
)
static

Definition at line 321 of file p_cache.c.

321  {
322  RzIODesc *desc = (RzIODesc *)user;
323  ut64 size, blockaddr;
324  int byteaddr;
325  if (!desc || !desc->cache) {
326  return false;
327  }
328  RzIODescCache *cache = (RzIODescCache *)v;
329  blockaddr = RZ_IO_DESC_CACHE_SIZE * k;
331  if (size <= blockaddr) {
332  ht_up_delete(desc->cache, k);
333  return true;
334  }
335  if (size <= (blockaddr + RZ_IO_DESC_CACHE_SIZE - 1)) {
336  // this looks scary, but it isn't
337  byteaddr = (int)(size - blockaddr) - 1;
338  cache->cached &= cleanup_masks[byteaddr];
339  }
340  return true;
341 }
const char * desc
Definition: bin_vsf.c:19
const char * k
Definition: dsignal.c:11
const char * v
Definition: dsignal.c:12
voidpf void uLong size
Definition: ioapi.h:138
const ut64 cleanup_masks[]
Definition: p_cache.c:9
RZ_API ut64 rz_io_desc_size(RzIODesc *desc)
Definition: io_desc.c:224
#define RZ_IO_DESC_CACHE_SIZE
Definition: rz_io.h:169
static int
Definition: sfsocketcall.h:114
ut64(WINAPI *w32_GetEnabledXStateFeatures)()

References rz_io_desc_cache_t::cached, cleanup_masks, desc, int, k, RZ_IO_DESC_CACHE_SIZE, rz_io_desc_size(), ut64(), and v.

Referenced by rz_io_desc_cache_cleanup().

◆ __desc_cache_commit_cb()

static bool __desc_cache_commit_cb ( void *  user,
const ut64  k,
const void *  v 
)
static

Definition at line 278 of file p_cache.c.

278  {
279  RzIODesc *desc = (RzIODesc *)user;
280  int byteaddr, i;
281  ut8 buf[RZ_IO_DESC_CACHE_SIZE] = { 0 };
282  if (!desc || !desc->io) {
283  return false;
284  }
285  const RzIODescCache *dcache = v;
286  ut64 blockaddr = RZ_IO_DESC_CACHE_SIZE * k;
287  for (i = byteaddr = 0; byteaddr < RZ_IO_DESC_CACHE_SIZE; byteaddr++) {
288  if (dcache->cached & (0x1LL << byteaddr)) {
289  buf[i] = dcache->cdata[byteaddr];
290  i++;
291  } else if (i > 0) {
292  rz_io_pwrite_at(desc->io, blockaddr + byteaddr - i, buf, i);
293  i = 0;
294  }
295  }
296  if (i > 0) {
297  rz_io_pwrite_at(desc->io, blockaddr + RZ_IO_DESC_CACHE_SIZE - i, buf, i);
298  }
299  return true;
300 }
lzma_index ** i
Definition: index.h:629
voidpf void * buf
Definition: ioapi.h:138
uint8_t ut8
Definition: lh5801.h:11
RZ_API int rz_io_pwrite_at(RzIO *io, ut64 paddr, const ut8 *buf, int len)
Definition: io.c:277
ut8 cdata[RZ_IO_DESC_CACHE_SIZE]
Definition: rz_io.h:172

References rz_io_desc_cache_t::cached, rz_io_desc_cache_t::cdata, desc, i, k, RZ_IO_DESC_CACHE_SIZE, rz_io_pwrite_at(), ut64(), and v.

Referenced by rz_io_desc_cache_commit().

◆ __desc_cache_list_cb()

static bool __desc_cache_list_cb ( void *  user,
const ut64  k,
const void *  v 
)
static

Definition at line 199 of file p_cache.c.

199  {
200  RzList *writes = (RzList *)user;
201  RzIOCache *cache = NULL;
202  ut64 blockaddr;
203  int byteaddr, i;
204  if (!writes) {
205  return false;
206  }
207  const RzIODescCache *dcache = v;
208  blockaddr = k * RZ_IO_DESC_CACHE_SIZE;
209  for (i = byteaddr = 0; byteaddr < RZ_IO_DESC_CACHE_SIZE; byteaddr++) {
210  if (dcache->cached & (0x1LL << byteaddr)) {
211  if (!cache) {
212  cache = RZ_NEW0(RzIOCache);
213  if (!cache) {
214  return false;
215  }
216  cache->data = malloc(RZ_IO_DESC_CACHE_SIZE - byteaddr);
217  if (!cache->data) {
218  free(cache);
219  return false;
220  }
221  cache->itv.addr = blockaddr + byteaddr;
222  }
223  cache->data[i] = dcache->cdata[byteaddr];
224  i++;
225  } else if (cache) {
226  ut8 *data = realloc(cache->data, i);
227  if (!data) {
228  __riocache_free((void *)cache);
229  return false;
230  }
231  cache->data = data;
232  cache->itv.size = i;
233  i = 0;
234  rz_list_push(writes, cache);
235  cache = NULL;
236  }
237  }
238  if (cache) {
239 #if 0
240  cache->size = i;
241  cache->to = blockaddr + RZ_IO_DESC_CACHE_SIZE;
242 #endif
243  cache->itv.size = i;
244  rz_list_push(writes, cache);
245  }
246  return true;
247 }
#define NULL
Definition: cris-opc.c:27
RZ_API void Ht_() free(HtName_(Ht) *ht)
Definition: ht_inc.c:130
RZ_API RZ_BORROW RzListIter * rz_list_push(RZ_NONNULL RzList *list, void *item)
Alias for rz_list_append.
Definition: list.c:60
void * realloc(void *ptr, size_t size)
Definition: malloc.c:144
void * malloc(size_t size)
Definition: malloc.c:123
static void __riocache_free(void *user)
Definition: p_cache.c:190
#define RZ_NEW0(x)
Definition: rz_types.h:284
ut64 addr
Definition: rz_itv.h:15
ut64 size
Definition: rz_itv.h:16
RzInterval itv
Definition: rz_io.h:163
ut8 * data
Definition: rz_io.h:164

References __riocache_free(), rz_interval_t::addr, rz_io_desc_cache_t::cached, rz_io_desc_cache_t::cdata, rz_io_cache_t::data, free(), i, rz_io_cache_t::itv, k, malloc(), NULL, realloc(), RZ_IO_DESC_CACHE_SIZE, rz_list_push(), RZ_NEW0, rz_interval_t::size, ut64(), and v.

Referenced by rz_io_desc_cache_list().

◆ __desc_fini_cb()

static bool __desc_fini_cb ( void *  user,
void *  data,
ut32  id 
)
static

Definition at line 349 of file p_cache.c.

349  {
350  RzIODesc *desc = (RzIODesc *)data;
351  if (desc->cache) {
352  ht_up_free(desc->cache);
353  desc->cache = NULL;
354  }
355  return true;
356 }

References desc, and NULL.

Referenced by rz_io_desc_cache_fini(), and rz_io_desc_cache_fini_all().

◆ __riocache_free()

static void __riocache_free ( void *  user)
static

Definition at line 190 of file p_cache.c.

190  {
191  RzIOCache *cache = (RzIOCache *)user;
192  if (cache) {
193  free(cache->data);
194  free(cache->odata);
195  }
196  free(cache);
197 }
ut8 * odata
Definition: rz_io.h:165

References rz_io_cache_t::data, free(), and rz_io_cache_t::odata.

Referenced by __desc_cache_list_cb(), and rz_io_desc_cache_list().

◆ pcache_kv_free()

static void pcache_kv_free ( HtUPKv *  kv)
static

Definition at line 75 of file p_cache.c.

75  {
76  free(kv->value);
77 }

References free().

Referenced by rz_io_desc_cache_init().

◆ rz_io_desc_cache_cleanup()

RZ_API void rz_io_desc_cache_cleanup ( RzIODesc desc)

Definition at line 343 of file p_cache.c.

343  {
344  if (desc && desc->cache) {
345  ht_up_foreach(desc->cache, __desc_cache_cleanup_cb, desc);
346  }
347 }
static bool __desc_cache_cleanup_cb(void *user, const ut64 k, const void *v)
Definition: p_cache.c:321

References __desc_cache_cleanup_cb(), and desc.

Referenced by rz_io_desc_exchange(), and rz_io_desc_resize().

◆ rz_io_desc_cache_commit()

RZ_API bool rz_io_desc_cache_commit ( RzIODesc desc)

Definition at line 302 of file p_cache.c.

302  {
303  RzIODesc *current;
304  if (!desc || !(desc->perm & RZ_PERM_W) || !desc->io || !desc->io->files || !desc->io->p_cache) {
305  return false;
306  }
307  if (!desc->cache) {
308  return true;
309  }
310  current = desc->io->desc;
311  desc->io->desc = desc;
312  desc->io->p_cache = false;
313  ht_up_foreach(desc->cache, __desc_cache_commit_cb, desc);
314  ht_up_free(desc->cache);
315  desc->cache = NULL;
316  desc->io->p_cache = true;
317  desc->io->desc = current;
318  return true;
319 }
static bool __desc_cache_commit_cb(void *user, const ut64 k, const void *v)
Definition: p_cache.c:278
#define RZ_PERM_W
Definition: rz_types.h:94

References __desc_cache_commit_cb(), desc, NULL, and RZ_PERM_W.

Referenced by rz_write_pcache_commit_handler().

◆ rz_io_desc_cache_fini()

RZ_API void rz_io_desc_cache_fini ( RzIODesc desc)

Definition at line 358 of file p_cache.c.

358  {
359  __desc_fini_cb(NULL, (void *)desc, 0);
360 }
static bool __desc_fini_cb(void *user, void *data, ut32 id)
Definition: p_cache.c:349

References __desc_fini_cb(), desc, and NULL.

Referenced by rz_io_desc_free().

◆ rz_io_desc_cache_fini_all()

RZ_API void rz_io_desc_cache_fini_all ( RzIO io)

Definition at line 362 of file p_cache.c.

362  {
363  if (io && io->files) {
365  }
366 }
RZ_API bool rz_id_storage_foreach(RzIDStorage *storage, RzIDStorageForeachCb cb, void *user)
Definition: idpool.c:254
RzIDStorage * files
Definition: rz_io.h:75

References __desc_fini_cb(), rz_io_t::files, NULL, and rz_id_storage_foreach().

Referenced by cb_iopcache(), cb_iopcacheread(), cb_iopcachewrite(), and rz_io_fini().

◆ rz_io_desc_cache_init()

RZ_API bool rz_io_desc_cache_init ( RzIODesc desc)

Definition at line 79 of file p_cache.c.

79  {
80  if (!desc || desc->cache) {
81  return false;
82  }
83  return (desc->cache = ht_up_new(NULL, pcache_kv_free, NULL)) ? true : false;
84 }
#define true
static void pcache_kv_free(HtUPKv *kv)
Definition: p_cache.c:75

References desc, NULL, pcache_kv_free(), and true.

Referenced by rz_io_desc_cache_write().

◆ rz_io_desc_cache_list()

RZ_API RzList* rz_io_desc_cache_list ( RzIODesc desc)

Definition at line 249 of file p_cache.c.

249  {
250  if (!desc || !desc->io || !desc->io->desc || !desc->io->p_cache || !desc->cache) {
251  return NULL;
252  }
254  if (!writes) {
255  return NULL;
256  }
257  ht_up_foreach(desc->cache, __desc_cache_list_cb, writes);
258  RzIODesc *current = desc->io->desc;
259  desc->io->desc = desc;
260  desc->io->p_cache = false;
261 
262  RzIOCache *c;
263  RzListIter *iter;
264  rz_list_foreach (writes, iter, c) {
265  const ut64 itvSize = rz_itv_size(c->itv);
266  c->odata = calloc(1, itvSize);
267  if (!c->odata) {
268  rz_list_free(writes);
269  return NULL;
270  }
271  rz_io_pread_at(desc->io, rz_itv_begin(c->itv), c->odata, itvSize);
272  }
273  desc->io->p_cache = true;
274  desc->io->desc = current;
275  return writes;
276 }
RZ_API RZ_OWN RzList * rz_list_newf(RzListFree f)
Returns a new initialized RzList pointer and sets the free method.
Definition: list.c:248
RZ_API void rz_list_free(RZ_NONNULL RzList *list)
Empties the list and frees the list pointer.
Definition: list.c:137
void * calloc(size_t number, size_t size)
Definition: malloc.c:102
static bool __desc_cache_list_cb(void *user, const ut64 k, const void *v)
Definition: p_cache.c:199
RZ_API int rz_io_pread_at(RzIO *io, ut64 paddr, ut8 *buf, int len)
Definition: io.c:269
static ut64 rz_itv_begin(RzInterval itv)
Definition: rz_itv.h:34
static ut64 rz_itv_size(RzInterval itv)
Definition: rz_itv.h:38
void(* RzListFree)(void *ptr)
Definition: rz_list.h:11
#define c(i)
Definition: sha256.c:43

References __desc_cache_list_cb(), __riocache_free(), c, calloc(), desc, NULL, rz_io_pread_at(), rz_itv_begin(), rz_itv_size(), rz_list_free(), rz_list_newf(), and ut64().

Referenced by rz_core_io_pcache_print().

◆ rz_io_desc_cache_read()

RZ_API int rz_io_desc_cache_read ( RzIODesc desc,
ut64  paddr,
ut8 buf,
int  len 
)

Definition at line 142 of file p_cache.c.

142  {
143  RzIODescCache *cache;
144  ut8 *ptr = buf;
145  ut64 caddr, desc_sz = rz_io_desc_size(desc);
146  int cbaddr, amount = 0;
147  if ((len < 1) || !desc || (desc_sz <= paddr) || !desc->io || !desc->cache) {
148  return 0;
149  }
150  if (len > desc_sz) {
151  len = (int)desc_sz;
152  }
153  if (paddr > (desc_sz - len)) {
154  len = (int)(desc_sz - paddr);
155  }
156  caddr = paddr / RZ_IO_DESC_CACHE_SIZE;
157  cbaddr = paddr % RZ_IO_DESC_CACHE_SIZE;
158  while (amount < len) {
159  // get an existing desc-cache, if it exists
160  if (!(cache = (RzIODescCache *)ht_up_find(desc->cache, caddr, NULL))) {
161  amount += (RZ_IO_DESC_CACHE_SIZE - cbaddr);
162  ptr += (RZ_IO_DESC_CACHE_SIZE - cbaddr);
163  goto beach;
164  }
165  if ((len - amount) > (RZ_IO_DESC_CACHE_SIZE - cbaddr)) {
166  amount += (RZ_IO_DESC_CACHE_SIZE - cbaddr);
167  for (; cbaddr < RZ_IO_DESC_CACHE_SIZE; cbaddr++) {
168  if (cache->cached & (0x1ULL << cbaddr)) {
169  *ptr = cache->cdata[cbaddr];
170  }
171  ptr++;
172  }
173  } else {
174  do {
175  if (cache->cached & (0x1ULL << cbaddr)) {
176  *ptr = cache->cdata[cbaddr];
177  }
178  ptr++;
179  amount++;
180  cbaddr++;
181  } while (len > amount);
182  }
183  beach:
184  caddr++;
185  cbaddr = 0;
186  }
187  return amount;
188 }
size_t len
Definition: 6502dis.c:15

References rz_io_desc_cache_t::cached, rz_io_desc_cache_t::cdata, desc, int, len, NULL, RZ_IO_DESC_CACHE_SIZE, rz_io_desc_size(), and ut64().

Referenced by rz_io_desc_read().

◆ rz_io_desc_cache_write()

RZ_API int rz_io_desc_cache_write ( RzIODesc desc,
ut64  paddr,
const ut8 buf,
int  len 
)

Definition at line 86 of file p_cache.c.

86  {
87  RzIODescCache *cache;
88  ut64 caddr, desc_sz = rz_io_desc_size(desc);
89  int cbaddr, written = 0;
90  if ((len < 1) || !desc || (desc_sz <= paddr) ||
91  !desc->io || (!desc->cache && !rz_io_desc_cache_init(desc))) {
92  return 0;
93  }
94  if (len > desc_sz) {
95  len = (int)desc_sz;
96  }
97  if (paddr > (desc_sz - len)) {
98  len = (int)(desc_sz - paddr);
99  }
100  caddr = paddr / RZ_IO_DESC_CACHE_SIZE;
101  cbaddr = paddr % RZ_IO_DESC_CACHE_SIZE;
102  while (written < len) {
103  // get an existing desc-cache, if it exists
104  if (!(cache = (RzIODescCache *)ht_up_find(desc->cache, caddr, NULL))) {
105  // create new desc-cache
106  cache = RZ_NEW0(RzIODescCache);
107  if (!cache) {
108  return 0;
109  }
110  // feed ht with the new desc-cache
111  ht_up_insert(desc->cache, caddr, cache);
112  }
113  // check if the remaining data fits into the cache
114  if ((len - written) > (RZ_IO_DESC_CACHE_SIZE - cbaddr)) {
115  written += (RZ_IO_DESC_CACHE_SIZE - cbaddr);
116  // this can be optimized
117  for (; cbaddr < RZ_IO_DESC_CACHE_SIZE; cbaddr++) {
118  // write to cache
119  cache->cdata[cbaddr] = *buf;
120  // save, that its cached
121  cache->cached |= (0x1ULL << cbaddr);
122  buf++;
123  }
124  } else {
125  // XXX this looks like very suspicious
126  do {
127  cache->cdata[cbaddr] = *buf;
128  cache->cached |= (0x1ULL << cbaddr);
129  buf++;
130  written++;
131  cbaddr++;
132  } while (len > written);
133  }
134  caddr++;
135  cbaddr = 0;
136  }
137  RzEventIOWrite iow = { paddr, buf, len };
138  rz_event_send(desc->io->event, RZ_EVENT_IO_WRITE, &iow);
139  return written;
140 }
RZ_API bool rz_io_desc_cache_init(RzIODesc *desc)
Definition: p_cache.c:79
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

References rz_io_desc_cache_t::cached, rz_io_desc_cache_t::cdata, desc, int, len, NULL, RZ_EVENT_IO_WRITE, rz_event_send(), rz_io_desc_cache_init(), RZ_IO_DESC_CACHE_SIZE, rz_io_desc_size(), RZ_NEW0, and ut64().

Referenced by rz_io_desc_write().

Variable Documentation

◆ cleanup_masks

const ut64 cleanup_masks[]

Definition at line 9 of file p_cache.c.

Referenced by __desc_cache_cleanup_cb().