2017-08-27 09:05:58 -07:00
|
|
|
/* radare2 - LGPL - Copyright 2017 - condret, MaskRay */
|
2009-02-05 22:08:46 +01:00
|
|
|
|
2017-08-22 07:42:16 +00:00
|
|
|
#include <stdlib.h>
|
2017-08-27 09:05:58 -07:00
|
|
|
#include <sdb.h>
|
|
|
|
#include "r_binheap.h"
|
|
|
|
#include "r_io.h"
|
|
|
|
#include "r_util.h"
|
|
|
|
#include "r_vector.h"
|
2009-02-05 22:08:46 +01:00
|
|
|
|
2017-08-22 07:42:16 +00:00
|
|
|
#define END_OF_MAP_IDS 0xffffffff
|
2014-01-25 18:06:17 -06:00
|
|
|
|
2017-08-27 09:05:58 -07:00
|
|
|
#define MAP_USE_HALF_CLOSED 0
|
|
|
|
|
|
|
|
struct map_event_t {
|
|
|
|
RIOMap *map;
|
|
|
|
ut64 addr;
|
|
|
|
int id; // distinct priority in [0, len(maps))
|
|
|
|
bool is_to;
|
|
|
|
};
|
|
|
|
|
|
|
|
// Sort by address, (addr, !is_to) precedes (addr, is_to)
|
|
|
|
static int _cmp_map_event(const void *a_, const void *b_) {
|
|
|
|
struct map_event_t *a = (void *)a_, *b = (void *)b_;
|
|
|
|
if (a->addr != b->addr) {
|
|
|
|
return a->addr < b->addr ? -1 : 1;
|
|
|
|
}
|
|
|
|
return a->is_to - b->is_to; // TODO swap if half-closed
|
|
|
|
}
|
|
|
|
|
|
|
|
static int _cmp_map_event_by_id(const void *a_, const void *b_) {
|
|
|
|
struct map_event_t *a = (void *)a_, *b = (void *)b_;
|
|
|
|
return a->id - b->id;
|
|
|
|
}
|
|
|
|
|
|
|
|
static bool _map_skyline_push(RVector *map_skyline, ut64 from, ut64 to, RIOMap *map) {
|
|
|
|
RIOMapSkyline *part = R_NEW (RIOMapSkyline);
|
|
|
|
if (!part) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
part->map = map;
|
|
|
|
part->from = from;
|
|
|
|
part->to = to - 1; // TODO half-closed
|
|
|
|
return r_vector_push (map_skyline, part);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Store map parts that are not covered by others into io->map_skyline
|
|
|
|
static void _calculate_skyline(RIO *io) {
|
|
|
|
#if MAP_USE_HALF_CLOSED
|
|
|
|
# error Please migrate to half-closed
|
|
|
|
#endif
|
|
|
|
#define PUSH
|
|
|
|
SdbListIter *iter;
|
|
|
|
RIOMap *map;
|
|
|
|
RVector events = {0};
|
|
|
|
RBinHeap heap;
|
|
|
|
struct map_event_t *ev;
|
|
|
|
bool *deleted = NULL;
|
|
|
|
r_vector_clear (&io->map_skyline, free);
|
|
|
|
if (!r_vector_reserve (&events, ls_length (io->maps) * 2) ||
|
|
|
|
!(deleted = calloc (ls_length (io->maps), 1))) {
|
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
|
|
|
|
int i = 0;
|
|
|
|
ls_foreach (io->maps, iter, map) {
|
|
|
|
if (!(ev = R_NEW (struct map_event_t))) {
|
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
ev->map = map;
|
|
|
|
ev->addr = map->from;
|
|
|
|
ev->is_to = false;
|
|
|
|
ev->id = i;
|
|
|
|
r_vector_push (&events, ev);
|
|
|
|
if (!(ev = R_NEW (struct map_event_t))) {
|
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
ev->map = map;
|
|
|
|
ev->addr = map->to;
|
|
|
|
ev->is_to = true;
|
|
|
|
ev->id = i;
|
|
|
|
r_vector_push (&events, ev);
|
|
|
|
i++;
|
|
|
|
}
|
|
|
|
r_vector_sort (&events, _cmp_map_event);
|
|
|
|
|
|
|
|
r_binheap_init (&heap, _cmp_map_event_by_id);
|
|
|
|
ut64 last;
|
|
|
|
RIOMap *last_map = NULL;
|
|
|
|
for (i = 0; i < events.len; i++) {
|
|
|
|
ev = events.a[i];
|
|
|
|
if (ev->is_to) {
|
|
|
|
deleted[ev->id] = true;
|
|
|
|
} else {
|
|
|
|
r_binheap_push (&heap, ev);
|
|
|
|
}
|
|
|
|
while (!r_binheap_empty (&heap) && deleted[((struct map_event_t *)r_binheap_top (&heap))->id]) {
|
|
|
|
r_binheap_pop (&heap);
|
|
|
|
}
|
|
|
|
ut64 to = ev->addr + ev->is_to; // TODO half-closed
|
|
|
|
map = r_binheap_empty (&heap) ? NULL : ((struct map_event_t *)r_binheap_top (&heap))->map;
|
|
|
|
if (!i) {
|
|
|
|
last = to;
|
|
|
|
last_map = map;
|
|
|
|
} else if (last != to || (!to && ev->is_to)) {
|
|
|
|
if (last_map != map) {
|
|
|
|
if (last_map && !_map_skyline_push (&io->map_skyline, last, to, last_map)) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
last = to;
|
|
|
|
last_map = map;
|
|
|
|
}
|
|
|
|
if (!to && ev->is_to) {
|
|
|
|
if (map) {
|
|
|
|
(void)_map_skyline_push (&io->map_skyline, last, to, map);
|
|
|
|
}
|
|
|
|
// This is a to == 2**64 event. There are no more skyline parts.
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
} else if (map && (!last_map || map->id > last_map->id)) {
|
|
|
|
last_map = map;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
out:
|
|
|
|
r_binheap_clear (&heap, NULL);
|
|
|
|
r_vector_clear (&events, free);
|
|
|
|
free (deleted);
|
|
|
|
}
|
|
|
|
|
2017-08-22 07:42:16 +00:00
|
|
|
R_API RIOMap* r_io_map_new(RIO* io, int fd, int flags, ut64 delta, ut64 addr, ut64 size) {
|
2017-08-27 00:39:34 +00:00
|
|
|
if (!size || !io || !io->maps || !io->map_ids) {
|
2017-08-22 07:42:16 +00:00
|
|
|
return NULL;
|
|
|
|
}
|
2017-08-26 23:29:30 +02:00
|
|
|
RIOMap* map = R_NEW0 (RIOMap);
|
2017-08-22 07:42:16 +00:00
|
|
|
if (!map || !io->map_ids || !r_id_pool_grab_id (io->map_ids, &map->id)) {
|
2015-04-10 13:11:18 +02:00
|
|
|
free (map);
|
|
|
|
return NULL;
|
|
|
|
}
|
2014-01-25 18:06:17 -06:00
|
|
|
map->fd = fd;
|
2017-08-22 07:42:16 +00:00
|
|
|
map->from = addr;
|
2017-08-27 00:39:34 +00:00
|
|
|
map->delta = delta;
|
|
|
|
if ((UT64_MAX - size + 1) < addr) {
|
|
|
|
r_io_map_new (io, fd, flags, UT64_MAX - addr + 1 + delta, 0LL, size - (UT64_MAX - addr) - 1);
|
|
|
|
size = UT64_MAX - addr + 1;
|
|
|
|
}
|
2017-08-22 07:42:16 +00:00
|
|
|
// RIOMap describes an interval of addresses (map->from; map->to)
|
2017-08-22 14:52:40 +00:00
|
|
|
map->to = addr + size - 1;
|
2014-01-25 18:06:17 -06:00
|
|
|
map->flags = flags;
|
|
|
|
map->delta = delta;
|
2017-08-22 07:42:16 +00:00
|
|
|
// new map lives on the top, being top the list's tail
|
2017-05-03 17:19:49 +02:00
|
|
|
ls_append (io->maps, map);
|
2017-08-27 09:05:58 -07:00
|
|
|
// TODO When maps are added in batch (sections), do not recalculate each time
|
|
|
|
_calculate_skyline (io);
|
2014-01-25 18:06:17 -06:00
|
|
|
return map;
|
|
|
|
}
|
|
|
|
|
2017-08-27 04:10:45 +00:00
|
|
|
R_API bool r_io_map_remap (RIO *io, ut32 id, ut64 addr) {
|
|
|
|
RIOMap *map;
|
|
|
|
ut64 size;
|
|
|
|
if (!(map = r_io_map_resolve (io, id))) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
size = map->to - map->from + 1;
|
|
|
|
map->from = addr;
|
|
|
|
if ((UT64_MAX - size + 1) < addr) {
|
|
|
|
r_io_map_new (io, map->fd, map->flags, UT64_MAX - addr + 1 + map->delta, 0LL, size - (UT64_MAX - addr) - 1);
|
|
|
|
size = UT64_MAX - addr + 1;
|
|
|
|
map->to = UT64_MAX;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
map->to = addr + size - 1;
|
2017-08-27 09:05:58 -07:00
|
|
|
_calculate_skyline (io);
|
2017-08-27 04:10:45 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2017-08-22 07:42:16 +00:00
|
|
|
static void _map_free(void* p) {
|
|
|
|
RIOMap* map = (RIOMap*) p;
|
|
|
|
if (map) {
|
|
|
|
free (map->name);
|
|
|
|
free (map);
|
|
|
|
}
|
2009-02-05 22:08:46 +01:00
|
|
|
}
|
|
|
|
|
2017-08-22 07:42:16 +00:00
|
|
|
R_API void r_io_map_init(RIO* io) {
|
|
|
|
if (io && !io->maps) {
|
|
|
|
io->maps = ls_newf ((SdbListFree)_map_free);
|
|
|
|
if (io->map_ids) {
|
|
|
|
r_id_pool_free (io->map_ids);
|
|
|
|
}
|
|
|
|
io->map_ids = r_id_pool_new (1, END_OF_MAP_IDS);
|
2014-01-25 18:06:17 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-08-22 07:42:16 +00:00
|
|
|
// check if a map with exact the same properties exists
|
|
|
|
R_API bool r_io_map_exists(RIO* io, RIOMap* map) {
|
|
|
|
SdbListIter* iter;
|
|
|
|
RIOMap* m;
|
|
|
|
if (!io || !io->maps || !map) {
|
|
|
|
return false;
|
2014-05-22 01:58:03 -05:00
|
|
|
}
|
2017-08-22 07:42:16 +00:00
|
|
|
ls_foreach (io->maps, iter, m) {
|
|
|
|
if (!memcmp (m, map, sizeof (RIOMap))) {
|
|
|
|
return true;
|
|
|
|
}
|
2014-05-22 01:58:03 -05:00
|
|
|
}
|
2017-08-22 07:42:16 +00:00
|
|
|
return false;
|
2014-05-22 01:58:03 -05:00
|
|
|
}
|
|
|
|
|
2017-08-22 07:42:16 +00:00
|
|
|
// check if a map with specified id exists
|
|
|
|
R_API bool r_io_map_exists_for_id(RIO* io, ut32 id) {
|
|
|
|
return r_io_map_resolve (io, id) != NULL;
|
2014-05-22 01:58:03 -05:00
|
|
|
}
|
2014-01-25 18:06:17 -06:00
|
|
|
|
2017-08-22 07:42:16 +00:00
|
|
|
R_API RIOMap* r_io_map_resolve(RIO* io, ut32 id) {
|
|
|
|
SdbListIter* iter;
|
|
|
|
RIOMap* map;
|
|
|
|
if (!io || !io->maps || !id) {
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
ls_foreach (io->maps, iter, map) {
|
|
|
|
if (map->id == id) {
|
2015-12-07 22:35:34 +01:00
|
|
|
return map;
|
|
|
|
}
|
2012-10-25 09:48:45 +02:00
|
|
|
}
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2017-08-22 07:42:16 +00:00
|
|
|
R_API RIOMap* r_io_map_add(RIO* io, int fd, int flags, ut64 delta, ut64 addr, ut64 size) {
|
|
|
|
//check if desc exists
|
|
|
|
RIODesc* desc = r_io_desc_get (io, fd);
|
|
|
|
if (desc) {
|
2017-08-26 23:29:30 +02:00
|
|
|
SdbListIter* iter;
|
|
|
|
RIOMap* map;
|
|
|
|
ls_foreach (io->maps, iter, map) {
|
|
|
|
if (map->fd == fd && map->from == addr) {
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
}
|
2017-08-22 07:42:16 +00:00
|
|
|
//a map cannot have higher permissions than the desc belonging to it
|
|
|
|
return r_io_map_new (io, fd, (flags & desc->flags) | (flags & R_IO_EXEC),
|
|
|
|
delta, addr, size);
|
2009-09-05 23:58:02 +00:00
|
|
|
}
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2017-08-22 07:42:16 +00:00
|
|
|
// gets first map where addr fits in
|
|
|
|
R_API RIOMap* r_io_map_get(RIO* io, ut64 addr) {
|
|
|
|
RIOMap* map;
|
|
|
|
SdbListIter* iter;
|
2017-08-26 23:29:30 +02:00
|
|
|
if (!io) {
|
2017-08-22 07:42:16 +00:00
|
|
|
return NULL;
|
2014-09-04 15:47:52 +02:00
|
|
|
}
|
2017-05-03 17:19:49 +02:00
|
|
|
ls_foreach_prev (io->maps, iter, map) {
|
2017-08-22 14:52:40 +00:00
|
|
|
if ((map->from <= addr) && (map->to >= addr)) {
|
2017-08-22 07:42:16 +00:00
|
|
|
return map;
|
|
|
|
}
|
2014-09-05 11:32:25 +02:00
|
|
|
}
|
2017-08-22 07:42:16 +00:00
|
|
|
return NULL;
|
2014-09-05 11:32:25 +02:00
|
|
|
}
|
|
|
|
|
2017-08-22 07:42:16 +00:00
|
|
|
R_API bool r_io_map_del(RIO* io, ut32 id) {
|
|
|
|
SdbListIter* iter;
|
|
|
|
RIOMap* map;
|
2017-08-26 23:29:30 +02:00
|
|
|
if (!io) {
|
2017-08-22 07:42:16 +00:00
|
|
|
return false;
|
2016-10-26 23:40:17 +02:00
|
|
|
}
|
2017-08-22 07:42:16 +00:00
|
|
|
ls_foreach (io->maps, iter, map) {
|
|
|
|
if (map->id == id) {
|
|
|
|
ls_delete (io->maps, iter);
|
|
|
|
r_id_pool_kick_id (io->map_ids, id);
|
2017-08-27 09:05:58 -07:00
|
|
|
_calculate_skyline (io);
|
2017-08-22 07:42:16 +00:00
|
|
|
return true;
|
|
|
|
}
|
2014-01-25 18:06:17 -06:00
|
|
|
}
|
2017-08-22 07:42:16 +00:00
|
|
|
return false;
|
2014-01-25 18:06:17 -06:00
|
|
|
}
|
|
|
|
|
2017-08-22 07:42:16 +00:00
|
|
|
//delete all maps with specified fd
|
|
|
|
R_API bool r_io_map_del_for_fd(RIO* io, int fd) {
|
|
|
|
SdbListIter* iter, * ator;
|
|
|
|
RIOMap* map;
|
|
|
|
bool ret = false;
|
2017-08-26 23:29:30 +02:00
|
|
|
if (!io) {
|
2017-08-22 07:42:16 +00:00
|
|
|
return ret;
|
2014-05-22 01:58:03 -05:00
|
|
|
}
|
2017-08-22 07:42:16 +00:00
|
|
|
ls_foreach_safe (io->maps, iter, ator, map) {
|
|
|
|
if (!map) {
|
|
|
|
ls_delete (io->maps, iter);
|
|
|
|
} else if (map->fd == fd) {
|
|
|
|
r_id_pool_kick_id (io->map_ids, map->id);
|
|
|
|
//delete iter and map
|
|
|
|
ls_delete (io->maps, iter);
|
|
|
|
ret = true;
|
2014-04-23 18:04:25 -05:00
|
|
|
}
|
|
|
|
}
|
2017-08-27 09:05:58 -07:00
|
|
|
if (ret) {
|
|
|
|
_calculate_skyline (io);
|
|
|
|
}
|
2017-08-22 07:42:16 +00:00
|
|
|
return ret;
|
2014-04-23 18:04:25 -05:00
|
|
|
}
|
|
|
|
|
2017-08-22 07:42:16 +00:00
|
|
|
//brings map with specified id to the tail of of the list
|
|
|
|
//return a boolean denoting whether is was possible to priorized
|
|
|
|
R_API bool r_io_map_priorize(RIO* io, ut32 id) {
|
|
|
|
SdbListIter* iter;
|
|
|
|
RIOMap* map;
|
2017-08-26 23:29:30 +02:00
|
|
|
if (!io) {
|
2017-08-22 07:42:16 +00:00
|
|
|
return false;
|
2012-10-25 12:55:28 +02:00
|
|
|
}
|
2017-08-22 07:42:16 +00:00
|
|
|
ls_foreach (io->maps, iter, map) {
|
|
|
|
//search for iter with the correct map
|
|
|
|
if (map->id == id) {
|
|
|
|
ls_split_iter (io->maps, iter);
|
|
|
|
ls_append (io->maps, map);
|
2017-08-27 09:05:58 -07:00
|
|
|
_calculate_skyline (io);
|
2015-09-14 02:08:31 +02:00
|
|
|
return true;
|
2012-02-07 01:51:56 +01:00
|
|
|
}
|
|
|
|
}
|
2015-09-14 02:08:31 +02:00
|
|
|
return false;
|
2012-02-07 01:51:56 +01:00
|
|
|
}
|
|
|
|
|
2017-08-22 07:42:16 +00:00
|
|
|
R_API bool r_io_map_priorize_for_fd(RIO* io, int fd) {
|
|
|
|
SdbListIter* iter, * ator;
|
2012-10-25 12:55:28 +02:00
|
|
|
RIOMap *map;
|
2017-08-22 07:42:16 +00:00
|
|
|
SdbList* list;
|
|
|
|
if (!io || !io->maps) {
|
|
|
|
return false;
|
2017-08-18 20:03:29 +02:00
|
|
|
}
|
2017-08-22 07:42:16 +00:00
|
|
|
if (!(list = ls_new ())) {
|
|
|
|
return false;
|
2012-10-25 12:55:28 +02:00
|
|
|
}
|
2017-08-22 07:42:16 +00:00
|
|
|
//we need a clean list for this, or this becomes a segfault-field
|
|
|
|
r_io_map_cleanup (io);
|
|
|
|
//tempory set to avoid free the map and to speed up ls_delete a bit
|
|
|
|
io->maps->free = NULL;
|
|
|
|
ls_foreach_safe (io->maps, iter, ator, map) {
|
|
|
|
if (map->fd == fd) {
|
|
|
|
ls_prepend (list, map);
|
|
|
|
ls_delete (io->maps, iter);
|
2014-05-22 01:58:03 -05:00
|
|
|
}
|
|
|
|
}
|
2017-08-22 16:09:45 -07:00
|
|
|
ls_join (io->maps, list);
|
2017-08-22 07:42:16 +00:00
|
|
|
ls_free (list);
|
|
|
|
io->maps->free = _map_free;
|
2017-08-27 09:05:58 -07:00
|
|
|
_calculate_skyline (io);
|
2017-08-22 07:42:16 +00:00
|
|
|
return true;
|
2014-05-22 01:58:03 -05:00
|
|
|
}
|
2009-02-05 22:08:46 +01:00
|
|
|
|
2017-08-22 07:42:16 +00:00
|
|
|
|
|
|
|
//may fix some inconsistencies in io->maps
|
|
|
|
R_API void r_io_map_cleanup(RIO* io) {
|
|
|
|
SdbListIter* iter, * ator;
|
|
|
|
RIOMap* map;
|
|
|
|
if (!io || !io->maps) {
|
|
|
|
return;
|
2017-08-08 18:00:39 +02:00
|
|
|
}
|
2017-08-22 07:42:16 +00:00
|
|
|
//remove all maps if no descs exist
|
|
|
|
if (!io->files) {
|
|
|
|
r_io_map_fini (io);
|
|
|
|
r_io_map_init (io);
|
|
|
|
return;
|
|
|
|
}
|
2017-08-27 09:05:58 -07:00
|
|
|
bool del = false;
|
2017-08-22 07:42:16 +00:00
|
|
|
ls_foreach_safe (io->maps, iter, ator, map) {
|
|
|
|
//remove iter if the map is a null-ptr, this may fix some segfaults
|
|
|
|
if (!map) {
|
|
|
|
ls_delete (io->maps, iter);
|
2017-08-27 09:05:58 -07:00
|
|
|
del = true;
|
2017-08-22 07:42:16 +00:00
|
|
|
} else if (!r_io_desc_get (io, map->fd)) {
|
|
|
|
//delete map and iter if no desc exists for map->fd in io->files
|
|
|
|
r_id_pool_kick_id (io->map_ids, map->id);
|
|
|
|
ls_delete (io->maps, iter);
|
2017-08-27 09:05:58 -07:00
|
|
|
del = true;
|
2009-02-05 22:08:46 +01:00
|
|
|
}
|
|
|
|
}
|
2017-08-27 09:05:58 -07:00
|
|
|
if (del) {
|
|
|
|
_calculate_skyline (io);
|
|
|
|
}
|
2017-05-03 17:19:49 +02:00
|
|
|
}
|
|
|
|
|
2017-08-22 07:42:16 +00:00
|
|
|
R_API void r_io_map_fini(RIO* io) {
|
|
|
|
if (!io) {
|
|
|
|
return;
|
2012-08-13 04:33:01 +02:00
|
|
|
}
|
2017-08-22 07:42:16 +00:00
|
|
|
ls_free (io->maps);
|
|
|
|
io->maps = NULL;
|
|
|
|
r_id_pool_free (io->map_ids);
|
|
|
|
io->map_ids = NULL;
|
2017-08-27 09:05:58 -07:00
|
|
|
r_vector_clear (&io->map_skyline, free);
|
2009-02-05 22:08:46 +01:00
|
|
|
}
|
2014-04-23 18:04:25 -05:00
|
|
|
|
2017-08-22 07:42:16 +00:00
|
|
|
R_API void r_io_map_set_name(RIOMap* map, const char* name) {
|
|
|
|
if (!map || !name) {
|
|
|
|
return;
|
2016-06-30 23:38:08 +02:00
|
|
|
}
|
2017-08-22 07:42:16 +00:00
|
|
|
free (map->name);
|
|
|
|
map->name = strdup (name);
|
2014-04-23 18:04:25 -05:00
|
|
|
}
|
2014-10-07 03:07:45 +02:00
|
|
|
|
2017-08-22 07:42:16 +00:00
|
|
|
R_API void r_io_map_del_name(RIOMap* map) {
|
|
|
|
if (map) {
|
|
|
|
R_FREE (map->name);
|
2014-10-07 03:07:45 +02:00
|
|
|
}
|
|
|
|
}
|
2014-10-22 11:01:51 +02:00
|
|
|
|
2017-08-23 13:48:35 +00:00
|
|
|
R_API bool r_io_map_is_in_range(RIOMap* map, ut64 from, ut64 to) { //rename pls
|
|
|
|
if (!map || (to < from)) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
if (R_BETWEEN (map->from, from, map->to)) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
if (R_BETWEEN (map->from, to, map->to)) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
if (map->from > from && to > map->to) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2017-08-22 07:42:16 +00:00
|
|
|
//TODO: Kill it with fire
|
|
|
|
R_API RIOMap* r_io_map_add_next_available(RIO* io, int fd, int flags, ut64 delta, ut64 addr, ut64 size, ut64 load_align) {
|
|
|
|
RIOMap* map;
|
|
|
|
SdbListIter* iter;
|
|
|
|
ut64 next_addr = addr,
|
|
|
|
end_addr = next_addr + size;
|
|
|
|
ls_foreach (io->maps, iter, map) {
|
2017-08-22 16:09:45 -07:00
|
|
|
next_addr = R_MAX (next_addr, map->to + (load_align - (map->to % load_align)) % load_align);
|
2017-08-22 07:42:16 +00:00
|
|
|
// XXX - This does not handle when file overflow 0xFFFFFFFF000 -> 0x00000FFF
|
|
|
|
// adding the check for the map's fd to see if this removes contention for
|
|
|
|
// memory mapping with multiple files.
|
|
|
|
|
|
|
|
if (map->fd == fd && ((map->from <= next_addr && next_addr < map->to) ||
|
|
|
|
(map->from <= end_addr && end_addr < map->to))) {
|
|
|
|
//return r_io_map_add(io, fd, flags, delta, map->to, size);
|
2017-08-22 16:09:45 -07:00
|
|
|
next_addr = map->to + (load_align - (map->to % load_align)) % load_align;
|
2017-08-22 07:42:16 +00:00
|
|
|
return r_io_map_add_next_available (io, fd, flags, delta, next_addr, size, load_align);
|
|
|
|
} else {
|
|
|
|
break;
|
2014-10-22 11:01:51 +02:00
|
|
|
}
|
|
|
|
}
|
2017-08-22 07:42:16 +00:00
|
|
|
return r_io_map_new (io, fd, flags, delta, next_addr, size);
|
2014-10-22 11:01:51 +02:00
|
|
|
}
|