Unverified Commit c7182ddb by van den Bosch Committed by GitHub

Testreorganisation project struct (#291)

parent d454a72f
......@@ -142,18 +142,8 @@ fn mock_program() -> Term<Program> {
#[test]
fn backward_fixpoint() {
let project = Project {
program: mock_program(),
cpu_architecture: String::from("x86_64"),
stack_pointer_register: Variable {
name: String::from("RSP"),
size: ByteSize::new(8),
is_temp: false,
},
calling_conventions: BTreeMap::new(),
register_set: BTreeSet::new(),
datatype_properties: DatatypeProperties::mock(),
};
let mut project = Project::mock_x64();
project.program = mock_program();
let mock_con = Context::new(&project);
let mut computation = create_computation(mock_con.clone(), None);
......
......@@ -163,7 +163,7 @@ mod tests {
calling_convention: None,
},
};
let mut project = Project::mock_empty();
let mut project = Project::mock_x64();
project.program.term.subs.insert(sub.tid.clone(), sub);
remove_dead_var_assignments(&mut project);
......
......@@ -3,8 +3,7 @@ use std::collections::HashSet;
#[test]
fn test_compute_return_values_of_call() {
let project = Project::mock_empty();
let cconv = CallingConvention::mock_x64();
let project = Project::mock_x64();
let graph = crate::analysis::graph::get_program_cfg(&project.program, HashSet::new());
let context = Context::new(&project, &graph);
......@@ -19,8 +18,12 @@ fn test_compute_return_values_of_call() {
},
};
// Test returning a value of unknown origin (since RAX does not contain a reference to the input register).
let return_values =
context.compute_return_values_of_call(&mut caller_state, &callee_state, &cconv, &call);
let return_values = context.compute_return_values_of_call(
&mut caller_state,
&callee_state,
project.get_standard_calling_convention().unwrap(),
&call,
);
let expected_val = DataDomain::from_target(
AbstractIdentifier::from_var(Tid::new("call_tid"), &Variable::mock("RAX", 8)),
Bitvector::from_i64(0).into(),
......@@ -37,8 +40,12 @@ fn test_compute_return_values_of_call() {
AbstractIdentifier::from_var(Tid::new("caller"), &Variable::mock("RDI", 8)),
Bitvector::from_i64(0).into(),
);
let return_values =
context.compute_return_values_of_call(&mut caller_state, &callee_state, &cconv, &call);
let return_values = context.compute_return_values_of_call(
&mut caller_state,
&callee_state,
project.get_standard_calling_convention().unwrap(),
&call,
);
assert_eq!(return_values.iter().len(), 3);
assert_eq!(return_values[0], (&Variable::mock("RAX", 8), expected_val));
}
......@@ -622,7 +622,7 @@ mod tests {
calling_convention: None,
},
};
let mut program = Program::mock_empty();
let mut program = Program::mock_x64();
program.subs.insert(sub_term.tid.clone(), sub_term);
let program_term = Term {
tid: Tid::new("program".to_string()),
......
......@@ -591,7 +591,7 @@ pub fn mock_project_with_intraprocedural_control_flow(
symbol_call_config: Vec<(ExternSymbol, Vec<bool>)>,
sub_name: &str,
) -> Project {
let mut program = Program::mock_empty();
let mut program = Program::mock_x64();
let mocked_sub = mock_sub_with_name_and_symbol_calls(sub_name, symbol_call_config);
program.subs.insert(mocked_sub.tid.clone(), mocked_sub);
......
......@@ -184,7 +184,7 @@ pub mod tests {
use super::*;
fn mock_project() -> Project {
let mut project = Project::mock_empty();
let mut project = Project::mock_x64();
let mut sub = Sub::mock("func");
let mut block1 = Blk::mock_with_tid("block1");
let block2 = Blk::mock_with_tid("block2");
......
......@@ -444,7 +444,7 @@ mod tests {
#[test]
fn check_parameter_arg_for_taint() {
let project = Project::mock_empty();
let project = Project::mock_x64();
let runtime_memory_image = RuntimeMemoryImage::mock();
let pi_results = PointerInferenceComputation::mock(&project);
let context = Context::mock(&project, &runtime_memory_image, &pi_results);
......@@ -475,7 +475,7 @@ mod tests {
#[test]
fn handle_generic_call() {
let project = Project::mock_empty();
let project = Project::mock_x64();
let runtime_memory_image = RuntimeMemoryImage::mock();
let pi_results = PointerInferenceComputation::mock(&project);
let context = Context::mock(&project, &runtime_memory_image, &pi_results);
......@@ -496,7 +496,7 @@ mod tests {
#[test]
fn update_def() {
let project = Project::mock_empty();
let project = Project::mock_x64();
let runtime_memory_image = RuntimeMemoryImage::mock();
let pi_results = PointerInferenceComputation::mock(&project);
let context = Context::mock(&project, &runtime_memory_image, &pi_results);
......@@ -549,7 +549,7 @@ mod tests {
#[test]
fn update_jump() {
let project = Project::mock_empty();
let project = Project::mock_x64();
let runtime_memory_image = RuntimeMemoryImage::mock();
let pi_results = PointerInferenceComputation::mock(&project);
let context = Context::mock(&project, &runtime_memory_image, &pi_results);
......
......@@ -201,6 +201,34 @@ mod tests {
short_size: ByteSize::new(2),
}
}
/// Datatype sizes according to System V ABI
pub fn mock_x64() -> DatatypeProperties {
DatatypeProperties {
char_size: ByteSize::new(1),
double_size: ByteSize::new(8),
float_size: ByteSize::new(4),
integer_size: ByteSize::new(4),
long_double_size: ByteSize::new(16),
long_long_size: ByteSize::new(8),
long_size: ByteSize::new(8),
pointer_size: ByteSize::new(8),
short_size: ByteSize::new(2),
}
}
pub fn mock_arm32() -> DatatypeProperties {
DatatypeProperties {
char_size: ByteSize::new(1),
double_size: ByteSize::new(8),
float_size: ByteSize::new(4),
integer_size: ByteSize::new(4),
long_double_size: ByteSize::new(8),
long_long_size: ByteSize::new(8),
long_size: ByteSize::new(4),
pointer_size: ByteSize::new(4),
short_size: ByteSize::new(2),
}
}
}
#[test]
......
......@@ -37,16 +37,107 @@ impl Program {
#[cfg(test)]
mod tests {
use crate::intermediate_representation::{Arg, CallingConvention, Datatype};
use super::*;
impl Program {
pub fn mock_empty() -> Program {
/// Returns extern symbol with argument/return register according to calling convention
fn create_extern_symbol(
name: &str,
cconv: CallingConvention,
arg_type: Option<Datatype>,
return_type: Option<Datatype>,
) -> ExternSymbol {
ExternSymbol {
tid: Tid::new(name),
addresses: vec![],
name: name.to_string(),
calling_convention: Some(cconv.name),
parameters: match arg_type {
Some(data_type) => {
vec![Arg::from_var(
cconv.integer_parameter_register[0].clone(),
Some(data_type),
)]
}
None => vec![],
},
return_values: match return_type {
Some(data_type) => {
vec![Arg::from_var(
cconv.integer_return_register[0].clone(),
Some(data_type),
)]
}
None => vec![],
},
no_return: false,
has_var_args: false,
}
}
fn add_extern_symbols_to_program(a: Vec<(Tid, ExternSymbol)>) -> Program {
Program {
subs: BTreeMap::new(),
extern_symbols: BTreeMap::new(),
extern_symbols: BTreeMap::from_iter(a),
entry_points: BTreeSet::new(),
address_base_offset: 0,
address_base_offset: 0x1000u64,
}
}
/// Returns Program with malloc, free and other_function
pub fn mock_x64() -> Program {
let malloc = Program::create_extern_symbol(
"malloc",
CallingConvention::mock_x64(),
Some(Datatype::Integer),
Some(Datatype::Pointer),
);
let free = Program::create_extern_symbol(
"free",
CallingConvention::mock_x64(),
Some(Datatype::Pointer),
None,
);
let other_function = Program::create_extern_symbol(
"other_function",
CallingConvention::mock_x64(),
None,
None,
);
Program::add_extern_symbols_to_program(vec![
(malloc.tid.clone(), malloc),
(free.tid.clone(), free),
(other_function.tid.clone(), other_function),
])
}
/// Returns Program with malloc, free and other_function
pub fn mock_arm32() -> Program {
let malloc = Program::create_extern_symbol(
"malloc",
CallingConvention::mock_arm32(),
Some(Datatype::Integer),
Some(Datatype::Pointer),
);
let free = Program::create_extern_symbol(
"free",
CallingConvention::mock_arm32(),
Some(Datatype::Pointer),
None,
);
let other_function = Program::create_extern_symbol(
"other_function",
CallingConvention::mock_arm32(),
None,
None,
);
Program::add_extern_symbols_to_program(vec![
(malloc.tid.clone(), malloc),
(free.tid.clone(), free),
(other_function.tid.clone(), other_function),
])
}
}
}
......@@ -249,21 +249,68 @@ mod tests {
use super::*;
impl Project {
pub fn mock_empty() -> Project {
let register_set = vec!["RAX", "RCX", "RDX", "RBX", "RSP", "RBP", "RSI", "RDI"]
.into_iter()
.map(|name| Variable::mock(name, ByteSize::new(8)))
.collect();
/// Returns project with x64 calling convention and mocked program.
pub fn mock_x64() -> Project {
let mut none_cconv_register: Vec<Variable> = vec![
"RAX", "RBX", "RSP", "RBP", "R10", "R11", "R12", "R13", "R14", "R15",
]
.into_iter()
.map(|name| Variable::mock(name, ByteSize::new(8)))
.collect();
let mut integer_register = CallingConvention::mock_x64().integer_parameter_register;
integer_register.append(&mut none_cconv_register);
let calling_conventions: BTreeMap<String, CallingConvention> =
BTreeMap::from([("__stdcall".to_string(), CallingConvention::mock_x64())]);
Project {
program: Term {
tid: Tid::new("program_tid"),
term: Program::mock_empty(),
term: Program::mock_x64(),
},
cpu_architecture: "x86_64".to_string(),
stack_pointer_register: Variable::mock("RSP", 8u64),
calling_conventions: BTreeMap::new(),
register_set,
datatype_properties: DatatypeProperties::mock(),
calling_conventions,
register_set: integer_register.iter().cloned().collect(),
datatype_properties: DatatypeProperties::mock_x64(),
}
}
pub fn mock_arm32() -> Project {
let none_cconv_4byte_register: Vec<Variable> = vec!["r12", "r14", "r15"]
.into_iter()
.map(|name| Variable::mock(name, ByteSize::new(4)))
.collect();
let none_cconv_16byte_register: Vec<Variable> = vec![
"q0", "q1", "q2", "q3", "q8", "q9", "q10", "q11", "q12", "q13", "q14", "q15",
]
.into_iter()
.map(|name| Variable::mock(name, ByteSize::new(16)))
.collect();
let callee_saved_register = CallingConvention::mock_arm32().callee_saved_register;
let integer_register = CallingConvention::mock_arm32()
.integer_parameter_register
.into_iter()
.chain(none_cconv_4byte_register)
.chain(none_cconv_16byte_register)
.chain(callee_saved_register);
Project {
program: Term {
tid: Tid::new("program_tid"),
term: Program::mock_x64(),
},
cpu_architecture: "arm32".to_string(),
stack_pointer_register: Variable::mock("sp", 4u64),
calling_conventions: BTreeMap::from([(
"__stdcall".to_string(),
CallingConvention::mock_arm32(),
)]),
register_set: integer_register.collect(),
datatype_properties: DatatypeProperties::mock_arm32(),
}
}
}
......
......@@ -257,7 +257,7 @@ mod tests {
let sub_1_tid = &sub_1.tid;
let sub_2_tid = &sub_2.tid;
let sub_3_tid = &sub_3.tid;
let mut project = Project::mock_empty();
let mut project = Project::mock_x64();
project.program.term.subs = BTreeMap::from_iter([
(sub_1_tid.clone(), sub_1.clone()),
(sub_2_tid.clone(), sub_2.clone()),
......
use crate::intermediate_representation::{Bitvector, Tid};
use std::collections::BTreeMap;
use std::iter::FromIterator;
use super::*;
......@@ -21,9 +19,7 @@ fn test_get_variable_parameters() {
&Variable::mock("RSI", 8 as u64),
IntervalDomain::new(global_address.clone(), global_address).into(),
);
let mut project = Project::mock_empty();
let cconv = CallingConvention::mock_x64();
project.calling_conventions = BTreeMap::from_iter([(cconv.name.clone(), cconv)]);
let project = Project::mock_x64();
let mut output: Vec<Arg> = Vec::new();
output.push(Arg::from_var(
......@@ -110,7 +106,7 @@ fn test_parse_format_string_parameters() {
"%s: Unable to open \'%s\', errno=%d\n",
"%s %lli",
];
let properties = DatatypeProperties::mock();
let properties = DatatypeProperties::mock_x64();
let expected_outputs: Vec<Vec<(Datatype, ByteSize)>> = vec![
vec![
(Datatype::from("s".to_string()), properties.pointer_size),
......
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