Skip to content

Commit

Permalink
Merge pull request #1 from XVilka/master
Browse files Browse the repository at this point in the history
Second draft of integrating cparse
  • Loading branch information
radare committed Jul 18, 2012
2 parents e3329e7 + f4d9099 commit 590379f
Show file tree
Hide file tree
Showing 16 changed files with 6,525 additions and 51 deletions.
13 changes: 11 additions & 2 deletions libr/anal/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,21 @@ include ../config.mk

LDFLAGS+=${BN_LIBS}

foo: pre libr_anal.${EXT_SO} libr_anal.${EXT_AR} plugins
foo: pre lemon cparse_pre libr_anal.${EXT_SO} libr_anal.${EXT_AR} plugins

include ${STATIC_ANAL_PLUGINS}
STATIC_OBJS=$(subst ../ar,p/../ar,$(subst anal_,p/anal_,$(STATIC_OBJ)))
OBJLIBS=meta.o reflines.o ref.o op.o fcn.o bb.o var.o anal.o cond.o value.o cc.o diff.o type.o fcnstore.o
OBJ=${STATIC_OBJS} ${OBJLIBS}
CPARSE_OBJS=./cparse/cparse.o ./cparse/lex.yy.o ./cparse/tree.o
OBJ=${STATIC_OBJS} ${OBJLIBS} ${CPARSE_OBJS}

lemon:
${CC} ./cparse/lemon.c -o lemon

cparse_pre: lemon
./lemon ./cparse/cparse.y
flex ./cparse/cparse.l
${CC} ${CFLAGS} -c ./cparse/cparse.c

pre:
@if [ ! -e libr_anal.${EXT_SO} ]; then rm -f ${STATIC_OBJS} ; fi
Expand Down
16 changes: 16 additions & 0 deletions libr/anal/cparse/README
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
TODO
====

1. Add support of typedef
2. Add support of preprocessor #define, #if
3. Add support of initialization
4. Separate sign from the type, use mask for that
5. Support for multidimensional arrays
6. Support for enums
7. Support for bitfields

LICENSE
=======

This software shipped under public domain

49 changes: 49 additions & 0 deletions libr/anal/cparse/cdata.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
struct Token {
int dval;
char* sval;
};

typedef struct Token Token;

#define R_ANAL_TYPE_CHAR 0
#define R_ANAL_TYPE_SHORT 1
#define R_ANAL_TYPE_INT 2
#define R_ANAL_TYPE_LONG 3
#define R_ANAL_TYPE_LONGLONG 4
#define R_ANAL_TYPE_FLOAT 5
#define R_ANAL_TYPE_DOUBLE 6
#define R_ANAL_TYPE_VOID 7
#define R_ANAL_TYPE_SIGNED 8
#define R_ANAL_TYPE_UNSIGNED 9

#define R_ANAL_UINT8_T 1
#define R_ANAL_UINT16_T 2
#define R_ANAL_UINT32_T 3
#define R_ANAL_UINT64_T 4

#define NONE_SIGN 11
#define NONE_MODIFIER 12

#define R_ANAL_VAR_STATIC 0
#define R_ANAL_VAR_CONST 1
#define R_ANAL_VAR_REGISTER 2
#define R_ANAL_VAR_VOLATILE 3

#define R_ANAL_FMODIFIER_NONE 0
#define R_ANAL_FMODIFIER_STATIC 1
#define R_ANAL_FMODIFIER_VOLATILE 2
#define R_ANAL_FMODIFIER_INLINE 3

#define R_ANAL_CALLCONV_NONE 0
#define R_ANAL_CALLCONV_STDCALL 1
#define R_ANAL_CALLCONV_CCALL 2

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_function_node(char* name, short ret_type, RAnalType *args, short fmodifier, short callconvention, char* attributes);

int print_tree(RAnalType *tmp);

