2016-03-13 23:11:31 +00:00
/* radare2 - LGPL - Copyright 2008-2016 - pancake, nibble */
2009-02-05 21:08:46 +00:00
# include "r_io.h"
2016-03-13 23:11:31 +00:00
// no link
# include "r_cons.h"
2014-11-07 02:48:27 +00:00
2010-04-08 10:29:47 +00:00
R_API void r_io_section_init ( RIO * io ) {
2011-04-18 22:59:16 +00:00
io - > next_section_id = 0 ;
2009-09-08 18:16:52 +00:00
io - > enforce_rwx = 0 ; // do not enforce RWX section permissions by default
io - > enforce_seek = 0 ; // do not limit seeks out of the file by default
2011-04-19 12:43:48 +00:00
io - > sections = r_list_new ( ) ;
2016-08-08 08:45:32 +00:00
if ( ! io - > sections ) {
return ;
}
2016-01-03 02:03:35 +00:00
io - > sections - > free = r_io_section_free ;
2009-09-08 02:14:19 +00:00
}
2009-02-05 21:08:46 +00:00
2012-02-16 00:26:50 +00:00
#if 0
2011-05-13 10:24:17 +00:00
static int cmpaddr ( void * _a , void * _b ) {
RIOSection * a = _a , * b = _b ;
return ( a - > vaddr > b - > vaddr ) ;
}
2012-02-16 00:26:50 +00:00
# endif
2011-05-13 10:24:17 +00:00
2011-09-03 01:10:01 +00:00
R_API RIOSection * r_io_section_get_name ( RIO * io , const char * name ) {
RListIter * iter ;
RIOSection * s ;
2011-10-24 15:16:54 +00:00
if ( name )
2011-09-03 01:10:01 +00:00
r_list_foreach ( io - > sections , iter , s ) {
2016-08-08 08:45:32 +00:00
if ( ! strcmp ( name , s - > name ) ) {
2011-09-03 01:10:01 +00:00
return s ;
2016-08-08 08:45:32 +00:00
}
2011-09-03 01:10:01 +00:00
}
return NULL ;
}
2016-01-03 00:40:09 +00:00
// update name and rwx, size is experimental
2016-01-03 00:36:16 +00:00
static RIOSection * findMatching ( RIO * io , ut64 paddr , ut64 vaddr , ut64 size , ut64 vsize , int rwx , const char * name ) {
RListIter * iter ;
RIOSection * s ;
r_list_foreach ( io - > sections , iter , s ) {
if ( s - > offset ! = paddr ) continue ;
if ( s - > vaddr ! = vaddr ) continue ;
2016-01-03 00:40:09 +00:00
# if 1
if ( s - > size ! = size ) continue ;
if ( s - > vsize ! = vsize ) continue ;
# else
2016-01-03 00:36:16 +00:00
s - > size = size ;
s - > vsize = vsize ;
2016-01-03 00:40:09 +00:00
# endif
2016-01-03 00:36:16 +00:00
s - > rwx = rwx ;
if ( name & & strcmp ( name , s - > name ) ) {
2016-01-03 02:03:35 +00:00
s - > name = strdup ( name ) ;
2016-01-03 00:36:16 +00:00
}
return s ;
}
return NULL ;
}
2014-08-25 01:45:11 +00:00
R_API RIOSection * r_io_section_add ( RIO * io , ut64 offset , ut64 vaddr , ut64 size , ut64 vsize , int rwx , const char * name , ut32 bin_id , int fd ) {
2011-09-03 01:10:01 +00:00
int update = 0 ;
2012-09-27 17:35:19 +00:00
RIOSection * s ;
2016-07-05 10:46:28 +00:00
if ( ! size | | size = = UT64_MAX | | size = = UT32_MAX ) { //hacky things which might give bad output in case size == UT32_MAX for 64bit elf. Check on basis of size, offset and file size would be a good idea.
#if 0
2016-03-22 12:16:32 +00:00
eprintf ( " Invalid size (0x%08 " PFMT64x
" ) for section '%s' at 0x%08 " PFMT64x " \n " ,
size , name , vaddr ) ;
2016-07-05 10:46:28 +00:00
# endif
2014-08-25 01:58:22 +00:00
return NULL ;
2012-01-31 02:34:23 +00:00
}
2016-01-03 00:36:16 +00:00
s = findMatching ( io , offset , vaddr , size , vsize , rwx , name ) ;
if ( s ) {
return s ;
}
2012-09-27 17:35:19 +00:00
s = r_io_section_get_name ( io , name ) ;
2016-07-03 17:32:06 +00:00
if ( ! s ) {
2016-01-03 02:03:35 +00:00
s = R_NEW0 ( RIOSection ) ;
2012-09-27 17:35:19 +00:00
s - > id = io - > next_section_id + + ;
2016-03-22 12:16:32 +00:00
} else {
update = 1 ;
}
2010-02-18 17:58:28 +00:00
s - > offset = offset ;
2009-02-05 21:08:46 +00:00
s - > vaddr = vaddr ;
2010-02-18 17:58:28 +00:00
s - > size = size ;
s - > vsize = vsize ;
2009-02-05 21:08:46 +00:00
s - > rwx = rwx ;
2012-11-30 00:06:30 +00:00
s - > arch = s - > bits = 0 ;
2014-05-08 23:35:04 +00:00
s - > bin_id = bin_id ;
s - > fd = fd ;
2011-09-03 01:10:01 +00:00
if ( ! update ) {
2016-01-03 02:03:35 +00:00
if ( name ) s - > name = strdup ( name ) ;
else s - > name = strdup ( " " ) ;
2011-10-25 18:30:05 +00:00
r_list_append ( io - > sections , s ) ;
2012-11-30 00:06:30 +00:00
}
2014-08-25 01:45:11 +00:00
return s ;
2009-02-05 21:08:46 +00:00
}
2010-04-08 10:29:47 +00:00
R_API RIOSection * r_io_section_get_i ( RIO * io , int idx ) {
2011-04-19 12:43:48 +00:00
RListIter * iter ;
RIOSection * s ;
2016-01-22 15:38:12 +00:00
if ( ! io | | ! io - > sections )
return NULL ;
2011-04-19 12:43:48 +00:00
r_list_foreach ( io - > sections , iter , s ) {
2011-04-18 22:59:16 +00:00
if ( s - > id = = idx )
2009-02-05 21:08:46 +00:00
return s ;
}
return NULL ;
}
2010-04-08 10:29:47 +00:00
R_API int r_io_section_rm ( RIO * io , int idx ) {
2016-01-22 15:38:12 +00:00
RListIter * iter ;
RIOSection * s ;
2016-08-08 08:45:32 +00:00
if ( ! io | | ! io - > sections ) {
2016-01-22 15:38:12 +00:00
return false ;
2016-08-08 08:45:32 +00:00
}
2016-01-22 15:38:12 +00:00
r_list_foreach ( io - > sections , iter , s ) {
if ( s - > id = = idx ) {
r_list_delete ( io - > sections , iter ) ;
return true ;
}
}
return false ;
2009-02-05 21:08:46 +00:00
}
2014-09-16 21:07:28 +00:00
R_API int r_io_section_rm_all ( RIO * io , int fd ) {
RIOSection * section ;
RListIter * iter , * ator ;
2016-08-08 08:45:32 +00:00
if ( ! io | | ! io - > sections ) {
2015-09-14 00:08:31 +00:00
return false ;
2016-08-08 08:45:32 +00:00
}
2014-09-16 21:07:28 +00:00
r_list_foreach_safe ( io - > sections , iter , ator , section ) {
2015-01-22 01:22:29 +00:00
if ( section - > fd = = fd | | fd = = - 1 )
2014-09-16 21:07:28 +00:00
r_list_delete ( io - > sections , iter ) ;
}
2015-09-14 00:08:31 +00:00
return true ;
2014-09-16 21:07:28 +00:00
}
2016-01-03 02:03:35 +00:00
R_API void r_io_section_free ( void * ptr ) {
RIOSection * s = ( RIOSection * ) ptr ;
if ( s ) {
free ( s - > name ) ;
free ( s ) ;
}
}
2014-05-16 01:48:14 +00:00
R_API void r_io_section_clear ( RIO * io ) {
r_list_free ( io - > sections ) ;
io - > sections = r_list_new ( ) ;
2016-08-08 08:45:32 +00:00
if ( ! io - > sections ) {
return ;
}
2016-01-03 02:03:35 +00:00
io - > sections - > free = r_io_section_free ;
2014-05-16 01:48:14 +00:00
}
2009-02-05 21:08:46 +00:00
// TODO: implement as callback
2010-04-08 10:29:47 +00:00
R_API void r_io_section_list ( RIO * io , ut64 offset , int rad ) {
2009-02-05 21:08:46 +00:00
int i = 0 ;
2011-04-19 12:43:48 +00:00
RListIter * iter ;
RIOSection * s ;
2010-02-21 10:35:49 +00:00
2010-08-15 23:50:01 +00:00
if ( io - > va | | io - > debug )
2015-09-09 20:01:29 +00:00
offset = r_io_section_vaddr_to_maddr_try ( io , offset ) ;
2014-05-21 19:01:21 +00:00
// XXX - Should this print the section->id or the location in the
// rio sections array?
2011-10-25 18:30:05 +00:00
r_list_foreach ( io - > sections , iter , s ) {
2012-11-14 02:25:32 +00:00
if ( rad ) {
char * n = strdup ( s - > name ) ;
r_name_filter ( n , strlen ( n ) ) ;
2015-08-08 18:15:13 +00:00
io - > cb_printf ( " f section.%s % " PFMT64d " 0x% " PFMT64x " \n " ,
2013-03-17 23:38:04 +00:00
n , s - > size , s - > vaddr ) ;
2015-08-08 18:15:13 +00:00
io - > cb_printf ( " S 0x%08 " PFMT64x " 0x%08 " PFMT64x " 0x%08 "
2013-03-17 23:38:04 +00:00
PFMT64x " 0x%08 " PFMT64x " %s %s \n " , s - > offset ,
s - > vaddr , s - > size , s - > vsize , n , r_str_rwx_i ( s - > rwx ) ) ;
2012-11-30 00:06:30 +00:00
} else {
2015-08-08 18:15:13 +00:00
io - > cb_printf ( " [%02d] %c 0x%08 " PFMT64x " %s va=0x%08 " PFMT64x
2014-06-26 23:43:04 +00:00
" sz=0x%04 " PFMT64x " vsz=0x%04 " PFMT64x " %s " ,
2014-05-21 19:01:21 +00:00
i , ( offset > = s - > offset & & offset < s - > offset + s - > size ) ? ' * ' : ' . ' ,
2010-04-08 10:29:47 +00:00
s - > offset , r_str_rwx_i ( s - > rwx ) , s - > vaddr , s - > size , s - > vsize , s - > name ) ;
2012-11-30 00:06:30 +00:00
if ( s - > arch & & s - > bits )
2015-08-08 18:15:13 +00:00
io - > cb_printf ( " ; %s %d \n " , r_sys_arch_str ( s - > arch ) , s - > bits ) ;
else io - > cb_printf ( " \n " ) ;
2012-11-30 00:06:30 +00:00
}
2009-02-05 21:08:46 +00:00
i + + ;
}
}
2015-01-27 14:35:42 +00:00
2015-10-13 18:48:14 +00:00
# define PRINT_CURRENT_SEEK \
if ( i > 0 & & len ! = 0 ) { \
if ( seek = = UT64_MAX ) seek = 0 ; \
io - > cb_printf ( " => 0x%08 " PFMT64x " | " , seek ) ; \
for ( j = 0 ; j < width ; j + + ) { \
io - > cb_printf ( \
( ( j * mul ) + min > = seek & & \
( j * mul ) + min < = seek + len ) \
? " ^ " : " - " ) ; \
} \
io - > cb_printf ( " | 0x%08 " PFMT64x " \n " , seek + len ) ; \
}
2016-03-13 23:11:31 +00:00
static void list_section_visual_vaddr ( RIO * io , ut64 seek , ut64 len , int use_color , int cols ) {
2014-11-07 02:48:27 +00:00
ut64 mul , min = - 1 , max = - 1 ;
2011-04-19 12:43:48 +00:00
RListIter * iter ;
RIOSection * s ;
2015-10-13 18:48:14 +00:00
int j , i = 0 ;
2016-03-13 23:11:31 +00:00
int width = cols - 60 ;
2015-10-11 20:52:53 +00:00
if ( width < 1 ) width = 30 ;
2015-10-13 18:48:14 +00:00
r_list_foreach ( io - > sections , iter , s ) {
2016-08-08 08:45:32 +00:00
if ( min = = - 1 | | s - > vaddr < min ) {
2015-10-13 18:48:14 +00:00
min = s - > vaddr ;
2016-08-08 08:45:32 +00:00
}
if ( max = = - 1 | | s - > vaddr + s - > size > max ) {
2015-10-13 18:48:14 +00:00
max = s - > vaddr + s - > size ;
2016-08-08 08:45:32 +00:00
}
2015-10-13 18:48:14 +00:00
}
mul = ( max - min ) / width ;
if ( min ! = - 1 & & mul ! = 0 ) {
const char * color = " " , * color_end = " " ;
char buf [ 128 ] ;
i = 0 ;
r_list_foreach ( io - > sections , iter , s ) {
r_num_units ( buf , s - > size ) ;
if ( use_color ) {
color_end = Color_RESET ;
if ( s - > rwx & 1 ) { // exec bit
color = Color_GREEN ;
} else if ( s - > rwx & 2 ) { // write bit
color = Color_RED ;
} else {
color = " " ;
color_end = " " ;
}
} else {
color = " " ;
color_end = " " ;
}
2015-10-15 19:56:17 +00:00
io - > cb_printf ( " %02d%c %s0x%08 " PFMT64x " %s | " , i ,
2015-10-13 18:48:14 +00:00
( seek > = s - > vaddr & & seek < s - > vaddr + s - > size ) ? ' * ' : ' ' ,
//(seek>=s->vaddr && seek<s->vaddr+s->size)?'*':' ',
2015-10-15 19:56:17 +00:00
color , s - > vaddr , color_end ) ;
2015-10-13 18:48:14 +00:00
for ( j = 0 ; j < width ; j + + ) {
ut64 pos = min + ( j * mul ) ;
ut64 npos = min + ( ( j + 1 ) * mul ) ;
if ( s - > vaddr < npos & & ( s - > vaddr + s - > size ) > pos )
io - > cb_printf ( " # " ) ;
else io - > cb_printf ( " - " ) ;
}
2015-10-15 19:56:17 +00:00
io - > cb_printf ( " | %s0x%08 " PFMT64x " %s %s %s %04s \n " ,
2015-10-13 18:48:14 +00:00
color , s - > vaddr + s - > size , color_end ,
2015-10-15 19:56:17 +00:00
r_str_rwx_i ( s - > rwx ) , s - > name , buf ) ;
2015-10-13 18:48:14 +00:00
i + + ;
2016-08-08 08:45:32 +00:00
}
2015-10-13 18:48:14 +00:00
PRINT_CURRENT_SEEK ;
}
}
2009-02-05 21:08:46 +00:00
2016-03-13 23:11:31 +00:00
static void list_section_visual_paddr ( RIO * io , ut64 seek , ut64 len , int use_color , int cols ) {
2015-10-13 18:48:14 +00:00
ut64 mul , min = - 1 , max = - 1 ;
RListIter * iter ;
RIOSection * s ;
int j , i = 0 ;
2016-03-13 23:11:31 +00:00
int width = cols - 60 ;
2015-10-13 18:48:14 +00:00
if ( width < 1 ) width = 30 ;
seek = r_io_section_vaddr_to_maddr_try ( io , seek ) ;
2011-04-19 12:43:48 +00:00
r_list_foreach ( io - > sections , iter , s ) {
2010-02-18 17:58:28 +00:00
if ( min = = - 1 | | s - > offset < min )
min = s - > offset ;
if ( max = = - 1 | | s - > offset + s - > size > max )
max = s - > offset + s - > size ;
2009-02-05 21:08:46 +00:00
}
mul = ( max - min ) / width ;
if ( min ! = - 1 & & mul ! = 0 ) {
2014-11-07 02:48:27 +00:00
const char * color = " " , * color_end = " " ;
2015-10-13 10:55:38 +00:00
char buf [ 128 ] ;
2009-02-05 21:08:46 +00:00
i = 0 ;
2011-10-25 18:30:05 +00:00
r_list_foreach ( io - > sections , iter , s ) {
2015-10-13 10:55:38 +00:00
r_num_units ( buf , s - > size ) ;
2014-11-07 02:48:27 +00:00
if ( use_color ) {
color_end = Color_RESET ;
if ( s - > rwx & 1 ) { // exec bit
color = Color_GREEN ;
} else if ( s - > rwx & 2 ) { // write bit
color = Color_RED ;
} else {
color = " " ;
color_end = " " ;
}
} else {
color = " " ;
color_end = " " ;
}
2015-10-15 19:56:17 +00:00
io - > cb_printf ( " %02d%c %s0x%08 " PFMT64x " %s | " , i ,
2015-10-13 18:48:14 +00:00
( seek > = s - > offset & & seek < s - > offset + s - > size ) ? ' * ' : ' ' ,
2015-10-15 19:56:17 +00:00
color , s - > offset , color_end ) ;
2015-10-11 20:52:53 +00:00
for ( j = 0 ; j < width ; j + + ) {
ut64 pos = min + ( j * mul ) ;
ut64 npos = min + ( ( j + 1 ) * mul ) ;
if ( s - > offset < npos & & ( s - > offset + s - > size ) > pos )
2015-08-08 18:15:13 +00:00
io - > cb_printf ( " # " ) ;
else io - > cb_printf ( " - " ) ;
2009-02-05 21:08:46 +00:00
}
2015-10-15 19:56:17 +00:00
io - > cb_printf ( " | %s0x%08 " PFMT64x " %s %s %s %04s \n " ,
2015-10-13 18:48:14 +00:00
color , s - > offset + s - > size , color_end ,
2015-10-15 19:56:17 +00:00
r_str_rwx_i ( s - > rwx ) , s - > name , buf ) ;
2015-10-13 18:48:14 +00:00
2009-02-05 21:08:46 +00:00
i + + ;
}
2015-10-13 18:48:14 +00:00
PRINT_CURRENT_SEEK ;
2009-02-05 21:08:46 +00:00
}
}
2015-10-13 18:48:14 +00:00
/* TODO: move to print ??? support pretty print of ranges following an array of offsetof */
2016-03-13 23:11:31 +00:00
R_API void r_io_section_list_visual ( RIO * io , ut64 seek , ut64 len , int use_color , int cols ) {
if ( io - > va ) list_section_visual_vaddr ( io , seek , len , use_color , cols ) ;
else list_section_visual_paddr ( io , seek , len , use_color , cols ) ;
2015-10-13 18:48:14 +00:00
}
2014-05-28 02:34:12 +00:00
R_API RIOSection * r_io_section_vget ( RIO * io , ut64 vaddr ) {
2012-12-05 23:55:22 +00:00
RListIter * iter ;
RIOSection * s ;
r_list_foreach ( io - > sections , iter , s ) {
2013-01-03 00:43:23 +00:00
if ( vaddr > = s - > vaddr & & vaddr < s - > vaddr + s - > vsize )
2012-12-05 23:55:22 +00:00
return s ;
}
return NULL ;
}
2016-01-03 02:03:35 +00:00
// maddr == section->offset
R_API RIOSection * r_io_section_mget_in ( RIO * io , ut64 maddr ) {
2011-04-19 12:43:48 +00:00
RIOSection * s ;
2014-05-28 02:34:12 +00:00
RListIter * iter ;
2011-04-19 12:43:48 +00:00
r_list_foreach ( io - > sections , iter , s ) {
2014-05-28 02:34:12 +00:00
if ( ( maddr > = s - > offset & & maddr < ( s - > offset + s - > size ) ) )
2009-02-05 21:08:46 +00:00
return s ;
}
return NULL ;
}
2015-12-09 20:17:49 +00:00
R_API RIOSection * r_io_section_mget_prev ( RIO * io , ut64 maddr ) {
RIOSection * s ;
RListIter * iter ;
r_list_foreach_prev ( io - > sections , iter , s ) {
if ( ( maddr > = s - > offset & & maddr < ( s - > offset + s - > size ) ) )
return s ;
}
return NULL ;
}
2014-05-31 10:14:49 +00:00
// XXX: rename this
R_API ut64 r_io_section_get_offset ( RIO * io , ut64 maddr ) {
2016-01-03 02:03:35 +00:00
RIOSection * s = r_io_section_mget_in ( io , maddr ) ;
2014-06-27 01:10:09 +00:00
return s ? s - > offset : UT64_MAX ;
2009-02-05 21:08:46 +00:00
}
2014-05-31 10:14:49 +00:00
// XXX: must be renamed, this is confusing
R_API ut64 r_io_section_get_vaddr ( RIO * io , ut64 maddr ) {
2016-01-03 02:03:35 +00:00
RIOSection * s = r_io_section_mget_in ( io , maddr ) ;
2014-06-27 01:10:09 +00:00
return s ? s - > vaddr : UT64_MAX ;
2009-02-05 21:08:46 +00:00
}
2010-04-08 10:29:47 +00:00
// TODO: deprecate
R_API int r_io_section_get_rwx ( RIO * io , ut64 offset ) {
2016-01-03 02:03:35 +00:00
RIOSection * s = r_io_section_mget_in ( io , offset ) ;
2009-09-08 02:14:19 +00:00
return s ? s - > rwx : R_IO_READ | R_IO_WRITE | R_IO_EXEC ;
}
2010-04-08 10:29:47 +00:00
R_API int r_io_section_overlaps ( RIO * io , RIOSection * s ) {
2009-02-05 21:08:46 +00:00
int i = 0 ;
2011-04-19 12:43:48 +00:00
RListIter * iter ;
RIOSection * s2 ;
2011-10-25 18:30:05 +00:00
r_list_foreach ( io - > sections , iter , s2 ) {
2015-08-25 11:20:19 +00:00
if ( ! ( s - > rwx & R_IO_MAP ) ) continue ;
2009-02-05 21:08:46 +00:00
if ( s ! = s2 ) {
2010-02-18 17:58:28 +00:00
if ( s - > offset > = s2 - > offset ) {
if ( s2 - > offset + s2 - > size < s - > offset )
2009-02-05 21:08:46 +00:00
return i ;
} else {
2010-02-18 17:58:28 +00:00
if ( s - > offset + s - > size < s2 - > offset )
2009-02-05 21:08:46 +00:00
return i ;
}
}
i + + ;
}
return - 1 ;
}
2015-09-09 20:01:29 +00:00
/* returns the conversion from vaddr to maddr if the given vaddr is in a mapped
* region , otherwise it returns the original address */
R_API ut64 r_io_section_vaddr_to_maddr_try ( RIO * io , ut64 vaddr ) {
ut64 res = r_io_section_vaddr_to_maddr ( io , vaddr ) ;
return res = = UT64_MAX ? vaddr : res ;
}
/* returns the conversion from vaddr to maddr if the given vaddr is in a mapped
* region , UT64_MAX otherwise */
R_API ut64 r_io_section_vaddr_to_maddr ( RIO * io , ut64 vaddr ) {
2011-04-19 12:43:48 +00:00
RListIter * iter ;
RIOSection * s ;
2011-10-25 18:30:05 +00:00
r_list_foreach ( io - > sections , iter , s ) {
2015-08-25 11:20:19 +00:00
if ( ! ( s - > rwx & R_IO_MAP ) ) continue ;
2011-10-25 18:30:05 +00:00
if ( vaddr > = s - > vaddr & & vaddr < s - > vaddr + s - > vsize ) {
2011-04-19 12:43:48 +00:00
return ( vaddr - s - > vaddr + s - > offset ) ;
2011-10-25 18:30:05 +00:00
}
2009-02-05 21:08:46 +00:00
}
2015-09-09 20:01:29 +00:00
return UT64_MAX ;
2010-02-18 17:58:28 +00:00
}
2015-09-09 20:01:29 +00:00
/* returns the conversion from file offset to vaddr if the given offset is
* mapped somewhere , UT64_MAX otherwise */
R_API ut64 r_io_section_maddr_to_vaddr ( RIO * io , ut64 offset ) {
2015-12-09 20:17:49 +00:00
/* Use reverse iterator, since sections that are at the
* end of the list are usually the bigger ones */
RIOSection * s = r_io_section_mget_prev ( io , offset ) ;
2014-05-28 02:34:12 +00:00
if ( s ) {
io - > section = s ;
return ( s - > vaddr + offset - s - > offset ) ;
2010-02-18 17:58:28 +00:00
}
2012-08-13 11:16:06 +00:00
return UT64_MAX ;
2009-02-05 21:08:46 +00:00
}
2011-10-25 18:30:05 +00:00
2014-05-28 02:34:12 +00:00
// TODO: deprecate ?
2015-07-04 23:44:45 +00:00
R_API int r_io_section_exists_for_paddr ( RIO * io , ut64 paddr , int hasperm ) {
2016-01-03 02:03:35 +00:00
RIOSection * s = r_io_section_mget_in ( io , paddr ) ;
2016-08-08 08:45:32 +00:00
if ( s ) {
if ( hasperm ) {
return ( s - > rwx & hasperm ) ;
}
return true ;
}
return false ;
2014-05-22 06:58:03 +00:00
}
2014-05-28 02:34:12 +00:00
// TODO: deprecate ?
2015-07-04 23:44:45 +00:00
R_API int r_io_section_exists_for_vaddr ( RIO * io , ut64 vaddr , int hasperm ) {
2014-05-28 02:34:12 +00:00
RIOSection * s = r_io_section_vget ( io , vaddr ) ;
2016-08-07 12:07:52 +00:00
if ( s ) {
if ( hasperm ) {
return ( s - > rwx & hasperm ) ;
}
return true ;
}
return false ;
2014-05-22 06:58:03 +00:00
}
2014-05-28 02:34:12 +00:00
// dupped in vio.c
2011-10-25 18:30:05 +00:00
R_API ut64 r_io_section_next ( RIO * io , ut64 o ) {
RListIter * iter ;
RIOSection * s ;
2016-02-20 21:51:34 +00:00
ut64 addr , newsec = UT64_MAX ;
2011-10-25 18:30:05 +00:00
r_list_foreach ( io - > sections , iter , s ) {
2016-02-20 21:51:34 +00:00
addr = s - > vaddr ;
if ( s - > vaddr > o & & s - > vaddr < newsec ) {
newsec = s - > vaddr ;
2013-03-17 23:38:04 +00:00
}
2016-02-20 21:51:34 +00:00
addr = s - > vaddr + s - > vsize ;
if ( addr > o & & addr < newsec ) {
newsec = s - > vaddr ;
2011-10-25 18:30:05 +00:00
}
}
2016-02-20 21:51:34 +00:00
return newsec ;
2011-10-25 18:30:05 +00:00
}
2012-11-30 00:06:30 +00:00
2014-06-11 00:07:38 +00:00
R_API RList * r_io_section_get_in_paddr_range ( RIO * io , ut64 addr , ut64 endaddr ) {
2014-06-27 01:10:09 +00:00
RIOSection * s ;
2014-06-11 00:07:38 +00:00
RListIter * iter ;
RList * sections = r_list_new ( ) ;
2016-05-24 20:22:15 +00:00
if ( ! sections ) return NULL ;
2016-01-03 02:03:35 +00:00
sections - > free = r_io_section_free ;
2014-06-11 00:07:38 +00:00
ut64 sec_from , sec_to ;
2014-06-27 01:10:09 +00:00
r_list_foreach ( io - > sections , iter , s ) {
2015-08-25 11:20:19 +00:00
if ( ! ( s - > rwx & R_IO_MAP ) ) continue ;
2014-06-27 01:10:09 +00:00
sec_from = s - > offset ;
sec_to = sec_from + s - > size ;
if ( sec_from < = addr & & addr < sec_to ) r_list_append ( sections , s ) ;
if ( sec_from < endaddr & & endaddr < sec_to ) r_list_append ( sections , s ) ;
if ( addr < = sec_from & & sec_to < = endaddr ) r_list_append ( sections , s ) ;
2014-06-11 00:07:38 +00:00
}
return sections ;
}
R_API RList * r_io_section_get_in_vaddr_range ( RIO * io , ut64 addr , ut64 endaddr ) {
2014-06-27 01:10:09 +00:00
RIOSection * s ;
2014-06-11 00:07:38 +00:00
RListIter * iter ;
RList * sections = r_list_new ( ) ;
2016-05-24 20:22:15 +00:00
if ( ! sections ) return NULL ;
2016-07-03 17:32:06 +00:00
//Here section->free is not needed and wrong since we are appending into
//the list sections from io->sections that are widely used so just free the
//list but not the elements to avoid UAF. r_io_free will free sections for us
2014-06-11 00:07:38 +00:00
ut64 sec_from , sec_to ;
2014-06-27 01:10:09 +00:00
r_list_foreach ( io - > sections , iter , s ) {
2016-08-08 08:45:32 +00:00
if ( ! ( s - > rwx & R_IO_MAP ) ) {
continue ;
}
2014-06-27 01:10:09 +00:00
sec_from = s - > vaddr ;
sec_to = sec_from + s - > vsize ;
2016-07-03 17:32:06 +00:00
if ( sec_from < = addr & & addr < sec_to ) r_list_append ( sections , s ) ;
if ( sec_from < endaddr & & endaddr < sec_to ) r_list_append ( sections , s ) ;
if ( addr < = sec_from & & sec_to < = endaddr ) r_list_append ( sections , s ) ;
2014-06-11 00:07:38 +00:00
}
return sections ;
}
2014-05-22 06:58:03 +00:00
R_API RIOSection * r_io_section_get_first_in_paddr_range ( RIO * io , ut64 addr , ut64 endaddr ) {
2014-06-27 01:10:09 +00:00
RIOSection * s = NULL ;
2014-05-22 06:58:03 +00:00
RListIter * iter ;
2014-06-11 00:07:38 +00:00
ut64 sec_from , sec_to ;
2014-06-27 01:10:09 +00:00
r_list_foreach ( io - > sections , iter , s ) {
2016-08-08 08:45:32 +00:00
if ( ! ( s - > rwx & R_IO_MAP ) ) {
continue ;
}
2014-06-27 01:10:09 +00:00
sec_to = s - > offset + s - > size ;
sec_from = s - > offset ;
2014-05-22 06:58:03 +00:00
if ( sec_from < = addr & & addr < sec_to ) break ;
//if (map->from == addr && endaddr == sec_to) r_list_append(maps, map);
if ( sec_from < endaddr & & endaddr < sec_to ) break ;
if ( addr < = sec_from & & sec_to < = endaddr ) break ;
2014-06-27 01:10:09 +00:00
s = NULL ;
2014-05-22 06:58:03 +00:00
}
2014-06-27 01:10:09 +00:00
return s ;
2014-05-22 06:58:03 +00:00
}
R_API RIOSection * r_io_section_get_first_in_vaddr_range ( RIO * io , ut64 addr , ut64 endaddr ) {
2014-06-27 01:10:09 +00:00
RIOSection * s = NULL ;
2014-05-22 06:58:03 +00:00
RListIter * iter ;
2014-06-11 00:07:38 +00:00
ut64 sec_from , sec_to ;
2014-06-27 01:10:09 +00:00
r_list_foreach ( io - > sections , iter , s ) {
2015-08-25 11:20:19 +00:00
if ( ! ( s - > rwx & R_IO_MAP ) ) continue ;
2014-06-27 01:10:09 +00:00
sec_to = s - > vaddr + s - > vsize ;
sec_from = s - > vaddr ;
2014-05-22 06:58:03 +00:00
if ( sec_from < = addr & & addr < sec_to ) break ;
//if (map->from == addr && endaddr == sec_to) r_list_append(maps, map);
if ( sec_from < endaddr & & endaddr < sec_to ) break ;
if ( addr < = sec_from & & sec_to < = endaddr ) break ;
2014-06-27 01:10:09 +00:00
s = NULL ;
2014-05-22 06:58:03 +00:00
}
2014-06-27 01:10:09 +00:00
return s ;
2014-05-22 06:58:03 +00:00
}
2012-11-30 00:06:30 +00:00
R_API int r_io_section_set_archbits ( RIO * io , ut64 addr , const char * arch , int bits ) {
2014-05-28 02:34:12 +00:00
RIOSection * s = r_io_section_vget ( io , addr ) ;
2015-09-14 00:08:31 +00:00
if ( ! s ) return false ;
2012-11-30 00:06:30 +00:00
if ( arch ) {
s - > arch = r_sys_arch_id ( arch ) ;
s - > bits = bits ;
} else {
s - > arch = 0 ;
s - > bits = 0 ;
}
2015-09-14 00:08:31 +00:00
return true ;
2012-11-30 00:06:30 +00:00
}
R_API const char * r_io_section_get_archbits ( RIO * io , ut64 addr , int * bits ) {
2014-05-28 02:34:12 +00:00
RIOSection * s = r_io_section_vget ( io , addr ) ;
2016-08-07 15:37:33 +00:00
if ( ! s | | ! s - > bits | | ! s - > arch ) {
return NULL ;
}
if ( bits ) {
* bits = s - > bits ;
}
2012-11-30 00:06:30 +00:00
return r_sys_arch_str ( s - > arch ) ;
}
2014-05-08 23:35:04 +00:00
R_API RIOSection * r_io_section_getv_bin_id ( RIO * io , ut64 vaddr , ut32 bin_id ) {
RListIter * iter ;
RIOSection * s ;
r_list_foreach ( io - > sections , iter , s ) {
2016-08-08 08:45:32 +00:00
if ( ! ( s - > rwx & R_IO_MAP ) | | s - > bin_id ! = bin_id ) {
continue ;
}
if ( vaddr > = s - > vaddr & & vaddr < s - > vaddr + s - > vsize ) {
2014-05-08 23:35:04 +00:00
return s ;
2016-08-08 08:45:32 +00:00
}
2014-05-08 23:35:04 +00:00
}
return NULL ;
}
R_API int r_io_section_set_archbits_bin_id ( RIO * io , ut64 addr , const char * arch , int bits , ut32 bin_id ) {
RIOSection * s = r_io_section_getv_bin_id ( io , addr , bin_id ) ;
2016-08-08 08:45:32 +00:00
if ( s ) {
if ( arch ) {
s - > arch = r_sys_arch_id ( arch ) ;
s - > bits = bits ;
} else {
s - > arch = 0 ;
s - > bits = 0 ;
}
return true ;
2014-05-08 23:35:04 +00:00
}
2016-08-08 08:45:32 +00:00
return false ;
2014-05-16 01:48:14 +00:00
}