* Remove all references to r_meta as a separated library

- Initial merge into r_anal
  - Prefix R_META_* as R_META_TYPE_
  - Deprecate folder type and rename Cm->Cf (like in p cmd)
This commit is contained in:
pancake 2011-03-01 19:06:22 +01:00
parent 1535b4c5c1
commit 80a5cb0651
13 changed files with 109 additions and 853 deletions

View File

@ -1,6 +1,6 @@
/* radare - LGPL - Copyright 2008-2010 nibble<develsec.org> + pancake<nopcode.org> */
/* radare - LGPL - Copyright 2008-2011 nibble<develsec.org> + pancake<nopcode.org> */
#include <r_meta.h>
#include <r_anal.h>
R_API RMeta *r_meta_new() {
RMeta *m = R_NEW (RMeta);
@ -18,17 +18,14 @@ R_API void r_meta_free(RMeta *m) {
free (m);
}
R_API int r_meta_count(RMeta *m, int type, ut64 from, ut64 to, struct r_meta_count_t *c) {
R_API int r_meta_count(RMeta *m, int type, ut64 from, ut64 to) {
RMetaItem *d;
RListIter *iter;
int count = 0;
r_list_foreach (m->data, iter, d) {
if (d->type == type || type == R_META_ANY) {
if (d->type == type || type == R_META_TYPE_ANY) {
if (from >= d->from && d->to < to) {
if (c) {
/* */
}
count++;
}
}
@ -42,14 +39,14 @@ R_API char *r_meta_get_string(RMeta *m, int type, ut64 addr) {
RMetaItem *d;
switch(type) {
case R_META_COMMENT:
case R_META_FOLDER:
case R_META_ANY:
case R_META_TYPE_COMMENT:
case R_META_TYPE_ANY:
break;
case R_META_CODE:
case R_META_DATA:
case R_META_STRING:
case R_META_STRUCT:
case R_META_TYPE_CODE:
case R_META_TYPE_DATA:
case R_META_TYPE_STRING:
case R_META_TYPE_FORMAT:
case R_META_TYPE_MAGIC:
/* we should remove overlapped types and so on.. */
return "(Unsupported meta type)";
default:
@ -57,15 +54,12 @@ R_API char *r_meta_get_string(RMeta *m, int type, ut64 addr) {
return "(Unhandled meta type)";
}
r_list_foreach (m->data, iter, d) {
if (d->type == type || type == R_META_ANY) {
if (d->type == type || type == R_META_TYPE_ANY) {
if (d->from == addr)
switch (d->type) {
case R_META_COMMENT:
case R_META_TYPE_COMMENT:
str = r_str_concatf (str, "; %s\n", d->str);
break;
case R_META_FOLDER:
str = r_str_concatf (str, "; FOLDER %"PFMT64d" bytes\n", d->size);
break;
}
}
}
@ -78,7 +72,7 @@ R_API int r_meta_del(RMeta *m, int type, ut64 from, ut64 size, const char *str)
RMetaItem *d;
r_list_foreach (m->data, iter, d) {
if (d->type == type || type == R_META_ANY) {
if (d->type == type || type == R_META_TYPE_ANY) {
if (str != NULL && !strstr(d->str, str))
continue;
if (from >= d->from && from <= d->to) {
@ -105,10 +99,10 @@ R_API int r_meta_cleanup(RMeta *m, ut64 from, ut64 to) {
}
r_list_foreach (m->data, iter, d) {
switch (d->type) {
case R_META_CODE:
case R_META_DATA:
case R_META_STRING:
case R_META_STRUCT:
case R_META_TYPE_CODE:
case R_META_TYPE_DATA:
case R_META_TYPE_STRING:
case R_META_TYPE_FORMAT:
#if 0
|__| |__| |___| |_|
|__| |_| |_| |___|
@ -152,14 +146,13 @@ R_API RMetaItem *r_meta_item_new(int type) {
R_API int r_meta_add(RMeta *m, int type, ut64 from, ut64 to, const char *str) {
RMetaItem *mi = r_meta_item_new (type);
switch (type) {
case R_META_CODE:
case R_META_DATA:
case R_META_STRING:
case R_META_STRUCT:
case R_META_TYPE_CODE:
case R_META_TYPE_DATA:
case R_META_TYPE_STRING:
case R_META_TYPE_FORMAT:
/* we should remove overlapped types and so on.. */
r_meta_cleanup (m, from, to);
case R_META_COMMENT:
case R_META_FOLDER:
case R_META_TYPE_COMMENT:
mi->size = R_ABS (to-from);//size;
mi->type = type;
mi->from = from;
@ -181,7 +174,7 @@ R_API RMetaItem *r_meta_find(RMeta *m, ut64 off, int type, int where) {
RListIter *iter;
if (off)
r_list_foreach (m->data, iter, d) {
if (d->type == type || type == R_META_ANY) {
if (d->type == type || type == R_META_TYPE_ANY) {
switch (where) {
case R_META_WHERE_PREV:
if (d->from < off)
@ -233,12 +226,11 @@ int r_meta_get_bounds(RMeta *m, ut64 addr, int type, ut64 *from, ut64 *to)
R_API const char *r_meta_type_to_string(int type) {
// XXX: use type as '%c'
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_COMMENT: return "CC";
case R_META_FOLDER: return "CF";
case R_META_TYPE_CODE: return "Cc";
case R_META_TYPE_DATA: return "Cd";
case R_META_TYPE_STRING: return "Cs";
case R_META_TYPE_FORMAT: return "Cf";
case R_META_TYPE_COMMENT: return "CC";
}
return "(...)";
}
@ -274,7 +266,7 @@ R_API int r_meta_list(RMeta *m, int type) {
RListIter *iter;
RMetaItem *d;
r_list_foreach (m->data, iter, d) {
if (d->type == type || type == R_META_ANY) {
if (d->type == type || type == R_META_TYPE_ANY) {
printmetaitem (m, d);
count++;
}

View File

@ -26,7 +26,7 @@ CF 20
// how to define a structure or complex types?
// how to define arrays?
#include <r_meta.h>
#include <r_anal.h>
typedef struct r_meta_type_t {
char name[32];

View File

@ -227,7 +227,7 @@ core->inc = 0;
refline = filter_refline (line);
if (show_comments)
if ((comment = r_meta_get_string (core->meta, R_META_COMMENT, at))) {
if ((comment = r_meta_get_string (core->meta, R_META_TYPE_COMMENT, at))) {
r_cons_strcat (refline);
r_cons_strcat (" ");
r_cons_strcat (comment);
@ -323,10 +323,10 @@ if (core->inc == 0)
stackptr = 0;
}
// TODO: implement ranged meta find (if not at the begging of function..
mi = r_meta_find (core->meta, at, R_META_ANY, R_META_WHERE_HERE);
mi = r_meta_find (core->meta, at, R_META_TYPE_ANY, R_META_WHERE_HERE);
if (mi)
switch (mi->type) {
case R_META_STRING:
case R_META_TYPE_STRING:
// TODO: filter string (r_str_unscape)
{
char *out = r_str_unscape (mi->str);
@ -338,7 +338,7 @@ if (core->inc == 0)
free (refline);
line = refline = NULL;
continue;
case R_META_DATA:
case R_META_TYPE_DATA:
{
int delta = at-mi->from;
core->print->flags &= ~R_PRINT_FLAGS_HEADER;
@ -352,7 +352,7 @@ if (core->inc == 0)
line = refline = NULL;
}
continue;
case R_META_STRUCT:
case R_META_TYPE_FORMAT:
r_print_format (core->print, at, buf+idx, len-idx, mi->str);
ret = (int)mi->size;
free (line);
@ -521,17 +521,17 @@ strcpy (extra, pad);
int ret = r_io_read_at (core->io, analop.ref, (void *)&word, sizeof (word));
if (ret == sizeof (word)) {
RMetaItem *mi2 = r_meta_find (core->meta, (ut64)word,
R_META_ANY, R_META_WHERE_HERE);
R_META_TYPE_ANY, R_META_WHERE_HERE);
if (!mi2) {
mi2 = r_meta_find (core->meta, (ut64)analop.ref,
R_META_ANY, R_META_WHERE_HERE);
R_META_TYPE_ANY, R_META_WHERE_HERE);
if (mi2) {
char *str = r_str_unscape (mi2->str);
r_cons_printf (" (at=0x%08"PFMT64x") (len=%"PFMT64d") \"%s\" ", analop.ref, mi2->size, str);
free (str);
} else r_cons_printf ("; => 0x%08x ", word);
} else {
if (mi2->type == R_META_STRING) {
if (mi2->type == R_META_TYPE_STRING) {
char *str = r_str_unscape (mi2->str);
r_cons_printf (" (at=0x%08x) (len=%"PFMT64d") \"%s\" ", word, mi2->size, str);
free (str);
@ -3504,7 +3504,7 @@ static int cmd_meta(void *data, const char *input) {
char file[1024];
switch (*input) {
case '*':
r_meta_list (core->meta, R_META_ANY);
r_meta_list (core->meta, R_META_TYPE_ANY);
break;
case 't':
switch (input[1]) {
@ -3553,11 +3553,12 @@ static int cmd_meta(void *data, const char *input) {
}
} else eprintf ("Cannot find meta information at 0x%08"PFMT64x"\n", core->offset);
break;
case 'C':
case 'S':
case 's':
// XXX: use R_META_TYPE_XXX here
case 'C': /* comment */
case 's': /* string */
case 'd': /* data */
case 'm': /* struct */
case 'm': /* magic */
case 'f': /* formatted */
switch (input[1]) {
case '-':
if (input[2]==' ')
@ -3658,28 +3659,29 @@ static int cmd_meta(void *data, const char *input) {
if (input[1]!='*') {
if (input[1]==' ')
addr = r_num_math (core->num, input+2);
r_meta_del (core->meta, R_META_ANY, addr, 1, "");
r_meta_del (core->meta, R_META_TYPE_ANY, addr, 1, "");
} else r_meta_cleanup (core->meta, 0LL, UT64_MAX);
break;
case '\0':
case '?':
eprintf (
"Usage: C[-LCsSmxX?] [...]\n"
"Usage: C[-LCvsdfm?] [...]\n"
" C* # List meta info in r2 commands\n"
" C-[@][ addr] # delete metadata at given address\n"
" CL[-] [addr] # show 'code line' information (bininfo)\n"
" CC [string] # add comment\n"
" Cv[-] offset reg name # add var substitution\n"
" Cs[-] [size] [[addr]] # add string\n"
" CS[-] [size] # ...\n"
" Cd[-] [fmt] [..] # hexdump data\n"
" Cm[-] [fmt] [..] # format memory\n");
" Cd[-] [size] # hexdump data\n"
" Cf[-] [sz] [fmt..] # format memory (see pf?)\n"
" Cm[-] [sz] [fmt..] # magic parse (see pm?)\n");
break;
case 'F':
{
RAnalFcn *f = r_anal_fcn_find (core->anal, core->offset,
R_ANAL_FCN_TYPE_FCN|R_ANAL_FCN_TYPE_SYM);
r_anal_fcn_from_string (core->anal, f, input+2);
if (f) r_anal_fcn_from_string (core->anal, f, input+2);
else eprintf ("Cannot find function here\n");
}
break;
}
@ -3750,8 +3752,8 @@ static int r_core_cmd_pipe(RCore *core, char *radare_cmd, char *shell_cmd) {
pipe (fds);
radare_cmd = r_str_trim_head (radare_cmd);
shell_cmd = r_str_trim_head (shell_cmd);
if (fork()) {
dup2(fds[1], 1);
if (fork ()) {
dup2 (fds[1], 1);
close (fds[1]);
close (fds[0]);
r_core_cmd (core, radare_cmd, 0);
@ -3776,7 +3778,7 @@ static int r_core_cmd_pipe(RCore *core, char *radare_cmd, char *shell_cmd) {
static int r_core_cmd_subst(RCore *core, char *cmd) {
char *ptr, *ptr2, *str;
int i, len = strlen(cmd), pipefd, ret;
int i, len = strlen (cmd), pipefd, ret;
if (!*cmd || cmd[0]=='\0')
return 0;
@ -3855,7 +3857,7 @@ static int r_core_cmd_subst(RCore *core, char *cmd) {
for (;;) {
char buf[1024];
int ret;
printf ("> "); fflush (stdout);
write (1, "> ", 2);
fgets (buf, sizeof (buf)-1, stdin); // XXX use r_line ??
if (feof (stdin))
break;

View File

@ -137,13 +137,13 @@ R_API int r_core_bin_load(RCore *r, const char *file) {
r_flag_name_filter (name);
snprintf (str, R_FLAG_NAME_SIZE, "sym.%s", name);
if (!strncmp (symbol->type,"OBJECT", 6))
r_meta_add (r->meta, R_META_DATA, va?baddr+symbol->rva:symbol->offset,
r_meta_add (r->meta, R_META_TYPE_DATA, va?baddr+symbol->rva:symbol->offset,
(va?baddr+symbol->rva:symbol->offset)+symbol->size, name);
r_flag_set (r->flags, str, va?baddr+symbol->rva:symbol->offset,
symbol->size, 0);
dname = r_bin_demangle (r->bin, symbol->name);
if (dname) {
r_meta_add (r->meta, R_META_COMMENT, va?baddr+symbol->rva:symbol->offset,
r_meta_add (r->meta, R_META_TYPE_COMMENT, va?baddr+symbol->rva:symbol->offset,
symbol->size, dname);
free (dname);
}
@ -170,7 +170,7 @@ R_API int r_core_bin_load(RCore *r, const char *file) {
r_list_foreach (list, iter, string) {
/* Jump the withespaces before the string */
for (i=0;*(string->string+i)==' ';i++);
r_meta_add (r->meta, R_META_STRING, va?baddr+string->rva:string->offset,
r_meta_add (r->meta, R_META_TYPE_STRING, va?baddr+string->rva:string->offset,
(va?baddr+string->rva:string->offset)+string->size, string->string+i);
r_flag_name_filter (string->string);
snprintf (str, R_FLAG_NAME_SIZE, "str.%s", string->string);
@ -214,7 +214,7 @@ R_API int r_core_bin_load(RCore *r, const char *file) {
R_BIN_SCN_WRITABLE (section->srwx)?'w':'-',
R_BIN_SCN_EXECUTABLE (section->srwx)?'x':'-',
section->name);
r_meta_add (r->meta, R_META_COMMENT, va?baddr+section->rva:section->offset,
r_meta_add (r->meta, R_META_TYPE_COMMENT, va?baddr+section->rva:section->offset,
va?baddr+section->rva:section->offset, str);
}
}

View File

@ -90,7 +90,7 @@ R_API int r_core_project_save(RCore *core, const char *file) {
r_io_section_list (core->io, core->offset, 1);
r_cons_flush ();
r_str_write (fd, "# meta\n");
r_meta_list (core->meta, R_META_ANY);
r_meta_list (core->meta, R_META_TYPE_ANY);
r_cons_flush ();
r_str_write (fd, "# seek\n");
r_str_writef (fd, "s 0x%08"PFMT64x, core->offset);

View File

@ -669,16 +669,16 @@ R_API void r_core_visual_define (RCore *core) {
// detect type of string
// find EOS
// capture string value
r_meta_add (core->meta, R_META_STRING, off, off+core->blocksize, "");
r_meta_add (core->meta, R_META_TYPE_STRING, off, off+core->blocksize, "");
break;
case 'd': // TODO: check
r_meta_add (core->meta, R_META_DATA, off, off+core->blocksize, "");
r_meta_add (core->meta, R_META_TYPE_DATA, off, off+core->blocksize, "");
break;
case 'c': // TODO: check
r_meta_add (core->meta, R_META_CODE, off, off+core->blocksize, "");
r_meta_add (core->meta, R_META_TYPE_CODE, off, off+core->blocksize, "");
break;
case 'u':
r_meta_del (core->meta, R_META_ANY, off, 1, "");
r_meta_del (core->meta, R_META_TYPE_ANY, off, 1, "");
r_flag_unset_i (core->flags, off);
r_anal_fcn_del (core->anal, off);
break;

View File

@ -447,6 +447,49 @@ R_API boolt r_anal_cc_update (RAnal *anal, RAnalCC *cc, RAnalOp *op);
//R_API int r_anal_cc_register (RAnal *anal, RAnalCC *cc);
//R_API int r_anal_cc_unregister (RAnal *anal, RAnalCC *cc);
/* meta */
typedef struct r_meta_item_t {
ut64 from;
ut64 to;
ut64 size;
int type;
char *str;
} RMetaItem;
typedef struct r_meta_t {
RList *data;
PrintfCallback printf;
} RMeta;
enum {
R_META_WHERE_PREV = -1,
R_META_WHERE_HERE = 0,
R_META_WHERE_NEXT = 1,
};
enum {
R_META_TYPE_ANY = -1,
R_META_TYPE_DATA = 'd',
R_META_TYPE_CODE = 'c',
R_META_TYPE_STRING = 's',
R_META_TYPE_FORMAT = 'f',
R_META_TYPE_MAGIC = 'm',
R_META_TYPE_COMMENT = 'C',
};
R_API RMeta *r_meta_new();
R_API void r_meta_free(RMeta *m);
R_API int r_meta_count(RMeta *m, int type, ut64 from, ut64 to);
R_API char *r_meta_get_string(RMeta *m, int type, ut64 addr);
R_API int r_meta_del(RMeta *m, int type, ut64 from, ut64 size, const char *str);
R_API int r_meta_add(RMeta *m, int type, ut64 from, ut64 size, const char *str);
R_API struct r_meta_item_t *r_meta_find(RMeta *m, ut64 off, int type, int where);
R_API int r_meta_cleanup(RMeta *m, ut64 from, ut64 to);
R_API const char *r_meta_type_to_string(int type);
R_API int r_meta_list(RMeta *m, int type);
R_API void r_meta_item_free(void *_item);
R_API RMetaItem *r_meta_item_new(int type);
/* plugin pointers */
extern RAnalPlugin r_anal_plugin_csr;
extern RAnalPlugin r_anal_plugin_avr;

View File

@ -57,7 +57,7 @@ typedef struct r_cons_t {
int noflush;
FILE *fdin; // FILE? and then int ??
int fdout; // only used in pipe.c :?? remove?
char *teefile;
const char *teefile;
int (*user_fgets)(char *buf, int len);
RConsEvent event_interrupt;
RConsEvent event_resize;

View File

@ -10,7 +10,6 @@
#include "r_parse.h"
#include "r_anal.h"
#include "r_cmd.h"
#include "r_meta.h"
#include "r_cons.h"
#include "r_line.h"
#include "r_print.h"

View File

@ -1,71 +0,0 @@
#ifndef _INCLUDE_R_META_H_
#define _INCLUDE_R_META_H_
#include <r_types.h>
#include <r_util.h>
#include <r_list.h>
#include <list.h>
typedef struct r_meta_count_t {
/* TODO: ... */
} RMetaCount;
#if 0
TODO:
We need a way to determine sections for other architectures, so we will
be able to read a mixed x86/ppc mach0 binary in a shot.
We also need a way to determine if the folder is opened or closed (bool)
We also need to specify which type of data is the contents of a data block
(hexdump, structure, ...) select print format command
#endif
/* old data_t */
typedef struct r_meta_item_t {
ut64 from;
ut64 to;
ut64 size;
int type;
// int times;
char *str;
} RMetaItem;
typedef struct r_meta_t {
RList *data;
PrintfCallback printf;
// struct reflines_t *reflines = NULL;
// RLIst *comments;
} RMeta;
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 = 'd',
R_META_CODE = 'c',
R_META_STRING = 's',
R_META_STRUCT = 'm',
/* line */
R_META_COMMENT = 'C',
R_META_FOLDER = 'f', // XXX deprecate?
};
#ifdef R_API
R_API RMeta *r_meta_new();
R_API void r_meta_free(RMeta *m);
R_API int r_meta_count(RMeta *m, int type, ut64 from, ut64 to, RMetaCount *c);
R_API char *r_meta_get_string(RMeta *m, int type, ut64 addr);
R_API int r_meta_del(RMeta *m, int type, ut64 from, ut64 size, const char *str);
R_API int r_meta_add(RMeta *m, int type, ut64 from, ut64 size, const char *str);
R_API struct r_meta_item_t *r_meta_find(RMeta *m, ut64 off, int type, int where);
R_API int r_meta_cleanup(RMeta *m, ut64 from, ut64 to);
R_API const char *r_meta_type_to_string(int type);
R_API int r_meta_list(RMeta *m, int type);
R_API void r_meta_item_free(void *_item);
R_API RMetaItem *r_meta_item_new(int type);
#endif
#endif

View File

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

View File

@ -1,8 +0,0 @@
include ../../config.mk
OBJ=test.o
BIN=test
# already apended${EXT_EXE}
BINDEPS=r_meta r_util
include ../../rules.mk

View File

@ -1,696 +0,0 @@
/*
* Copyright (C) 2008
* pancake <youterm.com>
*
* radare is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* radare is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with radare; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
*/
#include "main.h"
#include "code.h"
#include "data.h"
#include "undo.h"
#include "flags.h"
#include "arch/csr/dis.h"
#include "arch/arm/disarm.h"
#include "arch/ppc/ppc_disasm.h"
#include "arch/m68k/m68k_disasm.h"
#include "arch/x86/udis86/types.h"
#include "arch/x86/udis86/extern.h"
#include "list.h"
struct reflines_t *reflines = NULL;
static struct list_head vartypes;
static struct list_head data;
static struct list_head comments;
static struct list_head xrefs;
int data_set_len(ut64 off, ut64 len)
{
struct list_head *pos;
list_for_each(pos, &data) {
struct data_t *d = (struct data_t *)list_entry(pos, struct data_t, list);
if (off>= d->from && off<= d->to) {
d->to = d->from+len;
d->size = d->to-d->from+1;
return 0;
}
}
return -1;
}
ut64 data_prev(ut64 off, int type)
{
struct list_head *pos;
ut64 ret = 0;
list_for_each(pos, &data) {
struct data_t *d = (struct data_t *)list_entry(pos, struct data_t, list);
if (d->type == type) {
if (d->from < off && d->to > off)
ret = d->from;
}
}
return ret;
}
int data_get_fun_for(ut64 addr, ut64 *from, ut64 *to)
{
struct list_head *pos;
int n_functions = 0;
int n_xrefs = 0;
int n_dxrefs = 0;
struct data_t *rd = NULL;
ut64 lastfrom = 0LL;
list_for_each(pos, &data) {
struct data_t *d = (struct data_t *)list_entry(pos, struct data_t, list);
if (d->type == DATA_FUN) {
if (d->from < addr && d->from > lastfrom) {
rd = d;
}
}
}
if (rd) {
*from = rd->from;
*to = rd->to;
return 1;
}
return 0;
}
void data_info()
{
struct list_head *pos;
int n_functions = 0;
int n_xrefs = 0;
int n_dxrefs = 0;
list_for_each(pos, &data) {
struct data_t *d = (struct data_t *)list_entry(pos, struct data_t, list);
if (d->type == DATA_FUN)
n_functions++;
}
list_for_each(pos, &xrefs) {
struct xrefs_t *x = (struct xrefs_t *)list_entry(pos, struct xrefs_t, list);
if (x->type == 0)
n_dxrefs++;
else n_xrefs++;
}
cons_printf("functions: %d\n", n_functions);
cons_printf("data_xrefs: %d\n", n_dxrefs);
cons_printf("code_xrefs: %d\n", n_xrefs);
}
int data_set(ut64 off, int type)
{
struct list_head *pos;
list_for_each(pos, &data) {
struct data_t *d = (struct data_t *)list_entry(pos, struct data_t, list);
if (off>= d->from && off<= d->to) {
d->type = type;
return 0;
}
}
return -1;
}
struct data_t *data_add_arg(ut64 off, int type, const char *arg)
{
struct data_t *d;
if (arg == NULL)
return NULL;
d = data_add(off, type);
if (d != NULL)
strncpy(d->arg , arg, sizeof(d->arg));
return d;
}
void data_del(ut64 addr, int type,int len/* data or code */)
{
struct data_t *d;
struct list_head *pos;
list_for_each(pos, &data) {
d = (struct data_t *)list_entry(pos, struct data_t, list);
if (d->from == addr && type == d->type && (len==0||len==d->size)) {
list_del(&(d->list));
break;
}
}
}
struct data_t *data_add(ut64 off, int type)
{
ut64 tmp;
struct data_t *d = NULL;
struct list_head *pos;
__reloop:
// TODO: use safe foreach here
list_for_each(pos, &data) {
struct data_t *d = (struct data_t *)list_entry(pos, struct data_t, list);
if (d && (off>= d->from && off< d->to) ) {
list_del((&d->list));
goto __reloop;
}
}
if (type == DATA_CODE)
return d;
d = (struct data_t *)malloc(sizeof(struct data_t));
memset(d, '\0', sizeof(d));
d->arg[0]='\0';
d->from = off;
d->to = d->from + config.block_size; // 1 byte if no cursor // on strings should autodetect
if (config.cursor_mode) {
d->to = d->from + 1;
d->from+=config.cursor;
if (config.ocursor!=-1)
d->to = config.seek+config.ocursor;
if (d->to < d->from) {
tmp = d->to;
d->to = d->from;
d->from = tmp;
}
}
d->type = type;
if (d->to > d->from) {
// d->to++;
d->size = d->to - d->from+1;
} else d->size = d->from - d->to+1;
if (d->size<1)
d->size = 1;
list_add(&(d->list), &data);
return d;
}
ut64 data_seek_to(ut64 offset, int type, int idx)
{
ut64 ret = 0ULL;
struct list_head *pos;
int i = 0;
idx--;
list_for_each(pos, &xrefs) {
struct xrefs_t *d = (struct xrefs_t *)list_entry(pos, struct xrefs_t , list);
if (d->type == type || type == -1) {
if (d->addr == offset && idx == i) {
ret = d->from;
break;
}
i++;
}
}
return ret;
}
struct data_t *data_get(ut64 offset)
{
struct list_head *pos;
list_for_each(pos, &data) {
struct data_t *d = (struct data_t *)list_entry(pos, struct data_t, list);
if (offset >= d->from && offset < d->to)
return d;
}
return NULL;
}
struct data_t *data_get_range(ut64 offset)
{
struct list_head *pos;
list_for_each(pos, &data) {
struct data_t *d = (struct data_t *)list_entry(pos, struct data_t, list);
if (offset >= d->from && offset < d->to)
return d;
}
return NULL;
}
/* TODO: OPTIMIZE: perform cache here */
struct data_t *data_get_between(ut64 from, ut64 to)
{
int hex = 0;
int str = 0;
int fun = 0;
int stc = 0;
int code = 0;
struct list_head *pos;
struct data_t *d = NULL;
static struct data_t ret;
list_for_each(pos, &data) {
d = (struct data_t *)list_entry(pos, struct data_t, list);
//if (from >= d->from && to <= d->to) {
if (d->from >= from && d->to < to) {
switch(d->type) {
case DATA_HEX: hex++; break;
case DATA_STR: str++; break;
case DATA_CODE: code++; break;
case DATA_FUN: fun++; break;
case DATA_STRUCT: stc++; break;
}
}
}
#if 0
if (d == NULL)
return NULL;
if (hex>=str && hex>=code && hex>=fun && hex >= stc) {
d->type = DATA_HEX;
d->times = hex;
} else
if (str>=hex && str>=code && str>=fun && str >= stc) {
d->type = DATA_STR;
d->times = str;
} else
if (fun>=hex && fun>=str && fun>=code && fun >= stc) {
d->type = DATA_FUN;
d->times = fun;
} else
if (code>=hex && code>=str && code>=fun && code >=stc) {
d->type = DATA_CODE;
d->times = code;
} else
if (stc>=hex && stc>=str && stc>=fun && stc>=code) {
d->type = DATA_STRUCT;
d->times = stc;
}
// TODO add struct
//printf("0x%"PFMT64x"-0x%"PFMT64x": %d %d %d = %d\n", from, to, hex, str, code, d->type);
return d;
#endif
if (hex>=str && hex>=code && hex>=fun && hex >= stc) {
ret.type = DATA_HEX;
ret.times = hex;
} else
if (str>=hex && str>=code && str>=fun && str >= stc) {
ret.type = DATA_STR;
ret.times = str;
} else
if (fun>=hex && fun>=str && fun>=code && fun >= stc) {
ret.type = DATA_FUN;
ret.times = fun;
} else
if (code>=hex && code>=str && code>=fun && code >=stc) {
ret.type = DATA_CODE;
ret.times = code;
} else
if (stc>=hex && stc>=str && stc>=fun && stc>=code) {
ret.type = DATA_STRUCT;
ret.times = stc;
}
return &ret;
}
int data_type_range(ut64 offset)
{
struct data_t *d = data_get_range(offset);
if (d != NULL)
return d->type;
return -1;
}
int data_type(ut64 offset)
{
struct list_head *pos;
list_for_each(pos, &data) {
struct data_t *d = (struct data_t *)list_entry(pos, struct data_t, list);
if (offset == d->from)
return d->type;
}
return -1;
}
int data_end(ut64 offset)
{
struct list_head *pos;
list_for_each(pos, &data) {
struct data_t *d = (struct data_t *)list_entry(pos, struct data_t, list);
if (offset == d->from+d->size) // XXX: must be d->to..but is buggy ?
return d->type;
}
return -1;
}
int data_size(ut64 offset)
{
struct list_head *pos;
list_for_each(pos, &data) {
struct data_t *d = (struct data_t *)list_entry(pos, struct data_t, list);
if (offset == d->from)
return d->size;
}
return 0;
}
// TODO: add grep flags here
int data_list_ranges()
{
struct data_t *d;
struct list_head *pos;
list_for_each(pos, &data) {
d = (struct data_t *)list_entry(pos, struct data_t, list);
switch(d->type) {
case DATA_FUN:
cons_printf("ar+ 0x%08"PFMT64x" 0x%08"PFMT64x"\n",
d->from, d->to);
break;
}
}
}
/* TODO: add grep flags argument */
int data_list()
{
char *arg;
char label[1024];
struct data_t *d;
struct list_head *pos;
list_for_each(pos, &data) {
d = (struct data_t *)list_entry(pos, struct data_t, list);
label[0]='\0';
string_flag_offset(label, d->from, 0);
arg = NULL;
switch(d->type) {
case DATA_FOLD_O: cons_strcat("Cu "); break;
case DATA_FOLD_C: cons_strcat("Cf "); break;
case DATA_FUN: cons_strcat("CF "); break;
case DATA_HEX: cons_strcat("Cd "); break;
case DATA_STR: cons_strcat("Cs "); break;
case DATA_STRUCT: cons_strcat("Cm "); arg = d->arg; break;
default: cons_strcat("Cc "); break; }
cons_printf("%"PFMT64d" %s@ 0x%08"PFMT64x" ; %s", d->to-d->from, arg?arg:"", d->from, label);
#if 0
if (verbose)
if (d->type == DATA_STR) {
cons_printf(" (");
sprintf(label, "pz@0x%08"PFMT64x"", d->from);
radare_cmd(label, 0);
}else
#endif
cons_newline();
}
return 0;
}
/* -- metadata -- */
int data_xrefs_print(ut64 addr, int type)
{
char str[1024];
int n = 0;
struct xrefs_t *x;
struct list_head *pos;
list_for_each(pos, &xrefs) {
x = (struct xrefs_t *)list_entry(pos, struct xrefs_t, list);
if (x->addr == addr) {
str[0]='\0';
string_flag_offset(str, x->from, 0);
switch(type) {
case 0: if (x->type == type) { cons_printf("; 0x%08"PFMT64x" CODE xref 0x%08"PFMT64x" (%s)\n", addr, x->from, str); n++; } break;
case 1: if (x->type == type) { cons_printf("; 0x%08"PFMT64x" DATA xref 0x%08"PFMT64x" (%s)\n", addr, x->from), str; n++; } break;
default: { cons_printf("; 0x%08"PFMT64x" %s xref from 0x%08"PFMT64x" (%s)\n", addr, (x->type==1)?"DATA":(x->type==0)?"CODE":"UNKNOWN",x->from, str); n++; };
}
}
}
return n;
}
int data_xrefs_add(ut64 addr, ut64 from, int type)
{
struct xrefs_t *x;
struct list_head *pos;
/* avoid dup */
list_for_each(pos, &xrefs) {
x = (struct xrefs_t *)list_entry(pos, struct xrefs_t, list);
if (x->addr == addr && x->from == from)
return 0;
}
x = (struct xrefs_t *)malloc(sizeof(struct xrefs_t));
x->addr = addr;
x->from = from;
x->type = type;
list_add(&(x->list), &xrefs);
return 1;
}
int data_xrefs_at(ut64 addr)
{
int ctr = 0;
struct xrefs_t *x;
struct list_head *pos;
/* avoid dup */
list_for_each(pos, &xrefs) {
x = (struct xrefs_t *)list_entry(pos, struct xrefs_t, list);
if (x->addr == addr)
ctr++;
}
return ctr;
}
void data_xrefs_del(ut64 addr, ut64 from, int data /* data or code */)
{
struct xrefs_t *x;
struct list_head *pos;
list_for_each(pos, &xrefs) {
x = (struct xrefs_t *)list_entry(pos, struct xrefs_t, list);
if (x->addr == addr && x->from == from) {
list_del(&(x->list));
break;
}
}
}
void data_comment_del(ut64 offset, const char *str)
{
struct comment_t *cmt;
struct list_head *pos;
//ut64 off = get_math(str);
list_for_each(pos, &comments) {
cmt = list_entry(pos, struct comment_t, list);
#if 0
if (!pos)
return;
#endif
#if 0
if (off) {
if ((off == cmt->offset)) {
free(cmt->comment);
list_del(&(pos));
free(cmt);
if (str[0]=='*')
data_comment_del(offset, str);
pos = comments.next; // list_init
return;
}
} else {
#endif
if (offset == cmt->offset) {
if (str[0]=='*') {
free(cmt->comment);
list_del(&(pos));
free(cmt);
pos = comments.next; // list_init
//data_comment_del(offset, str);
} else
if (!strcmp(cmt->comment, str)) {
list_del(&(pos));
return;
}
}
#if 0
}
#endif
}
}
void data_comment_add(ut64 offset, const char *str)
{
struct comment_t *cmt;
char *ptr;
/* no null comments */
if (strnull(str))
return;
/* avoid dupped comments */
data_comment_del(offset, str);
cmt = (struct comment_t *) malloc(sizeof(struct comment_t));
cmt->offset = offset;
ptr = strdup(str);
if (ptr[strlen(ptr)-1]=='\n')
ptr[strlen(ptr)-1]='\0';
cmt->comment = ptr;
list_add_tail(&(cmt->list), &(comments));
}
void data_comment_list()
{
struct list_head *pos;
list_for_each(pos, &comments) {
struct comment_t *cmt = list_entry(pos, struct comment_t, list);
cons_printf("CC %s @ 0x%"PFMT64x"\n", cmt->comment, cmt->offset);
}
}
void data_xrefs_here(ut64 addr)
{
int count = 0;
char label[1024];
struct xrefs_t *x;
struct list_head *pos;
list_for_each(pos, &xrefs) {
x = (struct xrefs_t *)list_entry(pos, struct xrefs_t, list);
if (addr = x->addr) {
label[0]='\0';
string_flag_offset(label, x->from, 0);
cons_printf("%d %s xref 0x%08"PFMT64x" @ 0x%08"PFMT64x" ; %s\n",
count+1, x->type?"data":"code", x->from, x->addr, label);
count++;
}
}
if (count == 0) {
eprintf("No xrefs found\n");
}
}
void data_xrefs_list()
{
char label[1024];
struct xrefs_t *x;
struct list_head *pos;
list_for_each(pos, &xrefs) {
x = (struct xrefs_t *)list_entry(pos, struct xrefs_t, list);
label[0]='\0';
string_flag_offset(label, x->from, 0);
cons_printf("C%c 0x%08"PFMT64x" @ 0x%08"PFMT64x" ; %s\n", x->type?'d':'x', x->from, x->addr, label);
}
}
char *data_comment_get(ut64 offset, int lines)
{
struct list_head *pos;
char *str = NULL;
int cmtmargin = (int)config_get_i("asm.cmtmargin");
int cmtlines = config_get_i("asm.cmtlines");
char null[128];
memset(null,' ',126);
null[126]='\0';
if (cmtmargin<0) cmtmargin=0; else
// TODO: use screen width here
if (cmtmargin>80) cmtmargin=80;
null[cmtmargin] = '\0';
if (cmtlines<0)
cmtlines=0;
if (cmtlines) {
int i = 0;
list_for_each(pos, &comments) {
struct comment_t *cmt = list_entry(pos, struct comment_t, list);
if (cmt->offset == offset)
i++;
}
if (i>cmtlines)
cmtlines = i-cmtlines;
}
list_for_each(pos, &comments) {
struct comment_t *cmt = list_entry(pos, struct comment_t, list);
if (cmt->offset == offset) {
if (cmtlines) {
cmtlines--;
continue; // skip comment lines
}
if (str == NULL) {
str = malloc(1024);
str[0]='\0';
} else {
str = realloc(str, cmtmargin+strlen(str)+strlen(cmt->comment)+128);
}
strcat(str, null);
strcat(str, "; ");
strcat(str, cmt->comment);
strcat(str, "\n");
if (--lines == 0)
break;
}
}
return str;
}
void data_comment_init(int new)
{
INIT_LIST_HEAD(&(vartypes));
INIT_LIST_HEAD(&(xrefs));
INIT_LIST_HEAD(&(comments));
INIT_LIST_HEAD(&(data));
var_init();
}
void data_reflines_init()
{
int show_lines = (int) config_get_i("asm.lines");
reflines = NULL;
if (show_lines)
reflines = code_lines_init();
}
int data_printd(int delta)
{
int show_lines = (int)config_get("asm.lines");
ut64 offset = (ut64)config.seek + (ut64)delta;// - config.vaddr;
int lines = 0;
const char *ptr;
D {} else return 0;
ptr = data_comment_get(offset, config.height-cons_lines);
if (ptr && ptr[0]) {
int i;
for(i=0;ptr[i];i++)
if (ptr[i]=='\n') lines++;
C cons_printf(C_MAGENTA"%s"C_RESET, ptr);
else cons_strcat(ptr);
free((void *)ptr);
}
lines += data_xrefs_print(offset, -1);
return lines;
}