Rizin
unix-like reverse engineering framework and cli tools
io_desc.c
Go to the documentation of this file.
1 // SPDX-FileCopyrightText: 2017-2020 condret <condr3t@protonmail.com>
2 // SPDX-FileCopyrightText: 2017-2020 pancake <pancake@nopcode.org>
3 // SPDX-FileCopyrightText: 2017-2020 alvaro <alvaro.felipe91@gmail.com>
4 // SPDX-License-Identifier: LGPL-3.0-only
5 
6 #include <rz_io.h>
7 #include <sdb.h>
8 #include <string.h>
9 
10 // shall be used by plugins for creating descs
11 RZ_API RzIODesc *rz_io_desc_new(RzIO *io, RzIOPlugin *plugin, const char *uri, int perm, int mode, void *data) {
12  ut32 fd32 = 0;
13  // this is required for emscripten builds to work, but should assert
14  if (!io || !plugin || !uri) {
15  return NULL;
16  }
17  if (io->files) {
18  if (!rz_id_pool_grab_id(io->files->pool, &fd32)) {
19  return NULL;
20  }
21  }
23  if (desc) {
24  desc->fd = fd32;
25  desc->io = io;
26  desc->plugin = plugin;
27  desc->data = data;
28  desc->perm = perm;
29  // because the uri-arg may live on the stack
30  desc->uri = strdup(uri);
31  }
32  return desc;
33 }
34 
36  if (desc) {
37  free(desc->uri);
38  free(desc->referer);
39  free(desc->name);
41  if (desc->io && desc->io->files) {
42  rz_id_storage_delete(desc->io->files, desc->fd);
43  }
44  // free (desc->plugin);
45  }
46  free(desc);
47 }
48 
50  rz_return_val_if_fail(io && desc && desc->io, false);
51  if (!rz_id_storage_set(io->files, desc, desc->fd)) {
52  // TODO: use assert here
53  eprintf("You are using this API incorrectly\n");
54  eprintf("fd %d was probably not generated by this RzIO-instance\n", desc->fd);
56  return false;
57  }
58  return true;
59 }
60 
61 RZ_API bool rz_io_desc_del(RzIO *io, int fd) { // can we pass this a riodesc and check if it belongs to the desc->io ?
62  rz_return_val_if_fail(io && io->files, false);
65  if (desc == io->desc) {
66  io->desc = NULL;
67  }
68  // remove all dead maps
70  return true;
71 }
72 
74  rz_return_val_if_fail(io && io->files, NULL);
75  return (RzIODesc *)rz_id_storage_get(io->files, fd);
76 }
77 
79  rz_return_val_if_fail(desc && io && io->files, NULL);
80  const int next_fd = rz_io_fd_get_next(io, desc->fd);
81  if (next_fd == -1) {
82  return NULL;
83  }
84  return (RzIODesc *)rz_id_storage_get(io->files, next_fd);
85 }
86 
88  rz_return_val_if_fail(desc && io && io->files, NULL);
89  const int prev_fd = rz_io_fd_get_prev(io, desc->fd);
90  if (prev_fd == -1) {
91  return NULL;
92  }
93  return (RzIODesc *)rz_id_storage_get(io->files, prev_fd);
94 }
95 
97  int fd = rz_io_fd_get_highest(io);
98  if (fd == -1) {
99  return NULL;
100  }
101  return rz_io_desc_get(io, fd);
102 }
103 
105  int fd = rz_io_fd_get_lowest(io);
106  if (fd == -1) {
107  return NULL;
108  }
109  return rz_io_desc_get(io, fd);
110 }
111 
112 RZ_API RzIODesc *rz_io_desc_open(RzIO *io, const char *uri, int perm, int mode) {
113  rz_return_val_if_fail(io && uri, NULL);
114  RzIOPlugin *plugin = rz_io_plugin_resolve(io, uri, 0);
115  if (!plugin || !plugin->open) {
116  return NULL;
117  }
118  RzIODesc *desc = plugin->open(io, uri, perm, mode);
119  if (!desc) {
120  return NULL;
121  }
122  // for none static callbacks, those that cannot use rz_io_desc_new
123  if (!desc->name) {
124  desc->name = strdup(uri);
125  }
126  if (!desc->uri) {
127  desc->uri = strdup(uri);
128  }
129  if (!desc->plugin) {
130  desc->plugin = plugin;
131  }
132  if (!rz_io_desc_add(io, desc)) {
134  return NULL;
135  }
136  return desc;
137 }
138 
139 RZ_API RzIODesc *rz_io_desc_open_plugin(RzIO *io, RzIOPlugin *plugin, const char *uri, int perm, int mode) {
140  rz_return_val_if_fail(io && io->files && uri, NULL);
141  if (!plugin || !plugin->open || !plugin->check || !plugin->check(io, uri, false)) {
142  return NULL;
143  }
144  RzIODesc *desc = plugin->open(io, uri, perm, mode);
145  if (!desc) {
146  return NULL;
147  }
148  // for none static callbacks, those that cannot use rz_io_desc_new
149  if (!desc->plugin) {
150  desc->plugin = plugin;
151  }
152  if (!desc->uri) {
153  desc->uri = strdup(uri);
154  }
155  if (!desc->name) {
156  desc->name = strdup(uri);
157  }
158  if (!rz_io_desc_add(io, desc)) {
160  return NULL;
161  }
162  return desc;
163 }
164 
166  if (!desc || !desc->io || !desc->plugin) {
167  return false;
168  }
169  RzIO *io = desc->io;
170  RzEventIODescClose ev = { desc };
172  if (desc->plugin->close && desc->plugin->close(desc)) {
173  return false;
174  }
175  // remove entry from idstorage and free the desc-struct
176  rz_io_desc_del(io, desc->fd);
177  // remove all dead maps
178  rz_io_map_cleanup(io);
179  return true;
180 }
181 
182 // returns length of written bytes
185  if (len < 0) {
186  return -1;
187  }
188  // check pointers and pcache
189  if (desc->io && (desc->io->p_cache & 2)) {
192  }
193  return rz_io_plugin_write(desc, buf, len);
194 }
195 
196 // returns length of read bytes
198  // check pointers and permissions
199  if (!buf || !desc || !desc->plugin || !(desc->perm & RZ_PERM_R)) {
200  return -1;
201  }
203  if (desc->io->cachemode) {
204  if (seek != UT64_MAX && rz_io_cache_at(desc->io, seek)) {
205  return rz_io_cache_read(desc->io, seek, buf, len);
206  }
207  }
208  int ret = rz_io_plugin_read(desc, buf, len);
209  if (ret > 0 && desc->io->cachemode) {
211  } else if ((ret > 0) && desc->io && (desc->io->p_cache & 1)) {
212  ret = rz_io_desc_cache_read(desc, seek, buf, ret);
213  }
214  return ret;
215 }
216 
218  if (!desc || !desc->plugin || !desc->plugin->lseek) {
219  return (ut64)-1;
220  }
221  return desc->plugin->lseek(desc->io, desc, offset, whence);
222 }
223 
225  if (!desc || !desc->plugin || !desc->plugin->lseek) {
226  return 0LL;
227  }
230  // what to do if that seek fails?
232  return ret;
233 }
234 
243  if (!desc || !desc->plugin || !desc->plugin->get_buf) {
244  *size = 0;
245  return NULL;
246  }
247  return desc->plugin->get_buf(desc, size);
248 }
249 
251  if (desc && desc->plugin && desc->plugin->resize) {
252  bool ret = desc->plugin->resize(desc->io, desc, newsize);
253  if (desc->io && desc->io->p_cache) {
255  }
256  return ret;
257  }
258  return false;
259 }
260 
262  if (!desc || !desc->plugin || !desc->plugin->is_blockdevice) {
263  return false;
264  }
265  return desc->plugin->is_blockdevice(desc);
266 }
267 
269  if (!desc || !desc->plugin || !desc->plugin->is_chardevice) {
270  return false;
271  }
272  return desc->plugin->is_chardevice(desc);
273 }
274 
275 RZ_API bool rz_io_desc_exchange(RzIO *io, int fd, int fdx) {
276  RzIODesc *desc, *descx;
277  if (!(desc = rz_io_desc_get(io, fd)) || !(descx = rz_io_desc_get(io, fdx))) {
278  return false;
279  }
280  desc->fd = fdx;
281  descx->fd = fd;
282  rz_id_storage_set(io->files, desc, fdx);
283  rz_id_storage_set(io->files, descx, fd);
284  if (io->p_cache) {
285  HtUP *cache = desc->cache;
286  desc->cache = descx->cache;
287  descx->cache = cache;
290  }
291  void **it;
292  rz_pvector_foreach (&io->maps, it) {
293  RzIOMap *map = *it;
294  if (map->fd == fdx) {
295  map->perm &= (desc->perm | RZ_PERM_X);
296  } else if (map->fd == fd) {
297  map->perm &= (descx->perm | RZ_PERM_X);
298  }
299  }
300  return true;
301 }
302 
304  if (desc && desc->plugin) {
305  return desc->plugin->isdbg;
306  }
307  return false;
308 }
309 
311  //-1 and -2 are reserved
312  if (!desc) {
313  return -3;
314  }
315  if (!desc->plugin) {
316  return -4;
317  }
318  if (!desc->plugin->isdbg) {
319  return -5;
320  }
321  if (!desc->plugin->getpid) {
322  return -6;
323  }
324  return desc->plugin->getpid(desc);
325 }
326 
328  //-1 and -2 are reserved
329  if (!desc) {
330  return -3;
331  }
332  if (!desc->plugin) {
333  return -4;
334  }
335  if (!desc->plugin->isdbg) {
336  return -5;
337  }
338  if (!desc->plugin->gettid) {
339  return -6;
340  }
341  return desc->plugin->gettid(desc);
342 }
343 
345  if (!base || !desc || !desc->plugin || !desc->plugin->isdbg || !desc->plugin->getbase) {
346  return false;
347  }
348  return desc->plugin->getbase(desc, base);
349 }
350 
352  if (desc && buf && (rz_io_desc_seek(desc, addr, RZ_IO_SEEK_SET) == addr)) {
353  return rz_io_desc_read(desc, buf, len);
354  }
355  return 0;
356 }
357 
359  if (desc && buf && (rz_io_desc_seek(desc, addr, RZ_IO_SEEK_SET) == addr)) {
360  return rz_io_desc_write(desc, buf, len);
361  }
362  return 0;
363 }
364 
365 /* lifecycle */
366 
367 // TODO: move into io.c : rz_io_init
369  rz_return_val_if_fail(io, false);
370  rz_io_desc_fini(io);
371  // TODO: it leaks if called twice
372  // fd is signed
373  io->files = rz_id_storage_new(3, 0x80000000);
374  if (!io->files) {
375  return false;
376  }
377  return true;
378 }
379 
380 static bool desc_fini_cb(void *user, void *data, ut32 id) {
381  RzIODesc *desc = (RzIODesc *)data;
382  if (desc->plugin && desc->plugin->close) {
383  desc->plugin->close(desc);
384  }
386  return true;
387 }
388 
389 // closes all descs and frees all descs and io->files
391  rz_return_val_if_fail(io, false);
392  if (io->files) {
395  io->files = NULL;
396  }
397  // no map-cleanup here, to keep it modular useable
398  io->desc = NULL;
399  return true;
400 }
size_t len
Definition: 6502dis.c:15
#define RZ_IPI
Definition: analysis_wasm.c:11
const char * desc
Definition: bin_vsf.c:19
#define RZ_API
#define NULL
Definition: cris-opc.c:27
uint32_t ut32
size_t map(int syms, int left, int len)
Definition: enough.c:237
RZ_API void Ht_() free(HtName_(Ht) *ht)
Definition: ht_inc.c:130
RZ_API RzIODesc * rz_io_desc_open_plugin(RzIO *io, RzIOPlugin *plugin, const char *uri, int perm, int mode)
Definition: io_desc.c:139
RZ_IPI bool rz_io_desc_init(RzIO *io)
Definition: io_desc.c:368
RZ_API void rz_io_desc_free(RzIODesc *desc)
Definition: io_desc.c:35
RZ_API RzIODesc * rz_io_desc_open(RzIO *io, const char *uri, int perm, int mode)
Definition: io_desc.c:112
RZ_API RzIODesc * rz_io_desc_get_prev(RzIO *io, RzIODesc *desc)
Definition: io_desc.c:87
RZ_API RzIODesc * rz_io_desc_get_highest(RzIO *io)
Definition: io_desc.c:96
RZ_API bool rz_io_desc_is_blockdevice(RzIODesc *desc)
Definition: io_desc.c:261
static bool desc_fini_cb(void *user, void *data, ut32 id)
Definition: io_desc.c:380
RZ_API ut64 rz_io_desc_seek(RzIODesc *desc, ut64 offset, int whence)
Definition: io_desc.c:217
RZ_API bool rz_io_desc_add(RzIO *io, RzIODesc *desc)
Definition: io_desc.c:49
RZ_API ut64 rz_io_desc_size(RzIODesc *desc)
Definition: io_desc.c:224
RZ_API RzIODesc * rz_io_desc_new(RzIO *io, RzIOPlugin *plugin, const char *uri, int perm, int mode, void *data)
Definition: io_desc.c:11
RZ_API RzIODesc * rz_io_desc_get_lowest(RzIO *io)
Definition: io_desc.c:104
RZ_API bool rz_io_desc_exchange(RzIO *io, int fd, int fdx)
Definition: io_desc.c:275
RZ_API int rz_io_desc_get_tid(RzIODesc *desc)
Definition: io_desc.c:327
RZ_API bool rz_io_desc_resize(RzIODesc *desc, ut64 newsize)
Definition: io_desc.c:250
RZ_API int rz_io_desc_read_at(RzIODesc *desc, ut64 addr, ut8 *buf, int len)
Definition: io_desc.c:351
RZ_API RzIODesc * rz_io_desc_get(RzIO *io, int fd)
Definition: io_desc.c:73
RZ_API int rz_io_desc_get_pid(RzIODesc *desc)
Definition: io_desc.c:310
RZ_API bool rz_io_desc_is_chardevice(RzIODesc *desc)
Definition: io_desc.c:268
RZ_API int rz_io_desc_write_at(RzIODesc *desc, ut64 addr, const ut8 *buf, int len)
Definition: io_desc.c:358
RZ_IPI bool rz_io_desc_fini(RzIO *io)
Definition: io_desc.c:390
RZ_API bool rz_io_desc_del(RzIO *io, int fd)
Definition: io_desc.c:61
RZ_API int rz_io_desc_write(RzIODesc *desc, const ut8 *buf, int len)
Definition: io_desc.c:183
RZ_API int rz_io_desc_read(RzIODesc *desc, ut8 *buf, int len)
Definition: io_desc.c:197
RZ_API bool rz_io_desc_is_dbg(RzIODesc *desc)
Definition: io_desc.c:303
RZ_API RzIODesc * rz_io_desc_get_next(RzIO *io, RzIODesc *desc)
Definition: io_desc.c:78
RZ_API bool rz_io_desc_close(RzIODesc *desc)
Definition: io_desc.c:165
RZ_API bool rz_io_desc_get_base(RzIODesc *desc, ut64 *base)
Definition: io_desc.c:344
RZ_API ut8 * rz_io_desc_get_buf(RzIODesc *desc, RZ_OUT RZ_NONNULL ut64 *size)
Returns the underlying buffer of the io descriptor.
Definition: io_desc.c:241
voidpf void uLong size
Definition: ioapi.h:138
voidpf uLong offset
Definition: ioapi.h:144
const char int mode
Definition: ioapi.h:137
voidpf void * buf
Definition: ioapi.h:138
uint8_t ut8
Definition: lh5801.h:11
return strdup("=SP r13\n" "=LR r14\n" "=PC r15\n" "=A0 r0\n" "=A1 r1\n" "=A2 r2\n" "=A3 r3\n" "=ZF zf\n" "=SF nf\n" "=OF vf\n" "=CF cf\n" "=SN or0\n" "gpr lr .32 56 0\n" "gpr pc .32 60 0\n" "gpr cpsr .32 64 0 ____tfiae_________________qvczn\n" "gpr or0 .32 68 0\n" "gpr tf .1 64.5 0 thumb\n" "gpr ef .1 64.9 0 endian\n" "gpr jf .1 64.24 0 java\n" "gpr qf .1 64.27 0 sticky_overflow\n" "gpr vf .1 64.28 0 overflow\n" "gpr cf .1 64.29 0 carry\n" "gpr zf .1 64.30 0 zero\n" "gpr nf .1 64.31 0 negative\n" "gpr itc .4 64.10 0 if_then_count\n" "gpr gef .4 64.16 0 great_or_equal\n" "gpr r0 .32 0 0\n" "gpr r1 .32 4 0\n" "gpr r2 .32 8 0\n" "gpr r3 .32 12 0\n" "gpr r4 .32 16 0\n" "gpr r5 .32 20 0\n" "gpr r6 .32 24 0\n" "gpr r7 .32 28 0\n" "gpr r8 .32 32 0\n" "gpr r9 .32 36 0\n" "gpr r10 .32 40 0\n" "gpr r11 .32 44 0\n" "gpr r12 .32 48 0\n" "gpr r13 .32 52 0\n" "gpr r14 .32 56 0\n" "gpr r15 .32 60 0\n" "gpr r16 .32 64 0\n" "gpr r17 .32 68 0\n")
int off
Definition: pal.c:13
#define eprintf(x, y...)
Definition: rlcc.c:7
#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_DESC_CLOSE
Definition: rz_event.h:43
RZ_API bool rz_id_storage_set(RzIDStorage *storage, void *data, ut32 id)
Definition: idpool.c:131
RZ_API bool rz_id_pool_grab_id(RzIDPool *pool, ut32 *grabber)
Definition: idpool.c:34
RZ_API RzIDStorage * rz_id_storage_new(ut32 start_id, ut32 last_id)
Definition: idpool.c:80
RZ_API void rz_id_storage_free(RzIDStorage *storage)
Definition: idpool.c:270
RZ_API void * rz_id_storage_get(RzIDStorage *storage, ut32 id)
Definition: idpool.c:162
RZ_API bool rz_id_storage_foreach(RzIDStorage *storage, RzIDStorageForeachCb cb, void *user)
Definition: idpool.c:254
RZ_API void rz_id_storage_delete(RzIDStorage *storage, ut32 id)
Definition: idpool.c:221
RZ_API int rz_io_plugin_write(RzIODesc *desc, const ut8 *buf, int len)
Definition: io_plugin.c:89
RZ_API void rz_io_map_cleanup(RzIO *io)
Definition: io_map.c:287
RZ_API bool rz_io_cache_at(RzIO *io, ut64 addr)
Definition: io_cache.c:16
RZ_API bool rz_io_cache_read(RzIO *io, ut64 addr, ut8 *buf, int len)
Definition: io_cache.c:131
#define RZ_IO_SEEK_CUR
Definition: rz_io.h:16
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_desc_cache_fini(RzIODesc *desc)
Definition: p_cache.c:358
RZ_API int rz_io_desc_cache_write(RzIODesc *desc, ut64 paddr, const ut8 *buf, int len)
Definition: p_cache.c:86
RZ_API int rz_io_desc_cache_read(RzIODesc *desc, ut64 paddr, ut8 *buf, int len)
Definition: p_cache.c:142
RZ_API int rz_io_plugin_read(RzIODesc *desc, ut8 *buf, int len)
Definition: io_plugin.c:79
#define RZ_IO_SEEK_SET
Definition: rz_io.h:15
RZ_API int rz_io_fd_get_highest(RzIO *io)
Definition: io_fd.c:161
RZ_API void rz_io_desc_cache_cleanup(RzIODesc *desc)
Definition: p_cache.c:343
RZ_API int rz_io_fd_get_prev(RzIO *io, int fd)
Definition: io_fd.c:152
RZ_API RzIOPlugin * rz_io_plugin_resolve(RzIO *io, const char *filename, bool many)
Definition: io_plugin.c:54
RZ_API int rz_io_fd_get_lowest(RzIO *io)
Definition: io_fd.c:170
#define RZ_IO_SEEK_END
Definition: rz_io.h:17
RZ_API int rz_io_fd_get_next(RzIO *io, int fd)
Definition: io_fd.c:143
RZ_API char RZ_API void rz_sys_backtrace(void)
Print the backtrace at the point this function is called from.
Definition: sys.c:265
#define RZ_PERM_R
Definition: rz_types.h:93
#define RZ_NEW0(x)
Definition: rz_types.h:284
#define RZ_OUT
Definition: rz_types.h:51
#define RZ_NONNULL
Definition: rz_types.h:64
#define RZ_PERM_X
Definition: rz_types.h:95
#define UT64_MAX
Definition: rz_types_base.h:86
#define rz_pvector_foreach(vec, it)
Definition: rz_vector.h:334
RzIDPool * pool
Definition: rz_idpool.h:28
int fd
Definition: rz_io.h:96
int perm
Definition: rz_io.h:97
HtUP * cache
Definition: rz_io.h:101
bool(* check)(RzIO *io, const char *, bool many)
Definition: rz_io.h:141
RzIODesc *(* open)(RzIO *io, const char *, int perm, int mode)
Definition: rz_io.h:127
Definition: rz_io.h:59
RzPVector maps
Definition: rz_io.h:73
RzEvent * event
Definition: rz_io.h:90
RzIDStorage * files
Definition: rz_io.h:75
struct rz_io_desc_t * desc
Definition: rz_io.h:60
int p_cache
Definition: rz_io.h:71
ut64(WINAPI *w32_GetEnabledXStateFeatures)()
static const z80_opcode fd[]
Definition: z80_tab.h:997
static int addr
Definition: z80asm.c:58
static int seek(char *argv[])