mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-05 02:39:44 +02:00
277 lines
12 KiB
Text
277 lines
12 KiB
Text
/* ###
|
|
* IP: GHIDRA
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
%{
|
|
#ifdef CPUI_RULECOMPILE
|
|
#include "rulecompile.hh"
|
|
|
|
#define YYERROR_VERBOSE
|
|
|
|
extern RuleCompile *rulecompile;
|
|
extern int ruleparselex(void);
|
|
extern int ruleparseerror(const char *str);
|
|
|
|
%}
|
|
|
|
%union {
|
|
char ch;
|
|
string *str;
|
|
int8 *big;
|
|
int4 id;
|
|
OpCode opcode;
|
|
vector<OpCode> *opcodelist;
|
|
ConstraintGroup *group;
|
|
RHSConstant *rhsconst;
|
|
}
|
|
|
|
%token RIGHT_ARROW LEFT_ARROW DOUBLE_RIGHT_ARROW DOUBLE_LEFT_ARROW
|
|
%left OP_BOOL_OR
|
|
%left OP_BOOL_AND OP_BOOL_XOR
|
|
%left OP_INT_OR
|
|
%left OP_INT_XOR
|
|
%left OP_INT_AND
|
|
%left OP_INT_EQUAL OP_INT_NOTEQUAL OP_FLOAT_EQUAL OP_FLOAT_NOTEQUAL
|
|
%nonassoc OP_INT_LESS OP_INT_LESSEQUAL OP_INT_SLESS OP_INT_SLESSEQUAL OP_FLOAT_LESS OP_FLOAT_LESSEQUAL
|
|
%left OP_INT_LEFT OP_INT_RIGHT OP_INT_SRIGHT
|
|
%left OP_INT_ADD OP_INT_SUB OP_FLOAT_ADD OP_FLOAT_SUB
|
|
%left OP_INT_SDIV OP_INT_SREM OP_FLOAT_MULT OP_FLOAT_DIV OP_INT_MULT OP_INT_DIV OP_INT_REM
|
|
%right OP_BOOL_NEGATE OP_INT_NEGATE
|
|
%token OP_INT_ZEXT OP_INT_CARRY
|
|
%token OP_INT_BORROW OP_INT_SEXT OP_INT_SCARRY OP_INT_SBORROW OP_FLOAT_NAN
|
|
%token OP_FLOAT_ABS OP_FLOAT_SQRT OP_FLOAT_CEIL OP_FLOAT_FLOOR OP_FLOAT_ROUND
|
|
%token OP_FLOAT_INT2FLOAT OP_FLOAT_FLOAT2FLOAT
|
|
%token OP_FLOAT_TRUNC OP_BRANCH OP_BRANCHIND OP_CALL OP_CALLIND OP_RETURN
|
|
%token OP_CBRANCH OP_CALLOTHER OP_LOAD OP_STORE OP_PIECE OP_SUBPIECE OP_COPY
|
|
%token BADINTEGER BEFORE_KEYWORD AFTER_KEYWORD REMOVE_KEYWORD SET_KEYWORD ACTION_TICK
|
|
%token ISTRUE_KEYWORD ISFALSE_KEYWORD
|
|
|
|
|
|
%token <ch> CHAR
|
|
%token <big> INTB
|
|
%token <str> OP_IDENTIFIER VAR_IDENTIFIER CONST_IDENTIFIER OP_NEW_IDENTIFIER VAR_NEW_IDENTIFIER
|
|
%token <str> DOT_IDENTIFIER
|
|
|
|
%type <id> op_ident var_ident const_ident op_new_ident var_new_ident
|
|
%type <big> number
|
|
%type <opcode> op_any
|
|
%type <opcodelist> op_list
|
|
%type <rhsconst> rhs_const var_size
|
|
%type <group> opnode varnode deadnode statement statementlist orgroupmid actionlist action
|
|
%type <group> opnewnode varnewnode deadnewnode megaormid
|
|
|
|
%%
|
|
|
|
fullrule:
|
|
'{' statementlist actionlist '}' { rulecompile->setFullRule( rulecompile->mergeGroups($2,$3) ); }
|
|
| '{' statementlist '[' megaormid ']' '}' { $2->addConstraint( $4 ); rulecompile->setFullRule( $2 ); }
|
|
;
|
|
|
|
megaormid: statementlist actionlist { $$ = rulecompile->emptyOrGroup(); rulecompile->addOr($$,rulecompile->mergeGroups($1,$2)); }
|
|
| megaormid OP_INT_OR statementlist actionlist { $$ = rulecompile->addOr($1,rulecompile->mergeGroups($3,$4)); }
|
|
;
|
|
|
|
actionlist: ACTION_TICK { $$ = rulecompile->emptyGroup(); }
|
|
| actionlist action { $$ = rulecompile->mergeGroups($1,$2); }
|
|
;
|
|
|
|
statementlist: { $$ = rulecompile->emptyGroup(); }
|
|
| statementlist statement { $$ = rulecompile->mergeGroups($1,$2); }
|
|
;
|
|
|
|
action: opnewnode ';' { $$ = $1; }
|
|
| varnewnode ';' { $$ = $1; }
|
|
| deadnewnode ';' { $$ = $1; }
|
|
;
|
|
|
|
orgroupmid: statementlist { ConstraintGroup *newbase = rulecompile->emptyOrGroup(); $$ = rulecompile->addOr(newbase,$1); }
|
|
| orgroupmid OP_INT_OR statementlist { $$ = rulecompile->addOr($1,$3); }
|
|
;
|
|
|
|
statement: opnode ';' { $$ = $1; }
|
|
| varnode ';' { $$ = $1; }
|
|
| deadnode ';' { $$ = $1; }
|
|
| '[' orgroupmid ']' { $$ = rulecompile->emptyGroup(); $$->addConstraint($2); }
|
|
| '(' statementlist ')' { $$ = $2; }
|
|
;
|
|
|
|
opnode: op_ident { $$ = rulecompile->newOp($1); }
|
|
| opnode '(' op_list ')' { $$ = rulecompile->opCodeConstraint($1,$3); }
|
|
| varnode LEFT_ARROW op_ident { $$ = rulecompile->varDef($1,$3); }
|
|
| varnode RIGHT_ARROW op_ident { $$ = rulecompile->varDescend($1,$3); }
|
|
| varnode RIGHT_ARROW OP_BOOL_NEGATE op_ident { $$ = rulecompile->varUniqueDescend($1,$4); }
|
|
| opnode '(' OP_INT_EQUAL op_ident ')' { $$ = rulecompile->opCompareConstraint($1,$4,CPUI_INT_EQUAL); }
|
|
| opnode '(' OP_INT_NOTEQUAL op_ident ')' { $$ = rulecompile->opCompareConstraint($1,$4,CPUI_INT_NOTEQUAL); }
|
|
;
|
|
|
|
varnode: var_ident { $$ = rulecompile->newVarnode($1); }
|
|
| opnode LEFT_ARROW '(' INTB ')' var_ident { $$ = rulecompile->opInput($1,$4,$6); }
|
|
| opnode LEFT_ARROW var_ident { $$ = rulecompile->opInputAny($1,$3); }
|
|
| opnode RIGHT_ARROW var_ident { $$ = rulecompile->opOutput($1,$3); }
|
|
| varnode '(' OP_INT_EQUAL var_ident ')' { $$ = rulecompile->varCompareConstraint($1,$4,CPUI_INT_EQUAL); }
|
|
| varnode '(' OP_INT_NOTEQUAL var_ident ')' { $$ = rulecompile->varCompareConstraint($1,$4,CPUI_INT_NOTEQUAL); }
|
|
;
|
|
|
|
deadnode: opnode LEFT_ARROW '(' INTB ')' rhs_const { $$ = rulecompile->opInputConstVal($1,$4,$6); }
|
|
| opnode '=' op_ident { $$ = rulecompile->opCopy($1,$3); }
|
|
| varnode '=' var_ident { $$ = rulecompile->varCopy($1,$3); }
|
|
| varnode '=' rhs_const var_size { $$ = rulecompile->varConst($1,$3,$4); }
|
|
| const_ident '=' rhs_const { $$ = rulecompile->constNamedExpression($1,$3); }
|
|
| ISTRUE_KEYWORD '(' rhs_const ')' { $$ = rulecompile->booleanConstraint(true,$3); }
|
|
| ISFALSE_KEYWORD '(' rhs_const ')' { $$ = rulecompile->booleanConstraint(false,$3); }
|
|
;
|
|
|
|
opnewnode: op_new_ident '(' op_any BEFORE_KEYWORD op_ident ')' { $$ = rulecompile->opCreation($1,$3,false,$5); }
|
|
| op_new_ident '(' op_any AFTER_KEYWORD op_ident ')' { $$ = rulecompile->opCreation($1,$3,true,$5); }
|
|
| op_new_ident '(' op_any BEFORE_KEYWORD op_new_ident ')' { $$ = rulecompile->opCreation($1,$3,false,$5); }
|
|
| op_new_ident '(' op_any AFTER_KEYWORD op_new_ident ')' { $$ = rulecompile->opCreation($1,$3,true,$5); }
|
|
| op_ident { $$ = rulecompile->newOp($1); }
|
|
| opnewnode '(' SET_KEYWORD op_any ')' { $$ = rulecompile->newSetOpcode($1,$4); }
|
|
;
|
|
|
|
varnewnode: opnewnode DOUBLE_RIGHT_ARROW var_new_ident '(' INTB ')' { $$ = rulecompile->newUniqueOut($1,$3,-((int4)*$5)); delete $5; }
|
|
| opnewnode DOUBLE_RIGHT_ARROW var_new_ident '(' var_ident ')' { $$ = rulecompile->newUniqueOut($1,$3,$5); }
|
|
| opnewnode DOUBLE_LEFT_ARROW '(' rhs_const ')' var_ident { $$ = rulecompile->newSetInput($1,$4,$6); }
|
|
| opnewnode DOUBLE_LEFT_ARROW '(' rhs_const ')' var_new_ident { $$ = rulecompile->newSetInput($1,$4,$6); }
|
|
;
|
|
|
|
deadnewnode: opnewnode DOUBLE_LEFT_ARROW '(' rhs_const ')' rhs_const var_size { $$ = rulecompile->newSetInputConstVal($1,$4,$6,$7); }
|
|
| opnewnode DOUBLE_LEFT_ARROW '(' rhs_const ')' REMOVE_KEYWORD { $$ = rulecompile->removeInput($$,$4); }
|
|
;
|
|
|
|
rhs_const: number { $$ = rulecompile->constAbsolute($1); }
|
|
| '(' rhs_const ')' { $$ = $2; }
|
|
| const_ident { $$ = rulecompile->constNamed($1); }
|
|
| var_ident DOT_IDENTIFIER { $$ = rulecompile->dotIdentifier($1,$2); }
|
|
| rhs_const OP_INT_ADD rhs_const { $$ = rulecompile->constBinaryExpression($1,CPUI_INT_ADD,$3); }
|
|
| rhs_const OP_INT_SUB rhs_const { $$ = rulecompile->constBinaryExpression($1,CPUI_INT_SUB,$3); }
|
|
| rhs_const OP_INT_AND rhs_const { $$ = rulecompile->constBinaryExpression($1,CPUI_INT_AND,$3); }
|
|
| rhs_const OP_INT_OR rhs_const { $$ = rulecompile->constBinaryExpression($1,CPUI_INT_OR,$3); }
|
|
| rhs_const OP_INT_XOR rhs_const { $$ = rulecompile->constBinaryExpression($1,CPUI_INT_XOR,$3); }
|
|
| rhs_const OP_INT_MULT rhs_const { $$ = rulecompile->constBinaryExpression($1,CPUI_INT_MULT,$3); }
|
|
| rhs_const OP_INT_DIV rhs_const { $$ = rulecompile->constBinaryExpression($1,CPUI_INT_DIV,$3); }
|
|
| rhs_const OP_INT_EQUAL rhs_const { $$ = rulecompile->constBinaryExpression($1,CPUI_INT_EQUAL,$3); }
|
|
| rhs_const OP_INT_NOTEQUAL rhs_const { $$ = rulecompile->constBinaryExpression($1,CPUI_INT_NOTEQUAL,$3); }
|
|
| rhs_const OP_INT_LESS rhs_const { $$ = rulecompile->constBinaryExpression($1,CPUI_INT_LESS,$3); }
|
|
| rhs_const OP_INT_LESSEQUAL rhs_const { $$ = rulecompile->constBinaryExpression($1,CPUI_INT_LESSEQUAL,$3); }
|
|
| rhs_const OP_INT_SLESS rhs_const { $$ = rulecompile->constBinaryExpression($1,CPUI_INT_SLESS,$3); }
|
|
| rhs_const OP_INT_SLESSEQUAL rhs_const { $$ = rulecompile->constBinaryExpression($1,CPUI_INT_SLESSEQUAL,$3); }
|
|
| rhs_const OP_INT_LEFT rhs_const { $$ = rulecompile->constBinaryExpression($1,CPUI_INT_LEFT,$3); }
|
|
| rhs_const OP_INT_RIGHT rhs_const{ $$ = rulecompile->constBinaryExpression($1,CPUI_INT_RIGHT,$3); }
|
|
| rhs_const OP_INT_SRIGHT rhs_const{ $$ = rulecompile->constBinaryExpression($1,CPUI_INT_SRIGHT,$3); }
|
|
;
|
|
|
|
var_size: /* empty */ { $$ = (RHSConstant *)0; }
|
|
| ':' rhs_const { $$ = $2; }
|
|
;
|
|
|
|
number: INTB { $$ = $1; }
|
|
| OP_INT_SUB INTB { *$2 = -*$2; $$ = $2; }
|
|
;
|
|
|
|
op_any: OP_BOOL_OR { $$ = CPUI_BOOL_OR; }
|
|
| OP_BOOL_AND { $$ = CPUI_BOOL_AND; }
|
|
| OP_BOOL_XOR { $$ = CPUI_BOOL_XOR; }
|
|
| OP_BOOL_NEGATE { $$ = CPUI_BOOL_NEGATE; }
|
|
| OP_INT_NEGATE { $$ = CPUI_INT_NEGATE; }
|
|
| OP_INT_ADD { $$ = CPUI_INT_ADD; }
|
|
| OP_INT_SUB { $$ = CPUI_INT_SUB; }
|
|
| OP_INT_AND { $$ = CPUI_INT_AND; }
|
|
| OP_INT_OR { $$ = CPUI_INT_OR; }
|
|
| OP_INT_XOR { $$ = CPUI_INT_XOR; }
|
|
| OP_INT_MULT { $$ = CPUI_INT_MULT; }
|
|
| OP_INT_DIV { $$ = CPUI_INT_DIV; }
|
|
| OP_INT_REM { $$ = CPUI_INT_REM; }
|
|
| OP_INT_RIGHT { $$ = CPUI_INT_RIGHT; }
|
|
| OP_INT_LEFT { $$ = CPUI_INT_LEFT; }
|
|
| OP_INT_EQUAL { $$ = CPUI_INT_EQUAL; }
|
|
| OP_INT_NOTEQUAL { $$ = CPUI_INT_NOTEQUAL; }
|
|
| OP_INT_LESS { $$ = CPUI_INT_LESS; }
|
|
| OP_INT_LESSEQUAL { $$ = CPUI_INT_LESSEQUAL; }
|
|
| OP_INT_SDIV { $$ = CPUI_INT_SDIV; }
|
|
| OP_INT_SREM { $$ = CPUI_INT_SREM; }
|
|
| OP_INT_SRIGHT { $$ = CPUI_INT_SRIGHT; }
|
|
| OP_INT_SLESS { $$ = CPUI_INT_SLESS; }
|
|
| OP_INT_SLESSEQUAL { $$ = CPUI_INT_SLESSEQUAL; }
|
|
| OP_INT_ZEXT { $$ = CPUI_INT_ZEXT; }
|
|
| OP_INT_CARRY { $$ = CPUI_INT_CARRY; }
|
|
| OP_INT_SEXT { $$ = CPUI_INT_SEXT; }
|
|
| OP_INT_SCARRY { $$ = CPUI_INT_SCARRY; }
|
|
| OP_INT_SBORROW { $$ = CPUI_INT_SBORROW; }
|
|
| OP_FLOAT_ADD { $$ = CPUI_FLOAT_ADD; }
|
|
| OP_FLOAT_SUB { $$ = CPUI_FLOAT_SUB; }
|
|
| OP_FLOAT_MULT { $$ = CPUI_FLOAT_MULT; }
|
|
| OP_FLOAT_DIV { $$ = CPUI_FLOAT_DIV; }
|
|
| OP_FLOAT_EQUAL { $$ = CPUI_FLOAT_EQUAL; }
|
|
| OP_FLOAT_NOTEQUAL { $$ = CPUI_FLOAT_NOTEQUAL; }
|
|
| OP_FLOAT_LESS { $$ = CPUI_FLOAT_LESS; }
|
|
| OP_FLOAT_LESSEQUAL { $$ = CPUI_FLOAT_LESSEQUAL; }
|
|
| OP_FLOAT_NAN { $$ = CPUI_FLOAT_NAN; }
|
|
| OP_FLOAT_ABS { $$ = CPUI_FLOAT_ABS; }
|
|
| OP_FLOAT_SQRT { $$ = CPUI_FLOAT_SQRT; }
|
|
| OP_FLOAT_CEIL { $$ = CPUI_FLOAT_CEIL; }
|
|
| OP_FLOAT_FLOOR { $$ = CPUI_FLOAT_FLOOR; }
|
|
| OP_FLOAT_ROUND { $$ = CPUI_FLOAT_ROUND; }
|
|
| OP_FLOAT_INT2FLOAT { $$ = CPUI_FLOAT_INT2FLOAT; }
|
|
| OP_FLOAT_FLOAT2FLOAT { $$ = CPUI_FLOAT_FLOAT2FLOAT; }
|
|
| OP_FLOAT_TRUNC { $$ = CPUI_FLOAT_TRUNC; }
|
|
| OP_BRANCH { $$ = CPUI_BRANCH; }
|
|
| OP_BRANCHIND { $$ = CPUI_BRANCHIND; }
|
|
| OP_CALL { $$ = CPUI_CALL; }
|
|
| OP_CALLIND { $$ = CPUI_CALLIND; }
|
|
| OP_RETURN { $$ = CPUI_RETURN; }
|
|
| OP_CBRANCH { $$ = CPUI_CBRANCH; }
|
|
| OP_CALLOTHER { $$ = CPUI_CALLOTHER; }
|
|
| OP_LOAD { $$ = CPUI_LOAD; }
|
|
| OP_STORE { $$ = CPUI_STORE; }
|
|
| OP_PIECE { $$ = CPUI_PIECE; }
|
|
| OP_SUBPIECE { $$ = CPUI_SUBPIECE; }
|
|
| OP_COPY { $$ = CPUI_COPY; }
|
|
;
|
|
|
|
op_list: op_any { $$ = new vector<OpCode>; $$->push_back($1); }
|
|
| op_list op_any { $$ = $1; $$->push_back($2); }
|
|
;
|
|
|
|
op_ident: OP_IDENTIFIER { $$ = rulecompile->findIdentifier($1); }
|
|
;
|
|
|
|
var_ident: VAR_IDENTIFIER { $$ = rulecompile->findIdentifier($1); }
|
|
;
|
|
|
|
const_ident: CONST_IDENTIFIER { $$ = rulecompile->findIdentifier($1); }
|
|
;
|
|
|
|
op_new_ident: OP_NEW_IDENTIFIER { $$ = rulecompile->findIdentifier($1); }
|
|
;
|
|
|
|
var_new_ident: VAR_NEW_IDENTIFIER { $$ = rulecompile->findIdentifier($1); }
|
|
;
|
|
|
|
%%
|
|
|
|
inline int ruleparselex(void)
|
|
|
|
{
|
|
return rulecompile->nextToken();
|
|
}
|
|
|
|
int ruleparseerror(const char *s)
|
|
|
|
{
|
|
rulecompile->ruleError(s);
|
|
return 0;
|
|
}
|
|
|
|
#endif
|