ranjit jhala rupak majumdar

57
Ranjit Jhala Rupak Majumdar Bit-level Types for High-level Reasoning

Upload: tannar

Post on 16-Jan-2016

43 views

Category:

Documents


0 download

DESCRIPTION

Bit -level Types. for. High -level Reasoning. Ranjit Jhala Rupak Majumdar. The Problem. mget (u32 p) { if (p & 0x1 == 0){ error(“permission”); } pte = (p & 0xFFFFF000)>> 12; b = tab[pte] & 0xFFFFFFFC; o = p & 0xFFC; return m[(b+o)>>2]; }. - PowerPoint PPT Presentation

TRANSCRIPT

Page 1: Ranjit Jhala                    Rupak Majumdar

Ranjit Jhala Rupak Majumdar

Bit-level Types for

High-level Reasoning

Page 2: Ranjit Jhala                    Rupak Majumdar

The Problem

• Bit-level operators in low-level systems code• Why ?

– Interact with hardware – Reduce memory footprint

mget (u32 p) { if (p & 0x1 == 0){ error(“permission”); }

pte = (p & 0xFFFFF000)>> 12;

b = tab[pte] & 0xFFFFFFFC;

o = p & 0xFFC;

return m[(b+o)>>2];}

mget (u32 p) { if (p & 0x1 == 0){ error(“permission”); }

pte = (p & 0xFFFFF000)>> 12;

b = tab[pte] & 0xFFFFFFFC;

o = p & 0xFFC;

return m[(b+o)>>2];}

Page 3: Ranjit Jhala                    Rupak Majumdar

The Problem

• Bit-level operators in low-level systems code

• Inscrutable to humans, optimizers, verifiers

mget (u32 p) { if (p & 0x1 == 0){ error(“permission”); }

pte = (p & 0xFFFFF000)>> 12;

b = tab[pte] & 0xFFFFFFFC;

o = p & 0xFFC;

return m[(b+o)>>2];}

mget (u32 p) { if (p & 0x1 == 0){ error(“permission”); }

pte = (p & 0xFFFFF000)>> 12;

b = tab[pte] & 0xFFFFFFFC;

o = p & 0xFFC;

return m[(b+o)>>2];}

Page 4: Ranjit Jhala                    Rupak Majumdar

Whats going on ?

mget (u32 p) { if (p & 0x1 == 0){ error(“permission”); }

pte =(p & 0xFFFFF000)>>12;

b = tab[pte]& 0xFFFFFFFC;

o = p & 0xFFC;

return m[(b+o)>>2];}

mget (u32 p) { if (p & 0x1 == 0){ error(“permission”); }

pte =(p & 0xFFFFF000)>>12;

b = tab[pte]& 0xFFFFFFFC;

o = p & 0xFFC;

return m[(b+o)>>2];}

32

p

31 1

Page 5: Ranjit Jhala                    Rupak Majumdar

Whats going on ?

mget (u32 p) { if (p & 0x1 == 0){ error(“permission”); }

pte =(p & 0xFFFFF000)>>12;

b = tab[pte]& 0xFFFFFFFC;

o = p & 0xFFC;

return m[(b+o)>>2];}

mget (u32 p) { if (p & 0x1 == 0){ error(“permission”); }

pte =(p & 0xFFFFF000)>>12;

b = tab[pte]& 0xFFFFFFFC;

o = p & 0xFFC;

return m[(b+o)>>2];}

31 1

p

pte

12 20

20 11 120

Page 6: Ranjit Jhala                    Rupak Majumdar

Whats going on ?

mget (u32 p) { if (p & 0x1 == 0){ error(“permission”); }

pte =(p & 0xFFFFF000)>>12;

b = tab[pte]& 0xFFFFFFFC;

o = p & 0xFFC;

return m[(b+o)>>2];}

mget (u32 p) { if (p & 0x1 == 0){ error(“permission”); }

pte =(p & 0xFFFFF000)>>12;

b = tab[pte]& 0xFFFFFFFC;

o = p & 0xFFC;

return m[(b+o)>>2];}

p

pte

20 11 1

12 20

32

tab[pte]

Page 7: Ranjit Jhala                    Rupak Majumdar

Whats going on ?