27 changes: 27 additions & 0 deletions libr/anal/cparse/cparse.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
#define STRUCT 1
#define OBRACE 2
#define EBRACE 3
#define SEMICOLON 4
#define UNION 5
#define ASTERISK 6
#define LBRACKET 7
#define RBRACKET 8
#define NUMBER 9
#define CHAR 10
#define SHORT 11
#define INTEGER 12
#define LONG 13
#define FLOAT 14
#define DOUBLE 15
#define VOID 16
#define UINT8 17
#define UINT16 18
#define UINT32 19
#define UINT64 20
#define SIGNED 21
#define UNSIGNED 22
#define STATIC 23
#define CONST 24
#define REGISTER 25
#define VOLATILE 26
#define IDENTIFIER 27
77 changes: 77 additions & 0 deletions libr/anal/cparse/cparse.l
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
%{
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <r_anal.h>

#include "lexglb.h"
#include "cdata.h"
#include "cparse.h"

%}

%%
"void" { return(VOID); }
"char" { return(CHAR); }
"byte" { return(CHAR); }
"int" { return(INTEGER); }
"long" { return(LONG); }
"short" { return(SHORT); }
"float" { return(FLOAT); }
"double" { return(DOUBLE); }
"const" { return(CONST); }
"register" { return(REGISTER); }
"signed" { return(SIGNED); }
"unsigned" { return(UNSIGNED); }
"static" { return(STATIC); }
"volatile" { return(VOLATILE); }
"inline" { return(INLINE); }
"struct" { return(STRUCT); }
"union" { return(UNION); }
"function" { return(FUNCTION); }

"u8" { return(UINT8); }
"uint8_t" { return(UINT8); }
"u16" { return(UINT16); }
"uint16_t" { return(UINT16); }
"u32" { return(UINT32); }
"uint32_t" { return(UINT32); }
"u64" { return(UINT64); }
"uint64_t" { return(UINT64); }

"__attribute__" { return(ATTRIBUTE); }
"__stdcall" { return(STDCALL); }
"__ccall" { return(CCALL); }

"{" { return(OBRACE); }
"}" { return(EBRACE); }
"[" { return(LBRACKET); }
"]" { return(RBRACKET); }
"(" { return(LPARENT); }
")" { return(RPARENT); }
";" { return(SEMICOLON); }
"," { return(COMMA); }

[ \t\v\n\f] { }
[a-zA-Z_][a-zA-Z0-9_]* {
yylval.sval = strdup(yytext);
return(IDENTIFIER); }
[0-9]* {
yylval.dval = atoi(yytext);
return(NUMBER);
}
\/\/.*[\n] { /* remove comments */ }
\/\*[\n.]*\*\/ { /* remove comments */ }
\/\*([^\*]|\*[^/])*\*\/ { /* remove multiline comments */ }
. { /* ignore bad characters */ }

%%

void yyerror(char *s) {
printf("Error is %s\n", s);
}

int yywrap(void) {
return (1);
}

168 changes: 168 additions & 0 deletions libr/anal/cparse/cparse.y
Original file line number Diff line number Diff line change
@@ -0,0 +1,168 @@
%include {
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <r_anal.h>
#include "cdata.h"
}

%syntax_error {
printf("Syntax error!\n");
}

%name cdataParse

%token_type {Token}
%default_type {Token}

%type source {RAnalType *}
%type deflist {RAnalType *}
%type def {RAnalType *}
%type function {RAnalType *}
%type arglist {RAnalType *}
%type argdef {RAnalType *}
%type struct {RAnalType *}
%type union {RAnalType *}
%type variable {RAnalType *}
%type pointer {RAnalType *}
%type array {RAnalType *}

source(A) ::= deflist(B). { A = B; }
deflist(A) ::= def(B) SEMICOLON deflist(C). { B->next = C; A = B; }
deflist(A) ::= def(B) SEMICOLON. { A = B; }
def(A) ::= function(B). { A = B; }
def(A) ::= struct(B). { A = B; }
def(A) ::= union(B). { A = B; }
def(A) ::= variable(B). { A = B; }
def(A) ::= pointer(B). { A = B; }
def(A) ::= array(B). { A = B; }

