Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
C
cwe_checker
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
fact-depend
cwe_checker
Commits
c11a21e9
Commit
c11a21e9
authored
Sep 22, 2020
by
Enkelmann
Committed by
Enkelmann
Nov 03, 2020
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
implement conversion functions for jumps and defs.
parent
263c1498
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
459 additions
and
59 deletions
+459
-59
mod.rs
cwe_checker_rs/src/bil/mod.rs
+145
-0
variable.rs
cwe_checker_rs/src/bil/variable.rs
+25
-3
expression.rs
cwe_checker_rs/src/intermediate_representation/expression.rs
+2
-1
mod.rs
cwe_checker_rs/src/intermediate_representation/mod.rs
+40
-41
term.rs
cwe_checker_rs/src/intermediate_representation/term.rs
+31
-5
variable.rs
cwe_checker_rs/src/intermediate_representation/variable.rs
+5
-6
lib.rs
cwe_checker_rs/src/lib.rs
+2
-2
expressions.rs
cwe_checker_rs/src/pcode/expressions.rs
+0
-0
mod.rs
cwe_checker_rs/src/pcode/mod.rs
+0
-1
term.rs
cwe_checker_rs/src/pcode/term.rs
+0
-0
mod.rs
cwe_checker_rs/src/term/mod.rs
+209
-0
No files found.
cwe_checker_rs/src/bil/mod.rs
View file @
c11a21e9
use
crate
::
intermediate_representation
::
BinOpType
as
IrBinOpType
;
use
crate
::
intermediate_representation
::
ByteSize
;
use
crate
::
intermediate_representation
::
CastOpType
as
IrCastOpType
;
use
crate
::
intermediate_representation
::
Expression
as
IrExpression
;
use
crate
::
intermediate_representation
::
UnOpType
as
IrUnOpType
;
use
apint
::
Width
;
use
serde
::{
Deserialize
,
Serialize
};
use
serde
::{
Deserialize
,
Serialize
};
pub
mod
variable
;
pub
mod
variable
;
...
@@ -7,6 +13,13 @@ pub type Bitvector = apint::ApInt;
...
@@ -7,6 +13,13 @@ pub type Bitvector = apint::ApInt;
pub
type
BitSize
=
u16
;
pub
type
BitSize
=
u16
;
impl
From
<
BitSize
>
for
ByteSize
{
/// Convert to `ByteSize`, while always rounding up to the nearest full byte.
fn
from
(
bitsize
:
BitSize
)
->
ByteSize
{
((
bitsize
as
u64
+
7
)
/
8
)
.into
()
}
}
#[derive(Serialize,
Deserialize,
Debug,
PartialEq,
Eq,
Hash,
Clone)]
#[derive(Serialize,
Deserialize,
Debug,
PartialEq,
Eq,
Hash,
Clone)]
pub
enum
Expression
{
pub
enum
Expression
{
Var
(
Variable
),
Var
(
Variable
),
...
@@ -189,6 +202,100 @@ impl Expression {
...
@@ -189,6 +202,100 @@ impl Expression {
}
}
}
}
}
}
pub
fn
bitsize
(
&
self
)
->
BitSize
{
use
Expression
::
*
;
match
self
{
Var
(
var
)
=>
var
.bitsize
()
.unwrap
(),
Const
(
bitvector
)
=>
bitvector
.width
()
.to_usize
()
as
u16
,
Load
{
size
,
..
}
=>
*
size
,
Store
{
..
}
=>
0
,
BinOp
{
op
,
lhs
,
rhs
:
_
}
=>
{
use
BinOpType
::
*
;
match
op
{
EQ
|
NEQ
|
LT
|
LE
|
SLT
|
SLE
=>
1
,
_
=>
lhs
.bitsize
(),
}
}
UnOp
{
arg
,
..
}
=>
arg
.bitsize
(),
Cast
{
width
,
..
}
=>
*
width
,
Let
{
..
}
=>
panic!
(),
Unknown
{
description
:
_
,
type_
,
}
=>
type_
.bitsize
()
.unwrap
(),
IfThenElse
{
true_exp
,
..
}
=>
true_exp
.bitsize
(),
Extract
{
low_bit
,
high_bit
,
..
}
=>
high_bit
-
low_bit
,
Concat
{
left
,
right
}
=>
left
.bitsize
()
+
right
.bitsize
(),
}
}
}
impl
From
<
Expression
>
for
IrExpression
{
fn
from
(
expr
:
Expression
)
->
IrExpression
{
use
Expression
::
*
;
match
expr
{
Var
(
var
)
=>
IrExpression
::
Var
(
var
.into
()),
Const
(
bitvector
)
=>
IrExpression
::
Const
(
bitvector
),
Load
{
..
}
|
Store
{
..
}
|
Let
{
..
}
|
Unknown
{
..
}
|
IfThenElse
{
..
}
=>
{
panic!
()
}
BinOp
{
op
,
lhs
,
rhs
}
=>
IrExpression
::
BinOp
{
op
:
op
.into
(),
lhs
:
Box
::
new
(
IrExpression
::
from
(
*
lhs
)),
rhs
:
Box
::
new
(
IrExpression
::
from
(
*
rhs
)),
},
UnOp
{
op
,
arg
}
=>
IrExpression
::
UnOp
{
op
:
op
.into
(),
arg
:
Box
::
new
(
IrExpression
::
from
(
*
arg
)),
},
Cast
{
kind
,
width
,
arg
}
=>
{
use
CastType
::
*
;
match
kind
{
UNSIGNED
=>
IrExpression
::
Cast
{
arg
:
Box
::
new
(
IrExpression
::
from
(
*
arg
)),
op
:
IrCastOpType
::
IntZExt
,
size
:
width
.into
(),
},
SIGNED
=>
IrExpression
::
Cast
{
arg
:
Box
::
new
(
IrExpression
::
from
(
*
arg
)),
op
:
IrCastOpType
::
IntSExt
,
size
:
width
.into
(),
},
HIGH
=>
{
assert
!
(
width
%
8
==
0
);
let
low_byte
=
(
arg
.bitsize
()
-
BitSize
::
from
(
width
))
.into
();
IrExpression
::
Subpiece
{
arg
:
Box
::
new
(
IrExpression
::
from
(
*
arg
)),
low_byte
,
size
:
width
.into
(),
}
}
LOW
=>
IrExpression
::
Subpiece
{
arg
:
Box
::
new
(
IrExpression
::
from
(
*
arg
)),
low_byte
:
(
0
as
u64
)
.into
(),
size
:
width
.into
(),
},
}
}
Extract
{
low_bit
,
high_bit
,
arg
,
}
=>
IrExpression
::
Subpiece
{
size
:
(
high_bit
-
low_bit
+
1
)
.into
(),
low_byte
:
low_bit
.into
(),
arg
:
Box
::
new
(
IrExpression
::
from
(
*
arg
)),
},
Concat
{
left
,
right
}
=>
IrExpression
::
BinOp
{
op
:
IrBinOpType
::
Piece
,
lhs
:
Box
::
new
(
IrExpression
::
from
(
*
left
)),
rhs
:
Box
::
new
(
IrExpression
::
from
(
*
right
)),
},
}
}
}
}
#[derive(Serialize,
Deserialize,
Debug,
PartialEq,
Eq,
Hash,
Clone,
Copy)]
#[derive(Serialize,
Deserialize,
Debug,
PartialEq,
Eq,
Hash,
Clone,
Copy)]
...
@@ -222,12 +329,50 @@ pub enum BinOpType {
...
@@ -222,12 +329,50 @@ pub enum BinOpType {
SLE
,
SLE
,
}
}
impl
From
<
BinOpType
>
for
IrBinOpType
{
fn
from
(
op
:
BinOpType
)
->
IrBinOpType
{
use
BinOpType
::
*
;
use
IrBinOpType
::
*
;
match
op
{
PLUS
=>
IntAdd
,
MINUS
=>
IntSub
,
TIMES
=>
IntMult
,
DIVIDE
=>
IntDiv
,
SDIVIDE
=>
IntSDiv
,
MOD
=>
IntRem
,
SMOD
=>
IntSRem
,
LSHIFT
=>
IntLeft
,
RSHIFT
=>
IntRight
,
ARSHIFT
=>
IntSRight
,
AND
=>
IntAnd
,
OR
=>
IntOr
,
XOR
=>
IntXOr
,
EQ
=>
IntEqual
,
NEQ
=>
IntNotEqual
,
LT
=>
IntLess
,
LE
=>
IntLessEqual
,
SLT
=>
IntSLess
,
SLE
=>
IntSLessEqual
,
}
}
}
#[derive(Serialize,
Deserialize,
Debug,
PartialEq,
Eq,
Hash,
Clone,
Copy)]
#[derive(Serialize,
Deserialize,
Debug,
PartialEq,
Eq,
Hash,
Clone,
Copy)]
pub
enum
UnOpType
{
pub
enum
UnOpType
{
NEG
,
NEG
,
NOT
,
NOT
,
}
}
impl
From
<
UnOpType
>
for
IrUnOpType
{
fn
from
(
op
:
UnOpType
)
->
IrUnOpType
{
use
UnOpType
::
*
;
match
op
{
NEG
=>
IrUnOpType
::
Int2Comp
,
NOT
=>
IrUnOpType
::
IntNegate
,
}
}
}
#[derive(Serialize,
Deserialize,
Debug,
PartialEq,
Eq,
Hash,
Clone,
Copy)]
#[derive(Serialize,
Deserialize,
Debug,
PartialEq,
Eq,
Hash,
Clone,
Copy)]
pub
enum
Endianness
{
pub
enum
Endianness
{
LittleEndian
,
LittleEndian
,
...
...
cwe_checker_rs/src/bil/variable.rs
View file @
c11a21e9
use
super
::
BitSize
;
use
super
::
BitSize
;
use
crate
::
intermediate_representation
::
Variable
as
IrVariable
;
use
crate
::
prelude
::
*
;
use
crate
::
prelude
::
*
;
use
serde
::{
Deserialize
,
Serialize
};
use
serde
::{
Deserialize
,
Serialize
};
...
@@ -19,12 +20,33 @@ pub enum Type {
...
@@ -19,12 +20,33 @@ pub enum Type {
Unknown
,
Unknown
,
}
}
impl
Type
{
pub
fn
bitsize
(
&
self
)
->
Result
<
BitSize
,
Error
>
{
if
let
Type
::
Immediate
(
bitsize
)
=
self
{
Ok
(
*
bitsize
)
}
else
{
Err
(
anyhow!
(
"Not a register type"
))
}
}
}
impl
Variable
{
impl
Variable
{
pub
fn
bitsize
(
&
self
)
->
Result
<
BitSize
,
Error
>
{
pub
fn
bitsize
(
&
self
)
->
Result
<
BitSize
,
Error
>
{
if
let
Type
::
Immediate
(
bitsize
)
=
self
.type_
{
self
.type_
.bitsize
()
Ok
(
bitsize
)
}
}
impl
From
<
Variable
>
for
IrVariable
{
fn
from
(
var
:
Variable
)
->
IrVariable
{
let
size
=
if
let
Type
::
Immediate
(
bitsize
)
=
var
.type_
{
bitsize
.into
()
}
else
{
}
else
{
Err
(
anyhow!
(
"Not a register variable"
))
panic!
()
};
IrVariable
{
name
:
var
.name
,
size
,
is_temp
:
var
.is_temp
,
}
}
}
}
}
}
...
...
cwe_checker_rs/src/intermediate_representation/expression.rs
View file @
c11a21e9
...
@@ -38,6 +38,8 @@ pub enum BinOpType {
...
@@ -38,6 +38,8 @@ pub enum BinOpType {
IntNotEqual
,
IntNotEqual
,
IntLess
,
IntLess
,
IntSLess
,
IntSLess
,
IntLessEqual
,
IntSLessEqual
,
IntAdd
,
IntAdd
,
IntSub
,
IntSub
,
IntCarry
,
IntCarry
,
...
@@ -74,7 +76,6 @@ pub enum CastOpType {
...
@@ -74,7 +76,6 @@ pub enum CastOpType {
Int2Float
,
Int2Float
,
Float2Float
,
Float2Float
,
Trunc
,
Trunc
,
}
}
#[derive(Serialize,
Deserialize,
Debug,
PartialEq,
Eq,
Hash,
Clone,
Copy)]
#[derive(Serialize,
Deserialize,
Debug,
PartialEq,
Eq,
Hash,
Clone,
Copy)]
...
...
cwe_checker_rs/src/intermediate_representation/mod.rs
View file @
c11a21e9
...
@@ -12,51 +12,51 @@ pub use term::*;
...
@@ -12,51 +12,51 @@ pub use term::*;
// TODO: move ByteSize and BitSize into their own module
// TODO: move ByteSize and BitSize into their own module
#[derive(
#[derive(
Serialize,
Serialize,
Deserialize,
Deserialize,
Debug,
Debug,
PartialEq,
PartialEq,
Eq,
Eq,
PartialOrd,
PartialOrd,
Ord,
Ord,
Hash,
Hash,
Clone,
Clone,
Copy,
Copy,
Display,
Display,
Binary,
Binary,
Octal,
Octal,
LowerHex,
LowerHex,
UpperHex,
UpperHex,
From,
From,
Into,
Into,
Not,
Not,
Add,
Add,
Sub,
Sub,
Mul,
Mul,
Div,
Div,
Rem,
Rem,
Shr,
Shr,
Shl,
Shl,
AddAssign,
AddAssign,
SubAssign,
SubAssign,
MulAssign,
MulAssign,
DivAssign,
DivAssign,
RemAssign,
RemAssign,
ShrAssign,
ShrAssign,
ShlAssign,
ShlAssign,
Sum,
Sum,
)]
)]
#[serde(transparent)]
#[serde(transparent)]
pub
struct
ByteSize
(
u64
);
pub
struct
ByteSize
(
u64
);
impl
From
<
ByteSize
>
for
BitSize
{
impl
From
<
ByteSize
>
for
BitSize
{
fn
from
(
bytesize
:
ByteSize
)
->
BitSize
{
fn
from
(
bytesize
:
ByteSize
)
->
BitSize
{
u16
::
try_from
(
u64
::
from
(
bytesize
)
*
8
)
.unwrap
()
u16
::
try_from
(
u64
::
from
(
bytesize
)
*
8
)
.unwrap
()
}
}
}
}
impl
From
<
ByteSize
>
for
apint
::
BitWidth
{
impl
From
<
ByteSize
>
for
apint
::
BitWidth
{
fn
from
(
bytesize
:
ByteSize
)
->
apint
::
BitWidth
{
fn
from
(
bytesize
:
ByteSize
)
->
apint
::
BitWidth
{
apint
::
BitWidth
::
from
((
u64
::
from
(
bytesize
)
*
8
)
as
usize
)
apint
::
BitWidth
::
from
((
u64
::
from
(
bytesize
)
*
8
)
as
usize
)
}
}
}
}
\ No newline at end of file
cwe_checker_rs/src/intermediate_representation/term.rs
View file @
c11a21e9
use
super
::{
ByteSize
,
Expression
,
Variable
};
use
crate
::
prelude
::
*
;
use
crate
::
prelude
::
*
;
use
crate
::
term
::{
Term
,
Tid
};
use
crate
::
term
::{
Term
,
Tid
};
use
super
::{
Variable
,
Expression
,
ByteSize
};
#[derive(Serialize,
Deserialize,
Debug,
PartialEq,
Eq,
Hash,
Clone)]
#[derive(Serialize,
Deserialize,
Debug,
PartialEq,
Eq,
Hash,
Clone)]
pub
enum
Def
{
pub
enum
Def
{
...
@@ -18,4 +16,33 @@ pub enum Def {
...
@@ -18,4 +16,33 @@ pub enum Def {
var
:
Variable
,
var
:
Variable
,
value
:
Expression
,
value
:
Expression
,
},
},
}
}
\ No newline at end of file
#[derive(Serialize,
Deserialize,
Debug,
PartialEq,
Eq,
Hash,
Clone)]
pub
enum
Jmp
{
Branch
(
Tid
),
BranchInd
(
Expression
),
CBranch
{
target
:
Tid
,
condition
:
Expression
,
},
Call
{
target
:
Tid
,
return_
:
Option
<
Tid
>
,
},
CallInd
{
target
:
Expression
,
return_
:
Option
<
Tid
>
,
},
Return
(
Expression
),
CallOther
{
description
:
String
,
return_
:
Option
<
Tid
>
,
},
}
#[derive(Serialize,
Deserialize,
Debug,
PartialEq,
Eq,
Hash,
Clone)]
pub
struct
Blk
{
pub
defs
:
Vec
<
Term
<
Def
>>
,
pub
jmps
:
Vec
<
Term
<
Jmp
>>
,
}
cwe_checker_rs/src/intermediate_representation/variable.rs
View file @
c11a21e9
use
crate
::
prelude
::
*
;
use
super
::
ByteSize
;
use
super
::
ByteSize
;
use
crate
::
prelude
::
*
;
#[derive(Serialize,
Deserialize,
Debug,
PartialEq,
Eq,
Hash,
Clone)]
#[derive(Serialize,
Deserialize,
Debug,
PartialEq,
Eq,
Hash,
Clone)]
pub
struct
Variable
{
pub
struct
Variable
{
pub
name
:
String
,
pub
name
:
String
,
pub
size
:
ByteSize
,
pub
size
:
ByteSize
,
pub
is_temp
:
bool
,
pub
is_temp
:
bool
,
}
}
\ No newline at end of file
cwe_checker_rs/src/lib.rs
View file @
c11a21e9
...
@@ -11,10 +11,10 @@ pub mod abstract_domain;
...
@@ -11,10 +11,10 @@ pub mod abstract_domain;
pub
mod
analysis
;
pub
mod
analysis
;
pub
mod
bil
;
pub
mod
bil
;
pub
mod
ffi
;
pub
mod
ffi
;
pub
mod
intermediate_representation
;
pub
mod
pcode
;
pub
mod
term
;
pub
mod
term
;
pub
mod
utils
;
pub
mod
utils
;
pub
mod
pcode
;
pub
mod
intermediate_representation
;
mod
prelude
{
mod
prelude
{
pub
use
apint
::
Width
;
pub
use
apint
::
Width
;
...
...
cwe_checker_rs/src/pcode/expressions.rs
View file @
c11a21e9
This diff is collapsed.
Click to expand it.
cwe_checker_rs/src/pcode/mod.rs
View file @
c11a21e9
...
@@ -7,4 +7,3 @@ mod expressions;
...
@@ -7,4 +7,3 @@ mod expressions;
pub
use
expressions
::
*
;
pub
use
expressions
::
*
;
mod
term
;
mod
term
;
pub
use
term
::
*
;
pub
use
term
::
*
;
cwe_checker_rs/src/pcode/term.rs
View file @
c11a21e9
This diff is collapsed.
Click to expand it.
cwe_checker_rs/src/term/mod.rs
View file @
c11a21e9
use
crate
::
bil
::
*
;
use
crate
::
bil
::
*
;
use
crate
::
intermediate_representation
::
Def
as
IrDef
;
use
crate
::
intermediate_representation
::
Expression
as
IrExpression
;
use
crate
::
intermediate_representation
::
Jmp
as
IrJmp
;
use
serde
::{
Deserialize
,
Serialize
};
use
serde
::{
Deserialize
,
Serialize
};
pub
mod
symbol
;
pub
mod
symbol
;
...
@@ -37,6 +40,80 @@ pub struct Def {
...
@@ -37,6 +40,80 @@ pub struct Def {
pub
rhs
:
Expression
,
pub
rhs
:
Expression
,
}
}
impl
Def
{
fn
to_ir_defs
(
self
)
->
Vec
<
IrDef
>
{
match
self
.rhs
{
Expression
::
Load
{
address
,
..
}
=>
{
let
(
defs
,
cleaned_address
,
_
)
=
extract_loads_from_expression
(
*
address
,
0
);
let
mut
ir_defs
:
Vec
<
IrDef
>
=
defs
.into_iter
()
.map
(|
def
|
def
.to_ir_assignment
())
.collect
();
ir_defs
.push
(
IrDef
::
Load
{
address
:
cleaned_address
.into
(),
var
:
self
.lhs
.into
(),
});
ir_defs
}
Expression
::
Store
{
address
,
value
,
..
}
=>
{
let
(
mut
defs
,
cleaned_address
,
counter
)
=
extract_loads_from_expression
(
*
address
,
0
);
let
(
mut
more_defs
,
cleaned_value
,
_
)
=
extract_loads_from_expression
(
*
value
,
counter
);
defs
.append
(
&
mut
more_defs
);
let
mut
ir_defs
:
Vec
<
IrDef
>
=
defs
.into_iter
()
.map
(|
def
|
def
.to_ir_assignment
())
.collect
();
ir_defs
.push
(
IrDef
::
Store
{
address
:
cleaned_address
.into
(),
value
:
cleaned_value
.into
(),
});
ir_defs
}
Expression
::
IfThenElse
{
condition
,
true_exp
,
false_exp
,
}
=>
{
// We only match for conditional stores.
// Other usages of the `IfThenElse`-expression will result in panics.
let
(
address
,
value
)
=
match
(
*
true_exp
,
*
false_exp
)
{
(
Expression
::
Store
{
address
,
value
,
..
},
Expression
::
Var
(
var
))
|
(
Expression
::
Var
(
var
),
Expression
::
Store
{
address
,
value
,
..
})
if
var
==
self
.lhs
=>
{
(
address
,
value
)
}
_
=>
panic!
(),
};
let
(
mut
defs
,
_cleaned_condition
,
counter
)
=
extract_loads_from_expression
(
*
condition
,
0
);
let
(
mut
more_defs
,
cleaned_adress
,
counter
)
=
extract_loads_from_expression
(
*
address
,
counter
);
let
(
mut
even_more_defs
,
cleaned_value
,
_
)
=
extract_loads_from_expression
(
*
value
,
counter
);
defs
.append
(
&
mut
more_defs
);
defs
.append
(
&
mut
even_more_defs
);
let
mut
ir_defs
:
Vec
<
IrDef
>
=
defs
.into_iter
()
.map
(|
def
|
def
.to_ir_assignment
())
.collect
();
ir_defs
.push
(
IrDef
::
Store
{
address
:
cleaned_adress
.into
(),
value
:
IrExpression
::
Unknown
{
description
:
"BAP conditional store"
.into
(),
size
:
cleaned_value
.bitsize
()
.into
(),
},
});
ir_defs
}
_
=>
vec!
[
self
.to_ir_assignment
()],
}
}
fn
to_ir_assignment
(
self
)
->
IrDef
{
IrDef
::
Assign
{
var
:
self
.lhs
.into
(),
value
:
self
.rhs
.into
(),
}
}
}
#[derive(Serialize,
Deserialize,
Debug,
PartialEq,
Eq,
Hash,
Clone)]
#[derive(Serialize,
Deserialize,
Debug,
PartialEq,
Eq,
Hash,
Clone)]
pub
struct
Jmp
{
pub
struct
Jmp
{
pub
condition
:
Option
<
Expression
>
,
pub
condition
:
Option
<
Expression
>
,
...
@@ -51,6 +128,38 @@ pub enum JmpKind {
...
@@ -51,6 +128,38 @@ pub enum JmpKind {
Interrupt
{
value
:
isize
,
return_addr
:
Tid
},
Interrupt
{
value
:
isize
,
return_addr
:
Tid
},
}
}
impl
From
<
Jmp
>
for
IrJmp
{
fn
from
(
jmp
:
Jmp
)
->
IrJmp
{
match
jmp
.kind
{
JmpKind
::
Goto
(
Label
::
Direct
(
tid
))
=>
IrJmp
::
Branch
(
tid
),
JmpKind
::
Goto
(
Label
::
Indirect
(
expr
))
=>
IrJmp
::
BranchInd
(
expr
.into
()),
JmpKind
::
Return
(
Label
::
Indirect
(
expr
))
=>
IrJmp
::
Return
(
expr
.into
()),
JmpKind
::
Return
(
Label
::
Direct
(
_
))
=>
panic!
(),
JmpKind
::
Call
(
call
)
=>
{
let
return_
=
match
call
.return_
{
Some
(
Label
::
Direct
(
tid
))
=>
Some
(
tid
),
None
=>
None
,
_
=>
panic!
(),
};
match
call
.target
{
Label
::
Direct
(
tid
)
=>
IrJmp
::
Call
{
target
:
tid
,
return_
,
},
Label
::
Indirect
(
expr
)
=>
IrJmp
::
CallInd
{
target
:
expr
.into
(),
return_
,
},
}
}
JmpKind
::
Interrupt
{
value
,
return_addr
}
=>
IrJmp
::
CallOther
{
description
:
format!
(
"Interrupt {}"
,
value
),
return_
:
Some
(
return_addr
),
},
}
}
}
#[derive(Serialize,
Deserialize,
Debug,
PartialEq,
Eq,
Hash,
Clone)]
#[derive(Serialize,
Deserialize,
Debug,
PartialEq,
Eq,
Hash,
Clone)]
pub
struct
Call
{
pub
struct
Call
{
pub
target
:
Label
,
pub
target
:
Label
,
...
@@ -168,6 +277,106 @@ impl ArgIntent {
...
@@ -168,6 +277,106 @@ impl ArgIntent {
}
}
}
}
fn
extract_loads_from_expression
(
expr
:
Expression
,
counter
:
u64
)
->
(
Vec
<
Def
>
,
Expression
,
u64
)
{
use
Expression
::
*
;
match
expr
{
Load
{
memory
,
address
,
endian
,
size
,
}
=>
{
let
(
mut
defs
,
cleaned_address
,
mut
counter
)
=
extract_loads_from_expression
(
*
address
,
counter
);
counter
+=
1
;
let
temp_var
=
Variable
{
name
:
format!
(
"temp_{}"
,
counter
),
type_
:
Type
::
Immediate
(
size
),
is_temp
:
true
,
};
defs
.push
(
Def
{
lhs
:
temp_var
.clone
(),
rhs
:
Load
{
memory
,
address
:
Box
::
new
(
cleaned_address
),
endian
,
size
,
},
});
(
defs
,
Var
(
temp_var
),
counter
)
}
Var
(
_
)
|
Const
(
_
)
|
Unknown
{
..
}
=>
(
Vec
::
new
(),
expr
,
counter
),
Store
{
..
}
|
Let
{
..
}
|
IfThenElse
{
..
}
=>
panic!
(),
BinOp
{
op
,
lhs
,
rhs
}
=>
{
let
(
mut
defs
,
cleaned_lhs
,
counter
)
=
extract_loads_from_expression
(
*
lhs
,
counter
);
let
(
mut
defs_rhs
,
cleaned_rhs
,
counter
)
=
extract_loads_from_expression
(
*
rhs
,
counter
);
defs
.append
(
&
mut
defs_rhs
);
(
defs
,
BinOp
{
op
,
lhs
:
Box
::
new
(
cleaned_lhs
),
rhs
:
Box
::
new
(
cleaned_rhs
),
},
counter
,
)
}
UnOp
{
op
,
arg
}
=>
{
let
(
defs
,
cleaned_arg
,
counter
)
=
extract_loads_from_expression
(
*
arg
,
counter
);
(
defs
,
UnOp
{
op
,
arg
:
Box
::
new
(
cleaned_arg
),
},
counter
,
)
}
Cast
{
kind
,
width
,
arg
}
=>
{
let
(
defs
,
cleaned_arg
,
counter
)
=
extract_loads_from_expression
(
*
arg
,
counter
);
(
defs
,
Cast
{
kind
,
width
,
arg
:
Box
::
new
(
cleaned_arg
),
},
counter
,
)
}
Extract
{
low_bit
,
high_bit
,
arg
,
}
=>
{
let
(
defs
,
cleaned_arg
,
counter
)
=
extract_loads_from_expression
(
*
arg
,
counter
);
(
defs
,
Extract
{
low_bit
,
high_bit
,
arg
:
Box
::
new
(
cleaned_arg
),
},
counter
,
)
}
Concat
{
left
,
right
}
=>
{
let
(
mut
defs
,
cleaned_left
,
counter
)
=
extract_loads_from_expression
(
*
left
,
counter
);
let
(
mut
defs_right
,
cleaned_right
,
counter
)
=
extract_loads_from_expression
(
*
right
,
counter
);
defs
.append
(
&
mut
defs_right
);
(
defs
,
Concat
{
left
:
Box
::
new
(
cleaned_left
),
right
:
Box
::
new
(
cleaned_right
),
},
counter
,
)
}
}
}
#[cfg(test)]
#[cfg(test)]
mod
tests
{
mod
tests
{
use
super
::
*
;
use
super
::
*
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment