A CIL Tutorial - Department of Computer Science - ETH Zürich
A CIL Tutorial - Department of Computer Science - ETH Zürich A CIL Tutorial - Department of Computer Science - ETH Zürich
CHAPTER 1. THE AST 12 1.1 tut1.ml The function tut1FixInstr returns false if the instruction i is an assignment to a global variable called deleted. Otherwise it returns true. We'll be using this function as an argument to List.filter. let tut1FixInstr (i : instr) : bool = match i with | Set((Var vi, NoOffset), , loc) when vi.vname = "deleted" ∧ vi.vglob → E.log "%a: Deleted assignment: %a\n" d loc loc d instr i; false | → true The tut1FixStmt function inspects a statement. If the statement is a list of instructions, it overwrites the mutable skind eld of the statement with a list of instructions ltered by tut1FixInstr. Otherwise, it recursively descends into sub-statements. let rec tut1FixStmt (s : stmt) : unit = match s.skind with | Instr il → s.skind ← Instr(List.filter tut1FixInstr il) | If( , tb, fb, ) → tut1FixBlock tb; tut1FixBlock fb (∗ and so forth.∗) | → () and tut1FixBlock (b : block) : unit = List.iter tut1FixStmt b.bstmts let tut1FixFunction (fd : fundec) : unit = tut1FixBlock fd.sbody Now that we have dened a set of functions for traversing the AST of a function denition, we can write a function for the entry point into this module that iterates over all of the globals of a le. When we nd the function called target we invoke tut1FixFunction. let tut1 (f : file) : unit = List.iter (fun g → match g with | GFun (fd, loc) when fd.svar.vname = "target" → tut1FixFunction fd | → ()) f.globals
CHAPTER 1. THE AST 13 1.2 Printing the AST The function tut1FixInstr also uses CIL's logging and pretty-printing features. The call to E.log causes messages to be printed to stdout. It is similar to Printf.printf from the OCaml standard library with a few dierences that are documented in cil/ocamlutil/errormsg.mli. Most importantly, you can print elements of the CIL AST by using the %a format specier. Then, corresponding to that format you must supply two arguments: a function (unit → α → doc), and such an α that you want to print. Functions like this for the AST elements are dened in cil.ml (e.g. Cil.d exp for Cil.exp's). Functions for building objects of type doc are available in the Pretty module documented in cil/ocamlutil/pretty.mli. 1.3 test/tut1.c The module tut1.ml deletes writes inside functions named target to global variables named deleted. Thus, the function target below will return 37. # include int deleted = 37; ../test/tut1.c int target() { int l; deleted = 0; l = deleted; return l; } int main() { int r; r = target(); printf("r = %d\n", r); return 0; } We can build this le with the following command: $ ciltutcc --enable-tut1 -o tut1 test/tut1.c test/tut1.c:14: Deleted assignment: #line 14 "test/tut1.c" deleted = 0; Using the log message emitted by tut1FixInstr, ciltutcc informs us that it has removed an assignment to deleted. Now, we can run the resulting program:
- Page 1 and 2: A CIL Tutorial Using CIL for langua
- Page 3 and 4: Contents Preface 4 Introduction 5 0
- Page 5 and 6: CONTENTS 3 13 Whole-program Analysi
- Page 7 and 8: Introduction The C Intermediate Lan
- Page 9 and 10: References [1] clang: a C language
- Page 11 and 12: CHAPTER 0. OVERVIEW AND ORGANIZATIO
- Page 13: Chapter 1 The AST The Concrete Synt
- Page 17 and 18: References [1] Andrew W. Appel. Mod
- Page 19 and 20: CHAPTER 2. VISITING THE AST 17 open
- Page 21 and 22: CHAPTER 2. VISITING THE AST 19 $ ci
- Page 23 and 24: Chapter 3 Dataow Analysis Dataow An
- Page 25 and 26: CHAPTER 3. DATAFLOW ANALYSIS 23 Cod
- Page 27 and 28: CHAPTER 3. DATAFLOW ANALYSIS 25 let
- Page 29 and 30: CHAPTER 3. DATAFLOW ANALYSIS 27 and
- Page 31 and 32: CHAPTER 3. DATAFLOW ANALYSIS 29 let
- Page 33 and 34: CHAPTER 3. DATAFLOW ANALYSIS 31 DoC
- Page 35 and 36: CHAPTER 3. DATAFLOW ANALYSIS 33 tes
- Page 37 and 38: References [1] Aws Albarghouthi, Ra
- Page 39 and 40: CHAPTER 4. INSTRUMENTATION 37 type
- Page 41 and 42: CHAPTER 4. INSTRUMENTATION 39 metho
- Page 43 and 44: CHAPTER 4. INSTRUMENTATION 41 $ cil
- Page 45 and 46: CHAPTER 5. INTERPRETED CONSTRUCTORS
- Page 47 and 48: CHAPTER 5. INTERPRETED CONSTRUCTORS
- Page 49 and 50: Chapter 6 Overriding Functions When
- Page 51 and 52: CHAPTER 6. OVERRIDING FUNCTIONS 49
- Page 53 and 54: References [1] Kumar Avijit, Pratee
- Page 55 and 56: CHAPTER 7. TYPE QUALIFIERS 53 let c
- Page 57 and 58: CHAPTER 7. TYPE QUALIFIERS 55 let w
- Page 59 and 60: CHAPTER 7. TYPE QUALIFIERS 57 $ cil
- Page 61 and 62: Chapter 8 Dependant Type Qualiers O
- Page 63 and 64: CHAPTER 8. DEPENDANT TYPE QUALIFIER
CHAPTER 1. THE AST 12<br />
1.1 tut1.ml<br />
The function tut1FixInstr returns false if the instruction i is an assignment to a global variable<br />
called deleted. Otherwise it returns true. We'll be using this function as an argument to<br />
List.filter.<br />
let tut1FixInstr (i : instr) : bool =<br />
match i with<br />
| Set((Var vi, NoOffset), , loc)<br />
when vi.vname = "deleted" ∧ vi.vglob →<br />
E.log "%a: Deleted assignment: %a\n" d loc loc d instr i;<br />
false<br />
| → true<br />
The tut1FixStmt function inspects a statement. If the statement is a list <strong>of</strong> instructions, it overwrites<br />
the mutable skind eld <strong>of</strong> the statement with a list <strong>of</strong> instructions ltered by tut1FixInstr.<br />
Otherwise, it recursively descends into sub-statements.<br />
let rec tut1FixStmt (s : stmt) : unit =<br />
match s.skind with<br />
| Instr il →<br />
s.skind ← Instr(List.filter tut1FixInstr il)<br />
| If( , tb, fb, ) →<br />
tut1FixBlock tb;<br />
tut1FixBlock fb<br />
(∗ and so forth.∗)<br />
| → ()<br />
and tut1FixBlock (b : block) : unit = List.iter tut1FixStmt b.bstmts<br />
let tut1FixFunction (fd : fundec) : unit = tut1FixBlock fd.sbody<br />
Now that we have dened a set <strong>of</strong> functions for traversing the AST <strong>of</strong> a function denition, we can<br />
write a function for the entry point into this module that iterates over all <strong>of</strong> the globals <strong>of</strong> a le.<br />
When we nd the function called target we invoke tut1FixFunction.<br />
let tut1 (f : file) : unit =<br />
List.iter (fun g →<br />
match g with<br />
| GFun (fd, loc) when fd.svar.vname = "target" →<br />
tut1FixFunction fd<br />
| → ())<br />
f.globals