Frama-C-Plugin:将指针解析为指针

时间:2016-04-18 09:55:13

标签: frama-c

我正在开发一个frama-c-plugin,我想获取指针的值(不是它们指向的地址,而是指向该地址的值)。

这对于简单的指针到目前为止是有效的。现在我想处理指针指针。

例如:

int k=12;
int *l=&k;
int **m = &l;
int ***n = &m;

使用我的实际版本分析此代码时,我得到了值:

k=12
l=12
m=&k
n=&l

但我想要这些价值观:

k=12
l=12
m=12
n=12

因为它们都引用了相同的内存位置,其值为12(超过多个引用)

现在我的问题:是否有可能得到m和n的底值?

修改

很抱歉我对问题的描述不好,我在Frama-C-GUI中点击了错误的变量,这让我的问题变得混乱。我删除了初始问题的这一部分。

我的代码如下所示:

let rec rec_struct_solver vtype packed_fi vi_name act_offset=
    match vtype with
        | TComp( compinfo, bitsSizeofTypCache, attributes) ->(
            if compinfo.cstruct then (
                (*Do stuff for structs *)
            )
        )
        | TNamed (typeinfo, attributes) ->(
            (*Do Stuff for named types*)
        )
        | TPtr (typ1, attribute) -> (
            let rec loc_match typ2=
                match typ2 with
                    | TPtr(typ3, attribute) ->(
                        loc_match typ3
                    )
                    | TComp(_,_,_) -> (
                        rec_struct_solver typ2 None vi_name act_offset
                    )
                    | _ ->(
                        self#print_var_values stmt (Mem (Cil.evar vi), NoOffset) vi_name
                    )
            in
                loc_match typ1
        | _ -> (*do something for others*)

因此,如果指针指向另一个指针,它应该递归地执行函数loc_match,直到找到结构或非指针变量。

外部函数由:rec_struct_solver vtype None vi.vname NoOffset调用 我认为错误在部分(Mem(Cil.evar vi), NoOffset)中是int,因为它只解析了第一个指针步骤,但我不知道还应该使用什么作为构建lval的参数。

我希望问题现在更清楚了。

1 个答案:

答案 0 :(得分:3)

下面的代码可用于获取尽可能取消引用变量的cil表达式。 (直到结果不再是指针。)

open Cil_types

let dummy_loc = Cil_datatype.Location.unknown
let mk_exp_lval lv = Cil.new_exp ~loc:dummy_loc (Lval lv)

(* Build ( *^n )e until [e] has no longer a pointer type.
   invariant: typ == Cil.typeOf e *)
let rec deref typ e =
  match Cil.unrollType typ with
  | TPtr (typ_star_e, _) ->
    let star_e (* *e *) = mk_exp_lval (Cil.mkMem e NoOffset) in
    deref typ_star_e star_e
  | _ -> e

(* Build ( *^n vi *)
let deref_vi vi =
  deref vi.vtype (mk_exp_lval (Var vi, NoOffset))

使用您的示例,deref_vi vi_k将返回一个评估k的表达式,而deref_vi vi_n将返回与***vi_n对应的Cil表达式。你应该调整你的功能,或多或少做同样的事情,特别是在TPtr

的情况下