2010-02-01 10:55:56 +00:00
|
|
|
/* radare - LGPL - Copyright 2008-2010 pancake<nopcode.org> */
|
2009-02-05 21:08:46 +00:00
|
|
|
|
|
|
|
#include "r_io.h"
|
|
|
|
|
|
|
|
// XXX use section->foo
|
2009-09-08 02:14:19 +00:00
|
|
|
#define r_cons_printf printf
|
2009-02-05 21:08:46 +00:00
|
|
|
|
2009-09-08 02:14:19 +00:00
|
|
|
R_API void r_io_section_init(struct r_io_t *io)
|
|
|
|
{
|
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
|
2009-09-08 02:14:19 +00:00
|
|
|
INIT_LIST_HEAD(&(io->sections));
|
|
|
|
}
|
2009-02-05 21:08:46 +00:00
|
|
|
|
2010-02-18 17:58:28 +00:00
|
|
|
R_API void r_io_section_add(struct r_io_t *io, ut64 offset, ut64 vaddr, ut64 size, ut64 vsize, int rwx, const char *name)
|
2009-02-05 21:08:46 +00:00
|
|
|
{
|
|
|
|
struct r_io_section_t *s = (struct r_io_section_t *)malloc(sizeof(struct r_io_section_t));
|
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;
|
2009-09-08 02:14:19 +00:00
|
|
|
if (name)
|
|
|
|
strncpy(s->name, name, 254);
|
|
|
|
else s->name[0]='\0';
|
2009-02-05 21:08:46 +00:00
|
|
|
list_add(&(s->list), &io->sections);
|
|
|
|
}
|
|
|
|
|
2009-09-08 02:14:19 +00:00
|
|
|
R_API struct r_io_section_t *r_io_section_get_i(struct r_io_t *io, int idx)
|
2009-02-05 21:08:46 +00:00
|
|
|
{
|
|
|
|
int i = 0;
|
|
|
|
struct list_head *pos;
|
|
|
|
list_for_each_prev(pos, &io->sections) {
|
|
|
|
struct r_io_section_t *s = (struct r_io_section_t *)list_entry(pos, struct r_io_section_t, list);
|
|
|
|
if (i == idx)
|
|
|
|
return s;
|
|
|
|
i++;
|
|
|
|
}
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2009-09-08 02:14:19 +00:00
|
|
|
R_API int r_io_section_rm(struct r_io_t *io, int idx)
|
2009-02-05 21:08:46 +00:00
|
|
|
{
|
|
|
|
struct r_io_section_t *s = r_io_section_get_i(io, idx);
|
|
|
|
if (s != NULL) {
|
|
|
|
list_del((&s->list));
|
|
|
|
free(s);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
// TODO: implement as callback
|
2010-02-18 17:58:28 +00:00
|
|
|
R_API void r_io_section_list(struct r_io_t *io, ut64 offset, int rad)
|
2009-02-05 21:08:46 +00:00
|
|
|
{
|
|
|
|
int i = 0;
|
|
|
|
struct list_head *pos;
|
2010-02-21 10:35:49 +00:00
|
|
|
|
|
|
|
offset = io->va ? r_io_section_vaddr_to_offset (io, offset) : offset;
|
2009-02-05 21:08:46 +00:00
|
|
|
list_for_each_prev(pos, &io->sections) {
|
|
|
|
struct r_io_section_t *s = (struct r_io_section_t *)list_entry(pos, struct r_io_section_t, list);
|
|
|
|
if (rad) {
|
2010-02-18 17:58:28 +00:00
|
|
|
r_cons_printf("S 0x%08llx 0x%08llx 0x%08llx 0x%08llx %s\n",
|
|
|
|
s->offset, s->vaddr, s->size, s->vsize, s->name);
|
2009-02-05 21:08:46 +00:00
|
|
|
} else {
|
2010-02-18 17:58:28 +00:00
|
|
|
r_cons_printf("[%02d] %c offset=0x%08llx vaddr=0x%08llx size=0x%08llx vsize=%08llx %s",
|
2010-02-21 10:35:49 +00:00
|
|
|
i, (offset>=s->offset && offset<s->offset+s->size)?'*':'.',
|
2010-02-18 17:58:28 +00:00
|
|
|
s->offset, s->vaddr, s->size, s->vsize, s->name);
|
2009-09-08 02:14:19 +00:00
|
|
|
r_cons_printf("\n");
|
2009-02-05 21:08:46 +00:00
|
|
|
}
|
|
|
|
i++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-09-08 02:14:19 +00:00
|
|
|
/* TODO: move to print ??? support pretty print of ranges following an array of offsetof */
|
|
|
|
R_API void r_io_section_list_visual(struct r_io_t *io, ut64 seek, ut64 len)
|
2009-02-05 21:08:46 +00:00
|
|
|
{
|
2009-07-08 11:49:55 +00:00
|
|
|
ut64 min = -1;
|
|
|
|
ut64 max = -1;
|
|
|
|
ut64 mul;
|
2009-02-05 21:08:46 +00:00
|
|
|
int j, i;
|
|
|
|
struct list_head *pos;
|
|
|
|
int width = 78; //config.width-30;
|
|
|
|
|
2010-02-21 10:35:49 +00:00
|
|
|
seek = io->va ? r_io_section_vaddr_to_offset (io, seek) : seek;
|
2009-02-05 21:08:46 +00:00
|
|
|
list_for_each(pos, &io->sections) {
|
|
|
|
struct r_io_section_t *s = (struct r_io_section_t *)list_entry(pos, struct r_io_section_t, list);
|
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) {
|
|
|
|
i = 0;
|
|
|
|
list_for_each_prev(pos, &io->sections) {
|
|
|
|
struct r_io_section_t *s = (struct r_io_section_t *)list_entry(pos, struct r_io_section_t, list);
|
2010-02-18 17:58:28 +00:00
|
|
|
r_cons_printf("%02d 0x%08llx |", i, s->offset);
|
2009-02-05 21:08:46 +00:00
|
|
|
for(j=0;j<width;j++) {
|
2010-02-18 17:58:28 +00:00
|
|
|
if ((j*mul)+min >= s->offset && (j*mul)+min <=s->offset+s->size)
|
2009-09-08 02:14:19 +00:00
|
|
|
r_cons_printf("#");
|
2009-02-05 21:08:46 +00:00
|
|
|
else
|
2009-09-08 02:14:19 +00:00
|
|
|
r_cons_printf("-");
|
2009-02-05 21:08:46 +00:00
|
|
|
}
|
2010-02-21 10:35:49 +00:00
|
|
|
r_cons_printf("| 0x%08llx %s\n", s->offset+s->size, s->name);
|
2009-02-05 21:08:46 +00:00
|
|
|
i++;
|
|
|
|
}
|
|
|
|
/* current seek */
|
|
|
|
if (i>0 && len != 0) {
|
2009-09-08 02:14:19 +00:00
|
|
|
r_cons_printf("=> 0x%08llx |", seek);
|
2009-02-05 21:08:46 +00:00
|
|
|
for(j=0;j<width;j++) {
|
2010-02-01 10:55:56 +00:00
|
|
|
r_cons_printf (
|
2009-09-05 23:58:02 +00:00
|
|
|
((j*mul)+min >= seek &&
|
|
|
|
(j*mul)+min <= seek+len)
|
|
|
|
?"#":"-");
|
2009-02-05 21:08:46 +00:00
|
|
|
}
|
2009-09-08 02:14:19 +00:00
|
|
|
r_cons_printf("| 0x%08llx\n", seek+len);
|
2009-02-05 21:08:46 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-02-18 17:58:28 +00:00
|
|
|
R_API struct r_io_section_t *r_io_section_get(struct r_io_t *io, ut64 offset)
|
2009-02-05 21:08:46 +00:00
|
|
|
{
|
|
|
|
struct list_head *pos;
|
2010-02-01 10:55:56 +00:00
|
|
|
list_for_each (pos, &io->sections) {
|
2010-02-05 11:21:37 +00:00
|
|
|
RIOSection *s = (struct r_io_section_t *)list_entry(pos, struct r_io_section_t, list);
|
2010-02-18 17:58:28 +00:00
|
|
|
if (offset >= s->offset && offset <= s->offset + s->size)
|
2009-02-05 21:08:46 +00:00
|
|
|
return s;
|
|
|
|
}
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2010-02-18 17:58:28 +00:00
|
|
|
R_API ut64 r_io_section_get_offset(struct r_io_t *io, ut64 offset)
|
2009-02-05 21:08:46 +00:00
|
|
|
{
|
2010-02-18 17:58:28 +00:00
|
|
|
RIOSection *s = r_io_section_get(io, offset);
|
|
|
|
return s?s->offset:-1;
|
2009-02-05 21:08:46 +00:00
|
|
|
}
|
|
|
|
|
2010-02-18 17:58:28 +00:00
|
|
|
R_API ut64 r_io_section_get_vaddr(struct r_io_t *io, ut64 offset)
|
2009-02-05 21:08:46 +00:00
|
|
|
{
|
2010-02-18 17:58:28 +00:00
|
|
|
struct r_io_section_t *s = r_io_section_get(io, offset);
|
2009-09-08 02:14:19 +00:00
|
|
|
return s?s->vaddr:-1;
|
2009-02-05 21:08:46 +00:00
|
|
|
}
|
|
|
|
|
2010-02-18 17:58:28 +00:00
|
|
|
R_API int r_io_section_get_rwx(struct r_io_t *io, ut64 offset)
|
2009-09-08 02:14:19 +00:00
|
|
|
{
|
2010-02-18 17:58:28 +00:00
|
|
|
struct r_io_section_t *s = r_io_section_get(io, offset);
|
2009-09-08 02:14:19 +00:00
|
|
|
return s?s->rwx:R_IO_READ|R_IO_WRITE|R_IO_EXEC;
|
|
|
|
}
|
|
|
|
|
|
|
|
R_API int r_io_section_overlaps(struct r_io_t *io, struct r_io_section_t *s)
|
2009-02-05 21:08:46 +00:00
|
|
|
{
|
|
|
|
int i = 0;
|
|
|
|
struct list_head *pos;
|
|
|
|
list_for_each_prev(pos, &io->sections) {
|
|
|
|
struct r_io_section_t *s2 = (struct r_io_section_t *)list_entry(pos, struct r_io_section_t, list);
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2010-02-18 17:58:28 +00:00
|
|
|
R_API ut64 r_io_section_vaddr_to_offset(struct r_io_t *io, ut64 vaddr)
|
2009-02-05 21:08:46 +00:00
|
|
|
{
|
|
|
|
struct list_head *pos;
|
|
|
|
|
|
|
|
list_for_each_prev(pos, &io->sections) {
|
|
|
|
struct r_io_section_t *s = (struct r_io_section_t *)list_entry(pos, struct r_io_section_t, list);
|
2010-02-21 10:35:49 +00:00
|
|
|
if (vaddr >= s->vaddr && vaddr < s->vaddr + s->vsize)
|
2010-02-18 17:58:28 +00:00
|
|
|
return (vaddr - s->vaddr + s->offset);
|
2009-02-05 21:08:46 +00:00
|
|
|
}
|
2010-02-21 10:35:49 +00:00
|
|
|
return vaddr;
|
2010-02-18 17:58:28 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
R_API ut64 r_io_section_offset_to_vaddr(struct r_io_t *io, ut64 offset)
|
|
|
|
{
|
|
|
|
struct list_head *pos;
|
|
|
|
|
|
|
|
list_for_each_prev(pos, &io->sections) {
|
|
|
|
struct r_io_section_t *s = (struct r_io_section_t *)list_entry(pos, struct r_io_section_t, list);
|
2010-02-21 10:35:49 +00:00
|
|
|
if (offset >= s->offset && offset < s->offset + s->size)
|
2010-02-18 17:58:28 +00:00
|
|
|
return (s->vaddr + offset - s->offset);
|
|
|
|
}
|
2010-02-21 10:35:49 +00:00
|
|
|
return offset;
|
2009-02-05 21:08:46 +00:00
|
|
|
}
|