Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion src/builder/fpag_builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ use rustc_middle::ty;
use rustc_middle::ty::{Const, Ty, TyCtxt, TyKind, GenericArgsRef};
use rustc_span::source_map::Spanned;
use rustc_target::abi::FieldIdx;

use crate::builder::{call_graph_builder, special_function_handler};
use crate::graph::func_pag::FuncPAG;
use crate::graph::pag::PAGEdgeEnum;
Expand Down
50 changes: 50 additions & 0 deletions src/builder/special_function_handler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -80,12 +80,62 @@ lazy_static! {
};
}


lazy_static! {
static ref PRECISION_CRITICAL_FUNCTIONS: HashSet<KnownNames> = {
let mut set = HashSet::new();
set.insert(KnownNames::StdIntrinsicsTransmute);
set.insert(KnownNames::StdIntrinsicsOffset);
set.insert(KnownNames::StdIntrinsicsArithOffset);
set.insert(KnownNames::StdPtrConstPtrCast);
set.insert(KnownNames::StdPtrConstPtrAdd);
set.insert(KnownNames::StdPtrConstPtrSub);
set.insert(KnownNames::StdPtrConstPtrOffset);
set.insert(KnownNames::StdPtrConstPtrByteAdd);
set.insert(KnownNames::StdPtrConstPtrByteSub);
set.insert(KnownNames::StdPtrConstPtrByteOffset);
set.insert(KnownNames::StdPtrConstPtrWrappingAdd);
set.insert(KnownNames::StdPtrConstPtrWrappingSub);
set.insert(KnownNames::StdPtrConstPtrWrappingOffset);
set.insert(KnownNames::StdPtrConstPtrWrappingByteAdd);
set.insert(KnownNames::StdPtrConstPtrWrappingByteSub);
set.insert(KnownNames::StdPtrConstPtrWrappingByteOffset);
set.insert(KnownNames::StdPtrMutPtrCast);
set.insert(KnownNames::StdPtrMutPtrAdd);
set.insert(KnownNames::StdPtrMutPtrSub);
set.insert(KnownNames::StdPtrMutPtrOffset);
set.insert(KnownNames::StdPtrMutPtrByteAdd);
set.insert(KnownNames::StdPtrMutPtrByteSub);
set.insert(KnownNames::StdPtrMutPtrByteOffset);
set.insert(KnownNames::StdPtrMutPtrWrappingAdd);
set.insert(KnownNames::StdPtrMutPtrWrappingSub);
set.insert(KnownNames::StdPtrMutPtrWrappingOffset);
set.insert(KnownNames::StdPtrMutPtrWrappingByteAdd);
set.insert(KnownNames::StdPtrMutPtrWrappingByteSub);
set.insert(KnownNames::StdPtrMutPtrWrappingByteOffset);
set.insert(KnownNames::StdPtrNonNullAsPtr);
set.insert(KnownNames::StdPtrUniqueNewUnchecked);
set.insert(KnownNames::StdResultMapErr);
set.insert(KnownNames::RustRealloc);
set.insert(KnownNames::StdAllocRealloc);
set.insert(KnownNames::StdAllocAllocatorGrow);
set.insert(KnownNames::StdAllocAllocatorGrowZeroed);
set.insert(KnownNames::StdAllocAllocatorShrink);
set
};
}

/// Returns true if the function with `def_id` is specially handled.
pub fn is_specially_handled_function(acx: &mut AnalysisContext, def_id: DefId) -> bool {
let known_name = acx.get_known_name_for(def_id);
SPECIALLY_HANDLED_FUNCTIONS.contains(&known_name)
}


pub fn is_specially_handled_precision_critical_function(acx: &mut AnalysisContext, def_id: DefId) -> bool {
let known_name = acx.get_known_name_for(def_id);
PRECISION_CRITICAL_FUNCTIONS.contains(&known_name)
}
/// Handling calls to special functions.
///
/// Returns true if this callee function is handled as a special function.
Expand Down
36 changes: 31 additions & 5 deletions src/graph/call_graph.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,12 @@ use std::collections::hash_map::Entry;
use std::collections::{HashMap, HashSet};
use std::fmt::{self, Debug};
use std::hash::Hash;

use crate::mir::analysis_context::AnalysisContext;
use crate::mir::call_site::{BaseCallSite, CallType, CSBaseCallSite};
use crate::mir::function::{FuncId, CSFuncId};
use rustc_middle::mir::Location;
use crate::util::chunked_queue::{self, ChunkedQueue};
use crate::util::dot::Dot;

