From a3f90c27d0835809d09272e169d5a0b9f015760f Mon Sep 17 00:00:00 2001 From: Anton Kochkov Date: Fri, 7 Sep 2012 03:26:32 +0400 Subject: [PATCH] Added vala attributes --- .gitignore | 2 + libr/anal/cparse/cdata.h | 16 ++++---- libr/anal/cparse/cparse.y | 85 ++++++++++++++++++++------------------- libr/anal/cparse/tree.c | 42 ++++++++++++++----- libr/include/r_anal.h | 6 +-- 5 files changed, 87 insertions(+), 64 deletions(-) diff --git a/.gitignore b/.gitignore index 9d003d8ba4..d52fe76999 100644 --- a/.gitignore +++ b/.gitignore @@ -8,3 +8,5 @@ config.mk plugins.cfg langs.cfg .*.swp +*.un~ + diff --git a/libr/anal/cparse/cdata.h b/libr/anal/cparse/cdata.h index cc77c4676c..5b01de378d 100644 --- a/libr/anal/cparse/cdata.h +++ b/libr/anal/cparse/cdata.h @@ -29,13 +29,13 @@ typedef struct Token Token; #define R_ANAL_VAR_REGISTER 2 #define R_ANAL_VAR_VOLATILE 3 -RAnalType* new_variable_node(char* name, short type, short sign, short modifier); -RAnalType* new_pointer_node(char* name, short type, short sign, short modifier); -RAnalType* new_array_node(char* name, short type, short sign, short modifier, long size); -RAnalType* new_struct_node(char* name, RAnalType *defs); -RAnalType* new_union_node(char* name, RAnalType *defs); +RAnalType* new_variable_node(char* name, short type, short sign, short modifier, RAnalAttr *valattr); +RAnalType* new_pointer_node(char* name, short type, short sign, short modifier, RAnalAttr *valattr); +RAnalType* new_array_node(char* name, short type, short sign, short modifier, long size, RAnalAttr *valattr); +RAnalType* new_struct_node(char* name, RAnalType *defs, RAnalAttr *valattr); +RAnalType* new_union_node(char* name, RAnalType *defs, RAnalAttr *valattr); RAnalType* new_alloca_node(long address, long size, RAnalType *defs); -RAnalLocals* new_locals_node(RAnalType *defs); -RAnalFcnAttr* new_attribute(char* name, char* value); -RAnalType* new_function_node(char* name, short ret_type, RAnalType *args, short fmodifier, short callconvention, char* attributes, RAnalLocals *locals, RAnalFcnAttr *valattr); +RAnalLocals* new_locals_node(RAnalType *defs, RAnalAttr *valattr); +RAnalAttr* new_attribute(char* name, char* value); +RAnalType* new_function_node(char* name, short ret_type, RAnalType *args, short fmodifier, short callconvention, char* attributes, RAnalLocals *locals, RAnalAttr *valattr); diff --git a/libr/anal/cparse/cparse.y b/libr/anal/cparse/cparse.y index 17e8ed6502..4b220244b1 100644 --- a/libr/anal/cparse/cparse.y +++ b/libr/anal/cparse/cparse.y @@ -21,8 +21,8 @@ %type deflist {RAnalType *} %type def {RAnalType *} %type function {RAnalType *} -%type attriblist {RAnalFcnAttr *} -%type attrib {RAnalFcnAttr *} +%type attriblist {RAnalAttr *} +%type attrib {RAnalAttr *} %type arglist {RAnalType *} %type argdef {RAnalType *} %type struct {RAnalType *} @@ -55,6 +55,20 @@ def(A) ::= variable(B). { A = B; } def(A) ::= pointer(B). { A = B; } def(A) ::= array(B). { A = B; } +attriblist ::=. +attriblist(A) ::= attrib(B) attriblist(C). { + B->next = C; + A = B; +} +attrib(A) ::= LBRACKET name(B) RBRACKET. { + A = new_attribute(B.sval, NULL); +} +attrib(A) ::= LBRACKET name(B) EQUATION attrval(C) RBRACKET. { + A = new_attribute(B.sval, C.sval); +} +attrval(A) ::= IDENTIFIER(B). { A.sval = B.sval; } + + function(A) ::= attriblist(T) FUNCTION type(B) name(C) LPARENT arglist(D) RPARENT locals(E). { A = new_function_node(C.sval, B.dval, D, R_ANAL_FQUALIFIER_NONE, R_ANAL_CC_TYPE_NONE, NULL, E, T); } @@ -74,19 +88,6 @@ function(A) ::= attriblist(T) FUNCTION attribute(B) callconvention(C) fqualifier A = new_function_node(F.sval, E.dval, G, D.dval, C.dval, B.sval, H, T); } -attriblist ::=. -attriblist(A) ::= attrib(B) attriblist(C). { - B->next = C; - A = B; -} -attrib(A) ::= LBRACKET name(B) RBRACKET. { - A = new_attribute(B.sval, NULL); -} -attrib(A) ::= LBRACKET name(B) EQUATION attrval(C) RBRACKET. { - A = new_attribute(B.sval, C.sval); -} -attrval(A) ::= IDENTIFIER(B). { A.sval = B.sval; } - fqualifier(A) ::= INLINE. { A.sval = "inline"; A.dval = R_ANAL_FQUALIFIER_INLINE; } fqualifier(A) ::= VOLATILE. { A.sval = "volatile"; A.dval = R_ANAL_FQUALIFIER_VOLATILE; } fqualifier(A) ::= STATIC. { A.sval = "static"; A.dval = R_ANAL_FQUALIFIER_STATIC; } @@ -111,76 +112,76 @@ argdef(A) ::= pointer(B). { A = B; } argdef(A) ::= array(B). { A = B; } locals ::= . -locals(A) ::= OBRACE deflist (B) EBRACE. { - A = new_locals_node(B); +locals(A) ::= attriblist(T) OBRACE deflist (B) EBRACE. { + A = new_locals_node(B, T); } -struct(A) ::= STRUCT name(B) OBRACE deflist(C) EBRACE. { - A = new_struct_node(B.sval, C); +struct(A) ::= attriblist(T) STRUCT name(B) OBRACE deflist(C) EBRACE. { + A = new_struct_node(B.sval, C, T); } -union(A) ::= UNION name(B) OBRACE deflist(C) EBRACE. { - A = new_union_node(B.sval, C); +union(A) ::= attriblist(T) UNION name(B) OBRACE deflist(C) EBRACE. { + A = new_union_node(B.sval, C, T); } alloca(A) ::= ALLOCA AT address(B) LPARENT size(C) RPARENT OBRACE deflist(D) EBRACE. { A = new_alloca_node(B.dval, C.dval, D); } -variable(A) ::= qualifier(E) signedness(D) type(C) name(B). { - A = new_variable_node(B.sval, C.dval, D.dval, E.dval); +variable(A) ::= attriblist(T) qualifier(E) signedness(D) type(C) name(B). { + A = new_variable_node(B.sval, C.dval, D.dval, E.dval, T); } -variable(A) ::= qualifier(E) shorttype(C) name(B). { +variable(A) ::= attriblist(T) qualifier(E) shorttype(C) name(B). { switch (C.dval) { case R_ANAL_UINT8_T: - A = new_variable_node(B.sval, R_ANAL_VAR_TYPE_BYTE, R_ANAL_TYPE_UNSIGNED, E.dval); + A = new_variable_node(B.sval, R_ANAL_VAR_TYPE_BYTE, R_ANAL_TYPE_UNSIGNED, E.dval, T); break; case R_ANAL_UINT16_T: - A = new_variable_node(B.sval, R_ANAL_VAR_TYPE_WORD, R_ANAL_TYPE_UNSIGNED, E.dval); + A = new_variable_node(B.sval, R_ANAL_VAR_TYPE_WORD, R_ANAL_TYPE_UNSIGNED, E.dval, T); break; case R_ANAL_UINT32_T: - A = new_variable_node(B.sval, R_ANAL_VAR_TYPE_DWORD, R_ANAL_TYPE_UNSIGNED, E.dval); + A = new_variable_node(B.sval, R_ANAL_VAR_TYPE_DWORD, R_ANAL_TYPE_UNSIGNED, E.dval, T); break; case R_ANAL_UINT64_T: - A = new_variable_node(B.sval, R_ANAL_VAR_TYPE_QWORD, R_ANAL_TYPE_UNSIGNED, E.dval); + A = new_variable_node(B.sval, R_ANAL_VAR_TYPE_QWORD, R_ANAL_TYPE_UNSIGNED, E.dval, T); break; default: break; } } -pointer(A) ::= qualifier(E) signedness(D) type(C) ASTERISK name(B). { - A = new_pointer_node(B.sval, C.dval, D.dval, E.dval); +pointer(A) ::= attriblist(T) qualifier(E) signedness(D) type(C) ASTERISK name(B). { + A = new_pointer_node(B.sval, C.dval, D.dval, E.dval, T); } -pointer(A) ::= qualifier(E) shorttype(C) ASTERISK name(B). { +pointer(A) ::= attriblist(T) qualifier(E) shorttype(C) ASTERISK name(B). { switch (C.dval) { case R_ANAL_UINT8_T: - A = new_pointer_node(B.sval, R_ANAL_VAR_TYPE_BYTE, R_ANAL_TYPE_UNSIGNED, E.dval); + A = new_pointer_node(B.sval, R_ANAL_VAR_TYPE_BYTE, R_ANAL_TYPE_UNSIGNED, E.dval, T); break; case R_ANAL_UINT16_T: - A = new_pointer_node(B.sval, R_ANAL_VAR_TYPE_WORD, R_ANAL_TYPE_UNSIGNED, E.dval); + A = new_pointer_node(B.sval, R_ANAL_VAR_TYPE_WORD, R_ANAL_TYPE_UNSIGNED, E.dval, T); break; case R_ANAL_UINT32_T: - A = new_pointer_node(B.sval, R_ANAL_VAR_TYPE_DWORD, R_ANAL_TYPE_UNSIGNED, E.dval); + A = new_pointer_node(B.sval, R_ANAL_VAR_TYPE_DWORD, R_ANAL_TYPE_UNSIGNED, E.dval, T); break; case R_ANAL_UINT64_T: - A = new_pointer_node(B.sval, R_ANAL_VAR_TYPE_QWORD, R_ANAL_TYPE_UNSIGNED, E.dval); + A = new_pointer_node(B.sval, R_ANAL_VAR_TYPE_QWORD, R_ANAL_TYPE_UNSIGNED, E.dval, T); break; default: break; } } -array(A) ::= qualifier(F) signedness(E) type(D) name(B) LBRACKET size(C) RBRACKET. { - A = new_array_node(B.sval, D.dval, E.dval, F.dval, C.dval); +array(A) ::= attriblist(T) qualifier(F) signedness(E) type(D) name(B) LBRACKET size(C) RBRACKET. { + A = new_array_node(B.sval, D.dval, E.dval, F.dval, C.dval, T); } -array(A) ::= qualifier(F) shorttype(D) name(B) LBRACKET size(C) RBRACKET. { +array(A) ::= attriblist(T) qualifier(F) shorttype(D) name(B) LBRACKET size(C) RBRACKET. { switch (D.dval) { case R_ANAL_UINT8_T: - A = new_array_node(B.sval, R_ANAL_VAR_TYPE_BYTE, R_ANAL_TYPE_UNSIGNED, F.dval, C.dval); + A = new_array_node(B.sval, R_ANAL_VAR_TYPE_BYTE, R_ANAL_TYPE_UNSIGNED, F.dval, C.dval, T); break; case R_ANAL_UINT16_T: - A = new_array_node(B.sval, R_ANAL_VAR_TYPE_WORD, R_ANAL_TYPE_UNSIGNED, F.dval, C.dval); + A = new_array_node(B.sval, R_ANAL_VAR_TYPE_WORD, R_ANAL_TYPE_UNSIGNED, F.dval, C.dval, T); break; case R_ANAL_UINT32_T: - A = new_array_node(B.sval, R_ANAL_VAR_TYPE_DWORD, R_ANAL_TYPE_UNSIGNED, F.dval, C.dval); + A = new_array_node(B.sval, R_ANAL_VAR_TYPE_DWORD, R_ANAL_TYPE_UNSIGNED, F.dval, C.dval, T); break; case R_ANAL_UINT64_T: - A = new_array_node(B.sval, R_ANAL_VAR_TYPE_QWORD, R_ANAL_TYPE_UNSIGNED, F.dval, C.dval); + A = new_array_node(B.sval, R_ANAL_VAR_TYPE_QWORD, R_ANAL_TYPE_UNSIGNED, F.dval, C.dval, T); break; default: break; diff --git a/libr/anal/cparse/tree.c b/libr/anal/cparse/tree.c index e83b3b5937..6b65976904 100644 --- a/libr/anal/cparse/tree.c +++ b/libr/anal/cparse/tree.c @@ -11,7 +11,7 @@ static int new_tree() { return 0; } -RAnalType* new_variable_node(char* name, short type, short sign, short modifier) { +RAnalType* new_variable_node(char* name, short type, short sign, short modifier, RAnalAttr* valattr) { RAnalTypeVar *ivar = R_NEW (RAnalTypeVar); RAnalType *tmp; ivar->name = name; @@ -29,7 +29,7 @@ RAnalType* new_variable_node(char* name, short type, short sign, short modifier) return tmp; } -RAnalType* new_pointer_node(char* name, short type, short sign, short modifier) { +RAnalType* new_pointer_node(char* name, short type, short sign, short modifier, RAnalAttr* valattr) { RAnalTypePtr *iptr = R_NEW (RAnalTypePtr); RAnalType *tmp; iptr->name = name; @@ -47,7 +47,7 @@ RAnalType* new_pointer_node(char* name, short type, short sign, short modifier) return tmp; } -RAnalType* new_array_node(char* name, short type, short sign, short modifier, long size) { +RAnalType* new_array_node(char* name, short type, short sign, short modifier, long size, RAnalAttr *valattr) { RAnalTypeArray *iarr = R_NEW (RAnalTypeArray); RAnalType *tmp; iarr->name = name; @@ -67,7 +67,7 @@ RAnalType* new_array_node(char* name, short type, short sign, short modifier, lo return tmp; } -RAnalType* new_struct_node(char* name, RAnalType *defs) { +RAnalType* new_struct_node(char* name, RAnalType *defs, RAnalAttr *valattr) { RAnalTypeStruct *istr = R_NEW (RAnalTypeStruct); RAnalType *tmp = R_NEW (RAnalType); istr->name = name; @@ -83,7 +83,7 @@ RAnalType* new_struct_node(char* name, RAnalType *defs) { return tmp; } -RAnalType* new_union_node(char* name, RAnalType *defs) { +RAnalType* new_union_node(char* name, RAnalType *defs, RAnalAttr *valattr) { RAnalTypeUnion *iun = R_NEW (RAnalTypeUnion); RAnalType *tmp = R_NEW (RAnalType); iun->name = name; @@ -110,17 +110,37 @@ RAnalType* new_alloca_node(long address, long size, RAnalType *defs) { return tmp; } -RAnalLocals* new_locals_node(RAnalType *defs) { +RAnalLocals* new_locals_node(RAnalType *defs, RAnalAttr *valattr) { RAnalLocals *il = R_NEW (RAnalLocals); il->items = defs; return il; } -RAnalFcnAttr* new_attribute(char* name, char* value) { - RAnalFcnAttr *tmp = R_NEW0 (RAnalFcnAttr); - /* TODO: add parsing of various attributes */ +#define ENDIANESS_BIG 1234; +#define ENDIANESS_SMALL 3412; + +RAnalAttr* new_attribute(char* name, char* value) { + RAnalAttr *tmp = R_NEW0 (RAnalAttr); tmp->key = name; - tmp->value = atol(value); + /* TODO: add parsing of various attributes */ + if ((!strncmp(name, "pack", 4)) | + (!strncmp(name, "align", 5))) { + tmp->value = atol(value); + } else if ((!strncmp(name, "noreturn", 8)) | (!strncmp(name, "null", 4))) { + tmp->value = 0; + } else if (!strncmp(name, "color", 5)) { + /* TODO: Implement colorizing attributes */ + } else if (!strncmp(name, "format", 6)) { + /* TODO: Implement format attributes */ + } else if (!strncmp(name, "cconv", 5)) { + /* TODO: Implement calling convention stuff */ + } else if (!strncmp(name, "endian", 6)) { + if (!strncmp(value, "big", 3)) { + tmp->value = ENDIANESS_BIG; + } else { + tmp->value = ENDIANESS_SMALL; + } + } tmp->next = NULL; return tmp; } @@ -129,7 +149,7 @@ RAnalFcnAttr* new_attribute(char* name, char* value) { //item_list* new_function_node(char* name, item_list *rets, item_list *args) RAnalType* new_function_node(char* name, short ret_type, RAnalType *args, short fmodifier, short callconvention, char* attributes, - RAnalLocals *locals, RAnalFcnAttr* valattr) { + RAnalLocals *locals, RAnalAttr* valattr) { RAnalFunction *ifnc = R_NEW (RAnalFunction); RAnalType *tmp = R_NEW (RAnalType); ifnc->name = name; diff --git a/libr/include/r_anal.h b/libr/include/r_anal.h index b5ec034a2e..f7d6319310 100644 --- a/libr/include/r_anal.h +++ b/libr/include/r_anal.h @@ -269,11 +269,11 @@ typedef struct r_anal_locals_t { RAnalType *items; } RAnalLocals; -typedef struct r_anal_fcn_attr_t RAnalFcnAttr; -struct r_anal_fcn_attr_t { +typedef struct r_anal_attr_t RAnalAttr; +struct r_anal_attr_t { char *key; long value; - RAnalFcnAttr *next; + RAnalAttr *next; }; typedef struct r_anal_fcn_store_t {