mirror of
https://github.com/radareorg/radare2.git
synced 2024-11-27 15:10:53 +00:00
Use RPVector for io->maps - speedup map traversal ##io
- The 64K section bin now loads in 15s instead of 26s
This commit is contained in:
parent
88ad1ccd4a
commit
9a2effd5ed
@ -848,9 +848,8 @@ static RList* patch_relocs(RBin *b) {
|
||||
RIO *io = NULL;
|
||||
RBinObject *obj = NULL;
|
||||
struct Elf_(r_bin_elf_obj_t) *bin = NULL;
|
||||
RIOMap *g = NULL, *s = NULL;
|
||||
RIOMap *g = NULL;
|
||||
HtUU *relocs_by_sym;
|
||||
SdbListIter *iter;
|
||||
RBinElfReloc *relcs = NULL;
|
||||
RBinInfo *info;
|
||||
int cdsz;
|
||||
@ -878,10 +877,12 @@ static RList* patch_relocs(RBin *b) {
|
||||
info = obj ? obj->info: NULL;
|
||||
cdsz = info? (info->bits == 64? 8: info->bits == 32? 4: info->bits == 16 ? 4: 0): 0;
|
||||
|
||||
ls_foreach (io->maps, iter, s) {
|
||||
if (s->itv.addr > offset) {
|
||||
offset = s->itv.addr;
|
||||
g = s;
|
||||
void **it;
|
||||
r_pvector_foreach (&io->maps, it) {
|
||||
RIOMap *map = *it;
|
||||
if (map->itv.addr > offset) {
|
||||
offset = map->itv.addr;
|
||||
g = map;
|
||||
}
|
||||
}
|
||||
if (!g) {
|
||||
|
@ -556,7 +556,7 @@ static RList* patch_relocs(RBin *b) {
|
||||
RIO *io = NULL;
|
||||
RBinObject *obj = NULL;
|
||||
struct MACH0_(obj_t) *bin = NULL;
|
||||
RIOMap *g = NULL, *s = NULL;
|
||||
RIOMap *g = NULL;
|
||||
HtUU *relocs_by_sym = NULL;
|
||||
RIODesc *gotr2desc = NULL;
|
||||
|
||||
@ -600,12 +600,13 @@ static RList* patch_relocs(RBin *b) {
|
||||
|
||||
int cdsz = obj->info ? obj->info->bits / 8 : 8;
|
||||
|
||||
SdbListIter *iter;
|
||||
ut64 offset = 0;
|
||||
ls_foreach (io->maps, iter, s) {
|
||||
if (s->itv.addr > offset) {
|
||||
offset = s->itv.addr;
|
||||
g = s;
|
||||
void **vit;
|
||||
r_pvector_foreach (&io->maps, vit) {
|
||||
RIOMap *map = *vit;
|
||||
if (map->itv.addr > offset) {
|
||||
offset = map->itv.addr;
|
||||
g = map;
|
||||
}
|
||||
}
|
||||
if (!g) {
|
||||
|
@ -288,11 +288,11 @@ R_API ut64 r_core_anal_address(RCore *core, ut64 addr) {
|
||||
}
|
||||
} else {
|
||||
int _perm = -1;
|
||||
RIOMap *s;
|
||||
SdbListIter *iter;
|
||||
if (core->io) {
|
||||
// sections
|
||||
ls_foreach (core->io->maps, iter, s) {
|
||||
void **it;
|
||||
r_pvector_foreach (&core->io->maps, it) {
|
||||
RIOMap *s = *it;
|
||||
if (addr >= s->itv.addr && addr < (s->itv.addr + s->itv.size)) {
|
||||
// sections overlap, so we want to get the one with lower perms
|
||||
_perm = (_perm != -1) ? R_MIN (_perm, s->perm) : s->perm;
|
||||
|
@ -8576,13 +8576,13 @@ static const char *oldstr = NULL;
|
||||
|
||||
static int compute_coverage(RCore *core) {
|
||||
RListIter *iter;
|
||||
SdbListIter *iter2;
|
||||
RAnalFunction *fcn;
|
||||
RIOMap *map;
|
||||
int cov = 0;
|
||||
cov += r_meta_get_size(core->anal, R_META_TYPE_DATA);
|
||||
r_list_foreach (core->anal->fcns, iter, fcn) {
|
||||
ls_foreach (core->io->maps, iter2, map) {
|
||||
void **it;
|
||||
r_pvector_foreach (&core->io->maps, it) {
|
||||
RIOMap *map = *it;
|
||||
if (map->perm & R_PERM_X) {
|
||||
ut64 section_end = map->itv.addr + map->itv.size;
|
||||
ut64 s = r_anal_function_realsize (fcn);
|
||||
@ -8597,9 +8597,9 @@ static int compute_coverage(RCore *core) {
|
||||
|
||||
static int compute_code (RCore* core) {
|
||||
int code = 0;
|
||||
SdbListIter *iter;
|
||||
RIOMap *map;
|
||||
ls_foreach (core->io->maps, iter, map) {
|
||||
void **it;
|
||||
r_pvector_foreach (&core->io->maps, it) {
|
||||
RIOMap *map = *it;
|
||||
if (map->perm & R_PERM_X) {
|
||||
code += map->itv.size;
|
||||
}
|
||||
|
@ -393,9 +393,7 @@ static void cmd_open_bin(RCore *core, const char *input) {
|
||||
|
||||
// TODO: discuss the output format
|
||||
static void map_list(RIO *io, int mode, RPrint *print, int fd) {
|
||||
SdbListIter *iter;
|
||||
RIOMap *map;
|
||||
if (!io || !io->maps || !print || !print->cb_printf) {
|
||||
if (!io || !print || !print->cb_printf) {
|
||||
return;
|
||||
}
|
||||
if (mode == 'j') {
|
||||
@ -403,7 +401,10 @@ static void map_list(RIO *io, int mode, RPrint *print, int fd) {
|
||||
}
|
||||
bool first = true;
|
||||
char *om_cmds = NULL;
|
||||
ls_foreach_prev (io->maps, iter, map) { //this must be prev (LIFO)
|
||||
|
||||
void **it;
|
||||
r_pvector_foreach_prev (&io->maps, it) { //this must be prev (LIFO)
|
||||
RIOMap *map = *it;
|
||||
if (fd >= 0 && map->fd != fd) {
|
||||
continue;
|
||||
}
|
||||
@ -456,8 +457,6 @@ static void map_list(RIO *io, int mode, RPrint *print, int fd) {
|
||||
}
|
||||
|
||||
static void cmd_omfg(RCore *core, const char *input) {
|
||||
SdbListIter *iter;
|
||||
RIOMap *map;
|
||||
input = r_str_trim_head_ro (input);
|
||||
if (input) {
|
||||
int perm = *input
|
||||
@ -465,19 +464,23 @@ static void cmd_omfg(RCore *core, const char *input) {
|
||||
? r_str_rwx (input + 1)
|
||||
: r_str_rwx (input)
|
||||
: 7;
|
||||
void **it;
|
||||
switch (*input) {
|
||||
case '+':
|
||||
ls_foreach (core->io->maps, iter, map) {
|
||||
r_pvector_foreach (&core->io->maps, it) {
|
||||
RIOMap *map = *it;
|
||||
map->perm |= perm;
|
||||
}
|
||||
break;
|
||||
case '-':
|
||||
ls_foreach (core->io->maps, iter, map) {
|
||||
r_pvector_foreach (&core->io->maps, it) {
|
||||
RIOMap *map = *it;
|
||||
map->perm &= ~perm;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
ls_foreach (core->io->maps, iter, map) {
|
||||
r_pvector_foreach (&core->io->maps, it) {
|
||||
RIOMap *map = *it;
|
||||
map->perm = perm;
|
||||
}
|
||||
break;
|
||||
@ -486,8 +489,6 @@ static void cmd_omfg(RCore *core, const char *input) {
|
||||
}
|
||||
|
||||
static void cmd_omf(RCore *core, const char *input) {
|
||||
SdbListIter *iter;
|
||||
RIOMap *map;
|
||||
char *arg = strdup (r_str_trim_head_ro (input));
|
||||
if (!arg) {
|
||||
return;
|
||||
@ -498,7 +499,9 @@ static void cmd_omf(RCore *core, const char *input) {
|
||||
*sp++ = 0;
|
||||
int id = r_num_math (core->num, arg);
|
||||
int perm = (*sp)? r_str_rwx (sp): R_PERM_RWX;
|
||||
ls_foreach (core->io->maps, iter, map) {
|
||||
void **it;
|
||||
r_pvector_foreach (&core->io->maps, it) {
|
||||
RIOMap *map = *it;
|
||||
if (map->id == id) {
|
||||
map->perm = perm;
|
||||
break;
|
||||
@ -507,7 +510,9 @@ static void cmd_omf(RCore *core, const char *input) {
|
||||
} else {
|
||||
// change perms of current map
|
||||
int perm = (arg && *arg)? r_str_rwx (arg): R_PERM_RWX;
|
||||
ls_foreach (core->io->maps, iter, map) {
|
||||
void **it;
|
||||
r_pvector_foreach (&core->io->maps, it) {
|
||||
RIOMap *map = *it;
|
||||
if (r_itv_contain (map->itv, core->offset)) {
|
||||
map->perm = perm;
|
||||
}
|
||||
@ -521,9 +526,9 @@ static void r_core_cmd_omt(RCore *core, const char *arg) {
|
||||
|
||||
r_table_set_columnsf (t, "nnnnnnnss", "id", "fd", "pa", "pa_end", "size", "va", "va_end", "perm", "name", NULL);
|
||||
|
||||
SdbListIter *iter;
|
||||
RIOMap *m;
|
||||
ls_foreach_prev (core->io->maps, iter, m) {
|
||||
void **it;
|
||||
r_pvector_foreach (&core->io->maps, it) {
|
||||
RIOMap *m = *it;
|
||||
ut64 va = r_itv_begin (m->itv);
|
||||
ut64 va_end = r_itv_end (m->itv);
|
||||
ut64 pa = m->delta;
|
||||
@ -813,9 +818,9 @@ static void cmd_open_map(RCore *core, const char *input) {
|
||||
if (!list) {
|
||||
return;
|
||||
}
|
||||
SdbListIter *iter;
|
||||
RIOMap *map;
|
||||
ls_foreach_prev (core->io->maps, iter, map) {
|
||||
void **it;
|
||||
r_pvector_foreach_prev (&core->io->maps, it) {
|
||||
RIOMap *map = *it;
|
||||
char temp[32];
|
||||
snprintf (temp, sizeof (temp), "%d", map->fd);
|
||||
RListInfo *info = r_listinfo_new (map->name, map->itv, map->itv, map->perm, temp);
|
||||
@ -1426,9 +1431,9 @@ static int cmd_open(void *data, const char *input) {
|
||||
if (*input == '+') { // "o+"
|
||||
RIODesc *desc = r_io_desc_get (core->io, fd);
|
||||
if (desc && (desc->perm & R_PERM_W)) {
|
||||
SdbListIter *iter;
|
||||
RIOMap *map;
|
||||
ls_foreach_prev (core->io->maps, iter, map) {
|
||||
void **it;
|
||||
r_pvector_foreach_prev (&core->io->maps, it) {
|
||||
RIOMap *map = *it;
|
||||
if (map->fd == fd) {
|
||||
map->perm |= R_PERM_WX;
|
||||
}
|
||||
@ -1715,9 +1720,9 @@ static int cmd_open(void *data, const char *input) {
|
||||
perms |= core->io->desc->perm;
|
||||
}
|
||||
if (r_io_reopen (core->io, fd, perms, 644)) {
|
||||
SdbListIter *iter;
|
||||
RIOMap *map;
|
||||
ls_foreach_prev (core->io->maps, iter, map) {
|
||||
void **it;
|
||||
r_pvector_foreach_prev (&core->io->maps, it) {
|
||||
RIOMap *map = *it;
|
||||
if (map->fd == fd) {
|
||||
map->perm |= R_PERM_WX;
|
||||
}
|
||||
|
@ -647,9 +647,9 @@ R_API RList *r_core_get_boundaries_prot(RCore *core, int perm, const char *mode,
|
||||
RIOMap *m = r_io_map_get (core->io, from);
|
||||
int rwx = m? m->perm: part->map->perm;
|
||||
#else
|
||||
RIOMap *map;
|
||||
SdbListIter *iter;
|
||||
ls_foreach (core->io->maps, iter, map) {
|
||||
void **it;
|
||||
r_pvector_foreach (&core->io->maps, it) {
|
||||
RIOMap *map = *it;
|
||||
ut64 from = r_itv_begin (map->itv);
|
||||
ut64 to = r_itv_end (map->itv);
|
||||
int rwx = map->perm;
|
||||
@ -679,9 +679,9 @@ R_API RList *r_core_get_boundaries_prot(RCore *core, int perm, const char *mode,
|
||||
int mask = (mode[len - 1] == '.')? r_str_rwx (mode + len): 0;
|
||||
// bool only = (bool)(size_t)strstr (mode, ".only");
|
||||
|
||||
SdbListIter *iter;
|
||||
RIOMap *map;
|
||||
ls_foreach (core->io->maps, iter, map) {
|
||||
void **it;
|
||||
r_pvector_foreach (&core->io->maps, it) {
|
||||
RIOMap *map = *it;
|
||||
ut64 from = r_itv_begin (map->itv);
|
||||
//ut64 to = r_itv_end (map->itv);
|
||||
int rwx = map->perm;
|
||||
@ -766,10 +766,10 @@ R_API RList *r_core_get_boundaries_prot(RCore *core, int perm, const char *mode,
|
||||
to = R_MAX (to, addr + size);
|
||||
}
|
||||
if (from == UT64_MAX) {
|
||||
SdbListIter *iter;
|
||||
RIOMap *map;
|
||||
int mask = 1;
|
||||
ls_foreach (core->io->maps, iter, map) {
|
||||
void **it;
|
||||
r_pvector_foreach (&core->io->maps, it) {
|
||||
RIOMap *map = *it;
|
||||
ut64 from = r_itv_begin (map->itv);
|
||||
ut64 size = r_itv_size (map->itv);
|
||||
int rwx = map->perm;
|
||||
|
@ -137,9 +137,9 @@ static void GH(get_brks)(RCore *core, GHT *brk_start, GHT *brk_end) {
|
||||
}
|
||||
}
|
||||
} else {
|
||||
RIOMap *map;
|
||||
SdbListIter *iter;
|
||||
ls_foreach (core->io->maps, iter, map) {
|
||||
void **it;
|
||||
r_pvector_foreach (&core->io->maps, it) {
|
||||
RIOMap *map = *it;
|
||||
if (map->name) {
|
||||
if (strstr (map->name, "[heap]")) {
|
||||
*brk_start = map->itv.addr;
|
||||
@ -323,9 +323,9 @@ static bool GH(r_resolve_main_arena)(RCore *core, GHT *m_arena) {
|
||||
}
|
||||
}
|
||||
} else {
|
||||
RIOMap *map;
|
||||
SdbListIter *iter;
|
||||
ls_foreach (core->io->maps, iter, map) {
|
||||
void **it;
|
||||
r_pvector_foreach (&core->io->maps, it) {
|
||||
RIOMap *map = *it;
|
||||
if (map->name && strstr (map->name, "arena")) {
|
||||
libc_addr_sta = map->itv.addr;
|
||||
libc_addr_end = map->itv.addr + map->itv.size;
|
||||
|
@ -231,11 +231,8 @@ static bool __core_visual_gogo (RCore *core, int ch) {
|
||||
case 'g':
|
||||
if (core->io->va) {
|
||||
RIOMap *map = r_io_map_get (core->io, core->offset);
|
||||
if (!map) {
|
||||
SdbListIter *i = ls_tail (core->io->maps);
|
||||
if (i) {
|
||||
map = ls_iter_get (i);
|
||||
}
|
||||
if (!map && !r_pvector_empty (&core->io->maps)) {
|
||||
map = r_pvector_at (&core->io->maps, r_pvector_len (&core->io->maps) - 1);
|
||||
}
|
||||
if (map) {
|
||||
r_core_seek (core, r_itv_begin (map->itv), 1);
|
||||
@ -247,11 +244,8 @@ static bool __core_visual_gogo (RCore *core, int ch) {
|
||||
return true;
|
||||
case 'G':
|
||||
map = r_io_map_get (core->io, core->offset);
|
||||
if (!map) {
|
||||
SdbListIter *i = ls_head (core->io->maps);
|
||||
if (i) {
|
||||
map = ls_iter_get (i);
|
||||
}
|
||||
if (!map && !r_pvector_empty (&core->io->maps)) {
|
||||
map = r_pvector_at (&core->io->maps, 0);
|
||||
}
|
||||
if (map) {
|
||||
RPrint *p = core->print;
|
||||
@ -3431,13 +3425,13 @@ R_API int r_core_visual_cmd(RCore *core, const char *arg) {
|
||||
if (s) {
|
||||
entry = s->vaddr;
|
||||
} else {
|
||||
RIOMap *map = ls_pop (core->io->maps);
|
||||
RIOMap *map = r_pvector_pop (&core->io->maps);
|
||||
if (map) {
|
||||
entry = map->itv.addr;
|
||||
} else {
|
||||
entry = r_config_get_i (core->config, "bin.baddr");
|
||||
}
|
||||
ls_prepend (core->io->maps, map);
|
||||
r_pvector_push_front (&core->io->maps, map);
|
||||
}
|
||||
}
|
||||
if (entry != UT64_MAX) {
|
||||
|
@ -90,7 +90,7 @@ typedef struct r_io_t {
|
||||
int debug;
|
||||
//#warning remove debug from RIO
|
||||
RIDPool *map_ids;
|
||||
SdbList *maps; //from tail backwards maps with higher priority are found
|
||||
RPVector maps; //from tail backwards maps with higher priority are found
|
||||
RPVector map_skyline; // map parts that are not covered by others
|
||||
RPVector map_skyline_shadow; // map parts that are not covered by others
|
||||
RIDStorage *files;
|
||||
|
@ -229,6 +229,10 @@ static inline void **r_pvector_shrink(RPVector *vec) {
|
||||
#define r_pvector_foreach(vec, it) \
|
||||
for (it = (void **)(vec)->v.a; it != (void **)(vec)->v.a + (vec)->v.len; it++)
|
||||
|
||||
// like r_pvector_foreach() but inverse
|
||||
#define r_pvector_foreach_prev(vec, it) \
|
||||
for (it = (void **)(vec)->v.a + (vec)->v.len - 1; it != (void **)(vec)->v.a - 1; it--)
|
||||
|
||||
/*
|
||||
* example:
|
||||
*
|
||||
|
@ -223,8 +223,6 @@ R_API bool r_io_desc_is_chardevice(RIODesc *desc) {
|
||||
|
||||
R_API bool r_io_desc_exchange(RIO* io, int fd, int fdx) {
|
||||
RIODesc* desc, * descx;
|
||||
SdbListIter* iter;
|
||||
RIOMap* map;
|
||||
if (!(desc = r_io_desc_get (io, fd)) || !(descx = r_io_desc_get (io, fdx))) {
|
||||
return false;
|
||||
}
|
||||
@ -239,13 +237,13 @@ R_API bool r_io_desc_exchange(RIO* io, int fd, int fdx) {
|
||||
r_io_desc_cache_cleanup (desc);
|
||||
r_io_desc_cache_cleanup (descx);
|
||||
}
|
||||
if (io->maps) {
|
||||
ls_foreach (io->maps, iter, map) {
|
||||
if (map->fd == fdx) {
|
||||
map->perm &= (desc->perm | R_PERM_X);
|
||||
} else if (map->fd == fd) {
|
||||
map->perm &= (descx->perm | R_PERM_X);
|
||||
}
|
||||
void **it;
|
||||
r_pvector_foreach (&io->maps, it) {
|
||||
RIOMap *map = *it;
|
||||
if (map->fd == fdx) {
|
||||
map->perm &= (desc->perm | R_PERM_X);
|
||||
} else if (map->fd == fd) {
|
||||
map->perm &= (descx->perm | R_PERM_X);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
|
@ -147,7 +147,7 @@ R_API RIODesc *r_io_open_nomap(RIO *io, const char *uri, int perm, int mode) {
|
||||
|
||||
/* opens a file and maps it to 0x0 */
|
||||
R_API RIODesc* r_io_open(RIO* io, const char* uri, int perm, int mode) {
|
||||
r_return_val_if_fail (io && io->maps, NULL);
|
||||
r_return_val_if_fail (io, NULL);
|
||||
RIODesc* desc = r_io_open_nomap (io, uri, perm, mode);
|
||||
if (desc) {
|
||||
r_io_map_new (io, desc->fd, desc->perm, 0LL, 0LL, r_io_desc_size (desc));
|
||||
@ -157,7 +157,7 @@ R_API RIODesc* r_io_open(RIO* io, const char* uri, int perm, int mode) {
|
||||
|
||||
/* opens a file and maps it to an offset specified by the "at"-parameter */
|
||||
R_API RIODesc* r_io_open_at(RIO* io, const char* uri, int perm, int mode, ut64 at) {
|
||||
r_return_val_if_fail (io && io->maps && uri, NULL);
|
||||
r_return_val_if_fail (io && uri, NULL);
|
||||
|
||||
RIODesc* desc = r_io_open_nomap (io, uri, perm, mode);
|
||||
if (!desc) {
|
||||
|
180
libr/io/map.c
180
libr/io/map.c
@ -72,8 +72,6 @@ static bool _map_skyline_push(RPVector *map_skyline, ut64 from, ut64 to, RIOMap
|
||||
|
||||
// Store map parts that are not covered by others into io->map_skyline
|
||||
void io_map_calculate_skyline(RIO *io) {
|
||||
SdbListIter *iter;
|
||||
RIOMap *map;
|
||||
RPVector events;
|
||||
RBinHeap heap;
|
||||
struct map_event_t *ev;
|
||||
@ -81,15 +79,17 @@ void io_map_calculate_skyline(RIO *io) {
|
||||
r_pvector_clear (&io->map_skyline);
|
||||
r_pvector_clear (&io->map_skyline_shadow);
|
||||
r_pvector_init (&events, free);
|
||||
if (!r_pvector_reserve (&events, ls_length (io->maps) * 2) ||
|
||||
!(deleted = calloc (ls_length (io->maps), 1))) {
|
||||
if (!r_pvector_reserve (&events, r_pvector_len (&io->maps) * 2) ||
|
||||
!(deleted = calloc (r_pvector_len (&io->maps), 1))) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
int i = 0;
|
||||
// Last map has highest priority (it shadows previous maps),
|
||||
// we assign 0 to its event id.
|
||||
ls_foreach_prev (io->maps, iter, map) {
|
||||
void **it;
|
||||
r_pvector_foreach_prev (&io->maps, it) {
|
||||
RIOMap *map = *it;
|
||||
if (!(ev = R_NEW (struct map_event_t))) {
|
||||
goto out;
|
||||
}
|
||||
@ -126,7 +126,7 @@ void io_map_calculate_skyline(RIO *io) {
|
||||
r_binheap_pop (&heap);
|
||||
}
|
||||
ut64 to = ev->addr;
|
||||
map = r_binheap_empty (&heap) ? NULL : ((struct map_event_t *)r_binheap_top (&heap))->map;
|
||||
RIOMap *map = r_binheap_empty (&heap) ? NULL : ((struct map_event_t *)r_binheap_top (&heap))->map;
|
||||
if (!i) {
|
||||
last = to;
|
||||
last_map = map;
|
||||
@ -196,7 +196,7 @@ out:
|
||||
}
|
||||
|
||||
RIOMap* io_map_new(RIO* io, int fd, int perm, ut64 delta, ut64 addr, ut64 size, bool do_skyline) {
|
||||
if (!size || !io || !io->maps || !io->map_ids) {
|
||||
if (!size || !io || !io->map_ids) {
|
||||
return NULL;
|
||||
}
|
||||
RIOMap* map = R_NEW0 (RIOMap);
|
||||
@ -216,7 +216,7 @@ RIOMap* io_map_new(RIO* io, int fd, int perm, ut64 delta, ut64 addr, ut64 size,
|
||||
map->perm = perm;
|
||||
map->delta = delta;
|
||||
// new map lives on the top, being top the list's tail
|
||||
ls_append (io->maps, map);
|
||||
r_pvector_push (&io->maps, map);
|
||||
if (do_skyline) {
|
||||
io_map_calculate_skyline (io);
|
||||
}
|
||||
@ -266,23 +266,20 @@ static void _map_free(void* p) {
|
||||
}
|
||||
|
||||
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);
|
||||
r_return_if_fail (io);
|
||||
r_pvector_init (&io->maps, _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);
|
||||
}
|
||||
|
||||
// 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;
|
||||
}
|
||||
ls_foreach (io->maps, iter, m) {
|
||||
R_API bool r_io_map_exists(RIO *io, RIOMap *map) {
|
||||
r_return_val_if_fail (io && map, false);
|
||||
void **it;
|
||||
r_pvector_foreach (&io->maps, it) {
|
||||
RIOMap *m = *it;
|
||||
if (!memcmp (m, map, sizeof (RIOMap))) {
|
||||
return true;
|
||||
}
|
||||
@ -295,13 +292,11 @@ R_API bool r_io_map_exists_for_id(RIO* io, ut32 id) {
|
||||
return r_io_map_resolve (io, id) != NULL;
|
||||
}
|
||||
|
||||
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) {
|
||||
R_API RIOMap* r_io_map_resolve(RIO *io, ut32 id) {
|
||||
r_return_val_if_fail (io && id, false);
|
||||
void **it;
|
||||
r_pvector_foreach (&io->maps, it) {
|
||||
RIOMap *map = *it;
|
||||
if (map->id == id) {
|
||||
return map;
|
||||
}
|
||||
@ -334,9 +329,9 @@ R_API void r_io_update(RIO *io) {
|
||||
|
||||
R_API RIOMap* r_io_map_get_paddr(RIO* io, ut64 paddr) {
|
||||
r_return_val_if_fail (io, NULL);
|
||||
RIOMap* map;
|
||||
SdbListIter* iter;
|
||||
ls_foreach_prev (io->maps, iter, map) {
|
||||
void **it;
|
||||
r_pvector_foreach_prev (&io->maps, it) {
|
||||
RIOMap *map = *it;
|
||||
if (map->delta <= paddr && paddr <= map->delta + map->itv.size - 1) {
|
||||
return map;
|
||||
}
|
||||
@ -345,11 +340,11 @@ R_API RIOMap* r_io_map_get_paddr(RIO* io, ut64 paddr) {
|
||||
}
|
||||
|
||||
// gets first map where addr fits in
|
||||
R_API RIOMap* r_io_map_get(RIO* io, ut64 addr) {
|
||||
R_API RIOMap *r_io_map_get(RIO* io, ut64 addr) {
|
||||
r_return_val_if_fail (io, NULL);
|
||||
RIOMap* map;
|
||||
SdbListIter* iter;
|
||||
ls_foreach_prev (io->maps, iter, map) {
|
||||
void **it;
|
||||
r_pvector_foreach_prev (&io->maps, it) {
|
||||
RIOMap *map = *it;
|
||||
if (r_itv_contain (map->itv, addr)) {
|
||||
return map;
|
||||
}
|
||||
@ -378,13 +373,14 @@ R_API void r_io_map_reset(RIO* io) {
|
||||
io_map_calculate_skyline (io);
|
||||
}
|
||||
|
||||
R_API bool r_io_map_del(RIO* io, ut32 id) {
|
||||
R_API bool r_io_map_del(RIO *io, ut32 id) {
|
||||
r_return_val_if_fail (io, false);
|
||||
RIOMap* map;
|
||||
SdbListIter* iter;
|
||||
ls_foreach (io->maps, iter, map) {
|
||||
size_t i;
|
||||
for (i = 0; i < r_pvector_len (&io->maps); i++) {
|
||||
RIOMap *map = r_pvector_at (&io->maps, i);
|
||||
if (map->id == id) {
|
||||
ls_delete (io->maps, iter);
|
||||
r_pvector_remove_at (&io->maps, i);
|
||||
_map_free (map);
|
||||
r_id_pool_kick_id (io->map_ids, id);
|
||||
io_map_calculate_skyline (io);
|
||||
return true;
|
||||
@ -396,17 +392,20 @@ R_API bool r_io_map_del(RIO* io, ut32 id) {
|
||||
//delete all maps with specified fd
|
||||
R_API bool r_io_map_del_for_fd(RIO* io, int fd) {
|
||||
r_return_val_if_fail (io, false);
|
||||
SdbListIter* iter, * ator;
|
||||
RIOMap* map;
|
||||
bool ret = false;
|
||||
ls_foreach_safe (io->maps, iter, ator, map) {
|
||||
size_t i;
|
||||
for (i = 0; i < r_pvector_len (&io->maps);) {
|
||||
RIOMap *map = r_pvector_at (&io->maps, i);
|
||||
if (!map) {
|
||||
ls_delete (io->maps, iter);
|
||||
r_pvector_remove_at (&io->maps, i);
|
||||
} else if (map->fd == fd) {
|
||||
r_id_pool_kick_id (io->map_ids, map->id);
|
||||
//delete iter and map
|
||||
ls_delete (io->maps, iter);
|
||||
r_pvector_remove_at (&io->maps, i);
|
||||
_map_free (map);
|
||||
ret = true;
|
||||
} else {
|
||||
i++;
|
||||
}
|
||||
}
|
||||
if (ret) {
|
||||
@ -419,15 +418,14 @@ R_API bool r_io_map_del_for_fd(RIO* io, int fd) {
|
||||
//return a boolean denoting whether is was possible to priorized
|
||||
R_API bool r_io_map_priorize(RIO* io, ut32 id) {
|
||||
r_return_val_if_fail (io, false);
|
||||
RIOMap *map;
|
||||
SdbListIter *iter;
|
||||
ls_foreach (io->maps, iter, map) {
|
||||
size_t i;
|
||||
for (i = 0; i < r_pvector_len (&io->maps); i++) {
|
||||
RIOMap *map = r_pvector_at (&io->maps, i);
|
||||
// search for iter with the correct map
|
||||
if (map->id == id) {
|
||||
ls_split_iter (io->maps, iter);
|
||||
ls_append (io->maps, map);
|
||||
r_pvector_remove_at (&io->maps, i);
|
||||
r_pvector_push (&io->maps, map);
|
||||
io_map_calculate_skyline (io);
|
||||
free (iter);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -436,55 +434,45 @@ R_API bool r_io_map_priorize(RIO* io, ut32 id) {
|
||||
|
||||
R_API bool r_io_map_depriorize(RIO* io, ut32 id) {
|
||||
r_return_val_if_fail (io, false);
|
||||
RIOMap *map;
|
||||
SdbListIter *iter;
|
||||
ls_foreach (io->maps, iter, map) {
|
||||
size_t i;
|
||||
for (i = 0; i < r_pvector_len (&io->maps); i++) {
|
||||
RIOMap *map = r_pvector_at (&io->maps, i);
|
||||
// search for iter with the correct map
|
||||
if (map->id == id) {
|
||||
ls_split_iter (io->maps, iter);
|
||||
ls_prepend (io->maps, map);
|
||||
r_pvector_remove_at (&io->maps, i);
|
||||
r_pvector_push_front (&io->maps, map);
|
||||
io_map_calculate_skyline (io);
|
||||
free (iter);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
R_API bool r_io_map_priorize_for_fd(RIO* io, int fd) {
|
||||
SdbListIter* iter, * ator;
|
||||
RIOMap *map;
|
||||
SdbList* list;
|
||||
if (!io || !io->maps) {
|
||||
return false;
|
||||
}
|
||||
if (!(list = ls_new ())) {
|
||||
return false;
|
||||
}
|
||||
R_API bool r_io_map_priorize_for_fd(RIO *io, int fd) {
|
||||
r_return_val_if_fail (io, false);
|
||||
//we need a clean list for this, or this becomes a segfault-field
|
||||
r_io_map_cleanup (io);
|
||||
//temporary 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) {
|
||||
RPVector temp;
|
||||
r_pvector_init (&temp, NULL);
|
||||
size_t i;
|
||||
for (i = 0; i < r_pvector_len (&io->maps);) {
|
||||
RIOMap *map = r_pvector_at (&io->maps, i);
|
||||
if (map->fd == fd) {
|
||||
ls_prepend (list, map);
|
||||
ls_delete (io->maps, iter);
|
||||
r_pvector_push (&temp, map);
|
||||
r_pvector_remove_at (&io->maps, i);
|
||||
continue;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
ls_join (io->maps, list);
|
||||
ls_free (list);
|
||||
io->maps->free = _map_free;
|
||||
r_pvector_insert_range (&io->maps, r_pvector_len (&io->maps), temp.v.a, r_pvector_len (&temp));
|
||||
r_pvector_clear (&temp);
|
||||
io_map_calculate_skyline (io);
|
||||
return true;
|
||||
}
|
||||
|
||||
//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;
|
||||
}
|
||||
r_return_if_fail (io);
|
||||
//remove all maps if no descs exist
|
||||
if (!io->files) {
|
||||
r_io_map_fini (io);
|
||||
@ -492,16 +480,20 @@ R_API void r_io_map_cleanup(RIO* io) {
|
||||
return;
|
||||
}
|
||||
bool del = false;
|
||||
ls_foreach_safe (io->maps, iter, ator, map) {
|
||||
size_t i;
|
||||
for (i = 0; i < r_pvector_len (&io->maps);) {
|
||||
RIOMap *map = r_pvector_at (&io->maps, i);
|
||||
//remove iter if the map is a null-ptr, this may fix some segfaults
|
||||
if (!map) {
|
||||
ls_delete (io->maps, iter);
|
||||
r_pvector_remove_at (&io->maps, i);
|
||||
del = true;
|
||||
} 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);
|
||||
r_pvector_remove_at (&io->maps, i);
|
||||
del = true;
|
||||
} else {
|
||||
i++;
|
||||
}
|
||||
}
|
||||
if (del) {
|
||||
@ -511,8 +503,7 @@ R_API void r_io_map_cleanup(RIO* io) {
|
||||
|
||||
R_API void r_io_map_fini(RIO* io) {
|
||||
r_return_if_fail (io);
|
||||
ls_free (io->maps);
|
||||
io->maps = NULL;
|
||||
r_pvector_clear (&io->maps);
|
||||
r_id_pool_free (io->map_ids);
|
||||
io->map_ids = NULL;
|
||||
r_pvector_clear (&io->map_skyline);
|
||||
@ -538,11 +529,11 @@ R_API ut64 r_io_map_next_available(RIO* io, ut64 addr, ut64 size, ut64 load_alig
|
||||
if (load_align == 0) {
|
||||
load_align = 1;
|
||||
}
|
||||
RIOMap* map;
|
||||
SdbListIter* iter;
|
||||
ut64 next_addr = addr,
|
||||
end_addr = next_addr + size;
|
||||
ls_foreach (io->maps, iter, map) {
|
||||
void **it;
|
||||
r_pvector_foreach (&io->maps, it) {
|
||||
RIOMap *map = *it;
|
||||
ut64 to = r_itv_end (map->itv);
|
||||
next_addr = R_MAX (next_addr, to + (load_align - (to % load_align)) % load_align);
|
||||
// XXX - This does not handle when file overflow 0xFFFFFFFF000 -> 0x00000FFF
|
||||
@ -559,11 +550,10 @@ R_API ut64 r_io_map_next_available(RIO* io, ut64 addr, ut64 size, ut64 load_alig
|
||||
|
||||
// TODO: very similar to r_io_map_next_available. decide which one to use
|
||||
R_API ut64 r_io_map_next_address(RIO* io, ut64 addr) {
|
||||
RIOMap* map;
|
||||
SdbListIter* iter;
|
||||
ut64 lowest = UT64_MAX;
|
||||
|
||||
ls_foreach (io->maps, iter, map) {
|
||||
void **it;
|
||||
r_pvector_foreach (&io->maps, it) {
|
||||
RIOMap *map = *it;
|
||||
ut64 from = r_itv_begin (map->itv);
|
||||
if (from > addr && addr < lowest) {
|
||||
lowest = from;
|
||||
@ -578,12 +568,12 @@ R_API ut64 r_io_map_next_address(RIO* io, ut64 addr) {
|
||||
|
||||
R_API RList* r_io_map_get_for_fd(RIO* io, int fd) {
|
||||
RList* map_list = r_list_newf (NULL);
|
||||
SdbListIter* iter;
|
||||
RIOMap* map;
|
||||
if (!map_list) {
|
||||
return NULL;
|
||||
}
|
||||
ls_foreach (io->maps, iter, map) {
|
||||
void **it;
|
||||
r_pvector_foreach (&io->maps, it) {
|
||||
RIOMap *map = *it;
|
||||
if (map && map->fd == fd) {
|
||||
r_list_append (map_list, map);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user