/// Unique identifiers for call graph nodes.
pub type CGNodeId = NodeIndex<DefaultIx>;
/// Unique identifiers for call graph edges.
Expand All @@ -26,6 +25,8 @@ pub type CSCallGraph = CallGraph<CSFuncId, CSBaseCallSite>;

pub trait CGFunction: Copy + Clone + PartialEq + Eq + Hash + Debug {
fn dot_fmt(&self, acx: &AnalysisContext, f: &mut fmt::Formatter) -> fmt::Result;

fn get_func_id(&self) -> FuncId;
}

impl CGFunction for FuncId {
Expand All @@ -35,6 +36,10 @@ impl CGFunction for FuncId {
acx.get_function_reference(*self).to_string()
))
}

fn get_func_id(&self) -> FuncId {
*self
}
}

impl CGFunction for CSFuncId {
Expand All @@ -44,32 +49,52 @@ impl CGFunction for CSFuncId {
acx.get_function_reference(self.func_id).to_string(),
))
}

fn get_func_id(&self) -> FuncId {
self.func_id
}
}

pub trait CGCallSite: Copy + Clone + PartialEq + Eq + Hash + Debug {
fn dot_fmt(&self, f: &mut fmt::Formatter) -> fmt::Result;

fn get_location(&self) -> &Location;
}

impl CGCallSite for BaseCallSite {

fn dot_fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.write_fmt(format_args!("{:?}", self.location))
}

fn get_location(&self) -> &Location {
&self.location
}
}

impl CGCallSite for CSBaseCallSite {

fn dot_fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.write_fmt(format_args!("{:?}", self.location))
}

fn get_location(&self) -> &Location {
&self.location
}
}

#[derive(Debug)]
pub struct CallGraphNode<F: CGFunction> {
pub(crate) func: F,
pub(crate) req_cs: bool,
}

impl<F: CGFunction> CallGraphNode<F> {
pub fn new(func: F) -> Self {
CallGraphNode { func }
CallGraphNode {
func,
req_cs: false,
}
}
}

Expand Down Expand Up @@ -120,7 +145,7 @@ impl<F: CGFunction, S: CGCallSite> CallGraph<F, S> {

/// Helper function to get a node or insert a new
/// node if it does not exist in the map.
fn get_or_insert_node(&mut self, func: F) -> CGNodeId {
pub fn get_or_insert_node(&mut self, func: F) -> CGNodeId {
match self.func_nodes.entry(func) {
Entry::Occupied(o) => o.get().to_owned(),
Entry::Vacant(v) => {
Expand Down Expand Up @@ -207,6 +232,7 @@ impl<F: CGFunction, S: CGCallSite> CallGraph<F, S> {
self.reach_funcs.iter_copied()
}


/// Produce a dot file representation of the call graph
/// for displaying with Graphviz.
pub fn to_dot(&self, acx: &AnalysisContext, dot_path: &std::path::Path) {
Expand All @@ -226,4 +252,4 @@ impl<F: CGFunction, S: CGCallSite> CallGraph<F, S> {
Err(e) => panic!("Failed to write dot file output: {:?}", e),
};
}
}
}
4 changes: 3 additions & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
min_specialization, // for rustc_index::newtype_index
type_alias_impl_trait, // for impl Trait in trait definition, eg crate::mir::utils
trait_alias,
let_chains, // for let chains in match arms
)]
#![allow(
clippy::single_match,
Expand All @@ -31,11 +32,12 @@ extern crate rustc_serialize;
extern crate rustc_session;
extern crate rustc_span;
extern crate rustc_target;
extern crate rustc_attr;

pub mod builder;
pub mod graph;
pub mod mir;
pub mod pta;
pub mod rta;
pub mod pre_analysis;
pub mod pts_set;
pub mod util;
4 changes: 4 additions & 0 deletions src/mir/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,10 @@ impl<E: ContextElement> ContextCache<E> {
pub fn context_list(&self) -> &IndexVec<ContextId, Rc<Context<E>>> {
&self.context_list
}

pub fn get_context_iter(&self) -> std::collections::hash_map::Iter<'_, Rc<Context<E>>, ContextId> {
self.context_to_index_map.iter()
}
}


Expand Down
2 changes: 2 additions & 0 deletions src/pre_analysis/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
pub mod rta;
pub mod precision_critical_func_identification;
Loading