Skip to content

Commit

Permalink
Implement r_io_submap_set{from/to} (siol_eternal) #18476 ##io
Browse files Browse the repository at this point in the history
  • Loading branch information
condret committed May 30, 2021
1 parent d5dc2b7 commit cf800b2
Show file tree
Hide file tree
Showing 3 changed files with 61 additions and 8 deletions.
2 changes: 2 additions & 0 deletions libr/include/r_io.h
Original file line number Diff line number Diff line change
Expand Up @@ -353,6 +353,8 @@ R_API ut64 r_io_v2p(RIO *io, ut64 va);

//io_submap.c
R_API RIOSubMap *r_io_submap_new(RIO *io, RIOMapRef *mapref);
R_API bool r_io_submap_set_from(RIOSubMap *sm, const ut64 from);
R_API bool r_io_submap_set_to(RIOSubMap *sm, const ut64 to);

//io_bank.c
R_API RIOBank *r_io_bank_new(void);
Expand Down
48 changes: 40 additions & 8 deletions libr/io/io_bank.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
#include <r_io.h>
#include <r_util.h>

#define OLD_SM 0

R_API RIOBank *r_io_bank_new(void) {
RIOBank *bank = R_NEW0 (RIOBank);
if (!bank) {
Expand Down Expand Up @@ -140,21 +142,29 @@ R_API bool r_io_bank_map_add_top(RIO *io, const ut32 bankid, const ut32 mapid) {
if (r_io_submap_from (bd) < r_io_submap_from (sm) &&
r_io_submap_to (sm) < r_io_submap_to (bd)) {
// split bd into 2 maps => bd and bdsm
RIOSubMap *bdsm = R_NEW (RIOSubMap);
RIOSubMap *bdsm = R_NEWCOPY (RIOSubMap, bd);
if (!bdsm) {
free (sm);
return false;
}
bdsm->mapref = bd->mapref;
#if OLD_SM
bdsm->itv.addr = r_io_submap_to (sm) + 1;
bdsm->itv.size = r_io_submap_to (bd) - bdsm->itv.addr + 1;
bdsm->itv.size = r_io_submap_to (bd) - r_io_submap_from (bdsm) + 1;
bd->itv.size = r_io_submap_from (sm) - r_io_submap_from (bd);
#else
r_io_submap_set_from (bdsm, r_io_submap_to (sm) + 1);
r_io_submap_set_to (bd, r_io_submap_from (sm) - 1);
#endif
// TODO: insert and check return value, before adjusting sm size
return r_rbtree_cont_insert (bank->submaps, sm, _find_sm_by_vaddr_cb, NULL) &
r_rbtree_cont_insert (bank->submaps, bdsm, _find_sm_by_vaddr_cb, NULL);
}

#if OLD_SM
bd->itv.size = r_io_submap_from (sm) - r_io_submap_from (bd);
#else
r_io_submap_set_to (bd, r_io_submap_from (sm) -1);
#endif
entry = r_rbtree_cont_node_next (entry);
while (entry && r_io_submap_to (((RIOSubMap *)entry->data)) <= r_io_submap_to (sm)) {
//delete all submaps that are completly included in sm
Expand All @@ -165,8 +175,12 @@ R_API bool r_io_bank_map_add_top(RIO *io, const ut32 bankid, const ut32 mapid) {
}
if (entry && r_io_submap_from (((RIOSubMap *)entry->data)) <= r_io_submap_to (sm)) {
bd = (RIOSubMap *)entry->data;
#if OLD_SM
bd->itv.size = r_io_submap_to (bd) - r_io_submap_to (sm);
bd->itv.addr = r_io_submap_to (sm) + 1;
#else
r_io_submap_set_from (bd, r_io_submap_to (sm) + 1);
#endif
}
return r_rbtree_cont_insert (bank->submaps, sm, _find_sm_by_vaddr_cb, NULL);
}
Expand Down Expand Up @@ -198,28 +212,42 @@ R_API bool r_io_bank_map_priorize(RIO *io, const ut32 bankid, const ut32 mapid)
}
RIOSubMap *bd = (RIOSubMap *)entry->data;
if (r_itv_eq (bd->itv, sm->itv)) {
// no need to insert new sm, if boundaries match perfectly
// instead override mapref of existing node/submap
bd->mapref = *mapref;
free (sm);
return true;
}
if (r_io_submap_from (bd) < r_io_submap_from (sm) &&
r_io_submap_to (sm) < r_io_submap_to (bd)) {
// split bd into 2 maps => bd and bdsm
RIOSubMap *bdsm = R_NEW (RIOSubMap);
// bd completly overlaps sm on both ends,
// therefor split bd into 2 maps => bd and bdsm
// |---bd---||--sm--|-bdsm-|
RIOSubMap *bdsm = R_NEWCOPY (RIOSubMap, bd);
if (!bdsm) {
free (sm);
return false;
}
bdsm->mapref = bd->mapref;
#if OLD_SM
bdsm->itv.addr = r_io_submap_to (sm) + 1;
bdsm->itv.size = r_io_submap_to (bd) - bdsm->itv.addr + 1;
bd->itv.size = sm->itv.addr - bd->itv.addr;
bdsm->itv.size = r_io_submap_to (bd) - r_io_submap_from (bdsm) + 1;
bd->itv.size = r_io_submap_from (sm) - r_io_submap_from (bd);
#else
r_io_submap_set_from (bdsm, r_io_submap_to (sm) + 1);
r_io_submap_set_to (bd, r_io_submap_from (sm) - 1);
#endif
// TODO: insert and check return value, before adjusting sm size
return r_rbtree_cont_insert (bank->submaps, sm, _find_sm_by_vaddr_cb, NULL) &
r_rbtree_cont_insert (bank->submaps, bdsm, _find_sm_by_vaddr_cb, NULL);
}

// bd overlaps by it's upper boundary with sm, due to how _find_entry_submap_node works
// therefor no check is needed here, and the upper boundary can be adjusted safely
#if OLD_SM
bd->itv.size = r_io_submap_from (sm) - r_io_submap_from (bd);
#else
r_io_submap_set_to (bd, r_io_submap_from (sm) - 1);
#endif
entry = r_rbtree_cont_node_next (entry);
while (entry && r_io_submap_to (((RIOSubMap *)entry->data)) <= r_io_submap_to (sm)) {
//delete all submaps that are completly included in sm
Expand All @@ -230,8 +258,12 @@ R_API bool r_io_bank_map_priorize(RIO *io, const ut32 bankid, const ut32 mapid)
}
if (entry && r_io_submap_from (((RIOSubMap *)entry->data)) <= r_io_submap_to (sm)) {
bd = (RIOSubMap *)entry->data;
#if OLD_SM
bd->itv.size = r_io_submap_to (bd) - r_io_submap_to (sm);
bd->itv.addr = r_io_submap_to (sm) + 1;
#else
r_io_submap_set_from (bd, r_io_submap_to (sm) + 1);
#endif
}
return r_rbtree_cont_insert (bank->submaps, sm, _find_sm_by_vaddr_cb, NULL);
}
Expand Down
19 changes: 19 additions & 0 deletions libr/io/io_submap.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,22 @@ R_API RIOSubMap *r_io_submap_new(RIO *io, RIOMapRef *mapref) {
}
return sm;
}

R_API bool r_io_submap_set_from(RIOSubMap *sm, const ut64 from) {
r_return_val_if_fail (sm, false);
if (r_io_submap_to (sm) < from) {
return false;
}
sm->itv.size = sm->itv.addr + sm->itv.size - from;
sm->itv.addr = from;
return true;
}

R_API bool r_io_submap_set_to(RIOSubMap *sm, const ut64 to) {
r_return_val_if_fail (sm, false);
if (r_io_submap_from (sm) > to) {
return false;
}
sm->itv.size = sm->itv.size + r_io_submap_to (sm) - to;
return true;
}

0 comments on commit cf800b2

Please sign in to comment.