summaryrefslogtreecommitdiff
path: root/plugins/warp/src/convert.rs
blob: 85a06314412340154f67b8cf22ab4d8b50f2bc38 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
pub mod symbol;
pub mod types;

use binaryninja::function::Comment as BNComment;
use binaryninja::function::Function as BNFunction;
use binaryninja::platform::Platform;
use binaryninja::rc::Ref;
use binaryninja::variable::{Variable as BNVariable, VariableSourceType};
pub use symbol::*;
pub use types::*;
use warp::r#type::class::function::{Location, RegisterLocation, StackLocation};
use warp::signature::comment::FunctionComment;
use warp::target::Target;

pub fn bn_var_to_location(bn_variable: BNVariable) -> Option<Location> {
    match bn_variable.ty {
        VariableSourceType::StackVariableSourceType => {
            let stack_loc = StackLocation {
                offset: bn_variable.storage,
            };
            Some(Location::Stack(stack_loc))
        }
        VariableSourceType::RegisterVariableSourceType => {
            let reg_loc = RegisterLocation {
                id: bn_variable.storage as u64,
            };
            Some(Location::Register(reg_loc))
        }
        VariableSourceType::FlagVariableSourceType => None,
        VariableSourceType::CompositeReturnValueSourceType => None,
        VariableSourceType::CompositeParameterSourceType => None,
    }
}

pub fn bn_comment_to_comment(func: &BNFunction, bn_comment: BNComment) -> FunctionComment {
    let offset = (bn_comment.addr as i64) - (func.start() as i64);
    FunctionComment {
        offset,
        text: bn_comment.comment,
    }
}

pub fn comment_to_bn_comment(func: &BNFunction, comment: FunctionComment) -> BNComment {
    BNComment {
        addr: comment
            .offset
            .checked_add_unsigned(func.start())
            .unwrap_or_default() as u64,
        comment: comment.text,
    }
}

pub fn platform_to_target(platform: &Platform) -> Target {
    let arch_name = platform.arch().name();
    let platform_name = platform.name();
    // We do not want to populate the platform if we are actually only the architecture.
    if arch_name == platform_name {
        Target {
            architecture: Some(arch_name),
            platform: None,
        }
    } else {
        Target {
            architecture: Some(arch_name),
            platform: Some(platform_name),
        }
    }
}

pub fn target_to_platform(target: Target) -> Option<Ref<Platform>> {
    // First try using the platform, then try using the arch.
    match Platform::by_name(&target.platform.unwrap()) {
        None => Platform::by_name(&target.architecture.unwrap()).map(|platform| platform),
        Some(platform) => Some(platform),
    }
}