function(A) ::= FUNCTION type(B) name(C) LPARENT arglist(D) RPARENT. {
A = new_function_node(C.sval, B.dval, D, R_ANAL_FMODIFIER_NONE, R_ANAL_CALLCONV_NONE, NULL);
}
function(A) ::= FUNCTION fmodifier(B) type(C) name(D) LPARENT arglist(E) RPARENT. {
A = new_function_node(D.sval, C.dval, E, B.dval, R_ANAL_CALLCONV_NONE, NULL);
}
function(A) ::= FUNCTION callconvention(B) type(C) name(D) LPARENT arglist(E) RPARENT. {
A = new_function_node(D.sval, C.dval, E, R_ANAL_FMODIFIER_NONE, B.dval, NULL);
}
function(A) ::= FUNCTION callconvention(B) fmodifier(C) type(D) name(E) LPARENT arglist(F) RPARENT. {
A = new_function_node(E.sval, D.dval, F, C.dval, B.dval, NULL);
}
function(A) ::= FUNCTION attribute(B) fmodifier(C) type(D) name(E) LPARENT arglist(F) RPARENT. {
A = new_function_node(E.sval, D.dval, F, C.dval, R_ANAL_CALLCONV_NONE, B.sval);
}
function(A) ::= FUNCTION attribute(B) callconvention(C) fmodifier(D) type(E) name(F) LPARENT arglist(G) RPARENT. {
A = new_function_node(F.sval, E.dval, G, D.dval, C.dval, B.sval);
}

fmodifier(A) ::= INLINE. { A.sval = "inline"; A.dval = R_ANAL_FMODIFIER_INLINE; }
fmodifier(A) ::= VOLATILE. { A.sval = "volatile"; A.dval = R_ANAL_FMODIFIER_VOLATILE; }
fmodifier(A) ::= STATIC. { A.sval = "static"; A.dval = R_ANAL_FMODIFIER_STATIC; }

callconvention(A) ::= STDCALL. { A.sval = "__stdcall"; A.dval = R_ANAL_CALLCONV_STDCALL; }
callconvention(A) ::= CCALL. { A.sval = "__ccall"; A.dval = R_ANAL_CALLCONV_CCALL; }

attribute(A) ::= ATTRIBUTE LPARENT LPARENT name(B) RPARENT RPARENT. {
A.sval = B.sval; A.dval = 0;
}

arglist(A) ::= argdef(B) COMMA arglist(C). { B->next = C; A = B; }
arglist(A) ::= argdef(B). { A = B; }
argdef(A) ::= variable(B). { A = B; }
argdef(A) ::= pointer(B). { A = B; }
argdef(A) ::= array(B). { A = B; }

