Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Second draft of integrating cparse #1

Merged
merged 1 commit into from
Jul 18, 2012
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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