Commit 676e27a0 by Enkelmann Committed by Enkelmann

fixed some more special case for the IR conversion from BAP

parent 7d8a67d4
...@@ -266,19 +266,33 @@ impl From<Expression> for IrExpression { ...@@ -266,19 +266,33 @@ impl From<Expression> for IrExpression {
use CastType::*; use CastType::*;
match kind { match kind {
UNSIGNED => { UNSIGNED => {
assert!(width % 8 == 0); if width % 8 == 0 {
IrExpression::Cast { IrExpression::Cast {
arg: Box::new(IrExpression::from(*arg)), arg: Box::new(IrExpression::from(*arg)),
op: IrCastOpType::IntZExt, op: IrCastOpType::IntZExt,
size: width.into(), size: width.into(),
}
} else {
IrExpression::Unknown {
description: serde_json::to_string(&Cast { kind, width, arg })
.unwrap(),
size: width.into(),
}
} }
} }
SIGNED => { SIGNED => {
assert!(width % 8 == 0); if width % 8 == 0 {
IrExpression::Cast { IrExpression::Cast {
arg: Box::new(IrExpression::from(*arg)), arg: Box::new(IrExpression::from(*arg)),
op: IrCastOpType::IntSExt, op: IrCastOpType::IntSExt,
size: width.into(), size: width.into(),
}
} else {
IrExpression::Unknown {
description: serde_json::to_string(&Cast { kind, width, arg })
.unwrap(),
size: width.into(),
}
} }
} }
HIGH => { HIGH => {
...@@ -290,14 +304,19 @@ impl From<Expression> for IrExpression { ...@@ -290,14 +304,19 @@ impl From<Expression> for IrExpression {
))), ))),
rhs: Box::new(IrExpression::from(*arg)), rhs: Box::new(IrExpression::from(*arg)),
} }
} else { } else if width % 8 == 0 {
assert!(width % 8 == 0);
let low_byte = (arg.bitsize() - width).into(); let low_byte = (arg.bitsize() - width).into();
IrExpression::Subpiece { IrExpression::Subpiece {
arg: Box::new(IrExpression::from(*arg)), arg: Box::new(IrExpression::from(*arg)),
low_byte, low_byte,
size: width.into(), size: width.into(),
} }
} else {
IrExpression::Unknown {
description: serde_json::to_string(&Cast { kind, width, arg })
.unwrap(),
size: width.into(),
}
} }
} }
LOW => { LOW => {
...@@ -313,13 +332,18 @@ impl From<Expression> for IrExpression { ...@@ -313,13 +332,18 @@ impl From<Expression> for IrExpression {
rhs: Box::new(IrExpression::from(*arg)), rhs: Box::new(IrExpression::from(*arg)),
}), }),
} }
} else { } else if width % 8 == 0 {
assert!(width % 8 == 0);
IrExpression::Subpiece { IrExpression::Subpiece {
arg: Box::new(IrExpression::from(*arg)), arg: Box::new(IrExpression::from(*arg)),
low_byte: (0 as u64).into(), low_byte: (0 as u64).into(),
size: width.into(), size: width.into(),
} }
} else {
IrExpression::Unknown {
description: serde_json::to_string(&Cast { kind, width, arg })
.unwrap(),
size: width.into(),
}
} }
} }
} }
...@@ -329,12 +353,22 @@ impl From<Expression> for IrExpression { ...@@ -329,12 +353,22 @@ impl From<Expression> for IrExpression {
high_bit, high_bit,
arg, arg,
} => { } => {
assert!(low_bit % 8 == 0); if low_bit % 8 == 0 && (high_bit + 1) % 8 == 0 {
assert!((high_bit + 1) % 8 == 0); IrExpression::Subpiece {
IrExpression::Subpiece { size: (high_bit - low_bit + 1).into(),
size: (high_bit - low_bit + 1).into(), low_byte: low_bit.into(),
low_byte: low_bit.into(), arg: Box::new(IrExpression::from(*arg)),
arg: Box::new(IrExpression::from(*arg)), }
} else {
IrExpression::Unknown {
description: serde_json::to_string(&Extract {
low_bit,
high_bit,
arg,
})
.unwrap(),
size: (high_bit - low_bit + 1).into(),
}
} }
} }
Concat { left, right } => IrExpression::BinOp { Concat { left, right } => IrExpression::BinOp {
......
...@@ -436,36 +436,45 @@ impl ArgIntent { ...@@ -436,36 +436,45 @@ impl ArgIntent {
} }
} }
impl From<Arg> for IrArg { impl Arg {
/// Translate extern symbol argument types. /// Translate extern symbol argument types.
fn from(arg: Arg) -> IrArg { pub fn into_ir_args(self) -> Vec<IrArg> {
match arg.location { match self.location {
Expression::Var(var) => IrArg::Register(var.into()), Expression::Var(var) => vec![IrArg::Register(var.into())],
Expression::Concat { left, right } => match (*left, *right) {
(Expression::Var(var_left), Expression::Var(var_right)) => vec![
IrArg::Register(var_left.into()),
IrArg::Register(var_right.into()),
],
_ => panic!(),
},
Expression::Load { Expression::Load {
address, address,
size: bitsize, size: bitsize,
.. ..
} => { } => match *address {
let offset = match *address { Expression::Var(_) => vec![IrArg::Stack {
Expression::BinOp { offset: 0,
op: BinOpType::PLUS,
lhs,
rhs,
} => {
assert!(matches!(*lhs, Expression::Var(_)));
if let Expression::Const(bitvec) = *rhs {
bitvec.try_to_i64().unwrap()
} else {
panic!()
}
}
_ => panic!(),
};
IrArg::Stack {
offset,
size: bitsize.into(), size: bitsize.into(),
}],
Expression::BinOp {
op: BinOpType::PLUS,
lhs,
rhs,
} => {
assert!(matches!(*lhs, Expression::Var(_)));
let offset = if let Expression::Const(bitvec) = *rhs {
bitvec.try_to_i64().unwrap()
} else {
panic!()
};
vec![IrArg::Stack {
offset,
size: bitsize.into(),
}]
} }
} _ => panic!(),
},
_ => panic!(), _ => panic!(),
} }
} }
...@@ -505,7 +514,31 @@ fn extract_loads_from_expression(expr: Expression, counter: u64) -> (Vec<Def>, E ...@@ -505,7 +514,31 @@ fn extract_loads_from_expression(expr: Expression, counter: u64) -> (Vec<Def>, E
(defs, Var(temp_var), counter) (defs, Var(temp_var), counter)
} }
Var(_) | Const(_) | Unknown { .. } => (Vec::new(), expr, counter), Var(_) | Const(_) | Unknown { .. } => (Vec::new(), expr, counter),
Store { .. } | Let { .. } => panic!(), Let { .. } => panic!(),
Store {
memory,
address,
value,
endian,
size,
} => {
let (mut defs, cleaned_address, counter) =
extract_loads_from_expression(*address, counter);
let (mut more_defs, cleaned_value, counter) =
extract_loads_from_expression(*value, counter);
defs.append(&mut more_defs);
(
defs,
Store {
address: Box::new(cleaned_address),
value: Box::new(cleaned_value),
memory,
endian,
size,
},
counter,
)
}
IfThenElse { IfThenElse {
condition, condition,
true_exp, true_exp,
......
...@@ -61,13 +61,17 @@ impl From<ExternSymbol> for IrExternSymbol { ...@@ -61,13 +61,17 @@ impl From<ExternSymbol> for IrExternSymbol {
arg.intent, arg.intent,
ArgIntent::Input | ArgIntent::Both | ArgIntent::Unknown ArgIntent::Input | ArgIntent::Both | ArgIntent::Unknown
) { ) {
parameters.push(arg.clone().into()); for ir_arg in arg.clone().into_ir_args() {
parameters.push(ir_arg);
}
} }
if matches!( if matches!(
arg.intent, arg.intent,
ArgIntent::Output | ArgIntent::Both | ArgIntent::Unknown ArgIntent::Output | ArgIntent::Both | ArgIntent::Unknown
) { ) {
return_values.push(arg.into()); for ir_arg in arg.into_ir_args() {
return_values.push(ir_arg);
}
} }
} }
IrExternSymbol { IrExternSymbol {
......
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