简体   繁体   English

Frama-C插件开发:将值分析结果提取为OCaml整数

[英]Frama-C plugin development: Extract value analysis result as OCaml integers

I have read these two posts: Getting result of value analysis and Getting the values of statement . 我已经阅读了这两篇文章: 获得价值分析的结果获得陈述的价值 These two posts provide invaluable information on how to print the values of the value analysis. 这两个帖子提供了有关如何打印价值分析值的宝贵信息。

However, my task requires me to extract the integers stored in the value variable, and then do some math with the integers (I am only concerned with integer values). 但是,我的任务要求我提取存储在value变量中的整数,然后用整数进行一些数学计算(我只关心整数值)。 For example, if the value analysis result for some variable is {1, 2}, I want to get the result as an OCaml list of integers: [1, 2]. 例如,如果某个变量的值分析结果是{1,2},我想将结果作为整数的OCaml列表得到:[1,2]。 This way I can do math with it. 这样我就可以用它做数学。 If the result involves an interval, I assume I can define a type to handle it. 如果结果涉及间隔,我假设我可以定义一个类型来处理它。 For example, 例如,

type point_or_interval =
| Point of int
| Interval of int * int

The type of the value variable is defined as type t = Cvalue.Vt in the documentation. 值变量的type t = Cvalue.Vt在文档中定义为type t = Cvalue.Vt I have not been able to find this module in the source, so I do not know how to manipulate the value and extract the information that I need. 我无法在源代码中找到此模块,因此我不知道如何操作该值并提取我需要的信息。 How should I do this? 我该怎么做? A code illustration will be appreciated! 代码插图将不胜感激!

Edit: I have tried the following code. 编辑:我已经尝试了以下代码。 This code is copied verbatim from Getting result of value analysis , with only some modifications in the pretty_vi function. 此代码是从获取结果值分析中逐字复制的,只对pretty_vi函数进行了一些修改。 It is not working with my test input program - Locations.Location_Bytes.find_lonely_key function raises Not_found exception. 这不是我的测试输入程序的工作- Locations.Location_Bytes.find_lonely_key函数抛出Not_found例外。 My input program is also attached. 我的输入程序也附上了。

open Cil_types

(* Prints the value associated to variable [vi] before [stmt]. *)
let pretty_vi fmt stmt vi =
  let kinstr = Kstmt stmt in (* make a kinstr from a stmt *)
  let lval = (Var vi, NoOffset) in (* make an lval from a varinfo *)
  let loc = (* make a location from a kinstr + an lval *)
    !Db.Value.lval_to_loc kinstr ~with_alarms:CilE.warn_none_mode lval
  in    
  Db.Value.fold_state_callstack
    (fun state () ->
       (* for each state in the callstack *)
       let value = Db.Value.find state loc in (* obtain value for location *)
       let base, offset = Locations.Location_Bytes.find_lonely_key value in 
       (match offset with 
       | Ival.Set _ -> ()
       | Ival.Float _ -> ()
       | Ival.Top (_, _, _, _ )-> ());
       Format.fprintf fmt "%a -> %a@." Printer.pp_varinfo vi
         Db.Value.pretty value (* print mapping *)
    ) () ~after:false kinstr

(* Prints the state at statement [stmt] for each local variable in [kf],
   and for each global variable. *)
let pretty_local_and_global_vars kf fmt stmt =
  let locals = Kernel_function.get_locals kf in
  List.iter (fun vi -> pretty_vi fmt stmt vi) locals (*;
  Globals.Vars.iter (fun vi _ -> pretty_vi fmt stmt vi) *)

(* Visits each statement in [kf] and prints the result of Value before the
   statement. *)
class stmt_val_visitor kf =
  object (self)
    inherit Visitor.frama_c_inplace
    method! vstmt_aux stmt =
      (match stmt.skind with
       | Instr _ ->
         Format.printf "state for all variables before stmt: %a@.%a@."
           Printer.pp_stmt stmt (pretty_local_and_global_vars kf) stmt
       | _ -> ());
      Cil.DoChildren
  end

(* usage: frama-c file.c -load-script print_vals.ml *)
let () =
  Db.Main.extend (fun () ->
      Format.printf "computing value...@.";
      !Db.Value.compute ();
      let fun_name = "main" in
      Format.printf "visiting function: %s@." fun_name;
      let kf_vis = new stmt_val_visitor in
      let kf = Globals.Functions.find_by_name fun_name in
      let fundec = Kernel_function.get_definition kf in
      ignore (Visitor.visitFramacFunction (kf_vis kf) fundec);
      Format.printf "done!@.")

Test input program: 测试输入程序:

#include <stdio.h>

int main() {
    int a = 1;
    return 0;
}

What is the problem with this code? 这段代码有什么问题? Why is the mapping of the value not found? 为什么找不到值的映射?

General remark : if you are using an editor which supports Merlin , I seriously recommend using it. 一般说明 :如果您使用的是支持Merlin的编辑器,我认真推荐使用它。 It makes it easier to find in which module things are defined, which types are synonyms, and, combined with an auto-completion tool, Merlin allows you to find conversion functions much more easily. 它可以更容易地找到定义了哪些模块,哪些类型是同义词,并且结合自动完成工具,Merlin允许您更轻松地查找转换函数。

In particular, Merlin should help you find out that Cvalue.V.project_ival : Vt -> Ival.t converts a Vt into an Ival.t (assuming the value is convertible, eg it is not a pointer). 特别是,Merlin应该帮助你找出Cvalue.V.project_ival : Vt -> Ival.tVt转换为Ival.t (假设值是可转换的,例如它不是指针)。

Ival.t is a sophisticated interval-like value that can represent: Ival.t是一个复杂的区间值,可以表示:

  • a contiguous interval of floating-point values ( Ival.Float ); 连续的浮点值间隔( Ival.Float );
  • a small set of integer values ( Ival.Set ); Ival.Set整数值( Ival.Set );
  • or an actual integer interval ( Ival.Top , despite the name), with congruence information and optional bounds, eg [9..--]1%4 represents {x ∈ ℕ | x ≥ 9 ∧ x mod 4 = 1} 或实际整数区间( Ival.Top ,尽管名称),同余信息和可选边界,例如[9..--]1%4代表{x ∈ ℕ | x ≥ 9 ∧ x mod 4 = 1} [9..--]1%4 {x ∈ ℕ | x ≥ 9 ∧ x mod 4 = 1} {x ∈ ℕ | x ≥ 9 ∧ x mod 4 = 1} . {x ∈ ℕ | x ≥ 9 ∧ x mod 4 = 1}

Function Ival.min_and_max : Ival.t -> Integer.t option * Integer.t option takes an Ival.t and returns (assuming the interval does not contain a floating-point interval) a pair (maybe_min, maybe_max) , where maybe_min is None if there is no lower bound (minus infinity), or Some min otherwise, and symmetrically for maybe max . 函数Ival.min_and_max : Ival.t -> Integer.t option * Integer.t option接受Ival.t并返回(假设间隔不包含浮点间隔)一对(maybe_min, maybe_max) ,其中maybe_minNone如果没有下限(负无穷大),或Some min ,否则对称的maybe max It works both with Ival.Set and Ival.Top . 它适用于Ival.SetIval.Top

Note that Integer.t are not machine integers, but an implementation of arbitrary-precision integers. 请注意, Integer.t不是机器整数,而是任意精度整数的实现。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM