Commit 439dfc75 by Enkelmann

Fix implicit stores (#93)

parent c4125ece
...@@ -122,6 +122,35 @@ pub struct Expression { ...@@ -122,6 +122,35 @@ pub struct Expression {
pub input2: Option<Variable>, pub input2: Option<Variable>,
} }
impl From<Expression> for IrExpression {
/// Translates a P-Code expression into an expression of the internally used IR if possible.
/// Panics if translation is not possible,
/// e.g. for `LOAD`, `STORE` and and expressions that need the size of the output variable to be defined.
fn from(expr: Expression) -> IrExpression {
use ExpressionType::*;
match expr.mnemonic {
COPY => expr.input0.unwrap().into(),
LOAD | STORE | SUBPIECE => panic!(),
PIECE | INT_EQUAL | INT_NOTEQUAL | INT_LESS | INT_SLESS | INT_LESSEQUAL
| INT_SLESSEQUAL | INT_ADD | INT_SUB | INT_CARRY | INT_SCARRY | INT_SBORROW
| INT_XOR | INT_AND | INT_OR | INT_LEFT | INT_RIGHT | INT_SRIGHT | INT_MULT
| INT_DIV | INT_REM | INT_SDIV | INT_SREM | BOOL_XOR | BOOL_AND | BOOL_OR
| FLOAT_EQUAL | FLOAT_NOTEQUAL | FLOAT_LESS | FLOAT_LESSEQUAL | FLOAT_ADD
| FLOAT_SUB | FLOAT_MULT | FLOAT_DIV => IrExpression::BinOp {
op: expr.mnemonic.into(),
lhs: Box::new(expr.input0.unwrap().into()),
rhs: Box::new(expr.input1.unwrap().into()),
},
INT_NEGATE | INT_2COMP | BOOL_NEGATE | FLOAT_NEG | FLOAT_ABS | FLOAT_SQRT
| FLOAT_CEIL | FLOAT_FLOOR | FLOAT_ROUND | FLOAT_NAN => IrExpression::UnOp {
op: expr.mnemonic.into(),
arg: Box::new(expr.input0.unwrap().into()),
},
INT_ZEXT | INT_SEXT | INT2FLOAT | FLOAT2FLOAT | TRUNC => panic!(),
}
}
}
#[allow(non_camel_case_types)] #[allow(non_camel_case_types)]
#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Hash, Clone, Copy)] #[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Hash, Clone, Copy)]
pub enum ExpressionType { pub enum ExpressionType {
...@@ -176,7 +205,7 @@ pub enum ExpressionType { ...@@ -176,7 +205,7 @@ pub enum ExpressionType {
INT_2COMP, INT_2COMP,
BOOL_NEGATE, BOOL_NEGATE,
FLOAT_NEGATE, FLOAT_NEG,
FLOAT_ABS, FLOAT_ABS,
FLOAT_SQRT, FLOAT_SQRT,
FLOAT_CEIL, FLOAT_CEIL,
...@@ -253,7 +282,7 @@ impl From<ExpressionType> for IrUnOpType { ...@@ -253,7 +282,7 @@ impl From<ExpressionType> for IrUnOpType {
INT_NEGATE => IrUnOpType::IntNegate, INT_NEGATE => IrUnOpType::IntNegate,
INT_2COMP => IrUnOpType::Int2Comp, INT_2COMP => IrUnOpType::Int2Comp,
BOOL_NEGATE => IrUnOpType::BoolNegate, BOOL_NEGATE => IrUnOpType::BoolNegate,
FLOAT_NEGATE => IrUnOpType::FloatNegate, FLOAT_NEG => IrUnOpType::FloatNegate,
FLOAT_ABS => IrUnOpType::FloatAbs, FLOAT_ABS => IrUnOpType::FloatAbs,
FLOAT_SQRT => IrUnOpType::FloatSqrt, FLOAT_SQRT => IrUnOpType::FloatSqrt,
FLOAT_CEIL => IrUnOpType::FloatCeil, FLOAT_CEIL => IrUnOpType::FloatCeil,
......
...@@ -125,10 +125,6 @@ impl From<Def> for IrDef { ...@@ -125,10 +125,6 @@ impl From<Def> for IrDef {
fn from(def: Def) -> IrDef { fn from(def: Def) -> IrDef {
use super::ExpressionType::*; use super::ExpressionType::*;
match def.rhs.mnemonic { match def.rhs.mnemonic {
COPY => IrDef::Assign {
var: def.lhs.unwrap().into(),
value: def.rhs.input0.unwrap().into(),
},
LOAD => IrDef::Load { LOAD => IrDef::Load {
var: def.lhs.unwrap().into(), var: def.lhs.unwrap().into(),
address: def.rhs.input1.unwrap().into(), address: def.rhs.input1.unwrap().into(),
...@@ -137,19 +133,6 @@ impl From<Def> for IrDef { ...@@ -137,19 +133,6 @@ impl From<Def> for IrDef {
address: def.rhs.input1.unwrap().into(), address: def.rhs.input1.unwrap().into(),
value: def.rhs.input2.unwrap().into(), value: def.rhs.input2.unwrap().into(),
}, },
PIECE | INT_EQUAL | INT_NOTEQUAL | INT_LESS | INT_SLESS | INT_LESSEQUAL
| INT_SLESSEQUAL | INT_ADD | INT_SUB | INT_CARRY | INT_SCARRY | INT_SBORROW
| INT_XOR | INT_AND | INT_OR | INT_LEFT | INT_RIGHT | INT_SRIGHT | INT_MULT
| INT_DIV | INT_REM | INT_SDIV | INT_SREM | BOOL_XOR | BOOL_AND | BOOL_OR
| FLOAT_EQUAL | FLOAT_NOTEQUAL | FLOAT_LESS | FLOAT_LESSEQUAL | FLOAT_ADD
| FLOAT_SUB | FLOAT_MULT | FLOAT_DIV => IrDef::Assign {
var: def.lhs.unwrap().into(),
value: IrExpression::BinOp {
op: def.rhs.mnemonic.into(),
lhs: Box::new(def.rhs.input0.unwrap().into()),
rhs: Box::new(def.rhs.input1.unwrap().into()),
},
},
SUBPIECE => IrDef::Assign { SUBPIECE => IrDef::Assign {
var: def.lhs.clone().unwrap().into(), var: def.lhs.clone().unwrap().into(),
value: IrExpression::Subpiece { value: IrExpression::Subpiece {
...@@ -158,14 +141,6 @@ impl From<Def> for IrDef { ...@@ -158,14 +141,6 @@ impl From<Def> for IrDef {
arg: Box::new(def.rhs.input0.unwrap().into()), arg: Box::new(def.rhs.input0.unwrap().into()),
}, },
}, },
INT_NEGATE | INT_2COMP | BOOL_NEGATE | FLOAT_NEGATE | FLOAT_ABS | FLOAT_SQRT
| FLOAT_CEIL | FLOAT_FLOOR | FLOAT_ROUND | FLOAT_NAN => IrDef::Assign {
var: def.lhs.unwrap().into(),
value: IrExpression::UnOp {
op: def.rhs.mnemonic.into(),
arg: Box::new(def.rhs.input0.unwrap().into()),
},
},
INT_ZEXT | INT_SEXT | INT2FLOAT | FLOAT2FLOAT | TRUNC => IrDef::Assign { INT_ZEXT | INT_SEXT | INT2FLOAT | FLOAT2FLOAT | TRUNC => IrDef::Assign {
var: def.lhs.clone().unwrap().into(), var: def.lhs.clone().unwrap().into(),
value: IrExpression::Cast { value: IrExpression::Cast {
...@@ -174,6 +149,20 @@ impl From<Def> for IrDef { ...@@ -174,6 +149,20 @@ impl From<Def> for IrDef {
arg: Box::new(def.rhs.input0.unwrap().into()), arg: Box::new(def.rhs.input0.unwrap().into()),
}, },
}, },
_ => {
let target_var = def.lhs.unwrap();
if target_var.address.is_some() {
IrDef::Store {
address: IrExpression::Const(target_var.parse_to_bitvector()),
value: def.rhs.into(),
}
} else {
IrDef::Assign {
var: target_var.into(),
value: def.rhs.into(),
}
}
}
} }
} }
} }
...@@ -494,6 +483,32 @@ mod tests { ...@@ -494,6 +483,32 @@ mod tests {
) )
.unwrap(); .unwrap();
let _: IrDef = def.into(); let _: IrDef = def.into();
let def: Def = serde_json::from_str(
r#"
{
"lhs": {
"address": "004053e8",
"size": 4,
"is_virtual": false
},
"rhs": {
"mnemonic": "INT_XOR",
"input0": {
"name": "$load_temp0",
"size": 4,
"is_virtual": true
},
"input1": {
"name": "$U4780",
"size": 4,
"is_virtual": true
}
}
}
"#,
)
.unwrap();
let _: IrDef = def.into();
} }
#[test] #[test]
......
...@@ -875,8 +875,6 @@ public class PcodeExtractor extends GhidraScript { ...@@ -875,8 +875,6 @@ public class PcodeExtractor extends GhidraScript {
if (pcodeOp.getMnemonic().equals("STORE")) { if (pcodeOp.getMnemonic().equals("STORE")) {
return new Term<Def>(defTid, new Def(createExpression(pcodeOp), pcodeIndex)); return new Term<Def>(defTid, new Def(createExpression(pcodeOp), pcodeIndex));
// cast copy instructions that have address outputs into store instructions // cast copy instructions that have address outputs into store instructions
} else if (pcodeOp.getMnemonic().equals("COPY") && pcodeOp.getOutput().isAddress()) {
return new Term<Def>(defTid, new Def(new Expression("STORE", null, createVariable(pcodeOp.getOutput()), createVariable(pcodeOp.getInput(0))), pcodeIndex));
} }
return new Term<Def>(defTid, new Def(createVariable(pcodeOp.getOutput()), createExpression(pcodeOp), pcodeIndex)); return new Term<Def>(defTid, new Def(createVariable(pcodeOp.getOutput()), createExpression(pcodeOp), pcodeIndex));
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment