Rizin
unix-like reverse engineering framework and cli tools
io_default.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_userconf.h>
5 #include <rz_io.h>
6 #include <rz_lib.h>
7 #include <stdio.h>
8 
9 typedef struct rz_io_mmo_t {
10  char *filename;
11  int mode;
12  int perm;
13  bool nocache;
17 
18 static int iowhence2buf(int whence) {
19  switch (whence) {
20  case RZ_BUF_CUR:
21  return RZ_IO_SEEK_CUR;
22  case RZ_BUF_SET:
23  return RZ_IO_SEEK_SET;
24  case RZ_BUF_END:
25  return RZ_IO_SEEK_END;
26  default:
28  return -1;
29  }
30 }
31 
32 static ut64 rz_io_def_mmap_seek(RzIO *io, RzIOMMapFileObj *mmo, ut64 offset, int whence) {
33  rz_return_val_if_fail(io && mmo, UT64_MAX);
34  // NOTE: io->off should not be set here and code outside RzIO should not
35  // rely on it to get the current seek. They should use `rz_io_seek` instead.
36  // Keep it here until all use cases of io->off are converted.
37  io->off = rz_buf_seek(mmo->buf, offset, iowhence2buf(whence));
38  return io->off;
39 }
40 
42  if (!mmo) {
43  return;
44  }
45  free(mmo->filename);
46  rz_buf_free(mmo->buf);
47  free(mmo);
48 }
49 
50 static void disable_fd_cache(int fd) {
51 #if F_NOCACHE
52  fcntl(fd, F_NOCACHE, 1);
53 #elif O_DIRECT
54  int open_flags = fcntl(fd, F_GETFL);
55  fcntl(fd, F_SETFL, open_flags | O_DIRECT);
56 #endif
57 }
58 
62  if (!mmo) {
63  return NULL;
64  }
65  if (rz_str_startswith(filename, "file://")) {
66  filename += strlen("file://");
67  }
68  mmo->nocache = rz_str_startswith(filename, "nocache://");
69  if (mmo->nocache) {
70  filename += strlen("nocache://");
71  }
72  mmo->filename = strdup(filename);
73  mmo->perm = rz_sys_open_perms(perm);
74  mmo->mode = mode;
75  if (!mmo->nocache) {
76  mmo->buf = rz_buf_new_mmap(mmo->filename, mmo->perm, mmo->mode);
77  }
78  if (!mmo->buf) {
79  mmo->buf = rz_buf_new_file(mmo->filename, mmo->perm, mmo->mode);
80  if (!mmo->buf) {
82  return NULL;
83  }
84  if (mmo->nocache) {
85  disable_fd_cache(mmo->buf->fd);
86  }
87  }
88  return mmo;
89 }
90 
92  rz_return_val_if_fail(fd && fd->data, -1);
94  fd->data = NULL;
95  return 0;
96 }
97 
98 static bool rz_io_def_mmap_check_default(const char *filename) {
100  if (rz_str_startswith(filename, "file://")) {
101  filename += strlen("file://");
102  }
103  const char *peekaboo = (!strncmp(filename, "nocache://", 10))
104  ? NULL
105  : strstr(filename, "://");
106  return (!peekaboo || (peekaboo - filename) > 10);
107 }
108 
109 static int rz_io_def_mmap_read(RzIO *io, RzIODesc *fd, ut8 *buf, int count) {
110  rz_return_val_if_fail(fd && fd->data && buf, -1);
111  RzIOMMapFileObj *mmo = (RzIOMMapFileObj *)fd->data;
112  rz_return_val_if_fail(mmo && mmo->buf, -1);
113  return (int)rz_buf_read(mmo->buf, buf, count);
114 }
115 
116 static int rz_io_def_mmap_write(RzIO *io, RzIODesc *fd, const ut8 *buf, int count) {
117  rz_return_val_if_fail(io && fd && fd->data && buf, -1);
118  RzIOMMapFileObj *mmo = (RzIOMMapFileObj *)fd->data;
119  rz_return_val_if_fail(mmo && mmo->buf, -1);
120  return (int)rz_buf_write(mmo->buf, buf, count);
121 }
122 
123 static RzIODesc *rz_io_def_mmap_open(RzIO *io, const char *file, int perm, int mode) {
126  if (!mmo) {
127  return NULL;
128  }
129  RzIODesc *d = rz_io_desc_new(io, &rz_io_plugin_default, mmo->filename, perm, mode, mmo);
130  if (!d->name) {
131  d->name = strdup(mmo->filename);
132  }
133  return d;
134 }
135 
136 static ut64 rz_io_def_mmap_lseek(RzIO *io, RzIODesc *fd, ut64 offset, int whence) {
137  rz_return_val_if_fail(fd && fd->data, UT64_MAX);
138  return rz_io_def_mmap_seek(io, (RzIOMMapFileObj *)fd->data, offset, whence);
139 }
140 
142  return rz_buf_resize(mmo->buf, size);
143 }
144 
145 static bool __plugin_open_default(RzIO *io, const char *file, bool many) {
147 }
148 
149 // default open should permit opening
150 static RzIODesc *__open_default(RzIO *io, const char *file, int perm, int mode) {
152  return rz_io_def_mmap_open(io, file, perm, mode);
153  }
154  return NULL;
155 }
156 
157 static int __read(RzIO *io, RzIODesc *fd, ut8 *buf, int len) {
158  return rz_io_def_mmap_read(io, fd, buf, len);
159 }
160 
161 static int __write(RzIO *io, RzIODesc *fd, const ut8 *buf, int len) {
162  return rz_io_def_mmap_write(io, fd, buf, len);
163 }
164 
165 static ut64 __lseek(RzIO *io, RzIODesc *fd, ut64 offset, int whence) {
166  return rz_io_def_mmap_lseek(io, fd, offset, whence);
167 }
168 
169 static int __close(RzIODesc *fd) {
170  return rz_io_def_mmap_close(fd);
171 }
172 
173 static bool __resize(RzIO *io, RzIODesc *fd, ut64 size) {
174  rz_return_val_if_fail(io && fd && fd->data, false);
175  RzIOMMapFileObj *mmo = fd->data;
176  if (!(mmo->perm & RZ_PERM_W)) {
177  return false;
178  }
179  return rz_io_def_mmap_truncate(mmo, size);
180 }
181 
182 #if __UNIX__
183 static bool __is_blockdevice(RzIODesc *desc) {
184  rz_return_val_if_fail(desc && desc->data, false);
185  RzIOMMapFileObj *mmo = desc->data;
186  struct stat buf;
187  if (stat(mmo->filename, &buf) == -1) {
188  return false;
189  }
190  return ((buf.st_mode & S_IFBLK) == S_IFBLK);
191 }
192 #endif
193 
196  RzIOMMapFileObj *mmo = desc->data;
197  return rz_buf_data(mmo->buf, size);
198 }
199 
201  .name = "default",
202  .desc = "Open local files",
203  .license = "LGPL3",
204  .uris = "file://,nocache://",
205  .open = __open_default,
206  .close = __close,
207  .read = __read,
208  .check = __plugin_open_default,
209  .lseek = __lseek,
210  .write = __write,
211  .resize = __resize,
212 #if __UNIX__
213  .is_blockdevice = __is_blockdevice,
214 #endif
215  .get_buf = io_default_get_buf
216 };
217 
218 #ifndef RZ_PLUGIN_INCORE
220  .type = RZ_LIB_TYPE_IO,
221  .data = &rz_io_plugin_default,
223 };
224 #endif
size_t len
Definition: 6502dis.c:15
const char * desc
Definition: bin_vsf.c:19
#define RZ_API
#define NULL
Definition: cris-opc.c:27
static static sync static getppid static getegid const char static filename char static len const char char static bufsiz static mask static vfork const void static prot static getpgrp const char static swapflags static arg static fd static protocol static who struct sockaddr static addrlen static backlog struct timeval struct timezone static tz const struct iovec static count static mode const void const struct sockaddr static tolen const char static pathname void count
Definition: sflib.h:98
static static sync static getppid static getegid const char static filename char static len const char char static bufsiz static mask static vfork const void static prot static getpgrp const char static swapflags fcntl
Definition: sflib.h:79
RZ_API void Ht_() free(HtName_(Ht) *ht)
Definition: ht_inc.c:130
static int rz_io_def_mmap_close(RzIODesc *fd)
Definition: io_default.c:91
static RzIODesc * __open_default(RzIO *io, const char *file, int perm, int mode)
Definition: io_default.c:150
static ut64 rz_io_def_mmap_seek(RzIO *io, RzIOMMapFileObj *mmo, ut64 offset, int whence)
Definition: io_default.c:32
static bool __plugin_open_default(RzIO *io, const char *file, bool many)
Definition: io_default.c:145
static ut64 rz_io_def_mmap_lseek(RzIO *io, RzIODesc *fd, ut64 offset, int whence)
Definition: io_default.c:136
struct rz_io_mmo_t RzIOMMapFileObj
static int __write(RzIO *io, RzIODesc *fd, const ut8 *buf, int len)
Definition: io_default.c:161
static int rz_io_def_mmap_write(RzIO *io, RzIODesc *fd, const ut8 *buf, int count)
Definition: io_default.c:116
static bool __resize(RzIO *io, RzIODesc *fd, ut64 size)
Definition: io_default.c:173
RZ_API RzLibStruct rizin_plugin
Definition: io_default.c:219
static int iowhence2buf(int whence)
Definition: io_default.c:18
static void disable_fd_cache(int fd)
Definition: io_default.c:50
RzIOPlugin rz_io_plugin_default
Definition: io_default.c:200
static void rz_io_def_mmap_free(RzIOMMapFileObj *mmo)
Definition: io_default.c:41
static int rz_io_def_mmap_read(RzIO *io, RzIODesc *fd, ut8 *buf, int count)
Definition: io_default.c:109
static bool rz_io_def_mmap_check_default(const char *filename)
Definition: io_default.c:98
static int __read(RzIO *io, RzIODesc *fd, ut8 *buf, int len)
Definition: io_default.c:157
static ut64 __lseek(RzIO *io, RzIODesc *fd, ut64 offset, int whence)
Definition: io_default.c:165
static int __close(RzIODesc *fd)
Definition: io_default.c:169
RzIOMMapFileObj * rz_io_def_mmap_create_new_file(RzIO *io, const char *filename, int perm, int mode)
Definition: io_default.c:59
static int rz_io_def_mmap_truncate(RzIOMMapFileObj *mmo, ut64 size)
Definition: io_default.c:141
static ut8 * io_default_get_buf(RzIODesc *desc, ut64 *size)
Definition: io_default.c:194
static RzIODesc * rz_io_def_mmap_open(RzIO *io, const char *file, int perm, int mode)
Definition: io_default.c:123
voidpf void uLong size
Definition: ioapi.h:138
const char * filename
Definition: ioapi.h:137
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
static stat
Definition: sflib.h:131
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")
#define rz_warn_if_reached()
Definition: rz_assert.h:29
#define rz_return_val_if_fail(expr, val)
Definition: rz_assert.h:108
RZ_API bool rz_buf_resize(RZ_NONNULL RzBuffer *b, ut64 newsize)
Resize the buffer size.
Definition: buf.c:890
RZ_API st64 rz_buf_seek(RZ_NONNULL RzBuffer *b, st64 addr, int whence)
Modify the current cursor position in the buffer.
Definition: buf.c:1166
#define RZ_BUF_CUR
Definition: rz_buf.h:15
RZ_API RZ_OWN RzBuffer * rz_buf_new_mmap(const char *file, int flags, int mode)
Creates a new buffer from a file using rz_file_mmap.
Definition: buf.c:339
#define RZ_BUF_END
Definition: rz_buf.h:16
RZ_API st64 rz_buf_write(RZ_NONNULL RzBuffer *b, RZ_NONNULL const ut8 *buf, ut64 len)
Write len bytes of the buffer at the cursor.
Definition: buf.c:1181
#define RZ_BUF_SET
Definition: rz_buf.h:14
RZ_API void rz_buf_free(RzBuffer *b)
Free all internal data hold by the buffer and the buffer.
Definition: buf.c:1253
RZ_API st64 rz_buf_read(RZ_NONNULL RzBuffer *b, RZ_NONNULL RZ_OUT ut8 *buf, ut64 len)
RZ_DEPRECATE RZ_API RZ_BORROW ut8 * rz_buf_data(RZ_NONNULL RzBuffer *b, RZ_NONNULL RZ_OUT ut64 *size)
Return a borrowed array of bytes representing the buffer data.
Definition: buf.c:1287
RZ_API RZ_OWN RzBuffer * rz_buf_new_file(const char *file, int perm, int mode)
Creates a new buffer from a file.
Definition: buf.c:317
#define RZ_IO_SEEK_CUR
Definition: rz_io.h:16
RZ_API RzIODesc * rz_io_desc_new(RzIO *io, RzIOPlugin *plugin, const char *uri, int flags, int mode, void *data)
Definition: io_desc.c:11
#define RZ_IO_SEEK_SET
Definition: rz_io.h:15
#define RZ_IO_SEEK_END
Definition: rz_io.h:17
@ RZ_LIB_TYPE_IO
Definition: rz_lib.h:69
RZ_API bool rz_str_startswith(RZ_NONNULL const char *str, RZ_NONNULL const char *needle)
Checks if a string starts with a specifc sequence of characters (case sensitive)
Definition: str.c:3286
RZ_API int rz_sys_open_perms(int rizin_perms)
Convert rizin permissions (RZ_PERM_*) to posix permissions that can be passed to rz_sys_open .
Definition: sys.c:1718
#define RZ_NEW0(x)
Definition: rz_types.h:284
#define RZ_PERM_W
Definition: rz_types.h:94
#define UT64_MAX
Definition: rz_types_base.h:86
#define RZ_VERSION
Definition: rz_version.h:8
#define F_GETFL
Definition: sftypes.h:506
#define O_DIRECT
Definition: sftypes.h:498
#define F_SETFL
Definition: sftypes.h:507
#define d(i)
Definition: sha256.c:44
Definition: gzappend.c:170
int fd
Definition: rz_buf.h:50
bool nocache
Definition: io_default.c:13
RzBuffer * buf
Definition: io_default.c:15
ut8 modified
Definition: io_default.c:14
char * filename
Definition: io_default.c:10
const char * name
Definition: rz_io.h:115
const char * version
Definition: rz_io.h:117
Definition: rz_io.h:59
ut64 off
Definition: rz_io.h:61
Definition: sftypes.h:80
ut64(WINAPI *w32_GetEnabledXStateFeatures)()
static const z80_opcode fd[]
Definition: z80_tab.h:997