mget (u32 p) { if (p & 0x1 == 0){ error(“permission”); }

pte =(p & 0xFFFFF000)>>12;

b = tab[pte]& 0xFFFFFFFC;

o = p & 0xFFC;

return m[(b+o)>>2];}

mget (u32 p) { if (p & 0x1 == 0){ error(“permission”); }

pte =(p & 0xFFFFF000)>>12;

b = tab[pte]& 0xFFFFFFFC;

o = p & 0xFFC;

return m[(b+o)>>2];}

p

pte

20 11 1

12 20

b

30 2

20 10 11

o

1012 2

Page 8: Ranjit Jhala                    Rupak Majumdar

Whats going on ?

mget (u32 p) { if (p & 0x1 == 0){ error(“permission”); }

pte =(p & 0xFFFFF000)>>12;

b = tab[pte]& 0xFFFFFFFC;

o = p & 0xFFC;

return m[(b+o)>>2];}

mget (u32 p) { if (p & 0x1 == 0){ error(“permission”); }

pte =(p & 0xFFFFF000)>>12;

b = tab[pte]& 0xFFFFFFFC;

o = p & 0xFFC;

return m[(b+o)>>2];}

p

pte

12 20

b

30 2

20 10 11

o

1020 2

Page 9: Ranjit Jhala                    Rupak Majumdar

Q: How to infer complex information flow to understand, optimize, verify code ?

mget (u32 p) { if (p & 0x1 == 0){ error(“permission”); }

pte =(p & 0xFFFFF000)>>12;

b = tab[pte]& 0xFFFFFFFC;

o = p & 0xFFC;

return m[(b+o)>>2];}

mget (u32 p) { if (p & 0x1 == 0){ error(“permission”); }

pte =(p & 0xFFFFF000)>>12;

b = tab[pte]& 0xFFFFFFFC;

o = p & 0xFFC;

return m[(b+o)>>2];}

p

pte

12 20

b

30 2

20 10 11

o

1020 2

Page 10: Ranjit Jhala                    Rupak Majumdar

Plan

• Motivation

• Approach

Page 11: Ranjit Jhala                    Rupak Majumdar

Our approach: (1) Bit-level Types

p

pte

12 20

b

30 2

20 10 11

o

1020 2

p : {idx,20}{addr,10}{wr,1}{rd,1}

pte : {;,12}{idx,20}

b : {addr,30}{;,2}

o : {;,20}{addr,10}{;,2}

Bit-level TypesSequences of {name,size} pairs

Page 12: Ranjit Jhala                    Rupak Majumdar

Our approach: (2) Translation

p

pte

12 20

b

30 2

20 10 11

o

1020 2

p : {idx,20}{addr,10}{wr,1}{rd,1}

pte : {;,20}{idx,10}

b : {addr,30}{;,2}

o : {;,20}{addr,10}{;,2}

mget (p) { if (p & 0x1 == 0){ error(“permission”); }

pte =(p & 0xFFFFF000)>>12;

b = tab[pte]& 0xFFFFFFFC;

o = p & 0xFFC;

return m[(b+o)>>2];}

mget (p) { if (p & 0x1 == 0){ error(“permission”); }

pte =(p & 0xFFFFF000)>>12;

b = tab[pte]& 0xFFFFFFFC;

o = p & 0xFFC;

return m[(b+o)>>2];}

Expressions ! RecordsBit-ops ! Field accesses

