fixup: compiler error fixes

This commit is contained in:
0xllx0 authored and pancake committed 2026-01-18 06:11:24 +01:00
1 parent 7ada2d24fd
commit 08e8bf8ac0
30 files changed
+194 -152

No files matched your search

+1
View File
@@ -4,3 +4,4 @@ Cargo.lock
outputs
*.dot
*.orig
radare2-r2pipe-api
+1
View File
@@ -7,6 +7,7 @@ edition = "2018"
lazy_static = "1.4.0"
[dependencies.r2api]
package = "r2papi"
git = "https://github.com/radare/radare2-r2pipe-api"
[dependencies.r2pipe]
+2
View File
@@ -15,6 +15,7 @@ path = "src/lib.rs"
[features]
default = []
trace_log = ["log", "env_logger"]
profile = []
[dev-dependencies]
quickcheck = "0.9.2"
@@ -48,6 +49,7 @@ env_logger = { version = "0.7", optional = true }
git = "https://github.com/radareorg/r2pipe.rs"
[dependencies.r2api]
package = "r2papi"
git = "https://github.com/radare/radare2-r2pipe-api"
#path = "../radare2-r2pipe-api/rust/"
+44 -36
View File
@@ -91,7 +91,7 @@ impl<T: Clone + Debug + Hash + Eq + Copy> ConstraintSet<T> {
let constraint = self.set.pop_front().expect("Cannot be `None`");
// Match to see if this is an Eq constraint or an assert
let res = match constraint {
Constraint::Equality(_, box _) => self.solve_eq(&constraint),
Constraint::Equality(_, _) => self.solve_eq(&constraint),
Constraint::Assertion(_) => self.solve_assert(&constraint),
Constraint::AssertEquivalence(_) => self.solve_equivalence(&constraint),
_ => false,
@@ -131,18 +131,18 @@ impl<T: Clone + Debug + Hash + Eq + Copy> ConstraintSet<T> {
fn solve_eq(&mut self, constraint: &Constraint<T>) -> bool {
match *constraint {
Constraint::Equality(ni, box ref cs) => {
match *cs {
Constraint::Equality(ni, ref cs) => {
match **cs {
Constraint::Value(vt) => {
self.bindings.insert(ni, vt);
true
}
Constraint::Union(op1, op2) => {
Constraint::Union(op1, ref op2) => {
match self.bvalue(ni) {
ValueType::Scalar => {
// Both, op1 and op2, are scalars
self.bindings.insert(op1, ValueType::Scalar);
self.bindings.insert(op2, ValueType::Scalar);
self.bindings.insert(*op2, ValueType::Scalar);
true
}
ValueType::Reference => {
@@ -154,13 +154,13 @@ impl<T: Clone + Debug + Hash + Eq + Copy> ConstraintSet<T> {
Box::new(Constraint::Value(ValueType::Reference)),
)),
Box::new(Constraint::Equality(
op2,
*op2,
Box::new(Constraint::Value(ValueType::Scalar)),
)),
)),
Box::new(Constraint::And(
Box::new(Constraint::Equality(
op2,
*op2,
Box::new(Constraint::Value(ValueType::Reference)),
)),
Box::new(Constraint::Equality(
@@ -175,7 +175,7 @@ impl<T: Clone + Debug + Hash + Eq + Copy> ConstraintSet<T> {
ValueType::Unresolved => {
// Look at the Union
let op1_vt = self.bvalue(op1);
let op2_vt = self.bvalue(op2);
let op2_vt = self.bvalue(*op2);
let (vt, retval) = match (op1_vt, op2_vt) {
(ValueType::Invalid, _)
| (_, ValueType::Invalid)
@@ -184,7 +184,7 @@ impl<T: Clone + Debug + Hash + Eq + Copy> ConstraintSet<T> {
}
(ValueType::Reference, _) => {
self.bindings.insert(op2, ValueType::Scalar);
self.bindings.insert(*op2, ValueType::Scalar);
(ValueType::Reference, true)
}
@@ -214,29 +214,37 @@ impl<T: Clone + Debug + Hash + Eq + Copy> ConstraintSet<T> {
fn solve_assert(&mut self, constraint: &Constraint<T>) -> bool {
// Will be of the form, Assertion(<inner>)
// inner will be of the form Or(<c1>, <c2>)
if let &Constraint::Assertion(box Constraint::Or(box ref c1, box ref c2)) = constraint {
// c1, c2 will be of the form And(Eq(ci1), Eq(ci2))
[c1, c2].iter().any(|&ci| {
if let Constraint::And(
box Constraint::Equality(op1, box Constraint::Value(vt1)),
box Constraint::Equality(op2, box Constraint::Value(vt2)),
) = *ci
{
if self.bvalue(op1) == vt1 {
self.bindings.insert(op2, vt2);
true
} else if self.bvalue(op2) == vt2 {
self.bindings.insert(op1, vt1);
true
} else {
false
}
} else {
false
match constraint {
&Constraint::Assertion(ref c) => match **c {
Constraint::Or(ref c1, ref c2) => {
// c1, c2 will be of the form And(Eq(ci1), Eq(ci2))
[c1, c2].iter().any(|&ci| {
match **ci {
Constraint::And(ref bc1, ref bc2) => match (&**bc1, &**bc2) {
(Constraint::Equality(op1, bvt1), Constraint::Equality(op2, bvt2)) => match (&**bvt1, &**bvt2) {
(Constraint::Value(vt1), Constraint::Value(vt2)) => {
if &self.bvalue(*op1) == vt1 {
self.bindings.insert(*op2, *vt2);
true
} else if &self.bvalue(*op2) == vt2 {
self.bindings.insert(*op1, *vt1);
true
} else {
false
}
}
_ => false,
}
_ => false,
}
_ => false,
}
})
}
})
} else {
false
_ => false,
}
_ => false,
}
}
@@ -248,17 +256,17 @@ impl<T: Clone + Debug + Hash + Eq + Copy> ConstraintSet<T> {
impl<T: Debug + Clone + Copy> Display for Constraint<T> {
fn fmt(&self, f: &mut Formatter) -> Result<(), Error> {
let s = match *self {
Constraint::Union(op1, op2) => format!("{:?} U {:?}", op1, op2),
Constraint::Equality(op1, box ref op2) => format!("{:?} = {}", op1, op2),
Constraint::Union(op1, ref op2) => format!("{:?} U {:?}", op1, op2),
Constraint::Equality(op1, ref op2) => format!("{:?} = {}", op1, *op2),
Constraint::AssertEquivalence(ref ops) => {
ops.iter().fold("Assert ".to_owned(), |mut acc, s| {
acc.push_str(&format!("{:?} = ", s));
acc
})
}
Constraint::Assertion(box ref op) => format!("Assert {}", op),
Constraint::Or(box ref op1, box ref op2) => format!("{} \\/ {}", op1, op2),
Constraint::And(box ref op1, box ref op2) => format!("{} /\\ {}", op1, op2),
Constraint::Assertion(ref op) => format!("Assert {}", *op),
Constraint::Or(ref op1, ref op2) => format!("{} \\/ {}", *op1, *op2),
Constraint::And(ref op1, ref op2) => format!("{} /\\ {}", *op1, *op2),
Constraint::Value(ref vt) => format!("{:?}", vt),
};
write!(f, "{}", s)
@@ -49,6 +49,21 @@ pub struct CombineChange {
res: Either<(Option<CombinableOpInfo>, SSAValue), u64>,
}
impl CombineChange {
/// Gets the combine change SSA node.
pub const fn node(&self) -> SSAValue {
self.node
}
/// Left: The node and one of its args were combined. The tuple contains: the
/// structure of the combined node (if the node is a no-op then `None` is present)
/// and the index of the non-const operand of the combined node.
/// Right: The node and its args were combined into a constant value.
pub const fn res(&self) -> &Either<(Option<CombinableOpInfo>, SSAValue), u64> {
&self.res
}
}
impl Change for CombineChange {
fn as_any(&self) -> &dyn Any {
self
@@ -40,7 +40,7 @@ impl<Ix: IndexLike> IxBitSet<Ix> {
IxBitSet(BitSet::with_capacity(nbits), PhantomData)
}
pub fn iter(&self) -> Iter<Ix> {
pub fn iter(&self) -> Iter<'_, Ix> {
Iter(self.0.iter(), PhantomData)
}
@@ -497,11 +497,12 @@ impl<'cd, A: AstContext> LoopRefiner<'cd, A> {
gen_rule! {rule_While, |self, body| {
if let Seq(mut seq) = body {
if let Some(&Cond(c, box Break, None)) = seq.first() {
seq.remove(0);
Ok(Loop(PreChecked(self.cctx.mk_not(c)), Box::new(mk_seq_vec(seq))))
} else {
Err(Seq(seq))
match seq.first() {
Some(&Cond(c, ref b, None)) if matches!(**b, Break) => {
seq.remove(0);
Ok(Loop(PreChecked(self.cctx.mk_not(c)), Box::new(mk_seq_vec(seq))))
}
_ => Err(Seq(seq)),
}
} else {
Err(body)
@@ -510,11 +511,12 @@ impl<'cd, A: AstContext> LoopRefiner<'cd, A> {
gen_rule! {rule_DoWhile, |self, body| {
if let Seq(mut seq) = body {
if let Some(&Cond(c, box Break, None)) = seq.last() {
seq.pop();
Ok(Loop(PostChecked(self.cctx.mk_not(c)), Box::new(mk_seq_vec(seq))))
} else {
Err(Seq(seq))
match seq.last() {
Some(&Cond(c, ref b, None)) if matches!(**b, Break) => {
seq.pop();
Ok(Loop(PostChecked(self.cctx.mk_not(c)), Box::new(mk_seq_vec(seq))))
}
_ => Err(Seq(seq)),
}
} else {
Err(body)
+1 -1
View File
@@ -789,7 +789,7 @@ pub struct CASTConverter<'a> {
}
impl<'a> CASTConverter<'a> {
pub fn new(cfg: &CCFG) -> CASTConverter {
pub fn new(cfg: &CCFG) -> CASTConverter<'_> {
CASTConverter {
ast: CAST::new(&cfg.fname),
cfg: cfg,
+13 -6
View File
@@ -45,7 +45,7 @@ pub trait RBind {
fn is_unknown(&self) -> bool;
fn add_refs(&mut self, _: Vec<Self::SSARef>);
fn refs(&self) -> ::std::slice::Iter<Self::SSARef>;
fn refs(&self) -> ::std::slice::Iter<'_, Self::SSARef>;
}
/// Trait that describes variable bindings for a function.
@@ -59,8 +59,8 @@ pub trait RBindings {
fn binding(&self, _: &Self::Idx) -> Option<&Self::BTy>;
fn binding_mut(&mut self, _: &Self::Idx) -> Option<&mut Self::BTy>;
fn bindings(&self) -> RBinds<Self::BTy>;
fn bindings_mut(&mut self) -> RBindsMut<Self::BTy>;
fn bindings(&self) -> RBinds<'_, Self::BTy>;
fn bindings_mut(&mut self) -> RBindsMut<'_, Self::BTy>;
}
#[derive(Debug)]
@@ -125,13 +125,13 @@ impl<BTy: RBind> RBindings for RadecoBindings<BTy> {
self.binds.get_mut(*idx)
}
fn bindings(&self) -> RBinds<BTy> {
fn bindings(&self) -> RBinds<'_, BTy> {
RBinds {
binds: self.binds.iter(),
}
}
fn bindings_mut(&mut self) -> RBindsMut<BTy> {
fn bindings_mut(&mut self) -> RBindsMut<'_, BTy> {
RBindsMut {
binds: self.binds.iter_mut(),
}
@@ -150,6 +150,13 @@ pub struct Binding<T: fmt::Debug + Clone> {
set: HashSet<VarSet>,
}
impl<T: fmt::Debug + Clone> Binding<T> {
/// Gets the dynamic data type of the binding.
pub fn dty(&self) -> VarDataType {
self.dty
}
}
impl<'a, T: 'a + RBind> Iterator for RBindsMut<'a, T> {
type Item = &'a mut T;
fn next(&mut self) -> Option<&'a mut T> {
@@ -345,7 +352,7 @@ impl<T: Clone + fmt::Debug> RBind for Binding<T> {
self.ssa_refs.extend(refs);
}
fn refs(&self) -> ::std::slice::Iter<T> {
fn refs(&self) -> ::std::slice::Iter<'_, T> {
self.ssa_refs.iter()
}
}
+6 -6
View File
@@ -535,7 +535,7 @@ pub trait RModule<'b> {
fn function_by_ref_mut(&mut self, _: &Self::FnRef) -> Option<&mut Self::RFn>;
// Expose raw `Source`
fn source(&'b mut self) -> &Option<&'b mut dyn Source>;
fn source(&'b mut self) -> &'b Option<&'b mut dyn Source>;
}
impl<'a, F: RFunction> RModule<'a> for RadecoModule<'a, F> {
@@ -570,7 +570,7 @@ impl<'a, F: RFunction> RModule<'a> for RadecoModule<'a, F> {
self.functions.get_mut(fref)
}
fn source(&'a mut self) -> &Option<&'a mut dyn Source> {
fn source(&'a mut self) -> &'a Option<&'a mut dyn Source> {
&self.src
}
}
@@ -588,7 +588,7 @@ impl<B: RBindings> RFunction for RadecoFunction<B> {
self.bindings
.bindings()
.enumerate()
.filter({ |x| x.1.is_argument() })
.filter(|x| x.1.is_argument())
.collect()
}
@@ -596,7 +596,7 @@ impl<B: RBindings> RFunction for RadecoFunction<B> {
self.bindings
.bindings()
.enumerate()
.filter({ |x| x.1.is_local() })
.filter(|x| x.1.is_local())
.collect()
}
@@ -604,7 +604,7 @@ impl<B: RBindings> RFunction for RadecoFunction<B> {
self.bindings
.bindings()
.enumerate()
.filter({ |x| x.1.is_return() })
.filter(|x| x.1.is_return())
.collect()
}
@@ -612,7 +612,7 @@ impl<B: RBindings> RFunction for RadecoFunction<B> {
self.bindings
.bindings()
.enumerate()
.filter({ |x| x.1.is_modified() })
.filter(|x| x.1.is_modified())
.collect()
}
+1 -1
View File
@@ -103,7 +103,7 @@ pub fn init_call_ctx(rmod: &mut RadecoModule) {
.callgraph
.neighbors_directed(rfn.cgid(), Direction::Outgoing)
.detach();
for (csi, callee) in cgwalker.next(&rmod.callgraph) {
while let Some((csi, callee)) = cgwalker.next(&rmod.callgraph) {
let csite = rmod.callgraph[csi].csite;
// Get args of callee
let callee_off = rmod.callgraph[callee];
+19 -9
View File
@@ -43,9 +43,9 @@ use petgraph::Direction;
use petgraph::graph::{Graph, NodeIndex};
use petgraph::visit::EdgeRef;
use r2api::api_trait::R2Api;
use r2api::api_trait::R2PApi;
use r2api::structs::{
LCCInfo, LEntryInfo, LExportInfo, LOpInfo, LRelocInfo, LSectionInfo, LStringInfo, LSymbolInfo,
LCCInfo, LEntry, LExportInfo, LOpInfo, LRelocInfo, LSectionInfo, LStringInfo, LSymbolInfo,
LSymbolType, LVarInfo,
};
@@ -176,16 +176,16 @@ pub trait CGInfo {
impl CGInfo for CallGraph {
// Return a list of callers to function at offset, along with their callsites
fn callers<'a>(&'a self, idx: NodeIndex) -> Box<dyn Iterator<Item = (u64, NodeIndex)> + 'a> {
box self
Box::new(self
.edges_directed(idx, Direction::Incoming)
.map(|er| (er.weight().csite, er.target()))
.map(|er| (er.weight().csite, er.target())))
}
// Return (callsite, call target)
fn callees<'a>(&'a self, idx: NodeIndex) -> Box<dyn Iterator<Item = (u64, NodeIndex)> + 'a> {
box self
Box::new(self
.edges_directed(idx, Direction::Outgoing)
.map(|er| (er.weight().csite, er.target()))
.map(|er| (er.weight().csite, er.target())))
}
}
@@ -203,7 +203,7 @@ pub struct RadecoModule {
exports: Vec<LExportInfo>,
relocs: Vec<LRelocInfo>,
libs: Vec<String>,
entrypoint: Vec<LEntryInfo>,
entrypoint: Vec<LEntry>,
// Information from early/low-level analysis
/// Call graph for current module
pub callgraph: CallGraph,
@@ -404,6 +404,16 @@ pub struct RadecoFunction {
pub kind: FunctionKind,
}
impl RadecoFunction {
// Gets whether the Radeco function is recursive.
pub const fn is_recursive(&self) -> bool {
match self.is_recursive {
Some(true) => true,
_ => false,
}
}
}
#[derive(Default)]
/// Top-level loader used to initialize a `RadecoProject`
pub struct ProjectLoader<'a> {
@@ -478,7 +488,7 @@ impl<'a> ProjectLoader<'a> {
let mut r2 = R2::new(Some(&self.path)).expect("Unable to open r2");
let _ = r2.raw("e bin.minstr=1".to_string());
//New r2 process is launched thus it needs to analyze
r2.analyze_all();
r2.analyze_all().expect("analysis error");
let r2w = Rc::new(RefCell::new(r2));
self.source = Some(Rc::new(r2w));
};
@@ -948,7 +958,7 @@ impl<'a> ModuleLoader<'a> {
if self.load_datarefs {
for info in &aux_info {
if let Some(mut rfn) = rmod.functions.get_mut(&info.offset.unwrap()) {
if let Some(rfn) = rmod.functions.get_mut(&info.offset.unwrap()) {
rfn.datarefs = info.datarefs.clone().unwrap_or_default();
}
}
+17 -13
View File
@@ -10,9 +10,9 @@ use std::io::{Read, Write};
use std::path::{Path, PathBuf};
use std::rc::Rc;
use r2api::api_trait::R2Api;
use r2api::api_trait::R2PApi;
use r2api::structs::{
FunctionInfo, LCCInfo, LEntryInfo, LExportInfo, LFlagInfo, LFunctionInfo, LImportInfo, LOpInfo,
FunctionInfo, LCCInfo, LEntry, LExportInfo, LFlagInfo, LFunctionInfo, LImportInfo, LOpInfo,
LRegInfo, LRelocInfo, LSectionInfo, LStringInfo, LSymbolInfo, LVarInfo,
};
@@ -60,7 +60,7 @@ pub trait Source {
fn libraries(&self) -> Result<Vec<String>, SourceErr> {
unimplemented!()
}
fn entrypoint(&self) -> Result<Vec<LEntryInfo>, SourceErr> {
fn entrypoint(&self) -> Result<Vec<LEntry>, SourceErr> {
unimplemented!()
}
fn disassemble_function(&self, _name: &str) -> Result<Vec<LOpInfo>, SourceErr> {
@@ -140,7 +140,7 @@ pub trait Source {
}
}
// Cause R2Api requires borrowing mutably, while `Source` takes self which
// Cause R2PApi requires borrowing mutably, while `Source` takes self which
// is immutable.
// The only problem with this is that r2pipe is not thread safe, therefore
// using `r2` from multiple threads will cause results to be inconsistent.
@@ -155,10 +155,10 @@ pub trait Source {
// sense to have some sort of cached information so that concurrent reads can occur. This should
// be invalidated whenever some information is exported back to radare or some analysis is run on
// r2.
pub type WrappedR2Api<R> = Rc<RefCell<R>>;
pub type WrappedR2PApi<R> = Rc<RefCell<R>>;
// Implementation of `Source` trait for R2.
impl<R: R2Api> Source for WrappedR2Api<R> {
impl<R: R2PApi> Source for WrappedR2PApi<R> {
fn functions(&self) -> Result<Vec<FunctionInfo>, SourceErr> {
Ok(self.try_borrow_mut()?.fn_list()?)
}
@@ -205,8 +205,10 @@ impl<R: R2Api> Source for WrappedR2Api<R> {
Ok(self.try_borrow_mut()?.libraries()?)
}
fn entrypoint(&self) -> Result<Vec<LEntryInfo>, SourceErr> {
Ok(self.try_borrow_mut()?.entrypoint()?)
fn entrypoint(&self) -> Result<Vec<LEntry>, SourceErr> {
self.try_borrow_mut()
.map_err(SourceErr::from)
.and_then(|mut s| s.entry().map_err(SourceErr::from))
}
fn disassemble_n_bytes(&self, n: u64, at: u64) -> Result<Vec<LOpInfo>, SourceErr> {
@@ -238,7 +240,9 @@ impl<R: R2Api> Source for WrappedR2Api<R> {
}
fn raw(&self, cmd: String) -> Result<String, SourceErr> {
Ok(self.try_borrow_mut()?.raw(cmd))
self.try_borrow_mut()
.map_err(SourceErr::from)
.and_then(|mut s| s.raw(cmd).map_err(SourceErr::from))
}
fn send(&self, s: String) -> Result<(), SourceErr> {
@@ -355,7 +359,7 @@ impl Source for FileSource {
Ok(serde_json::from_str(&self.read_file(suffix::LIBRARY)?)?)
}
fn entrypoint(&self) -> Result<Vec<LEntryInfo>, SourceErr> {
fn entrypoint(&self) -> Result<Vec<LEntry>, SourceErr> {
Ok(serde_json::from_str(&self.read_file(suffix::ENTRY)?)?)
}
@@ -398,8 +402,8 @@ impl Source for FileSource {
}
}
impl<R: R2Api> From<WrappedR2Api<R>> for FileSource {
fn from(r2: WrappedR2Api<R>) -> FileSource {
impl<R: R2PApi> From<WrappedR2PApi<R>> for FileSource {
fn from(r2: WrappedR2PApi<R>) -> FileSource {
let bin_info = r2.borrow_mut().bin_info().expect("Failed to load bin_info");
let fname = bin_info.core.unwrap().file.unwrap();
let fname = Path::new(&fname).file_stem().unwrap();
@@ -531,7 +535,7 @@ impl<R: R2Api> From<WrappedR2Api<R>> for FileSource {
{
let entry = r2
.borrow_mut()
.entrypoint()
.entry()
.expect("Unable to load entry info from r2");
let json_str = serde_json::to_string(&entry).expect("Failed to encode to json");
fsource.write_file(suffix::ENTRY, &json_str);
+4 -3
View File
@@ -9,7 +9,7 @@ use std::process;
use serde_json;
use r2api::api_trait::R2Api;
use r2api::api_trait::R2PApi;
use r2api::structs::{FunctionInfo, LFlagInfo, LOpInfo, LRegInfo, LSectionInfo, LStringInfo};
use r2pipe::r2::R2;
@@ -98,7 +98,7 @@ pub trait Source {
// Implementation of `Source` trait for R2.
impl Source for R2
where
R2: R2Api,
R2: R2PApi,
{
fn functions(&mut self) -> Result<Vec<FunctionInfo>, &'static str> {
match self.fn_list() {
@@ -149,7 +149,8 @@ where
}
fn send(&mut self, s: &str) {
self.send(s);
// FIXME: this function should bubble-up the error
let _ = self.send(s);
}
}
-5
View File
@@ -38,11 +38,6 @@
#![doc(html_root_url = "https://radare.github.io/radeco-lib/")]
#![doc(html_logo_url = "http://rada.re/r/img/r2logo3.png")]
#![feature(box_patterns)]
#![feature(box_syntax)]
#![feature(slice_patterns)]
#![feature(try_trait)]
//#[cfg(test)] #[macro_use] extern crate quickcheck_macros;
extern crate petgraph;
extern crate regex;
+2 -2
View File
@@ -153,7 +153,7 @@ impl MOpcode {
self.info().1
}
pub fn to_string(&self) -> Cow<str> {
pub fn to_string(&self) -> Cow<'_, str> {
self.info().0
}
@@ -191,7 +191,7 @@ impl MOpcode {
}
}
fn info(&self) -> (Cow<str>, MArity) {
fn info(&self) -> (Cow<'_, str>, MArity) {
match *self {
MOpcode::OpAdd => (Cow::from("OpAdd"), MArity::Binary),
MOpcode::OpAnd => (Cow::from("OpAnd"), MArity::Binary),
+24 -31
View File
@@ -52,14 +52,14 @@ impl<'a> LowerSsa<'a> {
let entry_node = if let Some(en) = ssa.entry_node() {
en
} else {
let entry_node = ssa.insert_block(ir::MAddress::new(0, 0))?;
let entry_node = ssa.insert_block(ir::MAddress::new(0, 0)).ok_or(LoweringError::SsaError)?;
ssa.set_entry_node(entry_node);
entry_node
};
let exit_node = if let Some(en) = ssa.exit_node() {
en
} else {
let exit_node = ssa.insert_dynamic()?;
let exit_node = ssa.insert_dynamic().ok_or(LoweringError::SsaError)?;
ssa.set_exit_node(exit_node);
exit_node
};
@@ -103,8 +103,8 @@ impl<'a> LowerSsa<'a> {
if !self.fw_ref_values.is_empty() {
let undefined_values: Vec<_> = self.fw_ref_values.keys().collect();
return Err(LoweringError::InvalidAst(format!(
"values were used but not defined: {:?}",
undefined_values
"function {} values were used but not defined: {undefined_values:?}",
sfn.name,
)));
}
@@ -115,10 +115,10 @@ impl<'a> LowerSsa<'a> {
&mut self,
sregstate: Vec<(sast::NewValue, sast::PhysReg)>,
) -> Result<()> {
let regstate = self.ssa.registers_in(self.entry_node)?;
let regstate = self.ssa.registers_in(self.entry_node).ok_or(LoweringError::SsaError)?;
for (sast::NewValue(vr, ty), sreg) in sregstate {
let regid = self.index_of_reg(&sreg)?;
let val = self.ssa.insert_comment(lower_valueinfo(ty), sreg.0)?;
let val = self.ssa.insert_comment(lower_valueinfo(ty), sreg.0).ok_or(LoweringError::SsaError)?;
self.ssa.op_use(regstate, regid.to_u8(), val);
self.insert_new_value(vr, val)?;
}
@@ -129,7 +129,7 @@ impl<'a> LowerSsa<'a> {
&mut self,
sregstate: Vec<(sast::PhysReg, sast::Operand)>,
) -> Result<()> {
let regstate = self.ssa.registers_in(self.exit_node)?;
let regstate = self.ssa.registers_in(self.exit_node).ok_or(LoweringError::SsaError)?;
for (sreg, sop) in sregstate {
let regid = self.index_of_reg(&sreg)?;
let op = self.lower_operand(sop)?;
@@ -180,7 +180,7 @@ impl<'a> LowerSsa<'a> {
}
fn lower_exit_node(&mut self, sen: sast::ExitNode) -> Result<()> {
let node_addr = self.ssa.starting_address(self.exit_node)?;
let node_addr = self.ssa.starting_address(self.exit_node).ok_or(LoweringError::SsaError)?;
for sop in sen.ops {
let (res, opt_op_addr) = self.lower_operation(sop)?;
let op_addr = opt_op_addr.unwrap_or(node_addr);
@@ -197,7 +197,7 @@ impl<'a> LowerSsa<'a> {
Ok(match sopn {
sast::Operation::Phi(sast::NewValue(vr, ty), sops) => {
let vi = lower_valueinfo(ty);
let res = self.ssa.insert_phi(vi)?;
let res = self.ssa.insert_phi(vi).ok_or(LoweringError::SsaError)?;
// replacing forward refs with their values changes the order of
// phi node operands, so we wait until forward refs have been
// resolved before adding operands
@@ -220,7 +220,7 @@ impl<'a> LowerSsa<'a> {
}
sast::Expr::Resize(rst, ws, sop0) => (lower_resize_op(rst, ws), vec![sop0]),
};
let res = self.ssa.insert_op(opcode, vi, None)?;
let res = self.ssa.insert_op(opcode, vi, None).ok_or(LoweringError::SsaError)?;
for (i, sop) in sops.into_iter().enumerate() {
let op = self.lower_operand(sop)?;
self.ssa.op_use(res, i as u8, op);
@@ -230,7 +230,7 @@ impl<'a> LowerSsa<'a> {
}
sast::Operation::Call(opt_addr, srets, tgt, sargs) => {
let res = self.ssa.insert_op(IrOpcode::OpCall, scalar!(0), None)?;
let res = self.ssa.insert_op(IrOpcode::OpCall, scalar!(0), None).ok_or(LoweringError::SsaError)?;
let tgt_op = self.lower_operand(tgt)?;
self.ssa.op_use(res, 0, tgt_op);
for sarg in sargs {
@@ -246,7 +246,8 @@ impl<'a> LowerSsa<'a> {
}
let val = self
.ssa
.insert_comment(lower_valueinfo(sret.value.1), comment)?;
.insert_comment(lower_valueinfo(sret.value.1), comment)
.ok_or(LoweringError::SsaError)?;
self.ssa.op_use(val, regid.to_u8(), res);
self.insert_new_value(sret.value.0, val)?;
}
@@ -257,23 +258,23 @@ impl<'a> LowerSsa<'a> {
fn lower_operand(&mut self, sop: sast::Operand) -> Result<SSAValue> {
use std::collections::hash_map::Entry;
Ok(match sop {
match sop {
sast::Operand::ValueRef(r) => {
if let Some(x) = self.values.get(&r).cloned() {
x
Ok(x)
} else {
match self.fw_ref_values.entry(r) {
Entry::Occupied(o) => *o.get(),
Entry::Occupied(o) => Ok(*o.get()),
Entry::Vacant(v) => {
*v.insert(self.ssa.insert_undefined(ValueInfo::new_unresolved(
self.ssa.insert_undefined(ValueInfo::new_unresolved(
ir::WidthSpec::Unknown,
))?)
)).ok_or(LoweringError::SsaError).map(|b| *v.insert(b))
}
}
}
}
sast::Operand::Const(v) => self.ssa.insert_const(v, None)?,
})
sast::Operand::Const(v) => self.ssa.insert_const(v, None).ok_or(LoweringError::SsaError)
}
}
fn insert_new_value(&mut self, vr: sast::ValueRef, val: SSAValue) -> Result<()> {
@@ -300,10 +301,10 @@ impl<'a> LowerSsa<'a> {
fn block_at(&mut self, at: ir::MAddress) -> Result<SSABlock> {
use std::collections::hash_map::Entry;
// can't use `or_insert_with` because `ssa.insert_block` may fail
Ok(*match self.blocks.entry(at) {
Entry::Occupied(o) => o.into_mut(),
Entry::Vacant(v) => v.insert(self.ssa.insert_block(at)?),
})
match self.blocks.entry(at) {
Entry::Occupied(o) => Ok(*o.into_mut()),
Entry::Vacant(v) => self.ssa.insert_block(at).map(|b| *v.insert(b)).ok_or(LoweringError::SsaError),
}
}
fn index_of_reg(&self, sreg: &sast::PhysReg) -> Result<RegisterId> {
@@ -361,14 +362,6 @@ fn lower_valueinfo(sty: sast::Type) -> ValueInfo {
}
}
/// [`SSAStorage`][SSAStorage] methods return `Option`,
/// so we convert `None`s into [`SsaError`][LoweringError::SsaError]
impl From<::std::option::NoneError> for LoweringError {
fn from(_: ::std::option::NoneError) -> Self {
LoweringError::SsaError
}
}
impl error::Error for LoweringError {
fn description(&self) -> &str {
match *self {
+2 -2
View File
@@ -33,10 +33,10 @@ impl<V> RegisterMap<V> {
pub fn remove(&mut self, key: RegisterId) -> Option<V> {
self.map.remove(key.to_usize())
}
pub fn iter(&self) -> Iter<V> {
pub fn iter(&self) -> Iter<'_, V> {
self.into_iter()
}
pub fn iter_mut(&mut self) -> IterMut<V> {
pub fn iter_mut(&mut self) -> IterMut<'_, V> {
self.into_iter()
}
}
+1 -1
View File
@@ -217,7 +217,7 @@ where
if comment.len() < reg_len {
return false;
}
comment.split_off(reg_len);
let _ = comment.split_off(reg_len);
// Attition: Comment may be in format as: [email protected]
if comment == reg {
+1
View File
@@ -31,6 +31,7 @@ env_logger = { version = "0.7", optional = true }
git = "https://github.com/radareorg/r2pipe.rs"
[dependencies.r2api]
package = "r2papi"
git = "https://github.com/radare/radare2-r2pipe-api"
[dependencies.radeco-lib]
+2 -2
View File
@@ -167,12 +167,12 @@ pub fn load_proj_by_path(path: &str, max_it: u32) -> RadecoProject {
}
pub fn load_proj_tcp(url: &str, max_it: u32) -> Result<RadecoProject, &'static str> {
let r2p = R2Pipe::tcp(url)?;
let r2p = R2Pipe::tcp(url).map_err(|_| "error creating project from TCP URL")?;
Ok(load_project_by_r2pipe(r2p, max_it))
}
pub fn load_proj_http(url: &str, max_it: u32) -> Result<RadecoProject, &'static str> {
let r2p = R2Pipe::http(url)?;
let r2p = R2Pipe::http(url);
Ok(load_project_by_r2pipe(r2p, max_it))
}
+3 -3
View File
@@ -4,8 +4,8 @@ use syntect::parsing::SyntaxSet;
use syntect::util::{as_24_bit_terminal_escaped, LinesWithEndings};
lazy_static! {
static ref SYNTAX_SET: SyntaxSet = { SyntaxSet::load_defaults_newlines() };
static ref THEME_SET: ThemeSet = { ThemeSet::load_defaults() };
static ref SYNTAX_SET: SyntaxSet = SyntaxSet::load_defaults_newlines();
static ref THEME_SET: ThemeSet = ThemeSet::load_defaults();
}
pub fn print_highlighted(code: &str) {
@@ -14,6 +14,6 @@ pub fn print_highlighted(code: &str) {
for line in LinesWithEndings::from(code) {
let ranges: Vec<(Style, &str)> = h.highlight(line, &SYNTAX_SET);
let escaped = as_24_bit_terminal_escaped(&ranges[..], true);
print!("{}", escaped);
print!("{escaped}");
}
}
-1
View File
@@ -1,4 +1,3 @@
#![feature(box_patterns)]
#[cfg(feature = "trace_log")]
extern crate env_logger;
+1 -1
View File
@@ -13,7 +13,6 @@ path = "runec/main.rs"
[dependencies]
petgraph = "*"
rustc-serialize = "*"
clippy = {version = "*", optional = true}
regex = "*"
docopt = "*"
@@ -37,4 +36,5 @@ path = "../esil-rs"
git = "https://github.com/radareorg/r2pipe.rs"
[dependencies.r2api]
package = "r2papi"
git = "https://github.com/radare/radare2-r2pipe-api"
+6 -2
View File
@@ -2,6 +2,7 @@
extern crate rustyline;
use self::rustyline::error::ReadlineError;
use self::rustyline::history::FileHistory;
use self::rustyline::Editor;
use std::io::{self, Write};
@@ -67,7 +68,7 @@ impl Console {
pub fn read_command(&self) -> Vec<Command> {
let mut repeat: u32 = 1;
let mut cmd: Command;
let mut r = Editor::<()>::new();
let mut r = Editor::<(), FileHistory>::new().expect("unable to create rustyline Editor");
if let Err(_) = r.load_history("history.txt") {
self.print_info("No history found.");
@@ -79,7 +80,10 @@ impl Console {
match readline {
Ok(buffer) => {
r.add_history_entry(buffer.clone());
if let Err(err) = r.add_history_entry(buffer.clone()) {
println!("(!) Error adding history entry: {err}");
continue;
}
cmd = From::from(buffer.to_owned());
if cmd.is_chainable() {
+5 -4
View File
@@ -6,7 +6,6 @@
extern crate rune;
extern crate libsmt;
extern crate docopt;
extern crate rustc_serialize;
extern crate r2pipe;
extern crate r2api;
@@ -16,6 +15,8 @@ mod console;
use std::process::exit;
use docopt::Docopt;
use serde::{Deserialize, Serialize};
use rune::utils::utils::{Key, ValType, SAssignment};
use rune::utils::state::RInitialState;
use rune::explorer::explorer::PathExplorer;
@@ -27,7 +28,7 @@ use crate::interact::InteractiveExplorer;
use crate::console::Console;
use r2pipe::r2::R2;
use r2api::api_trait::R2Api;
use r2api::api_trait::R2PApi;
static USAGE: &'static str = "
runec. Interactive console for rune.
@@ -41,7 +42,7 @@ Options:
-p Load a previous configuration of state
";
#[derive(Debug, Clone, RustcDecodable)]
#[derive(Debug, Clone, Deserialize, Serialize)]
struct Args {
flag_help: bool,
flag_project: bool,
@@ -60,7 +61,7 @@ fn main() {
}
let mut stream = R2::new(Some(args.get_str("<file>"))).expect("Unable to spawn r2");
stream.init();
stream.init().expect("Unable to initialize the stream");
let _lreginfo = stream.reg_info().expect("Unable to retrieve register info.");
-2
View File
@@ -222,7 +222,6 @@ where Ctx: Context<IFn=qf_abv::QF_ABV_Fn>,
Ok(token_opt_) => token_opt_,
Err(_err) => {
panic!("ERROR tokenizing!");
continue;
}
};
if let Some(ref token) = token_opt {
@@ -235,7 +234,6 @@ where Ctx: Context<IFn=qf_abv::QF_ABV_Fn>,
Ok(operands_opt) => operands_opt,
Err(_err) => {
panic!("Error fetching operands!");
continue;
}
}
};
-1
View File
@@ -11,7 +11,6 @@ extern crate petgraph;
extern crate esil;
extern crate r2pipe;
extern crate r2api;
extern crate rustc_serialize;
extern crate regex;
extern crate libsmt;
#[macro_use] extern crate serde_derive;
+9 -8
View File
@@ -8,12 +8,13 @@ use std::hash::Hash;
use std::io::prelude::*;
use std::fs::File;
use rustc_serialize::{Decodable};
use rustc_serialize::json;
use serde::{Deserialize, Serialize};
use r2pipe::r2::R2;
use r2api::structs::LOpInfo;
use r2api::api_trait::R2Api;
use r2api::api_trait::R2PApi;
pub trait Decodable: for<'a> Deserialize<'a> + Serialize {}
pub trait InstructionStream {
type Output: Debug + Clone;
@@ -33,7 +34,7 @@ impl InstructionStream for R2 {
}
fn at(&mut self, addr: u64) -> Option<Self::Output> {
let addr_ = format!("{}", addr);
let addr_ = format!("{addr}");
Some(self.insts(Some(1), Some(&addr_)).unwrap()[0].clone())
}
}
@@ -42,10 +43,10 @@ impl InstructionStream for R2 {
// This is useful for tests, debug and other smaller applications.
// Maintains a HashMap from address to LOpInfo that it should provide
// when asked for that address.
#[derive(Clone, Debug, RustcDecodable, Default)]
#[derive(Clone, Debug, Deserialize, Serialize, Default)]
pub struct FileStream<I, Op>
where I: Debug + Clone + Decodable + Hash + PartialEq + Eq,
Op: Debug + Clone + Decodable
where I: Debug + Clone + Hash + PartialEq + Eq,
Op: Debug + Clone
{
insts: HashMap<I, Op>,
}
@@ -59,7 +60,7 @@ impl<I, Op> FileStream<I, Op>
let mut f = File::open(fname).expect("Failed to open file");
let mut s = String::new();
f.read_to_string(&mut s).expect("Failed to read from file");
self.insts = json::decode(&s).expect("Failed to decode json");
self.insts = serde_json::from_str::<HashMap<I, Op>>(&s).expect("Failed to decode json");
}
}
+1 -1
View File
@@ -2,7 +2,7 @@
use r2pipe::r2::R2;
use r2api::api_trait::R2Api;
use r2api::api_trait::R2PApi;
use crate::context::rune_ctx::RuneContext;
use crate::context::context::{ContextAPI};