* Initial working implementation of r_meta

- Added test program that sets and gets metadata.
  - It needs much more features and stuff
  - Integration with r_core is mandatory! :)
  - Hard simplification from the old r1 code
* Added r_str_concat and r_str_concatf in r_util
This commit is contained in:
pancake 2009-02-16 03:14:19 +01:00
parent 26b5e48ede
commit 05651257c9
10 changed files with 294 additions and 226 deletions

View File

@ -1,22 +1,65 @@
#ifndef _INCLUDE_R_META_H_
#define _INCLUDE_R_META_H_
#include <r_types.h>
#include <r_util.h>
#include <list.h>
struct r_meta_count_t {
int functions;
int xref_code;
int xref_data;
/* TODO: ... */
};
/* old data_t */
struct r_meta_item_t {
u64 from;
u64 to;
int type;
int times;
u64 size;
char arg[128];
int type;
// int times;
char *str;
struct list_head list;
};
struct r_meta_t {
// struct reflines_t *reflines = NULL;
struct list_head data;
struct list_head comments;
struct list_head xrefs;
// struct reflines_t *reflines = NULL;
// struct list_head comments;
// struct list_head xrefs;
};
enum {
R_META_WHERE_PREV = -1,
R_META_WHERE_HERE = 0,
R_META_WHERE_NEXT = 1,
};
enum {
R_META_ANY = -1,
/* content type */
R_META_DATA = 0,
R_META_CODE,
R_META_STRING,
R_META_STRUCT,
/* line */
R_META_FUNCTION,
R_META_COMMENT,
R_META_FOLDER,
R_META_XREF_CODE,
R_META_XREF_DATA,
};
int r_meta_init(struct r_meta_t *m);
struct r_meta_t *r_meta_new();
void r_meta_free(struct r_meta_t *m);
int r_meta_count(struct r_meta_t *m, int type, u64 from, u64 to, struct r_meta_count_t *c);
char *r_meta_get_string(struct r_meta_t *m, int type, u64 addr);
int r_meta_del(struct r_meta_t *m, int type, u64 from, u64 size, const char *str);
int r_meta_add(struct r_meta_t *m, int type, u64 from, u64 size, const char *str);
struct r_meta_item_t *r_meta_find(struct r_meta_t *m, u64 off, int type, int where);
const char *r_meta_type_to_string(int type);
int r_meta_list(struct r_meta_t *m, int type);
#endif

View File

@ -75,6 +75,8 @@ int r_str_re_replace(const char *str, const char *reg, const char *sub);
char *r_str_sub(char *string, char *pat, char *rep, int global);
int r_str_escape(char *buf);
char *r_str_home(const char *str);
char *r_str_concat(char *ptr, const char *string);
char *r_str_concatf(char *ptr, const char *fmt, ...);
/* hex */
int r_hex_pair2bin(const char *arg);

4
libr/meta/Makefile Normal file
View File

@ -0,0 +1,4 @@
NAME=r_meta
OBJ=meta.o
include ../rules.mk

View File

@ -10,31 +10,6 @@ r_meta
** We can store multiple linked lists depending on type of data, to
reduce the search space.
enum {
R_META_DATA,
R_META_CODE,
R_META_CODE_XREF,
R_META_DATA_XREF,
R_META_STRING,
R_META_FUNCTION,
R_META_STRUCT,
R_META_COMMENT,
R_META_FOLDER
}
struct r_meta_item_t {
int type;
u64 addr;
u64 size;
char *data;
struct list_head list;
};
struct r_meta_t {
struct list_head comments;
struct list_head xrefs;
};
struct r_meta_t * meta = r_meta_new();
/* get list of xrefs to this addr */

View File

