Add 'aos' to sdb-ize the esil, file.suppress_warnings renamed to file.nowarn

This commit is contained in:
pancake 2014-01-31 02:02:51 +01:00
parent a42c809984
commit 1f1367382b
14 changed files with 369 additions and 76 deletions

95
doc/kvast Normal file
View File

@ -0,0 +1,95 @@
kvast
=====
KeyValue storage for AST
To optimize serialized storage use a concatenated
string array and use the sdb array string api
eax=33
------
0.op=set []0=set,eax,33
0.a=eax
0.b=33
ebx=(8*(eax+4))
---------------
0.op=set []0=set,ebx,$1
0.a=ebx
0.b=$1
1.op=mul []1=mul,8,$2
1.a=8
1.b=$2
2.op=add []2=add,eax,4
2.a=eax
2.b=4
ebx=8*(eax+4)+3
---------------
0.op=set []0=set,ebx,$3
0.a=ebx
0.b=$3
1.op=mul []1=mul,8,$2
1.a=8
1.b=$2
2.op=add []2=add,eax,4
2.a=eax
2.b=4
3.op=add []3=add,$1,3
3.a=$1
3.b=3
ebx=8*(eax+4+ecx+2)+1
---------------------
0.op=set
0.a=ebx
0.b=$5
1.op=mul
1.a=8
1.b=$4
(
2.op=add
2.a=eax
2.b=4
// update toplevel b reference
3.op=add
3.a=$2
3.b=ecx
// update toplevel b reference
4.op=add
4.a=$3
4.b=2
}
// update toplevel b reference
5.op=add
5.a=$1
5.b=1
Parsing
=======
Parsing is done by a state machine which reads the expression string and creates a keyvalue string that represents the ESIL instruction.
This is an example
switch (ch) {
case '+':
case '-':
case '*':
case '/':
if (expect_arg) {
expect_arg = ch;
}
break;
}

View File

@ -22,7 +22,7 @@ STATIC_OBJS=$(addprefix $(LTOP)/anal/p/,$(STATIC_OBJ))
OBJLIBS=meta.o reflines.o ref.o op.o fcn.o bb.o var.o
OBJLIBS+=cond.o value.o cc.o diff.o types.o fcnstore.o
OBJLIBS+=hint.o vm.o anal.o data.o xrefs.o esil.o sign.o
OBJLIBS+=anal_ex.o switch.o state.o
OBJLIBS+=anal_ex.o switch.o state.o kvesil.o
OBJS=${STATIC_OBJS} ${OBJLIBS} ${CPARSE_OBJS}

View File

