Unverified Commit b9b6b6dd by Melvin Klimke Committed by GitHub

- Added C/C++ data type property information to the project struct (#173)

parent 08aa5544
......@@ -147,6 +147,7 @@ fn backward_fixpoint() {
is_temp: false,
},
calling_conventions: Vec::new(),
datatype_properties: DatatypeProperties::mock(),
};
let mock_con = Context::new(&project);
......
use crate::intermediate_representation::DatatypeProperties;
use super::*;
use std::collections::HashSet;
......@@ -22,6 +24,7 @@ fn mock_extern_symbol(name: &str) -> ExternSymbol {
parameters: vec![arg.clone()],
return_values: vec![arg],
no_return: false,
has_var_args: false,
}
}
......@@ -91,6 +94,7 @@ fn mock_project() -> (Project, Config) {
cpu_architecture: "x86_64".to_string(),
stack_pointer_register: register("RSP"),
calling_conventions: vec![cconv],
datatype_properties: DatatypeProperties::mock(),
},
Config {
allocation_symbols: vec!["malloc".into()],
......
......@@ -299,6 +299,7 @@ fn clear_parameters_on_the_stack_on_extern_calls() {
parameters: vec![stack_param],
return_values: Vec::new(),
no_return: false,
has_var_args: false,
};
// check the value before
let pointer = PointerDomain::new(new_id("time0", "RSP"), bv(-12)).into();
......
......@@ -410,6 +410,7 @@ mod tests {
parameters: Vec::new(),
return_values: vec![arg1, arg2],
no_return: false,
has_var_args: false,
};
let state = State::new(&symbol, &register("RSP"), Some(&pi_state));
(state, pi_state)
......
......@@ -35,6 +35,7 @@ impl ExternSymbol {
parameters: vec![Arg::mock_register("RDI"), Arg::mock_register("RSI")],
return_values: vec![Arg::mock_register("RAX")],
no_return: false,
has_var_args: true,
}
}
}
......
......@@ -6,7 +6,7 @@ use crate::{
use super::*;
fn extern_symbol(name: &str, return_args: Vec<Arg>) -> ExternSymbol {
fn extern_symbol(name: &str, return_args: Vec<Arg>, has_var_args: bool) -> ExternSymbol {
ExternSymbol {
tid: Tid::new(name.to_string()),
addresses: vec![],
......@@ -15,6 +15,7 @@ fn extern_symbol(name: &str, return_args: Vec<Arg>) -> ExternSymbol {
parameters: Vec::new(),
return_values: return_args,
no_return: false,
has_var_args,
}
}
......@@ -27,7 +28,7 @@ impl State {
let arg = Arg::Register(Variable::mock("RAX", 8 as u64));
let pi_state =
PointerInferenceState::new(&Variable::mock("RSP", 8 as u64), Tid::new("func"));
let symbol = extern_symbol("system", vec![arg]);
let symbol = extern_symbol("system", vec![arg], false);
let current_sub = Sub::mock("current");
let mut state = State::new(
&symbol,
......
......@@ -87,6 +87,29 @@ impl ByteSize {
}
}
/// Properties of C/C++ data types such as size.
#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Hash, Clone)]
pub struct DatatypeProperties {
/// Holds the size of the char type
pub char_size: ByteSize,
/// Holds the size of the double type
pub double_size: ByteSize,
/// Holds the size of the float type
pub float_size: ByteSize,
/// Holds the size of the integer type
pub integer_size: ByteSize,
/// Holds the size of the long double type
pub long_double_size: ByteSize,
/// Holds the size of the long long type
pub long_long_size: ByteSize,
/// Holds the size of the long type
pub long_size: ByteSize,
/// Holds the size of the pointer type
pub pointer_size: ByteSize,
/// Holds the size of the short type
pub short_size: ByteSize,
}
#[cfg(test)]
mod tests {
use apint::BitWidth;
......
use super::{ByteSize, CastOpType, Expression, Variable};
use super::{ByteSize, CastOpType, DatatypeProperties, Expression, Variable};
use crate::prelude::*;
use crate::utils::log::LogMessage;
use std::collections::HashSet;
......@@ -346,6 +346,8 @@ pub struct ExternSymbol {
pub return_values: Vec<Arg>,
/// If set to `true`, the function is assumed to never return to its caller when called.
pub no_return: bool,
/// If the function has a variable number of parameters, this flag is set to `true`.
pub has_var_args: bool,
}
impl ExternSymbol {
......@@ -444,6 +446,8 @@ pub struct Project {
pub stack_pointer_register: Variable,
/// The known calling conventions that may be used for calls to extern functions.
pub calling_conventions: Vec<CallingConvention>,
/// Contains the properties of C data types. (e.g. size)
pub datatype_properties: DatatypeProperties,
}
impl Project {
......@@ -635,6 +639,23 @@ mod tests {
parameters: vec![Arg::mock_register("RDI")],
return_values: vec![Arg::mock_register("RAX")],
no_return: false,
has_var_args: false,
}
}
}
impl DatatypeProperties {
pub fn mock() -> 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),
}
}
}
......@@ -649,6 +670,7 @@ mod tests {
cpu_architecture: "x86_64".to_string(),
stack_pointer_register: Variable::mock("RSP", 8u64),
calling_conventions: Vec::new(),
datatype_properties: DatatypeProperties::mock(),
}
}
}
......
......@@ -5,6 +5,7 @@ use crate::intermediate_representation::Arg as IrArg;
use crate::intermediate_representation::Blk as IrBlk;
use crate::intermediate_representation::ByteSize;
use crate::intermediate_representation::CallingConvention as IrCallingConvention;
use crate::intermediate_representation::DatatypeProperties;
use crate::intermediate_representation::Def as IrDef;
use crate::intermediate_representation::Expression as IrExpression;
use crate::intermediate_representation::ExternSymbol as IrExternSymbol;
......@@ -387,6 +388,8 @@ pub struct ExternSymbol {
pub arguments: Vec<Arg>,
/// If the function is assumed to never return to the caller, this flag is set to `true`.
pub no_return: bool,
/// If the function has a variable number of parameters, this flag is set to `true`.
pub has_var_args: bool,
}
impl From<ExternSymbol> for IrExternSymbol {
......@@ -431,6 +434,7 @@ impl From<ExternSymbol> for IrExternSymbol {
parameters,
return_values,
no_return: symbol.no_return,
has_var_args: symbol.has_var_args,
}
}
}
......@@ -525,6 +529,8 @@ pub struct Project {
pub register_properties: Vec<RegisterProperties>,
/// Information about known calling conventions for the given CPU architecture.
pub register_calling_convention: Vec<CallingConvention>,
/// Contains the properties of C data types. (e.g. size)
pub datatype_properties: DatatypeProperties,
}
impl Project {
......@@ -642,6 +648,7 @@ impl Project {
.into_iter()
.map(|cconv| cconv.into())
.collect(),
datatype_properties: self.datatype_properties,
}
}
}
......
......@@ -90,7 +90,18 @@ impl Setup {
"unaffected_register": [],
"killed_by_call_register": []
}
]
],
"datatype_properties": {
"char_size": 1,
"double_size": 8,
"float_size": 4,
"integer_size": 4,
"long_double_size": 8,
"long_long_size": 8,
"long_size": 4,
"pointer_size": 4,
"short_size": 2
}
}
"#,
)
......@@ -581,7 +592,8 @@ fn extern_symbol_deserialization() {
"intent": "OUTPUT"
}
],
"no_return": false
"no_return": false,
"has_var_args": false
}
"#,
)
......
......@@ -260,6 +260,7 @@ public class PcodeExtractor extends GhidraScript {
System.out.println(e);
}
project.setRegisterProperties(HelperFunctions.getRegisterList());
project.setDatatypeProperties(HelperFunctions.createDatatypeProperties());
return project;
}
......
package bil;
import com.google.gson.annotations.SerializedName;
public class DatatypeProperties {
@SerializedName("char_size")
private int charSize;
@SerializedName("double_size")
private int doubleSize;
@SerializedName("float_size")
private int floatSize;
@SerializedName("integer_size")
private int integerSize;
@SerializedName("long_double_size")
private int longDoubleSize;
@SerializedName("long_long_size")
private int longLongSize;
@SerializedName("long_size")
private int longSize;
@SerializedName("pointer_size")
private int pointerSize;
@SerializedName("short_size")
private int shortSize;
public DatatypeProperties(
int charSize,
int doubleSize,
int floatSize,
int integerSize,
int longDoubleSize,
int longLongSize,
int longSize,
int pointerSize,
int shortSize
) {
this.setCharSize(charSize);
this.setDoubleSize(doubleSize);
this.setFloatSize(floatSize);
this.setIntegerSize(integerSize);
this.setLongDoubleSize(longDoubleSize);
this.setLongLongSize(longLongSize);
this.setLongSize(longSize);
this.setPointerSize(pointerSize);
this.setShortSize(shortSize);
}
public void setCharSize(int size) {
this.charSize = size;
}
public void setDoubleSize(int size) {
this.doubleSize = size;
}
public void setFloatSize(int size) {
this.floatSize = size;
}
public void setIntegerSize(int size) {
this.integerSize = size;
}
public void setLongDoubleSize(int size) {
this.longDoubleSize = size;
}
public void setLongLongSize(int size) {
this.longLongSize = size;
}
public void setLongSize(int size) {
this.longSize = size;
}
public void setPointerSize(int size) {
this.pointerSize = size;
}
public void setShortSize(int size) {
this.shortSize = size;
}
}
......@@ -5,6 +5,7 @@ import java.util.HashMap;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import bil.DatatypeProperties;
import bil.RegisterProperties;
import bil.Variable;
import ghidra.program.model.address.Address;
......@@ -16,6 +17,7 @@ import ghidra.program.model.listing.FunctionManager;
import ghidra.program.model.pcode.PcodeOp;
import ghidra.program.model.pcode.Varnode;
import ghidra.program.model.symbol.SymbolTable;
import ghidra.program.model.data.DataOrganization;
import ghidra.program.util.VarnodeContext;
import ghidra.util.task.TaskMonitor;
import term.*;
......@@ -33,6 +35,26 @@ public final class HelperFunctions {
throw new UnsupportedOperationException();
}
/**
* @return new DatatypeProperties
*
* Creates the datatype sizes from the Compiler Specifications.
*/
public static DatatypeProperties createDatatypeProperties() {
DataOrganization dataOrga = ghidraProgram.getDataTypeManager().getDataOrganization();
return new DatatypeProperties(
dataOrga.getCharSize(),
dataOrga.getDoubleSize(),
dataOrga.getFloatSize(),
dataOrga.getIntegerSize(),
dataOrga.getLongDoubleSize(),
dataOrga.getLongLongSize(),
dataOrga.getLongSize(),
dataOrga.getPointerSize(),
dataOrga.getShortSize()
);
}
/**
*
......
......@@ -21,12 +21,22 @@ public class ExternSymbol {
private ArrayList<Arg> arguments;
@SerializedName("no_return")
private Boolean noReturn;
@SerializedName("has_var_args")
private Boolean hasVarArgs;
public ExternSymbol() {
this.setAddresses(new ArrayList<String>());
}
public ExternSymbol(Tid tid, ArrayList<String> addresses, String name, String callingConvention, ArrayList<Arg> arguments, Boolean noReturn) {
public ExternSymbol(
Tid tid,
ArrayList<String> addresses,
String name,
String callingConvention,
ArrayList<Arg> arguments,
Boolean noReturn,
Boolean hasVarArgs
) {
this.setTid(tid);
this.setAddresses(addresses);
this.setName(name);
......@@ -82,4 +92,12 @@ public class ExternSymbol {
public void setNoReturn(Boolean noReturn) {
this.noReturn = noReturn;
}
public Boolean getHasVarArgs() {
return hasVarArgs;
}
public void setHasVarArgs(Boolean hasVarArgs) {
this.hasVarArgs = hasVarArgs;
}
}
......@@ -101,6 +101,7 @@ public class ExternSymbolCreator {
extSym.setNoReturn(func.hasNoReturn());
extSym.setArguments(createArguments(func));
extSym.setCallingConvention(HelperFunctions.funcMan.getDefaultCallingConvention().toString());
extSym.setHasVarArgs(func.hasVarArgs());
}
if(!func.isExternal()) {
extSym.getAddresses().add(func.getEntryPoint().toString());
......
package term;
import bil.DatatypeProperties;
import bil.RegisterProperties;
import bil.Variable;
import internal.RegisterConvention;
......@@ -19,15 +20,24 @@ public class Project {
private String cpuArch;
@SerializedName("register_calling_convention")
private ArrayList<RegisterConvention> conventions;
@SerializedName("datatype_properties")
private DatatypeProperties datatype_properties;
public Project() {
}
public Project(Term<Program> program, String cpuArch, Variable stackPointerRegister, ArrayList<RegisterConvention> conventions) {
public Project(
Term<Program> program,
String cpuArch,
Variable stackPointerRegister,
ArrayList<RegisterConvention> conventions,
DatatypeProperties datatype_properties
) {
this.setProgram(program);
this.setCpuArch(cpuArch);
this.setStackPointerRegister(stackPointerRegister);
this.setRegisterConvention(conventions);
this.setDatatypeProperties(datatype_properties);
}
public Term<Program> getProgram() {
......@@ -69,4 +79,12 @@ public class Project {
public void setRegisterProperties(ArrayList<RegisterProperties> registerProperties) {
this.registerProperties = registerProperties;
}
public DatatypeProperties getDatatypeProperties() {
return datatype_properties;
}
public void setDatatypeProperties(DatatypeProperties datatype_properties) {
this.datatype_properties = datatype_properties;
}
}
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