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:
Florian Märkl 2020-04-07 12:43:41 +02:00 committed by GitHub
parent 88ad1ccd4a
commit 9a2effd5ed
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 173 additions and 180 deletions

View File

@ -848,9 +848,8 @@ static RList* patch_relocs(RBin *b) {
RIO *io = NULL; RIO *io = NULL;
RBinObject *obj = NULL; RBinObject *obj = NULL;
struct Elf_(r_bin_elf_obj_t) *bin = NULL; struct Elf_(r_bin_elf_obj_t) *bin = NULL;
RIOMap *g = NULL, *s = NULL; RIOMap *g = NULL;
HtUU *relocs_by_sym; HtUU *relocs_by_sym;
SdbListIter *iter;
RBinElfReloc *relcs = NULL; RBinElfReloc *relcs = NULL;
RBinInfo *info; RBinInfo *info;
int cdsz; int cdsz;
@ -878,10 +877,12 @@ static RList* patch_relocs(RBin *b) {
info = obj ? obj->info: NULL; info = obj ? obj->info: NULL;
cdsz = info? (info->bits == 64? 8: info->bits == 32? 4: info->bits == 16 ? 4: 0): 0; cdsz = info? (info->bits == 64? 8: info->bits == 32? 4: info->bits == 16 ? 4: 0): 0;
ls_foreach (io->maps, iter, s) { void **it;
if (s->itv.addr > offset) { r_pvector_foreach (&io->maps, it) {
offset = s->itv.addr; RIOMap *map = *it;
g = s; if (map->itv.addr > offset) {
offset = map->itv.addr;
g = map;
} }
} }
if (!g) { if (!g) {

View File

@ -556,7 +556,7 @@ static RList* patch_relocs(RBin *b) {
RIO *io = NULL; RIO *io = NULL;
RBinObject *obj = NULL; RBinObject *obj = NULL;
struct MACH0_(obj_t) *bin = NULL; struct MACH0_(obj_t) *bin = NULL;
RIOMap *g = NULL, *s = NULL; RIOMap *g = NULL;
HtUU *relocs_by_sym = NULL; HtUU *relocs_by_sym = NULL;
RIODesc *gotr2desc = NULL; RIODesc *gotr2desc = NULL;
@ -600,12 +600,13 @@ static RList* patch_relocs(RBin *b) {
int cdsz = obj->info ? obj->info->bits / 8 : 8; int cdsz = obj->info ? obj->info->bits / 8 : 8;
SdbListIter *iter;
ut64 offset = 0; ut64 offset = 0;
ls_foreach (io->maps, iter, s) { void **vit;
if (s->itv.addr > offset) { r_pvector_foreach (&io->maps, vit) {
offset = s->itv.addr; RIOMap *map = *vit;
g = s; if (map->itv.addr > offset) {
offset = map->itv.addr;
g = map;
} }
} }
if (!g) { if (!g) {

View File

@ -288,11 +288,11 @@ R_API ut64 r_core_anal_address(RCore *core, ut64 addr) {
} }
} else { } else {
int _perm = -1; int _perm = -1;
RIOMap *s;
SdbListIter *iter;
if (core->io) { if (core->io) {
// sections // 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)) { if (addr >= s->itv.addr && addr < (s->itv.addr + s->itv.size)) {
// sections overlap, so we want to get the one with lower perms // sections overlap, so we want to get the one with lower perms
_perm = (_perm != -1) ? R_MIN (_perm, s->perm) : s->perm; _perm = (_perm != -1) ? R_MIN (_perm, s->perm) : s->perm;

View File

@ -8576,13 +8576,13 @@ static const char *oldstr = NULL;
static int compute_coverage(RCore *core) { static int compute_coverage(RCore *core) {
RListIter *iter; RListIter *iter;
SdbListIter *iter2;
RAnalFunction *fcn; RAnalFunction *fcn;
RIOMap *map;
int cov = 0; int cov = 0;
cov += r_meta_get_size(core->anal, R_META_TYPE_DATA); cov += r_meta_get_size(core->anal, R_META_TYPE_DATA);
r_list_foreach (core->anal->fcns, iter, fcn) { 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) { if (map->perm & R_PERM_X) {
ut64 section_end = map->itv.addr + map->itv.size; ut64 section_end = map->itv.addr + map->itv.size;
ut64 s = r_anal_function_realsize (fcn); ut64 s = r_anal_function_realsize (fcn);
@ -8597,9 +8597,9 @@ static int compute_coverage(RCore *core) {
static int compute_code (RCore* core) { static int compute_code (RCore* core) {
int code = 0; int code = 0;
SdbListIter *iter; void **it;
RIOMap *map; r_pvector_foreach (&core->io->maps, it) {
ls_foreach (core->io->maps, iter, map) { RIOMap *map = *it;
if (map->perm & R_PERM_X) { if (map->perm & R_PERM_X) {
code += map->itv.size; code += map->itv.size;
} }

View File

@ -393,9 +393,7 @@ static void cmd_open_bin(RCore *core, const char *input) {
// TODO: discuss the output format // TODO: discuss the output format
static void map_list(RIO *io, int mode, RPrint *print, int fd) { static void map_list(RIO *io, int mode, RPrint *print, int fd) {
SdbListIter *iter; if (!io || !print || !print->cb_printf) {
RIOMap *map;
if (!io || !io->maps || !print || !print->cb_printf) {
return; return;
} }
if (mode == 'j') { if (mode == 'j') {
@ -403,7 +401,10 @@ static void map_list(RIO *io, int mode, RPrint *print, int fd) {
} }
bool first = true; bool first = true;
char *om_cmds = NULL; 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) { if (fd >= 0 && map->fd != fd) {
continue; 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) { static void cmd_omfg(RCore *core, const char *input) {
SdbListIter *iter;
RIOMap *map;
input = r_str_trim_head_ro (input); input = r_str_trim_head_ro (input);
if (input) { if (input) {
int perm = *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 + 1)
: r_str_rwx (input) : r_str_rwx (input)
: 7; : 7;
void **it;
switch (*input) { switch (*input) {
case '+': case '+':
ls_foreach (core->io->maps, iter, map) { r_pvector_foreach (&core->io->maps, it) {
RIOMap *map = *it;
map->perm |= perm; map->perm |= perm;
} }
break; break;
case '-': case '-':
ls_foreach (core->io->maps, iter, map) { r_pvector_foreach (&core->io->maps, it) {
RIOMap *map = *it;
map->perm &= ~perm; map->perm &= ~perm;
} }
break; break;
default: default:
ls_foreach (core->io->maps, iter, map) { r_pvector_foreach (&core->io->maps, it) {
RIOMap *map = *it;
map->perm = perm; map->perm = perm;
} }
break; break;
@ -486,8 +489,6 @@ static void cmd_omfg(RCore *core, const char *input) {
} }
static void cmd_omf(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)); char *arg = strdup (r_str_trim_head_ro (input));
if (!arg) { if (!arg) {
return; return;
@ -498,7 +499,9 @@ static void cmd_omf(RCore *core, const char *input) {
*sp++ = 0; *sp++ = 0;
int id = r_num_math (core->num, arg); int id = r_num_math (core->num, arg);
int perm = (*sp)? r_str_rwx (sp): R_PERM_RWX; 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) { if (map->id == id) {
map->perm = perm; map->perm = perm;
break; break;
@ -507,7 +510,9 @@ static void cmd_omf(RCore *core, const char *input) {
} else { } else {
// change perms of current map // change perms of current map
int perm = (arg && *arg)? r_str_rwx (arg): R_PERM_RWX; 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)) { if (r_itv_contain (map->itv, core->offset)) {
map->perm = perm; 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); r_table_set_columnsf (t, "nnnnnnnss", "id", "fd", "pa", "pa_end", "size", "va", "va_end", "perm", "name", NULL);
SdbListIter *iter; void **it;
RIOMap *m; r_pvector_foreach (&core->io->maps, it) {
ls_foreach_prev (core->io->maps, iter, m) { RIOMap *m = *it;
ut64 va = r_itv_begin (m->itv); ut64 va = r_itv_begin (m->itv);
ut64 va_end = r_itv_end (m->itv); ut64 va_end = r_itv_end (m->itv);
ut64 pa = m->delta; ut64 pa = m->delta;
@ -813,9 +818,9 @@ static void cmd_open_map(RCore *core, const char *input) {
if (!list) { if (!list) {
return; return;
} }
SdbListIter *iter; void **it;
RIOMap *map; r_pvector_foreach_prev (&core->io->maps, it) {
ls_foreach_prev (core->io->maps, iter, map) { RIOMap *map = *it;
char temp[32]; char temp[32];
snprintf (temp, sizeof (temp), "%d", map->fd); snprintf (temp, sizeof (temp), "%d", map->fd);
RListInfo *info = r_listinfo_new (map->name, map->itv, map->itv, map->perm, temp); 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+" if (*input == '+') { // "o+"
RIODesc *desc = r_io_desc_get (core->io, fd); RIODesc *desc = r_io_desc_get (core->io, fd);
if (desc && (desc->perm & R_PERM_W)) { if (desc && (desc->perm & R_PERM_W)) {
SdbListIter *iter; void **it;
RIOMap *map; r_pvector_foreach_prev (&core->io->maps, it) {
ls_foreach_prev (core->io->maps, iter, map) { RIOMap *map = *it;
if (map->fd == fd) { if (map->fd == fd) {
map->perm |= R_PERM_WX; map->perm |= R_PERM_WX;
} }
@ -1715,9 +1720,9 @@ static int cmd_open(void *data, const char *input) {
perms |= core->io->desc->perm; perms |= core->io->desc->perm;
} }
if (r_io_reopen (core->io, fd, perms, 644)) { if (r_io_reopen (core->io, fd, perms, 644)) {
SdbListIter *iter; void **it;
RIOMap *map; r_pvector_foreach_prev (&core->io->maps, it) {
ls_foreach_prev (core->io->maps, iter, map) { RIOMap *map = *it;
if (map->fd == fd) { if (map->fd == fd) {
map->perm |= R_PERM_WX; map->perm |= R_PERM_WX;
} }

View File

@ -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); RIOMap *m = r_io_map_get (core->io, from);
int rwx = m? m->perm: part->map->perm; int rwx = m? m->perm: part->map->perm;
#else #else
RIOMap *map; void **it;
SdbListIter *iter; r_pvector_foreach (&core->io->maps, it) {
ls_foreach (core->io->maps, iter, map) { RIOMap *map = *it;
ut64 from = r_itv_begin (map->itv); ut64 from = r_itv_begin (map->itv);
ut64 to = r_itv_end (map->itv); ut64 to = r_itv_end (map->itv);
int rwx = map->perm; 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; int mask = (mode[len - 1] == '.')? r_str_rwx (mode + len): 0;
// bool only = (bool)(size_t)strstr (mode, ".only"); // bool only = (bool)(size_t)strstr (mode, ".only");
SdbListIter *iter; void **it;
RIOMap *map; r_pvector_foreach (&core->io->maps, it) {
ls_foreach (core->io->maps, iter, map) { RIOMap *map = *it;
ut64 from = r_itv_begin (map->itv); ut64 from = r_itv_begin (map->itv);
//ut64 to = r_itv_end (map->itv); //ut64 to = r_itv_end (map->itv);
int rwx = map->perm; 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); to = R_MAX (to, addr + size);
} }
if (from == UT64_MAX) { if (from == UT64_MAX) {
SdbListIter *iter;
RIOMap *map;
int mask = 1; 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 from = r_itv_begin (map->itv);
ut64 size = r_itv_size (map->itv); ut64 size = r_itv_size (map->itv);
int rwx = map->perm; int rwx = map->perm;

View File

@ -137,9 +137,9 @@ static void GH(get_brks)(RCore *core, GHT *brk_start, GHT *brk_end) {
} }
} }
} else { } else {
RIOMap *map; void **it;
SdbListIter *iter; r_pvector_foreach (&core->io->maps, it) {
ls_foreach (core->io->maps, iter, map) { RIOMap *map = *it;
if (map->name) { if (map->name) {
if (strstr (map->name, "[heap]")) { if (strstr (map->name, "[heap]")) {
*brk_start = map->itv.addr; *brk_start = map->itv.addr;
@ -323,9 +323,9 @@ static bool GH(r_resolve_main_arena)(RCore *core, GHT *m_arena) {
} }
} }
} else { } else {
RIOMap *map; void **it;
SdbListIter *iter; r_pvector_foreach (&core->io->maps, it) {
ls_foreach (core->io->maps, iter, map) { RIOMap *map = *it;
if (map->name && strstr (map->name, "arena")) { if (map->name && strstr (map->name, "arena")) {
libc_addr_sta = map->itv.addr; libc_addr_sta = map->itv.addr;
libc_addr_end = map->itv.addr + map->itv.size; libc_addr_end = map->itv.addr + map->itv.size;

View File

@ -231,11 +231,8 @@ static bool __core_visual_gogo (RCore *core, int ch) {
case 'g': case 'g':
if (core->io->va) { if (core->io->va) {
RIOMap *map = r_io_map_get (core->io, core->offset); RIOMap *map = r_io_map_get (core->io, core->offset);
if (!map) { if (!map && !r_pvector_empty (&core->io->maps)) {
SdbListIter *i = ls_tail (core->io->maps); map = r_pvector_at (&core->io->maps, r_pvector_len (&core->io->maps) - 1);
if (i) {
map = ls_iter_get (i);
}
} }
if (map) { if (map) {
r_core_seek (core, r_itv_begin (map->itv), 1); 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; return true;
case 'G': case 'G':
map = r_io_map_get (core->io, core->offset); map = r_io_map_get (core->io, core->offset);
if (!map) { if (!map && !r_pvector_empty (&core->io->maps)) {
SdbListIter *i = ls_head (core->io->maps); map = r_pvector_at (&core->io->maps, 0);
if (i) {
map = ls_iter_get (i);
}
} }
if (map) { if (map) {
RPrint *p = core->print; RPrint *p = core->print;
@ -3431,13 +3425,13 @@ R_API int r_core_visual_cmd(RCore *core, const char *arg) {
if (s) { if (s) {
entry = s->vaddr; entry = s->vaddr;
} else { } else {
RIOMap *map = ls_pop (core->io->maps); RIOMap *map = r_pvector_pop (&core->io->maps);
if (map) { if (map) {
entry = map->itv.addr; entry = map->itv.addr;
} else { } else {
entry = r_config_get_i (core->config, "bin.baddr"); 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) { if (entry != UT64_MAX) {

View File

@ -90,7 +90,7 @@ typedef struct r_io_t {
int debug; int debug;
//#warning remove debug from RIO //#warning remove debug from RIO
RIDPool *map_ids; 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; // map parts that are not covered by others
RPVector map_skyline_shadow; // map parts that are not covered by others RPVector map_skyline_shadow; // map parts that are not covered by others
RIDStorage *files; RIDStorage *files;

View File

@ -229,6 +229,10 @@ static inline void **r_pvector_shrink(RPVector *vec) {
#define r_pvector_foreach(vec, it) \ #define r_pvector_foreach(vec, it) \
for (it = (void **)(vec)->v.a; it != (void **)(vec)->v.a + (vec)->v.len; 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: * example:
* *

View File

@ -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) { R_API bool r_io_desc_exchange(RIO* io, int fd, int fdx) {
RIODesc* desc, * descx; RIODesc* desc, * descx;
SdbListIter* iter;
RIOMap* map;
if (!(desc = r_io_desc_get (io, fd)) || !(descx = r_io_desc_get (io, fdx))) { if (!(desc = r_io_desc_get (io, fd)) || !(descx = r_io_desc_get (io, fdx))) {
return false; 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 (desc);
r_io_desc_cache_cleanup (descx); r_io_desc_cache_cleanup (descx);
} }
if (io->maps) { void **it;
ls_foreach (io->maps, iter, map) { r_pvector_foreach (&io->maps, it) {
if (map->fd == fdx) { RIOMap *map = *it;
map->perm &= (desc->perm | R_PERM_X); if (map->fd == fdx) {
} else if (map->fd == fd) { map->perm &= (desc->perm | R_PERM_X);
map->perm &= (descx->perm | R_PERM_X); } else if (map->fd == fd) {
} map->perm &= (descx->perm | R_PERM_X);
} }
} }
return true; return true;

View File

@ -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 */ /* opens a file and maps it to 0x0 */
R_API RIODesc* r_io_open(RIO* io, const char* uri, int perm, int mode) { 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); RIODesc* desc = r_io_open_nomap (io, uri, perm, mode);
if (desc) { if (desc) {
r_io_map_new (io, desc->fd, desc->perm, 0LL, 0LL, r_io_desc_size (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 */ /* 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_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); RIODesc* desc = r_io_open_nomap (io, uri, perm, mode);
if (!desc) { if (!desc) {

View File

@ -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 // Store map parts that are not covered by others into io->map_skyline
void io_map_calculate_skyline(RIO *io) { void io_map_calculate_skyline(RIO *io) {
SdbListIter *iter;
RIOMap *map;
RPVector events; RPVector events;
RBinHeap heap; RBinHeap heap;
struct map_event_t *ev; 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);
r_pvector_clear (&io->map_skyline_shadow); r_pvector_clear (&io->map_skyline_shadow);
r_pvector_init (&events, free); r_pvector_init (&events, free);
if (!r_pvector_reserve (&events, ls_length (io->maps) * 2) || if (!r_pvector_reserve (&events, r_pvector_len (&io->maps) * 2) ||
!(deleted = calloc (ls_length (io->maps), 1))) { !(deleted = calloc (r_pvector_len (&io->maps), 1))) {
goto out; goto out;
} }
int i = 0; int i = 0;
// Last map has highest priority (it shadows previous maps), // Last map has highest priority (it shadows previous maps),
// we assign 0 to its event id. // 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))) { if (!(ev = R_NEW (struct map_event_t))) {
goto out; goto out;
} }
@ -126,7 +126,7 @@ void io_map_calculate_skyline(RIO *io) {
r_binheap_pop (&heap); r_binheap_pop (&heap);
} }
ut64 to = ev->addr; 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) { if (!i) {
last = to; last = to;
last_map = map; 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) { 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; return NULL;
} }
RIOMap* map = R_NEW0 (RIOMap); 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->perm = perm;
map->delta = delta; map->delta = delta;
// new map lives on the top, being top the list's tail // 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) { if (do_skyline) {
io_map_calculate_skyline (io); io_map_calculate_skyline (io);
} }
@ -266,23 +266,20 @@ static void _map_free(void* p) {
} }
R_API void r_io_map_init(RIO* io) { R_API void r_io_map_init(RIO* io) {
if (io && !io->maps) { r_return_if_fail (io);
io->maps = ls_newf ((SdbListFree)_map_free); r_pvector_init (&io->maps, _map_free);
if (io->map_ids) { if (io->map_ids) {
r_id_pool_free (io->map_ids); r_id_pool_free (io->map_ids);
}
io->map_ids = r_id_pool_new (1, END_OF_MAP_IDS);
} }
io->map_ids = r_id_pool_new (1, END_OF_MAP_IDS);
} }
// check if a map with exact the same properties exists // check if a map with exact the same properties exists
R_API bool r_io_map_exists(RIO* io, RIOMap* map) { R_API bool r_io_map_exists(RIO *io, RIOMap *map) {
SdbListIter* iter; r_return_val_if_fail (io && map, false);
RIOMap* m; void **it;
if (!io || !io->maps || !map) { r_pvector_foreach (&io->maps, it) {
return false; RIOMap *m = *it;
}
ls_foreach (io->maps, iter, m) {
if (!memcmp (m, map, sizeof (RIOMap))) { if (!memcmp (m, map, sizeof (RIOMap))) {
return true; 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; return r_io_map_resolve (io, id) != NULL;
} }
R_API RIOMap* r_io_map_resolve(RIO* io, ut32 id) { R_API RIOMap* r_io_map_resolve(RIO *io, ut32 id) {
SdbListIter* iter; r_return_val_if_fail (io && id, false);
RIOMap* map; void **it;
if (!io || !io->maps || !id) { r_pvector_foreach (&io->maps, it) {
return NULL; RIOMap *map = *it;
}
ls_foreach (io->maps, iter, map) {
if (map->id == id) { if (map->id == id) {
return map; 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_API RIOMap* r_io_map_get_paddr(RIO* io, ut64 paddr) {
r_return_val_if_fail (io, NULL); r_return_val_if_fail (io, NULL);
RIOMap* map; void **it;
SdbListIter* iter; r_pvector_foreach_prev (&io->maps, it) {
ls_foreach_prev (io->maps, iter, map) { RIOMap *map = *it;
if (map->delta <= paddr && paddr <= map->delta + map->itv.size - 1) { if (map->delta <= paddr && paddr <= map->delta + map->itv.size - 1) {
return map; 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 // 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); r_return_val_if_fail (io, NULL);
RIOMap* map; void **it;
SdbListIter* iter; r_pvector_foreach_prev (&io->maps, it) {
ls_foreach_prev (io->maps, iter, map) { RIOMap *map = *it;
if (r_itv_contain (map->itv, addr)) { if (r_itv_contain (map->itv, addr)) {
return map; return map;
} }
@ -378,13 +373,14 @@ R_API void r_io_map_reset(RIO* io) {
io_map_calculate_skyline (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); r_return_val_if_fail (io, false);
RIOMap* map; size_t i;
SdbListIter* iter; for (i = 0; i < r_pvector_len (&io->maps); i++) {
ls_foreach (io->maps, iter, map) { RIOMap *map = r_pvector_at (&io->maps, i);
if (map->id == id) { 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); r_id_pool_kick_id (io->map_ids, id);
io_map_calculate_skyline (io); io_map_calculate_skyline (io);
return true; return true;
@ -396,17 +392,20 @@ R_API bool r_io_map_del(RIO* io, ut32 id) {
//delete all maps with specified fd //delete all maps with specified fd
R_API bool r_io_map_del_for_fd(RIO* io, int fd) { R_API bool r_io_map_del_for_fd(RIO* io, int fd) {
r_return_val_if_fail (io, false); r_return_val_if_fail (io, false);
SdbListIter* iter, * ator;
RIOMap* map;
bool ret = false; 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) { if (!map) {
ls_delete (io->maps, iter); r_pvector_remove_at (&io->maps, i);
} else if (map->fd == fd) { } else if (map->fd == fd) {
r_id_pool_kick_id (io->map_ids, map->id); r_id_pool_kick_id (io->map_ids, map->id);
//delete iter and map //delete iter and map
ls_delete (io->maps, iter); r_pvector_remove_at (&io->maps, i);
_map_free (map);
ret = true; ret = true;
} else {
i++;
} }
} }
if (ret) { 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 //return a boolean denoting whether is was possible to priorized
R_API bool r_io_map_priorize(RIO* io, ut32 id) { R_API bool r_io_map_priorize(RIO* io, ut32 id) {
r_return_val_if_fail (io, false); r_return_val_if_fail (io, false);
RIOMap *map; size_t i;
SdbListIter *iter; for (i = 0; i < r_pvector_len (&io->maps); i++) {
ls_foreach (io->maps, iter, map) { RIOMap *map = r_pvector_at (&io->maps, i);
// search for iter with the correct map // search for iter with the correct map
if (map->id == id) { if (map->id == id) {
ls_split_iter (io->maps, iter); r_pvector_remove_at (&io->maps, i);
ls_append (io->maps, map); r_pvector_push (&io->maps, map);
io_map_calculate_skyline (io); io_map_calculate_skyline (io);
free (iter);
return true; 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_API bool r_io_map_depriorize(RIO* io, ut32 id) {
r_return_val_if_fail (io, false); r_return_val_if_fail (io, false);
RIOMap *map; size_t i;
SdbListIter *iter; for (i = 0; i < r_pvector_len (&io->maps); i++) {
ls_foreach (io->maps, iter, map) { RIOMap *map = r_pvector_at (&io->maps, i);
// search for iter with the correct map // search for iter with the correct map
if (map->id == id) { if (map->id == id) {
ls_split_iter (io->maps, iter); r_pvector_remove_at (&io->maps, i);
ls_prepend (io->maps, map); r_pvector_push_front (&io->maps, map);
io_map_calculate_skyline (io); io_map_calculate_skyline (io);
free (iter);
return true; return true;
} }
} }
return false; return false;
} }
R_API bool r_io_map_priorize_for_fd(RIO* io, int fd) { R_API bool r_io_map_priorize_for_fd(RIO *io, int fd) {
SdbListIter* iter, * ator; r_return_val_if_fail (io, false);
RIOMap *map;
SdbList* list;
if (!io || !io->maps) {
return false;
}
if (!(list = ls_new ())) {
return false;
}
//we need a clean list for this, or this becomes a segfault-field //we need a clean list for this, or this becomes a segfault-field
r_io_map_cleanup (io); r_io_map_cleanup (io);
//temporary set to avoid free the map and to speed up ls_delete a bit RPVector temp;
io->maps->free = NULL; r_pvector_init (&temp, NULL);
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->fd == fd) { if (map->fd == fd) {
ls_prepend (list, map); r_pvector_push (&temp, map);
ls_delete (io->maps, iter); r_pvector_remove_at (&io->maps, i);
continue;
} }
i++;
} }
ls_join (io->maps, list); r_pvector_insert_range (&io->maps, r_pvector_len (&io->maps), temp.v.a, r_pvector_len (&temp));
ls_free (list); r_pvector_clear (&temp);
io->maps->free = _map_free;
io_map_calculate_skyline (io); io_map_calculate_skyline (io);
return true; return true;
} }
//may fix some inconsistencies in io->maps //may fix some inconsistencies in io->maps
R_API void r_io_map_cleanup(RIO* io) { R_API void r_io_map_cleanup(RIO* io) {
SdbListIter* iter, * ator; r_return_if_fail (io);
RIOMap* map;
if (!io || !io->maps) {
return;
}
//remove all maps if no descs exist //remove all maps if no descs exist
if (!io->files) { if (!io->files) {
r_io_map_fini (io); r_io_map_fini (io);
@ -492,16 +480,20 @@ R_API void r_io_map_cleanup(RIO* io) {
return; return;
} }
bool del = false; 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 //remove iter if the map is a null-ptr, this may fix some segfaults
if (!map) { if (!map) {
ls_delete (io->maps, iter); r_pvector_remove_at (&io->maps, i);
del = true; del = true;
} else if (!r_io_desc_get (io, map->fd)) { } else if (!r_io_desc_get (io, map->fd)) {
//delete map and iter if no desc exists for map->fd in io->files //delete map and iter if no desc exists for map->fd in io->files
r_id_pool_kick_id (io->map_ids, map->id); r_id_pool_kick_id (io->map_ids, map->id);
ls_delete (io->maps, iter); r_pvector_remove_at (&io->maps, i);
del = true; del = true;
} else {
i++;
} }
} }
if (del) { 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_API void r_io_map_fini(RIO* io) {
r_return_if_fail (io); r_return_if_fail (io);
ls_free (io->maps); r_pvector_clear (&io->maps);
io->maps = NULL;
r_id_pool_free (io->map_ids); r_id_pool_free (io->map_ids);
io->map_ids = NULL; io->map_ids = NULL;
r_pvector_clear (&io->map_skyline); 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) { if (load_align == 0) {
load_align = 1; load_align = 1;
} }
RIOMap* map;
SdbListIter* iter;
ut64 next_addr = addr, ut64 next_addr = addr,
end_addr = next_addr + size; 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); ut64 to = r_itv_end (map->itv);
next_addr = R_MAX (next_addr, to + (load_align - (to % load_align)) % load_align); next_addr = R_MAX (next_addr, to + (load_align - (to % load_align)) % load_align);
// XXX - This does not handle when file overflow 0xFFFFFFFF000 -> 0x00000FFF // 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 // 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) { R_API ut64 r_io_map_next_address(RIO* io, ut64 addr) {
RIOMap* map;
SdbListIter* iter;
ut64 lowest = UT64_MAX; ut64 lowest = UT64_MAX;
void **it;
ls_foreach (io->maps, iter, map) { r_pvector_foreach (&io->maps, it) {
RIOMap *map = *it;
ut64 from = r_itv_begin (map->itv); ut64 from = r_itv_begin (map->itv);
if (from > addr && addr < lowest) { if (from > addr && addr < lowest) {
lowest = from; 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) { R_API RList* r_io_map_get_for_fd(RIO* io, int fd) {
RList* map_list = r_list_newf (NULL); RList* map_list = r_list_newf (NULL);
SdbListIter* iter;
RIOMap* map;
if (!map_list) { if (!map_list) {
return NULL; return NULL;
} }
ls_foreach (io->maps, iter, map) { void **it;
r_pvector_foreach (&io->maps, it) {
RIOMap *map = *it;
if (map && map->fd == fd) { if (map && map->fd == fd) {
r_list_append (map_list, map); r_list_append (map_list, map);
} }