@ -2,6 +2,12 @@
#include "r_meta.h"
int r_meta_init(struct r_meta_t *m)
{
INIT_LIST_HEAD(&m->data);
return R_TRUE;
}
struct r_meta_t *r_meta_new()
{
struct r_meta_t *m = MALLOC_STRUCT(struct r_meta_t);
@ -11,35 +17,173 @@ struct r_meta_t *r_meta_new()
void r_meta_free(struct r_meta_t *m)
{
/* TODO: memory leak */
free(m);
}
int r_meta_init(struct r_meta_t *m)
{
INIT_LIST_HEAD(&m->data);
INIT_LIST_HEAD(&m->comments);
INIT_LIST_HEAD(&m->xrefs);
return R_TRUE;
}
/* snippet from data.c */
/* XXX: we should add a 4th arg to define next or prev */
u64 r_meta_prev(struct r_meta_t *m, u64 off, int type)
int r_meta_count(struct r_meta_t *m, int type, u64 from, u64 to, struct r_meta_count_t *c)
{
struct list_head *pos;
u64 ret = 0;
int count = 0;
list_for_each(pos, &m->data) {
struct r_meta_item_t *d = (struct r_meta_item_t *)
list_entry(pos, struct r_meta_item_t, list);
if (d->type == type) {
if (d->from < off && d->to > off)
ret = d->from;
if (d->type == type || type == R_META_ANY) {
if (from >= d->from && d->to < to) {
if (c) {
/* */
}
count++;
}
}
}
return count;
}
char *r_meta_get_string(struct r_meta_t *m, int type, u64 addr)
{
char *str = NULL;
struct list_head *pos;
switch(type) {
case R_META_FUNCTION:
case R_META_COMMENT:
case R_META_FOLDER:
case R_META_XREF_CODE:
case R_META_XREF_DATA:
case R_META_ANY:
break;
case R_META_CODE:
case R_META_DATA:
case R_META_STRING:
case R_META_STRUCT:
/* we should remove overlapped types and so on.. */
return "(Unsupported meta type)";
break;
default:
fprintf(stderr, "Unhandled\n");
return "(Unhandled meta type)";
}
list_for_each(pos, &m->data) {
struct r_meta_item_t *d = (struct r_meta_item_t *)
list_entry(pos, struct r_meta_item_t, list);
if (d->type == type || type == R_META_ANY) {
if (d->from == addr)
switch(d->type) {
case R_META_FUNCTION:
str = r_str_concatf(str, "; FUNCTION SIZE %lld\n", d->size);
break;
case R_META_COMMENT:
str = r_str_concatf(str, "; %s\n", d->str);
break;
case R_META_FOLDER:
str = r_str_concatf(str, "; FOLDER %lld bytes\n", d->size);
break;
case R_META_XREF_CODE:
str = r_str_concatf(str, "; CODE XREF FROM 0x%08llx\n", d->to);
break;
case R_META_XREF_DATA:
str = r_str_concatf(str, "; DATA XREF FROM 0x%08llx\n", d->to);
break;
}
}
}
return str;
}
int r_meta_del(struct r_meta_t *m, int type, u64 from, u64 size, const char *str)
{
int ret = R_FALSE;
struct list_head *pos, *n;
list_for_each_safe(pos, n, &m->data) {
struct r_meta_item_t *d = (struct r_meta_item_t *)
list_entry(pos, struct r_meta_item_t, list);
if (d->type == type || type == R_META_ANY) {
if (str != NULL && !strstr(d->str, str))
continue;
if (from >= d->from && from <= d->to) {
free(d->str);
list_del(&(d->list));
ret = R_TRUE;
}
}
}
return ret;
}
int r_meta_add(struct r_meta_t *m, int type, u64 from, u64 size, const char *str)
{
struct r_meta_item_t *mi;
switch(type) {
case R_META_CODE:
r_meta_del(m, R_META_CODE, from, size, str);
break;
case R_META_DATA:
case R_META_STRING:
case R_META_STRUCT:
/* we should remove overlapped types and so on.. */
case R_META_FUNCTION:
case R_META_COMMENT:
case R_META_FOLDER:
case R_META_XREF_CODE:
case R_META_XREF_DATA:
mi = MALLOC_STRUCT(struct r_meta_item_t);
mi->type = type;
mi->from = from;
mi->size = size;
mi->to = from+size;
if (str) mi->str = strdup(str);
else mi->str = NULL;
list_add(&(mi->list), &m->data);
break;
default:
return R_FALSE;
}
return R_TRUE;
}
/* snippet from data.c */
/* XXX: we should add a 4th arg to define next or prev */
struct r_meta_item_t *r_meta_find(struct r_meta_t *m, u64 off, int type, int where)
{
struct r_meta_item_t *it = NULL;
struct list_head *pos;
list_for_each(pos, &m->data) {
struct r_meta_item_t *d = (struct r_meta_item_t *)
list_entry(pos, struct r_meta_item_t, list);
if (d->type == type || type == R_META_ANY) {
switch(where) {
case R_META_WHERE_PREV:
if (d->from < off) {
if (it) {
if (d->from > it->from)
it = d;
} else it = d;
}
break;
case R_META_WHERE_HERE:
if (d->from < off && d->to > off)
it = d;
break;
case R_META_WHERE_NEXT:
if (d->from > off) {
if (it) {
if (d->from < it->from)
it = d;
} else it = d;
}
break;
}
}
}
return it;
}
#if 0
/* not necessary */
//int data_get_fun_for(u64 addr, u64 *from, u64 *to)
int r_meta_get_bounds(struct r_meta_t *m, u64 addr, int type, u64 *from, u64 *to)
{
@ -65,3 +209,38 @@ int r_meta_get_bounds(struct r_meta_t *m, u64 addr, int type, u64 *from, u64 *to
}
return 0;
}
#endif
const char *r_meta_type_to_string(int type)
{
switch(type) {
case R_META_CODE: return "Cc";
case R_META_DATA: return "Cd";
case R_META_STRING: return "Cs";
case R_META_STRUCT: return "Cm";
case R_META_FUNCTION: return "CF";
case R_META_COMMENT: return "CC";
case R_META_FOLDER: return "CF";
case R_META_XREF_CODE: return "Cx";
case R_META_XREF_DATA: return "CX";
}
return "(...)";
}
int r_meta_list(struct r_meta_t *m, int type)
{
int count = 0;
struct list_head *pos;
list_for_each(pos, &m->data) {
struct r_meta_item_t *d = (struct r_meta_item_t *)
list_entry(pos, struct r_meta_item_t, list);
if (d->type == type || type == R_META_ANY) {
printf("%s 0x%08llx 0x%08llx %d %s\n",
r_meta_type_to_string(d->type),
d->from, d->to, (int)(d->to-d->from), d->str);
count++;
}
}
return count;
}

5
libr/meta/t/Makefile Normal file
View File

@ -0,0 +1,5 @@
OBJ=test.o
BIN=test
BINDEPS=r_util r_meta
include ../../rules.mk

17
libr/meta/t/test.c Normal file
View File

@ -0,0 +1,17 @@
#include <r_meta.h>
int main()
{
struct r_meta_t *m = r_meta_new();
r_meta_add(m, R_META_FUNCTION, 0x8048300, 128, "main");
r_meta_add(m, R_META_COMMENT, 0x8048300, 1, "Everything starts here");
r_meta_add(m, R_META_FUNCTION, 0x8048200, 54, "entrypoint");
r_meta_list(m, R_META_ANY);
{
char *str = r_meta_get_string(m, R_META_ANY, 0x8048300);
printf("COMMENT:\n%s\n", str);
free(str);
}
return 0;
}

View File

@ -694,106 +694,3 @@ int data_printd(int delta)
lines += data_xrefs_print(offset, -1);
return lines;
}
/* variables */
int data_var_type_add(const char *typename, int size, const char *fmt)
{
struct var_type_t *d = (struct var_type_t *)
malloc(sizeof(struct var_type_t));
strncpy(d->name, typename, sizeof(d->name));
strncpy(d->fmt, fmt, sizeof(d->fmt));
d->size = size;
list_add(&(d->list), &vartypes);
return 0;
}
int data_var_type_del(const char *typename)
{
struct list_head *pos;
u64 ret = 0;
if (*typename==' ')typename=typename+1;
list_for_each(pos, &vartypes) {
struct var_type_t *d = (struct var_type_t *)list_entry(pos, struct var_type_t, list);
if (!strcmp(typename, d->name)) {
list_del(&(d->list));
return 1;
}
}
return 0;
}
int data_var_type_list()
{
struct list_head *pos;
u64 ret = 0;
list_for_each(pos, &vartypes) {
struct var_type_t *d = (struct var_type_t *)list_entry(pos, struct var_type_t, list);
cons_printf("%s %d %s\n", d->name, d->size, d->fmt);
}
return ret;
}
const char *data_var_type_get(const char *datatype)
{
struct list_head *pos;
u64 ret = 0;
list_for_each(pos, &vartypes) {
struct var_type_t *d = (struct var_type_t *)list_entry(pos, struct var_type_t, list);
//eprintf("---(%s)(%s)\n", d->name, datatype);
if (!strcmp(datatype, d->name))
return d;
}
return NULL;
}
int data_var_help()
{
cons_printf(
"Usage: Cv [name] [size] [pm-format-string]\n"
" Cv int 4 d ; define 'int' type\n"
" Cv- int ; remove 'int' var type\n"
" Cv float 4 f\n");
return 0;
}
int data_var_cmd(const char *str)
{
int len;
char *vstr;
char *arg, *arg2;
STRALLOC(vstr, str, len);
if (*str==' ')str=str+1;
switch(*str) {
case '?':
return data_var_help();
case '\0':
/* list var types */
data_var_type_list();
break;
case '-':
data_var_type_del(str+1);
break;
default:
arg = strchr(str, ' ');
if (arg==NULL)
return data_var_help();
*arg='\0'; arg=arg+1;
arg2 = strchr(arg, ' ');
if (arg2==NULL)
return data_var_help();
*arg2='\0'; arg2=arg2+1;
data_var_type_add(str, atoi(arg), arg2);
break;
}
return 0;
}

View File

@ -1,77 +0,0 @@
#ifndef _INCLUDE_DATA_H_
#define _INCLUDE_DATA_H_
extern struct reflines_t *reflines;
//extern struct list_head data;
//extern struct list_head comments;
extern struct list_head traces;
struct data_t {
u64 from;
u64 to;
int type;
int times;
u64 size;
char arg[128];
struct list_head list;
};
struct var_type_t {
char name[128];
char fmt[128];
unsigned int size;
struct list_head list;
};
struct comment_t {
u64 offset;
const char *comment;
struct list_head list;
};
struct xrefs_t {
u64 addr; /* offset of the cross reference */
u64 from; /* where the code/data is referenced */
int type; /* 0 = code, 1 = data, -1 = unknown */
struct list_head list;
};
struct reflines_t {
u64 from;
u64 to;
int index;
struct list_head list;
};
int data_set_len(u64 off, u64 len);
void data_info();
int data_set(u64 off, int type);
struct data_t *data_add_arg(u64 off, int type, const char *arg);
struct data_t *data_add(u64 off, int type);
u64 data_seek_to(u64 offset, int type, int idx);
struct data_t *data_get(u64 offset);
struct data_t *data_get_range(u64 offset);
struct data_t *data_get_between(u64 from, u64 to);
int data_type_range(u64 offset);
int data_type(u64 offset);
int data_end(u64 offset);
int data_size(u64 offset);
u64 data_prev(u64 off, int type);
int data_list();
int data_xrefs_print(u64 addr, int type);
int data_xrefs_add(u64 addr, u64 from, int type);
int data_xrefs_at(u64 addr);
void data_xrefs_del(u64 addr, u64 from, int data /* data or code */);
void data_comment_del(u64 offset, const char *str);
void data_comment_add(u64 offset, const char *str);
void data_comment_list();
void data_xrefs_here(u64 addr);
void data_xrefs_list();
char *data_comment_get(u64 offset, int lines);
void data_comment_init(int new);
void data_reflines_init();
int data_printd(int delta);
const char *data_var_type_format(const char *datatype);
void data_del(u64 addr, int type,int len/* data or code */);
#endif

View File

@ -3,6 +3,7 @@
#include "r_types.h"
#include "r_util.h"
#include <stdio.h>
#include <stdarg.h>
/* stable code */
static const char *nullstr = "";
@ -221,6 +222,28 @@ char *r_str_dup(char *ptr, const char *string)
return ptr;
}
char *r_str_concat(char *ptr, const char *string)
{
if (!ptr)
return strdup(string);
ptr = realloc(ptr, strlen(string)+strlen(ptr)+1);
if (ptr == NULL)
return NULL;
strcat(ptr, string);
return ptr;
}
char *r_str_concatf(char *ptr, const char *fmt, ...)
{
char string[1024];
va_list ap;
va_start(ap, fmt);
vsnprintf(string, 1023, fmt, ap);
ptr = r_str_concat(ptr, string);
va_end(ap);
return ptr;
}
void *r_str_free(void *ptr)
{
free (ptr);