if (p.rd == 0){

Page 13: Ranjit Jhala                    Rupak Majumdar

Our approach: (2) Translation

p

pte

12 20

b

30 2

20 10 11

o

1020 2

p : {idx,20}{addr,10}{wr,1}{rd,1}

pte : {;,20}{idx,10}

b : {addr,30}{;,2}

o : {;,20}{addr,10}{;,2}

mget (p) { if (p & 0x1 == 0){ error(“permission”); }

pte =(p & 0xFFFFF000)>>12;

b = tab[pte]& 0xFFFFFFFC;

o = p & 0xFFC;

return m[(b+o)>>2];}

mget (p) { if (p & 0x1 == 0){ error(“permission”); }

pte =(p & 0xFFFFF000)>>12;

b = tab[pte]& 0xFFFFFFFC;

o = p & 0xFFC;

return m[(b+o)>>2];}

if (p.rd == 0){

Expressions ! RecordsBit-ops ! Field accesses

Page 14: Ranjit Jhala                    Rupak Majumdar

mget (p) { if (p & 0x1 == 0){ error(“permission”); }

pte =(p & 0xFFFFF000)>>12;

b = tab[pte]& 0xFFFFFFFC;

o = p & 0xFFC;

return m[(b+o)>>2];}

mget (p) { if (p & 0x1 == 0){ error(“permission”); }

pte =(p & 0xFFFFF000)>>12;

b = tab[pte]& 0xFFFFFFFC;

o = p & 0xFFC;

return m[(b+o)>>2];}

if (p.rd == 0){

Our approach: (2) Translation

p

pte

12 20

b

30 2

20 10 11

o

1020 2

p : {idx,20}{addr,10}{wr,1}{rd,1}

pte : {;,20}{idx,10}

b : {addr,30}{;,2}

o : {;,20}{addr,10}{;,2}

pte.idx = p.idx;

Expressions ! RecordsBit-ops ! Field accesses

Page 15: Ranjit Jhala                    Rupak Majumdar

Our approach: (2) Translation

p

pte

12 20

b

30 2

20 10 11

o

1020 2

p : {idx,20}{addr,10}{wr,1}{rd,1}

pte : {;,20}{idx,10}

b : {addr,30}{;,2}

o : {;,20}{addr,10}{;,2}

mget (p) { if (p & 0x1 == 0){ error(“permission”); }

pte =(p & 0xFFFFF000)>>12;

b = tab[pte]& 0xFFFFFFFC;

o = p & 0xFFC;

return m[(b+o)>>2];}

mget (p) { if (p & 0x1 == 0){ error(“permission”); }

pte =(p & 0xFFFFF000)>>12;

b = tab[pte]& 0xFFFFFFFC;

o = p & 0xFFC;

return m[(b+o)>>2];}

if (p.rd == 0){

pte.idx = p.idx;

Expressions ! RecordsBit-ops ! Field accesses

Page 16: Ranjit Jhala                    Rupak Majumdar

mget (p) { if (p & 0x1 == 0){ error(“permission”); }

pte =(p & 0xFFFFF000)>>12;

b = tab[pte]& 0xFFFFFFFC;

o = p & 0xFFC;

return m[(b+o)>>2];}

mget (p) { if (p & 0x1 == 0){ error(“permission”); }

pte =(p & 0xFFFFF000)>>12;

b = tab[pte]& 0xFFFFFFFC;

o = p & 0xFFC;

return m[(b+o)>>2];}

if (p.rd == 0){

pte.idx = p.idx;

Our approach: (2) Translation

p

pte

12 20

b

30 2

20 10 11

o

1020 2

p : {idx,20}{addr,10}{wr,1}{rd,1}

pte : {;,20}{idx,10}

b : {addr,30}{;,2}

o : {;,20}{addr,10}{;,2} b.addr = tab[pte.idx].addr;

Expressions ! RecordsBit-ops ! Field accesses

Page 17: Ranjit Jhala                    Rupak Majumdar

Our approach: (2) Translation

p

pte

12 20

b

30 2

20 10 11

o

1020 2

p : {idx,20}{addr,10}{wr,1}{rd,1}

pte : {;,20}{idx,10}

b : {addr,30}{;,2}

o : {;,20}{addr,10}{;,2}

mget (p) { if (p & 0x1 == 0){ error(“permission”); }

pte =(p & 0xFFFFF000)>>12;

b = tab[pte]& 0xFFFFFFFC;

o = p & 0xFFC;

return m[(b+o)>>2];}

mget (p) { if (p & 0x1 == 0){ error(“permission”); }

pte =(p & 0xFFFFF000)>>12;

b = tab[pte]& 0xFFFFFFFC;

o = p & 0xFFC;

return m[(b+o)>>2];}

b.addr = tab[pte.idx].addr;

if (p.rd == 0){

pte.idx = p.idx;

Expressions ! RecordsBit-ops ! Field accesses

Page 18: Ranjit Jhala                    Rupak Majumdar

mget (p) { if (p & 0x1 == 0){ error(“permission”); }

pte =(p & 0xFFFFF000)>>12;

b = tab[pte]& 0xFFFFFFFC;

o = p & 0xFFC;

return m[(b+o)>>2];}

mget (p) { if (p & 0x1 == 0){ error(“permission”); }

pte =(p & 0xFFFFF000)>>12;

b = tab[pte]& 0xFFFFFFFC;

o = p & 0xFFC;

return m[(b+o)>>2];}

b.addr = tab[pte.idx].addr;

if (p.rd == 0){

pte.idx = p.idx;

Our approach: (2) Translation

p

pte

12 20

b

30 2

20 10 11

o

1020 2

p : {idx,20}{addr,10}{wr,1}{rd,1}

pte : {;,20}{idx,10}

b : {addr,30}{;,2}

o : {;,20}{addr,10}{;,2} o.addr = p.addr;

Expressions ! RecordsBit-ops ! Field accesses

Page 19: Ranjit Jhala                    Rupak Majumdar

Our approach: (2) Translation

p

pte

12 20

b

30 2

20 10 11

o

1020 2

p : {idx,20}{addr,10}{wr,1}{rd,1}

pte : {;,20}{idx,10}

b : {addr,30}{;,2}

o : {;,20}{addr,10}{;,2}

mget (p) { if (p & 0x1 == 0){ error(“permission”); }

pte =(p & 0xFFFFF000)>>12;

b = tab[pte]& 0xFFFFFFFC;

o = p & 0xFFC;

return m[(b+o)>>2];}

mget (p) { if (p & 0x1 == 0){ error(“permission”); }

pte =(p & 0xFFFFF000)>>12;

b = tab[pte]& 0xFFFFFFFC;

o = p & 0xFFC;

return m[(b+o)>>2];}

o.addr = p.addr;

b.addr = tab[pte.idx].addr;

if (p.rd == 0){

pte.idx = p.idx;

Expressions ! RecordsBit-ops ! Field accesses

Page 20: Ranjit Jhala                    Rupak Majumdar

mget (p) { if (p & 0x1 == 0){ error(“permission”); }

pte =(p & 0xFFFFF000)>>12;

b = tab[pte]& 0xFFFFFFFC;

o = p & 0xFFC;

return m[(b+o)>>2];}

mget (p) { if (p & 0x1 == 0){ error(“permission”); }

pte =(p & 0xFFFFF000)>>12;

b = tab[pte]& 0xFFFFFFFC;

o = p & 0xFFC;

return m[(b+o)>>2];}

o.addr = p.addr;

b.addr = tab[pte.idx].addr;

if (p.rd == 0){

pte.idx = p.idx;

Our approach: (2) Translation

p

pte

12 20

b

30 2

20 10 11

o

1020 2

p : {idx,20}{addr,10}{wr,1}{rd,1}

pte : {;,20}{idx,10}

b : {addr,30}{;,2}

o : {;,20}{addr,10}{;,2} return m[b.addr + o.addr];

Expressions ! RecordsBit-ops ! Field accesses

Page 21: Ranjit Jhala                    Rupak Majumdar

Our approach: (2) Translation

p

pte

12 20

b

30 2

20 10 11

o

1020 2

p : {idx,20}{addr,10}{wr,1}{rd,1}

pte : {;,20}{idx,10}

b : {addr,30}{;,2}

o : {;,20}{addr,10}{;,2}

mget (p) { if (p & 0x1 == 0){ error(“permission”); }

pte =(p & 0xFFFFF000)>>12;

b = tab[pte]& 0xFFFFFFFC;

o = p & 0xFFC;

return m[(b+o)>>2];}

mget (p) { if (p & 0x1 == 0){ error(“permission”); }

pte =(p & 0xFFFFF000)>>12;

b = tab[pte]& 0xFFFFFFFC;

o = p & 0xFFC;

return m[(b+o)>>2];}

o.addr = p.addr;

return m[b.addr + o.addr];

b.addr = tab[pte.idx].addr;

if (p.rd == 0){

pte.idx = p.idx;

Expressions ! RecordsBit-ops ! Field accesses

Page 22: Ranjit Jhala                    Rupak Majumdar

Our approach

mget(p) { if (p & 0x1 == 0){ error(“permission”); }

pte =(p & 0xFFFFF000)>>12;

b = tab[pte]& 0xFFFFFFFC;

o = p & 0xFFC;

return m[(b+o)>>2];}

mget(p) { if (p & 0x1 == 0){ error(“permission”); }

pte =(p & 0xFFFFF000)>>12;

b = tab[pte]& 0xFFFFFFFC;

o = p & 0xFFC;

return m[(b+o)>>2];}

Low-level operations eliminated bit-level types + translation

o.addr = p.addr;

return m[b.addr + o.addr];

b.addr = tab[pte.idx].addr;

if (p.rd == 0){

pte.idx = p.idx;

Program can be understood, optimized, verified

Page 23: Ranjit Jhala                    Rupak Majumdar

Plan• Motivation

• Approach – Bit-level types + Translation

• Key: Bit-level type Inference

• Experiences

• Related work

Page 24: Ranjit Jhala                    Rupak Majumdar

Constraint-based Type InferenceAlgorithm:0. Variables for unknowns1. Generate constraints on vars2. Solve constraints

2a = b – 10b = 2006 - 1952

Alice’s age: a Bob’s age: b

= 22= 54

Remember these: If Alice doubles her age, she would still be

10 years younger than Bob, who was born in 1952. How old are Alice and Bob ?

Page 25: Ranjit Jhala                    Rupak Majumdar

Constraint-based Type InferenceAlgorithm:

0. Variables for unknown• bit-level types of all program expressions

1. Generate constraints on vars

2. Solve constraints

Page 26: Ranjit Jhala                    Rupak Majumdar

Plan• Motivation

• Approach – Bit-level types + Translation

• Key: Bit-level type Inference– Constraint Generation– Constraint Solving

• Experiences

• Related work

Page 27: Ranjit Jhala                    Rupak Majumdar

Constraint Generation

Type variables for each

expression: p p p&0x1 p&0x1 pte pte

mget (p) { if (p & 0x1 == 0){ error(“permission”); }

pte =(p & 0xFFFFF000)>>12;

b = tab[pte]& 0xFFFFFFFC;

o = p & 0xFFC;

return m[(b+o)>>2];}

mget (p) { if (p & 0x1 == 0){ error(“permission”); }

pte =(p & 0xFFFFF000)>>12;

b = tab[pte]& 0xFFFFFFFC;

o = p & 0xFFC;

return m[(b+o)>>2];}

Page 28: Ranjit Jhala                    Rupak Majumdar

Generating Zero Constraints

Mask:

p&0xFFC[31:12] = ;

p&0xFFC[1:0] = ;

mget (p) { if (p & 0x1 == 0){ error(“permission”); }

pte =(p & 0xFFFFF000)>>12;

b = tab[pte]& 0xFFFFFFFC;

o = p & 0xFFC;

return m[(b+o)>>2];}

mget (p) { if (p & 0x1 == 0){ error(“permission”); }

pte =(p & 0xFFFFF000)>>12;

b = tab[pte]& 0xFFFFFFFC;

o = p & 0xFFC;

return m[(b+o)>>2];}

020 02

1231 1 0

Page 29: Ranjit Jhala                    Rupak Majumdar

Generating Zero Constraints

012mget (p) { if (p & 0x1 == 0){ error(“permission”); }

pte =(p & 0xFFFFF000)>>12;

b = tab[pte]& 0xFFFFFFFC;

o = p & 0xFFC;

return m[(b+o)>>2];}

mget (p) { if (p & 0x1 == 0){ error(“permission”); }

pte =(p & 0xFFFFF000)>>12;

b = tab[pte]& 0xFFFFFFFC;

o = p & 0xFFC;

return m[(b+o)>>2];}

Shift:

e>>12[31:20]= ;

e is p&0xFFFFF000

2031

Page 30: Ranjit Jhala                    Rupak Majumdar

Why are zeros special ?Consider assignment (value flows e to x)

Should x and e have same bit-level type?

x = e

K

K +

Common idiom: k-bit values special case of k+-bit values• Equality results in unnecessary breaks• Zeros enable precise subtyping

subtypes(·)

·

x

e

Inequality constraint

x ¸ e

Page 31: Ranjit Jhala                    Rupak Majumdar

Generating Inequality Constraints

Mask:

p&0xFFC[11:2] ¸ p[11:2]

mget (p) { if (p & 0x1 == 0){ error(“permission”); }

pte =(p & 0xFFFFF000)>>12;

b = tab[pte]& 0xFFFFFFFC;

o = p & 0xFFC;

return m[(b+o)>>2];}

mget (p) { if (p & 0x1 == 0){ error(“permission”); }

pte =(p & 0xFFFFF000)>>12;

b = tab[pte]& 0xFFFFFFFC;

o = p & 0xFFC;

return m[(b+o)>>2];}

020 02

11 2

Page 32: Ranjit Jhala                    Rupak Majumdar

Shift:

e>>12[19:0] ¸ e[31:12]

012

Generating Inequality Constraints

mget (p) { if (p & 0x1 == 0){ error(“permission”); }

pte =(p & 0xFFFFF000)>>12;

b = tab[pte]& 0xFFFFFFFC;

o = p & 0xFFC;

return m[(b+o)>>2];}

mget (p) { if (p & 0x1 == 0){ error(“permission”); }

pte =(p & 0xFFFFF000)>>12;

b = tab[pte]& 0xFFFFFFFC;

o = p & 0xFFC;

return m[(b+o)>>2];}

19

31 12

0

e

e>>12

Page 33: Ranjit Jhala                    Rupak Majumdar

Generating Inequality Constraints

Assignment:

o ¸p&0xFFC

that is…

o[31:0] ¸ p&0xFFC[31:0]

mget (p) { if (p & 0x1 == 0){ error(“permission”); }

pte =(p & 0xFFFFF000)>>12;

b = tab[pte]& 0xFFFFFFFC;

o = p & 0xFFC;

return m[(b+o)>>2];}

mget (p) { if (p & 0x1 == 0){ error(“permission”); }

pte =(p & 0xFFFFF000)>>12;

b = tab[pte]& 0xFFFFFFFC;

o = p & 0xFFC;

return m[(b+o)>>2];}

Page 34: Ranjit Jhala                    Rupak Majumdar

Plan• Motivation

• Approach – Bit-level types + Translation

• Key: Bit-level type Inference– Constraint Generation– Constraint Solving

• Experiences

• Related work

Page 35: Ranjit Jhala                    Rupak Majumdar

Constraint SolutionsSolution is an assignment • A: type variables ! bit-level typesA()[i:j] = subsequence of A() from bit i

through j

20 10 11

p)= {idx,20}{addr,10}{wr,1}{rd,1}

• A(p)[12:1] = {addr,10} {wr,1}

• A(p)[31:2] = {idx,20} {addr,10}

• A(p)[31:5] = undefined

12 131 25

Page 36: Ranjit Jhala                    Rupak Majumdar

Constraint Solving OverviewSolution is an assignment • A: type variables ! bit-level types

A([i:j]) = subsequence from bit i through j

A satisfies:• zero Constraint : [i:j] = ;

– If A()[i:j] = ;i-j+1

• inequality Constraint: [i:j] · ’[i’:j’]– If A()[i:j] · A(’)[i’:j’]

• In both cases, A()[i:j] must be defined

Page 37: Ranjit Jhala                    Rupak Majumdar

Constraint Solving AlgorithmInput: Zero constraints {z_1,…,z_m}

Inequality constraints {c1,…,cn}

Output: Assignment satisfying all constraints

A = A0

for i in [1…n]:A = refine(A,ci)

return A

A0 = Initial asgn satisfying zero constraints (details in paper)

refine(A,ci) adjusts A such that:

• ci becomes satisfied

• earlier constraints stay satisfied • built using Split, Unify

Page 38: Ranjit Jhala                    Rupak Majumdar

Refine: Split(A,,k)

f,12

A() p,3212

A’()

A’ = Split(A,,12)

Throughout A, substitute:

p,12 + 12

f,12e,

where e , f are fresh

e,20

p,12-

f,12-

and substitute:

Page 39: Ranjit Jhala                    Rupak Majumdar

Refine: Split(A,,k)• Used to ensure A()[i:j] is defined

2

f,12

g,10

A() p,3211+1

A’()

A’’() e,20 h,2

e,20

A’ = Split(A,,12)

Ensure A([11:2] is defined

A’’ = Split(A’,,2)

11

11 2

A’’([11:2] defined

Page 40: Ranjit Jhala                    Rupak Majumdar

Refine: Unify(A,p,q)

p,

q,

Throughout A, substitute:

Page 41: Ranjit Jhala                    Rupak Majumdar

Refine(A, [31:12] · ’[19:0])

r :12

A(’) p : 32

A() ; :10 q :10

A(’)[19:0] undefined

A’ = Split(A,’,19+1)

A’’ = Unify(A’,q,t)

1231

019

r : 12

A’(’) t : 20

A’() ; :10 q :10

s : 12

1231

019

r : 12

A’’(’) t : 32

A’’() ; :10 t :10

A’’ satisfies constraint

t : 32

1231

019

A’(’)[19:0]

A’()[31:12] ·

Page 42: Ranjit Jhala                    Rupak Majumdar

Constraint SolvingInput: ConstraintsOutput: Assignment satisfying all constraints

A = A0

for i in [1…n]:A = refine(A,ci)

return A

Substitution (in Split, Unify)• ensures earlier constraints stay satisfied• most general solution found• Efficiently implemented using graphs

Page 43: Ranjit Jhala                    Rupak Majumdar

Plan• Motivation

• Approach – Bit-level types + Translation

• Key: Bit-level type Inference– Constraint Generation– Constraint Solving

• Experiences

• Related work

Page 44: Ranjit Jhala                    Rupak Majumdar

Experiences

Implemented bit-level type inference for C

• pmap: a kernel virtual memory system• Implements the code for our running example

• mondrian: a memory protection system

• scull: a linux device driver (1-3 Kloc)

• Inference/Translation takes less than 1s

Page 45: Ranjit Jhala                    Rupak Majumdar

Mondrian [Witchel et. al.]

• Bit packing for memory and permission bits– 2600 lines of code, generated 775 constraints– Translated to program without bit-operations– 18 different bit-packed structures

• 10 assertions provided by programmer– After translation, assertions verified using BLAST– 6 safe: all require bit-level reasoning

• Previously, verification was not possible

– 4 false positives: imprecise modeling of arrays

Page 46: Ranjit Jhala                    Rupak Majumdar

Cop outs (i.e. Future Work)1. Truly binary bit-vector operations

– x << y, x && y– Currently: Value-flow analysis to infer constants flowing

to y Break into a switch statement

2. Flow-sensitivity• Currently: SSA renaming

3. Arithmetic overflow• does a k-bit value “spill over”• Currently: Assume no overflow

4. Path-sensitivity (value dependent types)• Type of suffix depends on value of first field• e.g. Instruction decoder for architecture simulator

• Number/type of operands depends on opcode

Page 47: Ranjit Jhala                    Rupak Majumdar

Plan• Motivation

• Approach – Bit-level types + Translation

• Key: Bit-level type Inference– Constraint Generation– Constraint Solving

• Experiences

• Related work

Page 48: Ranjit Jhala                    Rupak Majumdar

Related Work• O Callahan – Jackson [ICSE 97]

– Type Inference

• Gupta et. al. [POPL 03, CC02] – Dataflow analyses for packing bit-sections

• Ramalingam et. al. [POPL 99] – Aggregate structure inference for COBOL

Page 49: Ranjit Jhala                    Rupak Majumdar

Conclusions• (Automatic) reasoning about Bit-operations hard

• Structure: bit-operations pack data into one word

• Structure Inferred via Bit-level Type Inference

• Structure Exploited via Translation to fields

• Precise, efficient reasoning about Bit-operations

Page 50: Ranjit Jhala                    Rupak Majumdar

Thank youThank you

Page 51: Ranjit Jhala                    Rupak Majumdar

Previous approaches model bitwise ops by:

1. Uninterpreted functions • Imprecise

2. Logical axioms • Inefficient

3. Bit-blasting terms into 32/64-bits• Lose high-level relationships

Q: How to infer complex information flow to understand, optimize, verify code ?

Page 52: Ranjit Jhala                    Rupak Majumdar

Refine• Two basic operations: split, unify• Split(A,,[i:j]): ensures A()[i:j] is defined

2

f : 12

g : 10

A() p : 32

11+1

A’()

A’’() e : 20 h:2

Split(A,,[11:2])A’ = in A, substitute:

p : +(11+1)

11+1

f : 11+1e :

where e , f are freshe : 20

A’’ = in A’, substitute:

f : +2 h : 2g :

where g,h are fresh

2

Page 53: Ranjit Jhala                    Rupak Majumdar

Our approach: (2) Translation

p

pte

12 20

b

30 2

20 10 11

o

1020 2

p : {idx,20}{addr,10}{wr,1}{rd,1}

pte : {;,20}{idx,10}

b : {addr,30}{;,2}

o : {;,20}{addr,10}{;,2}

mget (p) { if (p & 0x1 == 0){ error(“permission”); }

pte =(p & 0xFFFFF000)>>12;

b = tab[pte]& 0xFFFFFFFC;

o = p & 0xFFC;

return m[(b+o)>>2];}

mget (p) { if (p & 0x1 == 0){ error(“permission”); }

pte =(p & 0xFFFFF000)>>12;

b = tab[pte]& 0xFFFFFFFC;

o = p & 0xFFC;

return m[(b+o)>>2];}

• Expressions ! Records• Bit-ops ! Field accesses

if (p.rd == 0){

pte.idx = p.idx;

b.addr = tab[pte.idx].addr;

o.addr = p.addr;

return m[o.addr + p.addr];

Page 54: Ranjit Jhala                    Rupak Majumdar

Our approach: (2) Translation

p

pte

12 20

b

30 2

20 10 11

o

1020 2

p : {idx,20}{addr,10}{wr,1}{rd,1}

pte : {;,20}{idx,10}

b : {addr,30}{;,2}

o : {;,20}{addr,10}{;,2}

mget (p) { if (p & 0x1 == 0){ error(“permission”); }

pte =(p & 0xFFFFF000)>>12;

b = tab[pte]& 0xFFFFFFFC;

o = p & 0xFFC;

return m[(b+o)>>2];}

mget (p) { if (p & 0x1 == 0){ error(“permission”); }

pte =(p & 0xFFFFF000)>>12;

b = tab[pte]& 0xFFFFFFFC;

o = p & 0xFFC;

return m[(b+o)>>2];}

• Expressions ! Records• Bit-ops ! Field accesses

if (p.rd == 0){

Page 55: Ranjit Jhala                    Rupak Majumdar

Our approach: (2) Translation

p

pte

12 20

b

30 2

20 10 11

o

1020 2

p : {idx,20}{addr,10}{wr,1}{rd,1}

pte : {;,20}{idx,10}

b : {addr,30}{;,2}

o : {;,20}{addr,10}{;,2}

mget (p) { if (p & 0x1 == 0){ error(“permission”); }

pte =(p & 0xFFFFF000)>>12;

b = tab[pte]& 0xFFFFFFFC;

o = p & 0xFFC;

return m[(b+o)>>2];}

mget (p) { if (p & 0x1 == 0){ error(“permission”); }

pte =(p & 0xFFFFF000)>>12;

b = tab[pte]& 0xFFFFFFFC;

o = p & 0xFFC;

return m[(b+o)>>2];}

• Expressions ! Records• Bit-ops ! Field accesses

if (p.rd == 0){

pte.idx = p.idx;

b.addr = tab[pte.idx].addr;

o.addr = p.addr;

return m[o.addr + p.addr];

Page 56: Ranjit Jhala                    Rupak Majumdar

Our approach: (2) Translation

p

pte

12 20

b

30 2

20 10 11

o

1020 2

p : {idx,20}{addr,10}{wr,1}{rd,1}

pte : {;,20}{idx,10}

b : {addr,30}{;,2}

o : {;,20}{addr,10}{;,2}

mget (p) { if (p & 0x1 == 0){ error(“permission”); }

pte =(p & 0xFFFFF000)>>12;

b = tab[pte]& 0xFFFFFFFC;

o = p & 0xFFC;

return m[(b+o)>>2];}

mget (p) { if (p & 0x1 == 0){ error(“permission”); }

pte =(p & 0xFFFFF000)>>12;

b = tab[pte]& 0xFFFFFFFC;

o = p & 0xFFC;

return m[(b+o)>>2];}

• Expressions ! Records• Bit-ops ! Field accesses

if (p.rd == 0){

pte.idx = p.idx;

b.addr = tab[pte.idx].addr;

o.addr = p.addr;

return m[o.addr + p.addr];

Page 57: Ranjit Jhala                    Rupak Majumdar

Constraint SolutionsSolution is an assignment • A: variables ! bit-level typesA()[i:j] = subsequence of A() from bit i

through j

20 10 11

p)= {idx,20}{addr,10}{wr,1}{rd,1}

• A(p)[12:1] = {addr,10} {wr,1}

• A(p)[31:2] = {idx,20} {addr,10}

• A(p)[31:5] = undefined

12 131 25