struct(A) ::= STRUCT name(B) OBRACE deflist(C) EBRACE. {
A = new_struct_node(B.sval, C);
}
union(A) ::= UNION name(B) OBRACE deflist(C) EBRACE. {
A = new_union_node(B.sval, C);
}
variable(A) ::= modifier(E) signedness(D) type(C) name(B). {
A = new_variable_node(B.sval, C.dval, D.dval, E.dval);
}
variable(A) ::= modifier(E) shorttype(C) name(B). {
switch (C.dval) {
case UINT8_T:
A = new_variable_node(B.sval, R_ANAL_TYPE_SHORT, R_ANAL_TYPE_UNSIGNED, E.dval);
break;
case UINT16_T:
A = new_variable_node(B.sval, R_ANAL_TYPE_INT, R_ANAL_TYPE_UNSIGNED, E.dval);
break;
case UINT32_T:
A = new_variable_node(B.sval, R_ANAL_TYPE_LONG, R_ANAL_TYPE_UNSIGNED, E.dval);
break;
case UINT64_T:
A = new_variable_node(B.sval, R_ANAL_TYPE_LONGLONG, R_ANAL_TYPE_UNSIGNED, E.dval);
break;
default:
break;
}
}
pointer(A) ::= modifier(E) signedness(D) type(C) ASTERISK name(B). {
A = new_pointer_node(B.sval, C.dval, D.dval, E.dval);
}
pointer(A) ::= modifier(E) shorttype(C) ASTERISK name(B). {
switch (C.dval) {
case UINT8_T:
A = new_pointer_node(B.sval, R_ANAL_TYPE_SHORT, R_ANAL_TYPE_UNSIGNED, E.dval);
break;
case UINT16_T:
A = new_pointer_node(B.sval, R_ANAL_TYPE_INT, R_ANAL_TYPE_UNSIGNED, E.dval);
break;
case UINT32_T:
A = new_pointer_node(B.sval, R_ANAL_TYPE_LONG, R_ANAL_TYPE_UNSIGNED, E.dval);
break;
case UINT64_T:
A = new_pointer_node(B.sval, R_ANAL_TYPE_LONGLONG, R_ANAL_TYPE_UNSIGNED, E.dval);
break;
default:
break;
}
}
array(A) ::= modifier(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) ::= modifier(F) shorttype(D) name(B) LBRACKET size(C) RBRACKET. {
switch (D.dval) {
case UINT8_T:
A = new_array_node(B.sval, R_ANAL_TYPE_SHORT, R_ANAL_TYPE_UNSIGNED, F.dval, C.dval);
break;
case UINT16_T:
A = new_array_node(B.sval, R_ANAL_TYPE_INT, R_ANAL_TYPE_UNSIGNED, F.dval, C.dval);
break;
case UINT32_T:
A = new_array_node(B.sval, R_ANAL_TYPE_LONG, R_ANAL_TYPE_UNSIGNED, F.dval, C.dval);
break;
case UINT64_T:
A = new_array_node(B.sval, R_ANAL_TYPE_LONGLONG, R_ANAL_TYPE_UNSIGNED, F.dval, C.dval);
break;
default:
break;
}
}
size(A) ::= NUMBER(B). { A.dval = B.dval; }
type ::= .
type(A) ::= CHAR. { A.sval = "char"; A.dval = R_ANAL_TYPE_CHAR; }
type(A) ::= SHORT. { A.sval = "short"; A.dval = R_ANAL_TYPE_SHORT; }
type(A) ::= INTEGER. { A.sval = "int"; A.dval = R_ANAL_TYPE_INT; }
type(A) ::= LONG. { A.sval = "long"; A.dval = R_ANAL_TYPE_LONG; }
type(A) ::= LONG LONG. { A.sval = "long long"; A.dval = R_ANAL_TYPE_LONGLONG; }
type(A) ::= FLOAT. { A.sval = "float"; A.dval = R_ANAL_TYPE_FLOAT; }
type(A) ::= DOUBLE. { A.sval = "double"; A.dval = R_ANAL_TYPE_DOUBLE; }
type(A) ::= VOID. { A.sval = "void"; A.dval = R_ANAL_TYPE_VOID; }
shorttype(A) ::= UINT8. { A.dval = R_ANAL_UINT8_T; }
shorttype(A) ::= UINT16. { A.dval = R_ANAL_UINT16_T; }
shorttype(A) ::= UINT32. { A.dval = R_ANAL_UINT32_T; }
shorttype(A) ::= UINT64. { A.dval = R_ANAL_UINT64_T; }
signedness(A) ::= . { A.sval = ""; A.dval = NONE_SIGN; }
signedness(A) ::= SIGNED. { A.sval = "signed"; A.dval = R_ANAL_TYPE_SIGNED; }
signedness(A) ::= UNSIGNED. { A.sval = "unsigned"; A.dval = R_ANAL_TYPE_UNSIGNED; }
modifier(A) ::= . { A.sval = ""; A.dval = NONE_MODIFIER; }
modifier(A) ::= STATIC. { A.sval = "static"; A.dval = R_ANAL_VAR_STATIC; }
modifier(A) ::= CONST. {A.sval = "const"; A.dval = R_ANAL_VAR_CONST; }
modifier(A) ::= REGISTER. { A.sval = "register"; A.dval = R_ANAL_VAR_REGISTER; }
modifier(A) ::= VOLATILE. { A.sval = "volatile"; A.dval = R_ANAL_VAR_VOLATILE; }
name(A) ::= IDENTIFIER(B). { A.sval = B.sval; }

Loading

0 comments on commit 590379f

Please sign in to comment.