0

I'm developing a frama-c-plugin, where I want to get the values of pointers (not the address they are pointing to, but the value at that address).

This works so far for simple pointers. Now I want to handle pointers to pointers.

For example:

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

When analyzing this code with my actual version, I get the values:

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

But I want these values:

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

Since they all reference the same memory location with the value 12 (over multiple references)

Now my question: Is it possible to get the bottom-value of m and n?

EDIT

Sorry for my bad description of the problem, I made a mistake in the Frama-C-GUI by clicking on the wrong variable, which made my question confusing. I removed this part of the initial question.

My code looks like this:

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*)

So if the pointer points to another pointer, it should do the function loc_match recursivly, until it finds a struct or non-pointer-variable.

The outer function is called by: rec_struct_solver vtype None vi.vname NoOffset I think the error is int the part (Mem(Cil.evar vi), NoOffset), because it only resolves the first pointer-step, but I don't know what else I should use as parameter to build an lval.

I hope the problem is now clearer.

Thomas Böhm
  • 1,456
  • 1
  • 15
  • 27

1 Answers1

3

The code below can be used to obtain a cil expression that dereferences a variable as much as possible. (Until the result is no longer a pointer.)

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))

Using your example, deref_vi vi_k will return an expression that evaluates k, while deref_vi vi_n will return the Cil expression that corresponds to ***vi_n. You should adapt your function to do more or less the same thing, especially in the case TPtr

byako
  • 3,372
  • 2
  • 21
  • 36
  • But exactly that is what I want: I want the *-Operator, but not only one, but multiple times (dereference over multiple steps, like shown in my question). And I cannot apply `(Mem(Mem(Mem(Cil.evar vi))), NoOffset)` – Thomas Böhm Apr 19 '16 at 06:13
  • So I want to derefernce all pointers to get to the base-value. – Thomas Böhm Apr 19 '16 at 07:25
  • Do you have any idea if that is possible? Even the answer "not possible" helps, because than I have to chose a different approach to reach my goal. – Thomas Böhm Apr 21 '16 at 06:17
  • 2
    Yes you can use `Mem` as many times as needed, but it takes an `exp` and `(Mem (Cil.evar vi), NoOffset)` is an `lval` (see in `cil_types.mli`). So you have to build an `exp` from your `lval` with `Cil.new_exp (loc, Cil_types.Lval lval)`. – Anne Apr 21 '16 at 09:46
  • @Anne is correct. I've replaced my answer by a function that adds the proper number of `Mem`. – byako Apr 21 '16 at 10:36