On Wed, 29 Feb 2012, David Wagner wrote:
Hello,
I have been trying to find a tool that would allow to perform queries on C
code such as "what are the values, in all the codebase, that are passed as
second argument of 'func' ?".
Given the following code:
func(0, ENUM_VAL_2);
func(0, ENUM_VAL_1);
func(0, ENUM_VAL_1 | ENUM_VAL_3);
That paricular query would return (ENUM_VAL_1, ENUM_VAL_2, ENUM_VAL_1 |
ENUM_VAL_3).
Or queries like "give me a call graph for 'func'".
It is very easy for coccinelle to find this information. If you want it
presented exactly as you have shown with the parentheses and I guess no
duplicates, then it is a little more tricky but possible. You would do
your matches, then use a script rule (python or ocaml) to put the value in
a hash table, and then print out the values from the hashtable in the end.
But once you write that code once, you can use it over and over.
After some research, I remembered Coccinelle as it appeared on the result of
a search with some keywords...
Does that fall under Cocinelle's matching capabilities ? And if yes, what
effort would it require to be able to do such things ?
I don't know OCaml yet (I can try and learn it if it helps) and only have had
an introduction on formal methods and model checking some time ago ...
Perhaps there is a better suited tool ?
You don't need to know anything about formal methods or model checking.
If you are good with python, you don't need to know ocaml.
I used CScope for simpler queries
and still have some CScope-based tools to explore.
I also read about some tools around GXL (Graph eXchange Language) but
couldn't find anything up-to-date (except maybe GreQL, but it isn't
opensource).
With Coccinelle, you can make arbitrarily complicated matches. Look at
the examples on the webiste. They are a bit oriented towards bug finding,
but you should get the idea.
I also imagined it could be possible to parse the code and build an SQL
database from it but I'm not sure that it is fit and I can only begin to
imagine all the problems I would run into.
You can also use python or ocaml to insert information into a database.
Here is your semantic patch, using ocaml scripting:
@initialize:ocaml@
let tbl = Hashtbl.create 101
@match@
identifier virtual.func;
expression e1,e2;
@@
func(e1,e2)
@script:ocaml@
e2 << match.e2;
@@
if not (Hashtbl.mem tbl e2) then Hashtbl.add tbl e2 ()
@finalize:ocaml@
let elements =
Hashtbl.fold (fun key _ rest -> key :: rest) tbl [] in
Printf.printf "(%s)" (String.concat ", " elements)
func is a virtual identifier so you can give it on the command line:
spatch -sp_file david.cocci -D func=usb_submit_urb -dir /path/to/linux
gives
(flags, GFP_KERNEL, gfp_flags, GFP_ATOMIC, mf, gfp, mem_flags, GFP_NOIO,
gfp_mask, f)
If you want to do this on a large code base, you may want to run glimpse
or idutils on it first to improve efficiency. For glimpse, there is
coccinelle/scripts/glimpseindex_cocci.sh to use the right options. Then
run coccinelle with --use-glimpse. Glimpse is not free software though.
I guess you just run it in the normal way and then use the option
--use-idutils with spatch.
julia
_______________________________________________
Cocci mailing list
[email protected]
http://lists.diku.dk/mailman/listinfo/cocci
(Web access from inside DIKUs LAN only)