Rizin
unix-like reverse engineering framework and cli tools
io_map.c
Go to the documentation of this file.
1 // SPDX-FileCopyrightText: 2017-2020 condret <condr3t@protonmail.com>
2 // SPDX-FileCopyrightText: 2017-2020 MaskRay <i@maskray.me>
3 // SPDX-License-Identifier: LGPL-3.0-only
4 
5 #include <rz_io.h>
6 #include <stdlib.h>
7 #include <sdb.h>
8 #include "rz_util.h"
9 #include "rz_vector.h"
10 
11 #define END_OF_MAP_IDS UT32_MAX
12 
13 // Store map parts that are not covered by others into io->map_skyline
16  // Last map has highest priority (it shadows previous maps)
17  void **it;
18  rz_pvector_foreach (&io->maps, it) {
19  RzIOMap *map = (RzIOMap *)*it;
20  rz_skyline_add(&io->map_skyline, map->itv, map);
21  }
22 }
23 
24 RzIOMap *io_map_new(RzIO *io, int fd, int perm, ut64 delta, ut64 addr, ut64 size) {
25  if (!io || !io->map_ids) {
26  return NULL;
27  }
29  if (!map || !io->map_ids || !rz_id_pool_grab_id(io->map_ids, &map->id)) {
30  free(map);
31  return NULL;
32  }
33  map->fd = fd;
34  map->delta = delta;
35  if (size && (UT64_MAX - size + 1) < addr) {
37  io_map_new(io, fd, perm, delta - addr, 0LL, size + addr);
38  size = -(st64)addr;
39  }
40  // RzIOMap describes an interval of addresses (map->from; map->to)
41  map->itv = (RzInterval){ addr, size };
42  map->perm = perm;
43  map->delta = delta;
44  // new map lives on the top, being top the list's tail
45  rz_pvector_push(&io->maps, map);
46  rz_skyline_add(&io->map_skyline, map->itv, map);
47  return map;
48 }
49 
51  return io_map_new(io, fd, perm, delta, addr, size);
52 }
53 
55  RzIOMap *map = rz_io_map_resolve(io, id);
56  if (map) {
57  ut64 size = map->itv.size;
58  map->itv.addr = addr;
59  if (size && UT64_MAX - size + 1 < addr) {
60  map->itv.size = -addr;
61  rz_io_map_new(io, map->fd, map->perm, map->delta - addr, 0, size + addr);
62  }
64  return true;
65  }
66  return false;
67 }
68 
70  RzIOMap *map;
71  bool retval = false;
73  if (maps) {
74  map = rz_list_get_n(maps, 0);
75  if (map) {
76  retval = rz_io_map_remap(io, map->id, addr);
77  }
79  }
80  return retval;
81 }
82 
84 static void map_free(void *p) {
85  RzIOMap *map = (RzIOMap *)p;
86  if (map) {
87  free(map->name);
88  free(map);
89  }
90 }
91 
93 static void map_del(RzIO *io, RzIOMap *map) {
94  rz_return_if_fail(io && map);
95  RzEventIOMapDel ev = { map };
97  rz_id_pool_kick_id(io->map_ids, map->id);
98  map_free(map);
99 }
100 
102  rz_return_if_fail(io);
104  if (io->map_ids) {
106  }
108 }
109 
110 // check if a map with exact the same properties exists
112  rz_return_val_if_fail(io && map, false);
113  void **it;
114  rz_pvector_foreach (&io->maps, it) {
115  RzIOMap *m = *it;
116  if (!memcmp(m, map, sizeof(RzIOMap))) {
117  return true;
118  }
119  }
120  return false;
121 }
122 
123 // check if a map with specified id exists
125  return rz_io_map_resolve(io, id) != NULL;
126 }
127 
129  rz_return_val_if_fail(io && id, false);
130  void **it;
131  rz_pvector_foreach (&io->maps, it) {
132  RzIOMap *map = *it;
133  if (map->id == id) {
134  return map;
135  }
136  }
137  return NULL;
138 }
139 
140 RzIOMap *io_map_add(RzIO *io, int fd, int perm, ut64 delta, ut64 addr, ut64 size) {
141  // check if desc exists
142  RzIODesc *desc = rz_io_desc_get(io, fd);
143  if (desc) {
144  // a map cannot have higher permissions than the desc belonging to it
145  return io_map_new(io, fd, (perm & desc->perm) | (perm & RZ_PERM_X),
146  delta, addr, size);
147  }
148  return NULL;
149 }
150 
152  return io_map_add(io, fd, perm, delta, addr, size);
153 }
154 
156  return io_map_add(io, fd, perm, delta, addr, size);
157 }
158 
161 }
162 
165  void **it;
166  rz_pvector_foreach_prev(&io->maps, it) {
167  RzIOMap *map = *it;
168  if (map->delta <= paddr && paddr <= map->delta + (map->itv.size ? map->itv.size - 1 : 0)) {
169  return map;
170  }
171  }
172  return NULL;
173 }
174 
175 // gets first map where addr fits in
178  return rz_skyline_get(&io->map_skyline, addr);
179 }
180 
182  rz_return_val_if_fail(io, false);
183  return (bool)rz_io_map_get(io, addr);
184 }
185 
187  rz_io_map_fini(io);
188  rz_io_map_init(io);
190 }
191 
192 RZ_API bool rz_io_map_del(RzIO *io, ut32 id) {
193  rz_return_val_if_fail(io, false);
194  size_t i;
195  for (i = 0; i < rz_pvector_len(&io->maps); i++) {
196  RzIOMap *map = rz_pvector_at(&io->maps, i);
197  if (map->id == id) {
198  rz_pvector_remove_at(&io->maps, i);
199  map_del(io, map);
201  return true;
202  }
203  }
204  return false;
205 }
206 
207 // delete all maps with specified fd
209  rz_return_val_if_fail(io, false);
210  bool ret = false;
211  size_t i;
212  for (i = 0; i < rz_pvector_len(&io->maps);) {
213  RzIOMap *map = rz_pvector_at(&io->maps, i);
214  if (!map) {
215  rz_pvector_remove_at(&io->maps, i);
216  } else if (map->fd == fd) {
217  rz_pvector_remove_at(&io->maps, i);
218  map_del(io, map);
219  ret = true;
220  } else {
221  i++;
222  }
223  }
224  if (ret) {
226  }
227  return ret;
228 }
229 
230 // brings map with specified id to the tail of of the list
231 // return a boolean denoting whether is was possible to priorized
233  rz_return_val_if_fail(io, false);
234  size_t i;
235  for (i = 0; i < rz_pvector_len(&io->maps); i++) {
236  RzIOMap *map = rz_pvector_at(&io->maps, i);
237  // search for iter with the correct map
238  if (map->id == id) {
239  rz_pvector_remove_at(&io->maps, i);
240  rz_pvector_push(&io->maps, map);
241  rz_skyline_add(&io->map_skyline, map->itv, map);
242  return true;
243  }
244  }
245  return false;
246 }
247 
249  rz_return_val_if_fail(io, false);
250  size_t i;
251  for (i = 0; i < rz_pvector_len(&io->maps); i++) {
252  RzIOMap *map = rz_pvector_at(&io->maps, i);
253  // search for iter with the correct map
254  if (map->id == id) {
255  rz_pvector_remove_at(&io->maps, i);
258  return true;
259  }
260  }
261  return false;
262 }
263 
265  rz_return_val_if_fail(io, false);
266  // we need a clean list for this, or this becomes a segfault-field
267  rz_io_map_cleanup(io);
268  RzPVector temp;
269  rz_pvector_init(&temp, NULL);
270  size_t i;
271  for (i = 0; i < rz_pvector_len(&io->maps);) {
272  RzIOMap *map = rz_pvector_at(&io->maps, i);
273  if (map->fd == fd) {
274  rz_pvector_push(&temp, map);
275  rz_pvector_remove_at(&io->maps, i);
276  continue;
277  }
278  i++;
279  }
280  rz_pvector_insert_range(&io->maps, rz_pvector_len(&io->maps), temp.v.a, rz_pvector_len(&temp));
281  rz_pvector_clear(&temp);
283  return true;
284 }
285 
286 // may fix some inconsistencies in io->maps
288  rz_return_if_fail(io);
289  // remove all maps if no descs exist
290  if (!io->files) {
291  rz_io_map_fini(io);
292  rz_io_map_init(io);
293  return;
294  }
295  bool del = false;
296  size_t i;
297  for (i = 0; i < rz_pvector_len(&io->maps);) {
298  RzIOMap *map = rz_pvector_at(&io->maps, i);
299  if (!map) {
300  // remove iter if the map is a null-ptr, this may fix some segfaults. This should never happen.
302  rz_pvector_remove_at(&io->maps, i);
303  del = true;
304  } else if (!rz_io_desc_get(io, map->fd)) {
305  // delete map and iter if no desc exists for map->fd in io->files
306  map = rz_pvector_remove_at(&io->maps, i);
307  map_del(io, map);
308  del = true;
309  } else {
310  i++;
311  }
312  }
313  if (del) {
315  }
316 }
317 
319  rz_return_if_fail(io);
320  void **it;
321  rz_pvector_foreach (&io->maps, it) {
322  RzIOMap *map = *it;
323  RzEventIOMapDel ev = { map };
325  }
326  rz_pvector_clear(&io->maps);
328  io->map_ids = NULL;
330 }
331 
332 RZ_API void rz_io_map_set_name(RzIOMap *map, const char *name) {
333  if (!map || !name) {
334  return;
335  }
336  free(map->name);
337  map->name = strdup(name);
338 }
339 
341  if (map) {
342  RZ_FREE(map->name);
343  }
344 }
345 
346 // TODO: very similar to rz_io_map_next_address, decide which one to use
348  if (load_align == 0) {
349  load_align = 1;
350  }
351  void **it;
352  ut64 next_addr = addr,
353  end_addr = next_addr + size;
354  rz_pvector_foreach (&io->maps, it) {
355  RzIOMap *map = *it;
356  if (!rz_itv_size(map->itv)) {
357  break;
358  }
359  ut64 to = rz_itv_end(map->itv);
360  next_addr = RZ_MAX(next_addr, to + (load_align - (to % load_align)) % load_align);
361  if ((map->itv.addr <= next_addr && next_addr < to) || rz_itv_contain(map->itv, end_addr)) {
362  next_addr = to + (load_align - (to % load_align)) % load_align;
363  continue;
364  }
365  break;
366  }
367  return next_addr;
368 }
369 
370 // TODO: very similar to rz_io_map_next_available. decide which one to use
372  ut64 lowest = UT64_MAX;
373  void **it;
374  rz_pvector_foreach (&io->maps, it) {
375  RzIOMap *map = *it;
376  ut64 from = rz_itv_begin(map->itv);
377  if (from > addr && addr < lowest) {
378  lowest = from;
379  }
380  ut64 to = rz_itv_end(map->itv);
381  if (to > addr && to < lowest) {
382  lowest = to;
383  }
384  }
385  return lowest;
386 }
387 
388 RZ_API RzList /*<RzIOMap *>*/ *rz_io_map_get_for_fd(RzIO *io, int fd) {
389  RzList *map_list = rz_list_newf(NULL);
390  if (!map_list) {
391  return NULL;
392  }
393  void **it;
394  rz_pvector_foreach (&io->maps, it) {
395  RzIOMap *map = *it;
396  if (map && map->fd == fd) {
397  rz_list_append(map_list, map);
398  }
399  }
400  return map_list;
401 }
402 
403 RZ_API bool rz_io_map_resize(RzIO *io, ut32 id, ut64 newsize) {
404  RzIOMap *map;
405  if (!(map = rz_io_map_resolve(io, id))) {
406  return false;
407  }
408  ut64 addr = map->itv.addr;
409  if (newsize && UT64_MAX - newsize + 1 < addr) {
410  map->itv.size = -addr;
411  rz_io_map_new(io, map->fd, map->perm, map->delta - addr, 0, newsize + addr);
412  return true;
413  }
414  map->itv.size = newsize;
416  return true;
417 }
418 
426  ut64 base = (io->bits == 64) ? 0x60000000000ULL : 0x60000000ULL;
427  return rz_io_map_next_available(io, base, size, 0x200000);
428 }
429 
437  return &io->maps;
438 }
lzma_index ** i
Definition: index.h:629
static RzList * maps(RzBinFile *bf)
Definition: bin_bf.c:116
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
void io_map_calculate_skyline(RzIO *io)
Definition: io_map.c:14
RZ_API RzIOMap * rz_io_map_resolve(RzIO *io, ut32 id)
Definition: io_map.c:128
RZ_API void rz_io_map_cleanup(RzIO *io)
Definition: io_map.c:287
static void map_free(void *p)
Free-only. Be careful to only call this after sending RZ_EVENT_IO_MAP_DEL! (map_del does this)
Definition: io_map.c:84
RZ_API bool rz_io_map_exists_for_id(RzIO *io, ut32 id)
Definition: io_map.c:124
RZ_API void rz_io_map_init(RzIO *io)
Definition: io_map.c:101
RZ_API RzIOMap * rz_io_map_add(RzIO *io, int fd, int perm, ut64 delta, ut64 addr, ut64 size)
Definition: io_map.c:151
#define END_OF_MAP_IDS
Definition: io_map.c:11
RZ_API bool rz_io_map_del_for_fd(RzIO *io, int fd)
Definition: io_map.c:208
RZ_API bool rz_io_map_del(RzIO *io, ut32 id)
Definition: io_map.c:192
RZ_API bool rz_io_map_exists(RzIO *io, RzIOMap *map)
Definition: io_map.c:111
RZ_API void rz_io_map_del_name(RzIOMap *map)
Definition: io_map.c:340
RZ_API bool rz_io_map_remap_fd(RzIO *io, int fd, ut64 addr)
Definition: io_map.c:69
RZ_API bool rz_io_map_depriorize(RzIO *io, ut32 id)
Definition: io_map.c:248
RZ_API ut64 rz_io_map_next_available(RzIO *io, ut64 addr, ut64 size, ut64 load_align)
Definition: io_map.c:347
RZ_API bool rz_io_map_priorize(RzIO *io, ut32 id)
Definition: io_map.c:232
RZ_API ut64 rz_io_map_next_address(RzIO *io, ut64 addr)
Definition: io_map.c:371
RZ_API RzIOMap * rz_io_map_new(RzIO *io, int fd, int perm, ut64 delta, ut64 addr, ut64 size)
Definition: io_map.c:50
RzIOMap * io_map_new(RzIO *io, int fd, int perm, ut64 delta, ut64 addr, ut64 size)
Definition: io_map.c:24
RZ_API RzIOMap * rz_io_map_get_paddr(RzIO *io, ut64 paddr)
Definition: io_map.c:163
RZ_API void rz_io_map_reset(RzIO *io)
Definition: io_map.c:186
RZ_API RzIOMap * rz_io_map_get(RzIO *io, ut64 addr)
Definition: io_map.c:176
RZ_API bool rz_io_map_priorize_for_fd(RzIO *io, int fd)
Definition: io_map.c:264
RZ_API bool rz_io_map_remap(RzIO *io, ut32 id, ut64 addr)
Definition: io_map.c:54
RZ_API RzList * rz_io_map_get_for_fd(RzIO *io, int fd)
Definition: io_map.c:388
RZ_API bool rz_io_map_resize(RzIO *io, ut32 id, ut64 newsize)
Definition: io_map.c:403
RZ_API void rz_io_update(RzIO *io)
Definition: io_map.c:159
RZ_API bool rz_io_map_is_mapped(RzIO *io, ut64 addr)
Definition: io_map.c:181
RZ_API RZ_BORROW RzPVector * rz_io_maps(RzIO *io)
Returns the pointer to vector containing maps list.
Definition: io_map.c:435
static void map_del(RzIO *io, RzIOMap *map)
Free the map, also sending the appropriate event.
Definition: io_map.c:93
RzIOMap * io_map_add(RzIO *io, int fd, int perm, ut64 delta, ut64 addr, ut64 size)
Definition: io_map.c:140
RZ_API void rz_io_map_set_name(RzIOMap *map, const char *name)
Definition: io_map.c:332
RZ_API void rz_io_map_fini(RzIO *io)
Definition: io_map.c:318
RZ_API ut64 rz_io_map_location(RzIO *io, ut64 size)
Returns a memory location that can hold enough bytes without overlapping.
Definition: io_map.c:425
RZ_API RzIOMap * rz_io_map_add_batch(RzIO *io, int fd, int perm, ut64 delta, ut64 addr, ut64 size)
Definition: io_map.c:155
voidpf void uLong size
Definition: ioapi.h:138
void * p
Definition: libc.cpp:67
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 RZ_BORROW void * rz_list_get_n(RZ_NONNULL const RzList *list, ut32 n)
Returns the N-th element of the list.
Definition: list.c:574
RZ_API RZ_BORROW RzListIter * rz_list_append(RZ_NONNULL RzList *list, void *data)
Appends at the end of the list a new element.
Definition: list.c:288
RZ_API void rz_list_free(RZ_NONNULL RzList *list)
Empties the list and frees the list pointer.
Definition: list.c:137
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")
static void del(RzAnalysis *a, RzAnalysisMetaType type, const RzSpace *space, ut64 addr, ut64 size)
Definition: meta.c:155
#define rz_warn_if_reached()
Definition: rz_assert.h:29
#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_MAP_DEL
Definition: rz_event.h:44
RZ_API RzIDPool * rz_id_pool_new(ut32 start_id, ut32 last_id)
Definition: idpool.c:22
RZ_API bool rz_id_pool_grab_id(RzIDPool *pool, ut32 *grabber)
Definition: idpool.c:34
RZ_API void rz_id_pool_free(RzIDPool *pool)
Definition: idpool.c:72
RZ_API bool rz_id_pool_kick_id(RzIDPool *pool, ut32 kick)
Definition: idpool.c:53
RZ_API RzIODesc * rz_io_desc_get(RzIO *io, int fd)
Definition: io_desc.c:73
static ut64 rz_itv_begin(RzInterval itv)
Definition: rz_itv.h:34
static bool rz_itv_contain(RzInterval itv, ut64 addr)
Definition: rz_itv.h:52
struct rz_interval_t RzInterval
static ut64 rz_itv_end(RzInterval itv)
Definition: rz_itv.h:42
static ut64 rz_itv_size(RzInterval itv)
Definition: rz_itv.h:38
static void * rz_skyline_get(RzSkyline *skyline, ut64 addr)
Definition: rz_skyline.h:39
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 RZ_PERM_X
Definition: rz_types.h:95
#define RZ_FREE(x)
Definition: rz_types.h:369
#define RZ_BORROW
Definition: rz_types.h:63
#define st64
Definition: rz_types_base.h:10
#define RZ_MAX(x, y)
#define UT64_MAX
Definition: rz_types_base.h:86
static void ** rz_pvector_insert_range(RzPVector *vec, size_t index, void **first, size_t count)
Definition: rz_vector.h:289
static void ** rz_pvector_push_front(RzPVector *vec, void *x)
Definition: rz_vector.h:305
RZ_API void rz_pvector_init(RzPVector *vec, RzPVectorFree free)
Definition: vector.c:298
static size_t rz_pvector_len(const RzPVector *vec)
Definition: rz_vector.h:231
#define rz_pvector_foreach_prev(vec, it)
Definition: rz_vector.h:338
RZ_API void * rz_pvector_remove_at(RzPVector *vec, size_t index)
Definition: vector.c:355
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
static void * rz_pvector_at(const RzPVector *vec, size_t index)
Definition: rz_vector.h:236
#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
Definition: z80asm.h:102
Definition: rz_io.h:59
RzPVector maps
Definition: rz_io.h:73
RzEvent * event
Definition: rz_io.h:90
RzIDPool * map_ids
Definition: rz_io.h:72
RzIDStorage * files
Definition: rz_io.h:75
RzSkyline map_skyline
Definition: rz_io.h:74
int bits
Definition: rz_io.h:62
RzVector v
Definition: rz_vector.h:56
void * a
Definition: rz_vector.h:46
static st64 delta
Definition: vmenus.c:2425
ut64(WINAPI *w32_GetEnabledXStateFeatures)()
static const z80_opcode fd[]
Definition: z80_tab.h:997
static int addr
Definition: z80asm.c:58