@ -325,8 +325,8 @@ static ut64 num(struct r_anal_esil_t *c, const char *str) {
return r_num_get (NULL, str);
}
#define C(x) r_anal_esil(&c,x)
#define C(x) r_anal_esil(&c,x)
#ifdef MAIN
int main() {
RAnalEsil c = {

186
libr/anal/kvesil.c Normal file
View File

@ -0,0 +1,186 @@
/* radare - LGPL - Copyright 2014 - pancake */
#include <r_anal.h>
#include <stdio.h>
static const char *chstr(int ch) {
switch (ch) {
case '=': return "set";
case '+': return "add";
case '-': return "sub";
case '*': return "mul";
case '/': return "div";
case '&': return "and";
case '^': return "xor";
case '|': return "orr";
case '>': return "shr";
case '<': return "shl";
}
return "?";
}
R_API char *r_anal_esil_to_sdb(char *str) {
// tokenize string
#define TOK_NEW(x,y) (x<<24|(y+1))
#define TOK_OP(x) (x>>24)
#define TOK_ARG(x) str+(x&0xffffff)
char *p = str;
int tok[32], i = 0, t = 0;
tok[0] = 0;
for (i=0; p[i]; i++) {
char ch = p[i];
switch (ch) {
case '[': // TODO
case ']': // TODO
case ',':
case ';':
case '(':
case ')':
case '<':
case '>':
case '*':
case '+':
case '-':
case '/':
case '=':
p[i] = 0;
tok[t++] = TOK_NEW(ch, i);
break;
}
}
// build sdb
{
char *a = str;
char *b;
int idx = 0;
int top = 0;
int level = 0;
int stack[32];
stack[0] = 0;
for (i=0; i<t; i++) {
char op = TOK_OP(tok[i]);
b = TOK_ARG(tok[i]);
switch (op) {
case ',':
case ';':
level = 0;
a = TOK_ARG (tok[i]);
continue;
case '=':
if (TOK_OP (tok[i+1])=='=') {
printf ("TODO: cmp\n");
return NULL;
}
break;
case '(':
level++;
if (level>=(sizeof(stack)/sizeof(*stack))) {
printf ("ERROR: too many open parenthesis\n");
return NULL;
}
stack[level] = i;
a = TOK_ARG(tok[i]);
continue;
case ')':
level--;
if (level<0) {
printf ("ERROR: too many closing parenthesis\n");
return NULL;
}
top = stack[level];
continue;
}
if (*b) printf ("[]%d=%s,%s,%s\n", idx, chstr (op), a, b);
else printf ("[]%d=%s,%s,&%d\n", idx, chstr (op), a, idx+1);
a = b;
stack[level] = top = idx;
if (i>0) {
printf ("[2]%d=&%d\n", stack[level]-1, idx);
stack[level] = top = idx;
}
idx++;
}
}
return NULL;
}
#if 0
char *kvesil(char *str) {
char *a, *b, *o, *p;
char expect_arg = 0;
int idx = 0, level = 0;
b = 0;
eprintf ("(((%s)))\n", str);
for (a=o=p=str;*p;p++) {
char ch = *p;
printf ("= %c\n", ch);
switch (ch) {
case ';':
a = NULL;
b = NULL;
expect_arg = 0;
level = 0;
break;
case '(':
*p = 0;
level++;
break;
case ')':
*p = 0;
printf ("[]%d=%s,%s,$%d\n",
idx, chstr (expect_arg), a, idx+1);
level--;
break;
case '=':
*p = 0;
if (p[1]=='=') {
// comparison
printf ("TODO: cmp\n");
break;
}
case '+':
case '-':
case '*':
case '/':
*p = 0;
if (expect_arg) {
printf ("[]%d=%s,%s,%s\n",
idx, chstr (ch), a, b);
idx++;
a = p+1;
printf ("set\n");
expect_arg = 0;
} else {
printf ("zet\n");
/*
printf ("[]%d=%s,%s,$%d\n",
idx, chstr (ch), a, idx+1);
*/
b = p+1;
expect_arg = ch;
}
idx++;
break;
}
}
if (expect_arg) {
if (!b || !*b) {
printf ("Invalid expression\n");
return NULL;
} else {
printf ("[]%d=%s,%s,%s\n",
idx, chstr (expect_arg), a, b);
}
}
return "";
}
#endif
#if USE_MAIN
int main(int argc, char **argv) {
if (argc>1)
esil_tokenize(argv[1]);
//printf ("%s\n", kvesil (argv[1]));
return 0;
}
#endif

View File

@ -8,18 +8,18 @@
#define IFDBG if(0)
static Sdb *BIN_OBJS_ADDRS = NULL;
static Sdb *DB = NULL;
static void add_bin_obj_to_sdb(RBinJavaObj *bin);
static int add_sdb_bin_obj(const char *key, RBinJavaObj *bin_obj);
static int init(void *user) {
IFDBG eprintf ("Calling plugin init = %d.\n", BIN_OBJS_ADDRS?1:0);
if (!BIN_OBJS_ADDRS) {
IFDBG eprintf ("plugin BIN_OBJS_ADDRS beeing initted.\n");
BIN_OBJS_ADDRS = sdb_new ("bin.java", NULL, 0);
IFDBG eprintf ("Calling plugin init = %d.\n", DB?1:0);
if (!DB) {
IFDBG eprintf ("plugin DB beeing initted.\n");
DB = sdb_new ("bin.java", NULL, 0);
} else {
IFDBG eprintf ("plugin BIN_OBJS_ADDRS already initted.\n");
IFDBG eprintf ("plugin DB already initted.\n");
}
return 0;
}
@ -28,9 +28,9 @@ static int add_sdb_bin_obj(const char *key, RBinJavaObj *bin_obj) {
int result = R_FALSE;
char value[1024] = {0};
sdb_itoa ((ut64)(size_t)bin_obj, value);
if (key && bin_obj && BIN_OBJS_ADDRS) {
if (key && bin_obj && DB) {
IFDBG eprintf ("Adding %s:%s to the bin_objs db\n", key, value);
sdb_set (BIN_OBJS_ADDRS, key, value, 0);
sdb_set (DB, key, value, 0);
result = R_TRUE;
}
return result;
@ -52,19 +52,19 @@ static int load(RBinFile *arch) {
if (bin_obj) {
if (arch->o->kv == NULL) arch->o->kv = bin_obj->kv;
arch->o->bin_obj = bin_obj;
bin_obj->AllJavaBinObjs = BIN_OBJS_ADDRS;
bin_obj->AllJavaBinObjs = DB;
// XXX - /\ this is a hack, but (one way but) necessary to get access to
// the object addrs from anal. If only global variables are used,
// they get "lost" somehow after they are initialized and go out of
// scope.
//
// There are several points of indirection, but here is the gist:
// 1) RAnal->(through RBinBind) RBin->RBinJavaObj->BIN_OBJS_ADDRS
// 1) RAnal->(through RBinBind) RBin->RBinJavaObj->DB
//
// The purpose is to ensure that information about a give class file
// can be grabbed at any time from RAnal. This was tried with global
// variables, but failed when attempting to access the BIN_OBJS_ADDRS
// in the class.c scope. Once BIN_OBJS_ADDRS was moved here, it is initialized
// variables, but failed when attempting to access the DB
// in the class.c scope. Once DB was moved here, it is initialized
// once here and assigned to each of the other RBinJavaObjs.
//
// Now, the RAnal component of radare can get to each of the
@ -79,8 +79,8 @@ static int load(RBinFile *arch) {
static int destroy(RBinFile *arch) {
r_bin_java_free ((struct r_bin_java_obj_t*)arch->o->bin_obj);
sdb_free (BIN_OBJS_ADDRS);
BIN_OBJS_ADDRS = NULL;
sdb_free (DB);
DB = NULL;
return R_TRUE;
}

View File

@ -1,4 +1,4 @@
/* radare - LGPL - Copyright 2009-2013 - pancake, nibble */
/* radare - LGPL - Copyright 2009-2014 - pancake, nibble */
#include <r_types.h>
#include <r_list.h>

View File

@ -1,4 +1,4 @@
/* radare - LGPL - Copyright 2009-2013 - pancake */
/* radare - LGPL - Copyright 2009-2014 - pancake */
#if 1
/* TODO: Move into cmd_anal() */
@ -611,8 +611,7 @@ static int cmd_anal(void *data, const char *input) {
case 'e':
if (input[1] == 'r') {
r_debug_reg_list (core->dbg, 0, 0, 0);
} else
if (input[1] == ' ') {
} else if (input[1] == ' ') {
r_anal_esil_eval (core->anal, input+2);
} else eprintf ("Usage: ae [esil] # wip. analyze esil. (evaluable string intermediate language)\n");
break;
@ -622,6 +621,7 @@ static int cmd_anal(void *data, const char *input) {
"Usage: ao[e?] [len]\n"
" aoj display opcode analysis information in JSON\n"
" aoe emulate opcode at current offset\n"
" aos show sdb representation of esil expression\n"
" aoe 4 emulate 4 opcodes starting at current offset\n"
" ao 5 display opcode analysis of 5 opcodes\n");
} else
@ -640,6 +640,17 @@ static int cmd_anal(void *data, const char *input) {
}
r_core_anal_bytes (core, core->block, len, count, 'j');
} else
if (input[1]=='s') {
RAnalOp *op = r_core_op_anal (core, addr);
if (op != NULL) {
char *esil = strdup (R_STRBUF_SAFEGET (&op->esil));
char *o = r_anal_esil_to_sdb (esil);
// do stuff
free (esil);
free (o);
r_anal_op_free (op);
}
} else
if (input[1] == 'e') {
eprintf ("TODO: r_anal_op_execute: TODO: USE ESIL\n");
} else {

View File

@ -497,7 +497,7 @@ free (rf);
break;
case ' ': {
char *s = strdup (str+2);
char sl, n, rwx, *p;
char sl, n, rwx;
int len;
ut64 off;

View File

@ -4,7 +4,7 @@ static int cmd_open(void *data, const char *input) {
RCore *core = (RCore*)data;
int perms = R_IO_READ;
ut64 addr, baddr = r_config_get_i (core->config, "bin.baddr");
char *suppress_warning = r_config_get (core->config, "file.suppress_warnings");
int nowarn = r_config_get_i (core->config, "file.nowarn");
RIOMap *map = NULL;
RCoreFile *file;
RListIter *iter;
@ -38,7 +38,7 @@ static int cmd_open(void *data, const char *input) {
// MUST CLEAN BEFORE LOADING
if (!isn)
r_core_bin_load (core, fn, baddr);
} else if (!strcmp (suppress_warning, "false")) {
} else if (!nowarn) {
eprintf ("Cannot open file '%s'\n", fn);
}
} else {

View File

@ -371,7 +371,7 @@ c = 0;
case 'P':
{
// print the offset of the Previous opcode
char buf[64];
ut8 buf[64];
ut64 off = core->offset;
r_core_read_at (core, off-16, buf, 32);
off = findprevopsz (core, off, buf, 16);

View File

@ -835,7 +835,7 @@ R_API int r_core_config_init(RCore *core) {
SETPREF("file.type", "", "Type of current file");
SETPREF("file.loadmethod", "fail", "What to do when load addresses overlap: fail, overwrite, or append (next available)");
SETI("file.loadalign", 1024, "Alignment of load addresses");
SETPREF("file.suppress_warnings", "false", "Suppress file loading warning messages");
SETPREF("file.nowarn", "false", "Suppress file loading warning messages");
/* magic */
SETI("magic.depth", 100, "Recursivity depth in magic description strings");

View File

@ -300,7 +300,7 @@ R_API int r_core_bin_load(RCore *r, const char *file, ut64 baddr) {
R_API RIOMap *r_core_file_get_next_map (RCore *core, RCoreFile * fh, int mode, ut64 loadaddr) {
const char *loadmethod = r_config_get (core->config, "file.loadmethod");
RIOMap *map = r_io_map_add (core->io, fh->fd->fd, mode, 0, loadaddr, fh->size);
const char *suppress_warning = r_config_get (core->config, "file.suppress_warnings");
const char *suppress_warning = r_config_get (core->config, "file.nowarn");
if (map) return map;
@ -364,7 +364,7 @@ R_API RCoreFile *r_core_file_open_many(RCore *r, const char *file, int mode, ut6
RIODesc *fd;
RListIter *fd_iter;
ut64 current_loadaddr = loadaddr;
const char *suppress_warning = r_config_get (r->config, "file.suppress_warnings");
const char *suppress_warning = r_config_get (r->config, "file.nowarn");
const char *cp = NULL;
char *loadmethod = NULL;
@ -432,7 +432,7 @@ R_API RCoreFile *r_core_file_open(RCore *r, const char *file, int mode, ut64 loa
const char *cp;
RCoreFile *fh;
RIODesc *fd;
const char *suppress_warning = r_config_get (r->config, "file.suppress_warnings");
const char *suppress_warning = r_config_get (r->config, "file.nowarn");
if (!strcmp (file, "-")) {
file = "malloc://512";

View File

@ -882,6 +882,7 @@ R_API RAnalOp *r_anal_op_hexstr(RAnal *anal, ut64 addr,
const char *hexstr);
R_API char *r_anal_op_to_string(RAnal *anal, RAnalOp *op);
R_API const char *r_anal_op_to_esil_string(RAnal *anal, RAnalOp *op);
R_API char *r_anal_esil_to_sdb(char *str);
/* fcn.c */
R_API RAnalFunction *r_anal_fcn_new();

View File

@ -1021,27 +1021,27 @@ R_API RBinJavaCPTypeObj* r_bin_java_get_java_null_cp() {
R_API RBinJavaElementValueMetas* r_bin_java_get_ev_meta_from_tag(ut8 tag) {
ut16 i = 0;
RBinJavaElementValueMetas *result = &R_BIN_JAVA_ELEMENT_VALUE_METAS[13];
RBinJavaElementValueMetas *res = &R_BIN_JAVA_ELEMENT_VALUE_METAS[13];
for (i = 0; i < R_BIN_JAVA_ELEMENT_VALUE_METAS_SZ; i++ ) {
if (tag == R_BIN_JAVA_ELEMENT_VALUE_METAS[i].tag) {
result = &R_BIN_JAVA_ELEMENT_VALUE_METAS[i];
res = &R_BIN_JAVA_ELEMENT_VALUE_METAS[i];
break;
}
}
return result;
return res;
}
R_API RBinJavaCPTypeMetas* r_bin_java_get_cp_meta_from_tag(ut8 tag) {
ut16 i = 0;
// set default to unknown.
RBinJavaCPTypeMetas *result = &R_BIN_JAVA_CP_METAS[2];
RBinJavaCPTypeMetas *res = &R_BIN_JAVA_CP_METAS[2];
for (i = 0; i < R_BIN_JAVA_CP_METAS_SZ; i++ ) {
if (tag == R_BIN_JAVA_CP_METAS[i].tag) {
result = &R_BIN_JAVA_CP_METAS[i];
res = &R_BIN_JAVA_CP_METAS[i];
break;
}
}
return result;
return res;
}
void deinit_java_type_null() {
@ -1049,19 +1049,19 @@ void deinit_java_type_null() {
}
R_API ut8 r_bin_java_quick_check(ut8 expected_tag, ut8 actual_tag, ut32 actual_len, const char* name) {
ut8 result = 0;
ut8 res = 0;
if (expected_tag > R_BIN_JAVA_CP_METAS_SZ) {
eprintf ("Invalid tag '%d' expected 0x%02x for %s.\n",actual_tag, expected_tag, name);
result = 1;
res = 1;
}else if (expected_tag != actual_tag) {
eprintf ("Invalid tag '%d' expected 0x%02x for %s.\n",actual_tag, expected_tag, name);
result = 1;
res = 1;
}else if (actual_len < R_BIN_JAVA_CP_METAS[expected_tag].len) {
eprintf ("Unable to parse '%d' expected sz=0x%02x got 0x%02x for %s.\n",
actual_tag, R_BIN_JAVA_CP_METAS[expected_tag].len, actual_len, name);
result = 2;
res = 2;
}
return result;
return res;
}
R_API ut64 rbin_java_raw_to_long(ut8* raw, ut64 offset) {
@ -1073,19 +1073,19 @@ R_API ut64 rbin_java_raw_to_long(ut8* raw, ut64 offset) {
// 2) dont feel like figuring it out when google does it in O(1).
R_API double my_pow(ut64 base, int exp) {
ut8 flag=0;
ut64 result = 1;
ut64 res = 1;
if(exp < 0) {
flag = 1;
exp *= -1;
}
while (exp) {
if (exp & 1) result *= base;
if (exp & 1) res *= base;
exp >>= 1;
base *= base;
IFDBG eprintf ("Result: %"PFMT64d", base: %"PFMT64d", exp: %d\n", result, base, exp);
IFDBG eprintf ("Result: %"PFMT64d", base: %"PFMT64d", exp: %d\n", res, base, exp);
}
if(flag==0) return 1.0*result;
return (1.0/result);
if(flag==0) return 1.0*res;
return (1.0/res);
}
double rbin_java_raw_to_double(ut8* raw, ut64 offset) {
@ -1095,23 +1095,23 @@ double rbin_java_raw_to_double(ut8* raw, ut64 offset) {
long m = (e == 0) ?
(bits & 0xfffffffffffffLL) << 1 :
(bits & 0xfffffffffffffLL) | 0x10000000000000LL;
double result = 0.0;
double res = 0.0;
IFDBG eprintf ("Convert Long to Double: %08"PFMT64x"\n", bits);
if (0x7ff0000000000000LL == bits) {
result = INFINITY;
res = INFINITY;
}else if (0xfff0000000000000LL == bits) {
result = -INFINITY;
res = -INFINITY;
}else if (0x7ff0000000000001LL <= bits && bits <= 0x7fffffffffffffffLL ) {
result = NAN;
res = NAN;
}else if (0xfff0000000000001LL <= bits && bits <= 0xffffffffffffffffLL ) {
result = NAN;
res = NAN;
}else{
result = s* m* my_pow (2, e-1075);//XXXX TODO Get double to work correctly here
res = s* m* my_pow (2, e-1075);//XXXX TODO Get double to work correctly here
IFDBG eprintf (" High-bytes = %02x %02x %02x %02x\n", raw[0], raw[1], raw[2], raw[3]);
IFDBG eprintf (" Low-bytes = %02x %02x %02x %02x\n", raw[4], raw[5], raw[6], raw[7]);
IFDBG eprintf ("Convert Long to Double s: %d, m: 0x%08lx, e: 0x%08x, result: %f\n", s, m, e, result);
IFDBG eprintf ("Convert Long to Double s: %d, m: 0x%08lx, e: 0x%08x, res: %f\n", s, m, e, res);
}
return result;
return res;
}
R_API RBinJavaField* r_bin_java_read_next_method(RBinJavaObj *bin, ut64 offset) {
@ -1690,18 +1690,18 @@ R_API RBinJavaAttrInfo* r_bin_java_get_method_code_attribute(const RBinJavaField
rvalue: RBinJavaAttrInfo* if found otherwise NULL.
*/
RBinJavaAttrInfo *result = NULL, *attr = NULL;
RBinJavaAttrInfo *res = NULL, *attr = NULL;
RListIter *iter;
if (method) {
r_list_foreach (method->attributes, iter, attr ) {
if (attr && (attr->type == R_BIN_JAVA_ATTR_TYPE_CODE_ATTR) ) {
result = attr;
res = attr;
break;
}
}
}
return result;
return res;
}
R_API RBinJavaAttrInfo* r_bin_java_get_attr_from_field(RBinJavaField *field, R_BIN_JAVA_ATTR_TYPE attr_type, ut32 pos ) {
@ -1781,15 +1781,15 @@ R_API RBinJavaAttrInfo* r_bin_java_default_attr_new(ut8* buffer, ut64 sz, ut64 b
}
RBinJavaAttrMetas* r_bin_java_get_attr_type_by_name(const char *name) {
RBinJavaAttrMetas* result = &RBIN_JAVA_ATTRS_METAS[R_BIN_JAVA_ATTR_TYPE_UNKNOWN_ATTR];
RBinJavaAttrMetas* res = &RBIN_JAVA_ATTRS_METAS[R_BIN_JAVA_ATTR_TYPE_UNKNOWN_ATTR];
ut32 i = 0;
for (i = 0; i < RBIN_JAVA_ATTRS_METAS_SZ; i++) {
if (strcmp ( (const char *) name, RBIN_JAVA_ATTRS_METAS[i].name) == 0) {
result = &RBIN_JAVA_ATTRS_METAS[i];
res = &RBIN_JAVA_ATTRS_METAS[i];
break;
}
}
return result;
return res;
}
R_API RBinJavaAttrInfo* r_bin_java_read_next_attr(RBinJavaObj *bin, ut64 buf_offset) {
@ -2075,7 +2075,7 @@ R_API RList* r_bin_java_get_bin_obj_list_thru_obj(RBinJavaObj *bin_obj) {
R_API RBinJavaField * r_bin_java_get_method_code_attribute_with_addr(RBinJavaObj *bin, ut64 addr) {
RListIter *iter = NULL, *iter_tmp=NULL;
RBinJavaField *fm_type, *result = NULL;
RBinJavaField *fm_type, *res = NULL;
if (bin == NULL && R_BIN_JAVA_GLOBAL_BIN) bin = R_BIN_JAVA_GLOBAL_BIN;
else {
@ -2088,9 +2088,9 @@ R_API RBinJavaField * r_bin_java_get_method_code_attribute_with_addr(RBinJavaObj
size = r_bin_java_get_method_code_size(fm_type);
if ( addr >= offset && addr <= size + offset)
result = fm_type;
res = fm_type;
}
return result;
return res;
}
R_API RBinAddr * r_bin_java_get_entrypoint(RBinJavaObj* bin, int sym) {
@ -2374,14 +2374,14 @@ R_API RList* r_bin_java_enum_class_fields(RBinJavaObj *bin, ut16 class_idx) {
static int is_class_interface(RBinJavaObj *bin, RBinJavaCPTypeObj *cp_obj) {
RListIter *iter;
RBinJavaInterfaceInfo *interface_obj;
int result = R_FALSE;
int res = R_FALSE;
r_list_foreach(bin->interfaces_list, iter, interface_obj) {
if (interface_obj) {
result = cp_obj == interface_obj->cp_class;
if (result) break;
res = cp_obj == interface_obj->cp_class;
if (res) break;
}
}
return result;
return res;
}
/*
@ -7229,47 +7229,47 @@ R_API void r_bin_java_print_rtip_annotations_attr_summary(RBinJavaAttrInfo *attr
R_API RBinJavaCPTypeObj *r_bin_java_find_cp_name_and_type_info(ut16 name_idx, ut16 descriptor_idx) {
RListIter *iter, *iter_tmp;
RBinJavaCPTypeObj *result= NULL, *obj = NULL;
RBinJavaCPTypeObj *res= NULL, *obj = NULL;
IFDBG eprintf ("Looking for name_idx: %d and descriptor_idx: %d\n", name_idx, descriptor_idx);
r_list_foreach_safe (R_BIN_JAVA_GLOBAL_BIN->cp_list, iter, iter_tmp, obj) {
if(obj && obj->tag == R_BIN_JAVA_CP_NAMEANDTYPE) {
IFDBG eprintf ("RBinJavaCPTypeNameAndType has name_idx: %d and descriptor_idx: %d\n", obj->info.cp_name_and_type.name_idx, obj->info.cp_name_and_type.descriptor_idx);
if (obj->info.cp_name_and_type.name_idx == name_idx &&
obj->info.cp_name_and_type.descriptor_idx == descriptor_idx) {
result = obj;
res = obj;
break;
}
}
}
return result;
return res;
}
R_API RBinJavaCPTypeObj *r_bin_java_find_cp_ref_info_from_name_and_type (ut16 name_idx, ut16 descriptor_idx) {
RBinJavaCPTypeObj *result= NULL,
RBinJavaCPTypeObj *res= NULL,
*obj = r_bin_java_find_cp_name_and_type_info (name_idx, descriptor_idx);
if(obj)
result = r_bin_java_find_cp_ref_info (obj->metas->ord);
return result;
res = r_bin_java_find_cp_ref_info (obj->metas->ord);
return res;
}
R_API RBinJavaCPTypeObj *r_bin_java_find_cp_ref_info(ut16 name_and_type_idx) {
RListIter *iter, *iter_tmp;
RBinJavaCPTypeObj *result= NULL, *obj = NULL;
RBinJavaCPTypeObj *res= NULL, *obj = NULL;
r_list_foreach_safe (R_BIN_JAVA_GLOBAL_BIN->cp_list, iter, iter_tmp, obj) {
if(obj == NULL) {
if (obj == NULL) {
continue;
} else if (obj->tag == R_BIN_JAVA_CP_FIELDREF &&
obj->info.cp_field.name_and_type_idx == name_and_type_idx) {
result = obj;
res = obj;
break;
} else if (obj->tag == R_BIN_JAVA_CP_METHODREF &&
obj->info.cp_method.name_and_type_idx == name_and_type_idx) {
result = obj;
res = obj;
break;
}
}
return result;
return res;
}