Towards Shape Analysis for Device Drivers

Download Report

Transcript Towards Shape Analysis for Device Drivers

Footprint Analysis: A Shape Analysis
that Discovers Preconditions
Hongseok Yang
(Queen Mary, University of London)
(Joint work with Cristiano Calcagno, Dino Distefano,
and Peter O’Hearn)
void XXX_CancelIrp(PDEVICE_OBJECT
void XXX_CancelIrp(PDEVICE_OBJECT
DeviceObject, PIRP DeviceObject,
Irp)
{
………
PRESET_IRP
ResetIrp,temp,tempnext;
PDEVICE_EXTENSION de;
………
KeAcquireSpinLock(&de->ResetSpinLock,
&Irql);
KeAcquireSpinLock(&de->ResetSpinLock,
&Irql);
ResetIrp = (PRESET_IRP)de->Flink2;
while (ResetIrp !=NULL) {
if (ResetIrp->Irp == Irp) {
temp = (PRESET_IRP)de;
tempnext = temp->Flink2;
while (tempnext != ResetIrp) {
temp = tempnext; tempnext = temp->Flink2;
}
temp->Flink2 = ResetIrp->Flink2;
free(ResetIrp);
break;
}
else if (ResetIrp->Flink2 == (PRESET_IRP)de) break;
else ResetIrp = (PRESET_IRP)ResetIrp->Flink2;
}
KeReleaseSpinLock(&de->ResetSpinLock,
Irql);
KeReleaseSpinLock(&de->ResetSpinLock,
Irql);
……
IoCompleteRequest(Irp,
IO_NO_INCREMENT);
IoCompleteRequest(Irp,
IO_NO_INCREMENT);
}
PIRP Irp)
void XXX_CancelIrp(PDEVICE_OBJECT DeviceObject, PIRP Irp)
{
………
PRESET_IRP
ResetIrp,temp,tempnext;
PDEVICE_EXTENSION de;
………
KeAcquireSpinLock(&de->ResetSpinLock, &Irql);
ResetIrp = (PRESET_IRP)de->Flink2;
while (ResetIrp !=NULL) {
if (ResetIrp->Irp == Irp) {
temp = (PRESET_IRP)de;
tempnext = temp->Flink2;
while (tempnext != ResetIrp) {
temp = tempnext; tempnext = temp->Flink2;
}
temp->Flink2 = ResetIrp->Flink2;
free(ResetIrp);
break;
}
else if (ResetIrp->Flink2 == (PRESET_IRP)de) break;
else ResetIrp = (PRESET_IRP)ResetIrp->Flink2;
}
KeReleaseSpinLock(&de->ResetSpinLock, Irql);
……
IoCompleteRequest(Irp, IO_NO_INCREMENT);
}
Footprint Analysis
• Discovers safe preconditions of a piece
of code.
• Only the memory footprint of the code.
void XXX_CancelIrp(PDEVICE_OBJECT DeviceObject, PIRP Irp)
{
………
PRESET_IRP
ResetIrp,temp,tempnext;
PDEVICE_EXTENSION de;
………
KeAcquireSpinLock(&de->ResetSpinLock, &Irql);
ResetIrp = (PRESET_IRP)de->Flink2;
while (ResetIrp !=NULL) {
if (ResetIrp->Irp == Irp) {
temp = (PRESET_IRP)de;
tempnext = temp->Flink2;
while (tempnext != ResetIrp) {
temp = tempnext; tempnext = temp->Flink2;
}
temp->Flink2 = ResetIrp->Flink2;
free(ResetIrp);
break;
}
else if (ResetIrp->Flink2 == (PRESET_IRP)de) break;
else ResetIrp = (PRESET_IRP)ResetIrp->Flink2;
}
KeReleaseSpinLock(&de->ResetSpinLock, Irql);
……
IoCompleteRequest(Irp, IO_NO_INCREMENT);
}
(de aD Flink2:0)
void XXX_CancelIrp(PDEVICE_OBJECT DeviceObject, PIRP Irp)
{(de a Flink2: x ) * ls (RESET_IRP,Flink2) (x ,0)
D
0
0
………
(de
aD Flink2: XXXResetIrp,temp,tempnext;
x0) * ls (RESET_IRP,Flink2) (x0,de)
de)
PXXX_RESET_IRP
PDEVICE_EXTENSION deviceExtension;
(de
aD Flink2: x0) * ls (RESET_IRP,Flink2) (x0,x1) *
………
KeAcquireSpinLock(&deviceExtension->ResetSpinLock, &Irql);
ResetIrp = (PRESET_IRP)de->Flink2;
while (ResetIrp !=NULL) {
if (ResetIrp->Irp == Irp) {
temp = (PRESET_IRP)de;
tempnext = temp->Flink2;
while (tempnext != ResetIrp) {
temp = tempnext; tempnext = temp->Flink2;
}
temp->Flink2 = ResetIrp->Flink2;
free(ResetIrp);
break;
}
else if (ResetIrp->Flink2 == (PRESET_IRP)de) break;
else ResetIrp = (PRESET_IRP)ResetIrp->Flink2;
}
typedef struct {
KeReleaseSpinLock(&deviceExtension->ResetSpinLock, Irql);
typedef struct {
RESET_IRP* Flink2;
……
RESET_IRP* Flink2;
Irp;
IoCompleteRequest(Irp, IO_NO_INCREMENT); IRP*
} …
…
} DEVICE_EXTENSION;
(x1aR Irp:Irp)
} RESET_IRP, *PRESET_IRP;
(de aD Flink2:0)
void XXX_CancelIrp(PDEVICE_OBJECT DeviceObject, PIRP Irp)
{(de a Flink2: x ) * ls (RESET_IRP,Flink2) (x ,0)
D
0
0
………
(de
aD Flink2: XXXResetIrp,temp,tempnext;
x0) * ls (RESET_IRP,Flink2) (x0,de)
de)
PXXX_RESET_IRP
PDEVICE_EXTENSION deviceExtension;
(de
aD Flink2: x0) * ls (RESET_IRP,Flink2) (x0,x1) * (x1aR Irp:Irp)
………
KeAcquireSpinLock(&deviceExtension->ResetSpinLock, &Irql);
ResetIrp = (PRESET_IRP)de->Flink2;
de aD Flink2: de
while (ResetIrp !=NULL) {
if (ResetIrp->Irp == Irp) {
temp = (PRESET_IRP)de;
tempnext = temp->Flink2;
while (tempnext != ResetIrp) {
temp = tempnext; tempnext = temp->Flink2;
}
temp->Flink2 = ResetIrp->Flink2;
free(ResetIrp);
break;
}
else if (ResetIrp->Flink2 == (PRESET_IRP)de) break;
else ResetIrp = (PRESET_IRP)BusResetIrp->Flink2;
}
typedef struct {
KeReleaseSpinLock(&deviceExtension->ResetSpinLock, Irql);
typedef struct {
RESET_IRP* Flink2;
……
RESET_IRP* Flink2;
Irp;
IoCompleteRequest(Irp, IO_NO_INCREMENT); IRP*
} …
…
} DEVICE_EXTENSION;
} RESET_IRP, *PRESET_IRP;
(de aD Flink2:0)
void XXX_CancelIrp(PDEVICE_OBJECT DeviceObject, PIRP Irp)
{(de a Flink2: x ) * ls (RESET_IRP,Flink2) (x ,0)
D
0
0
………
(de
aD Flink2: XXXResetIrp,temp,tempnext;
x0) * ls (RESET_IRP,Flink2) (x0,de)
de)
PXXX_RESET_IRP
PDEVICE_EXTENSION deviceExtension;
(de
aD Flink2: x0) * ls (RESET_IRP,Flink2) (x0,x1) * (x1aR Irp:Irp)
………
KeAcquireSpinLock(&deviceExtension->ResetSpinLock, &Irql);
ResetIrp = (PRESET_IRP)de->Flink2;
de aD Flink2: de
while (ResetIrp !=NULL) {
if (ResetIrp->Irp == Irp) {
Æ de = ResetIrp
temp = (PRESET_IRP)de;
tempnext = temp->Flink2;
while (tempnext != ResetIrp) {
temp = tempnext; tempnext = temp->Flink2;
}
temp->Flink2 = ResetIrp->Flink2;
free(ResetIrp);
break;
}
else if (ResetIrp->Flink2 == (PRESET_IRP)de) break;
else ResetIrp = (PRESET_IRP)BusResetIrp->Flink2;
}
typedef struct {
KeReleaseSpinLock(&deviceExtension->ResetSpinLock, Irql);
typedef struct {
RESET_IRP* Flink2;
……
RESET_IRP* Flink2;
Irp;
IoCompleteRequest(Irp, IO_NO_INCREMENT); IRP*
} …
…
} DEVICE_EXTENSION;
} RESET_IRP, *PRESET_IRP;
(de aD Flink2:0)
void XXX_CancelIrp(PDEVICE_OBJECT DeviceObject, PIRP Irp)
{(de a Flink2: x ) * ls (RESET_IRP,Flink2) (x ,0)
D
0
0
………
(de
aD Flink2: XXXResetIrp,temp,tempnext;
x0) * ls (RESET_IRP,Flink2) (x0,de)
de)
PXXX_RESET_IRP
PDEVICE_EXTENSION deviceExtension;
(de
aD Flink2: x0) * ls (RESET_IRP,Flink2) (x0,x1) * (x1aR Irp:Irp)
………
KeAcquireSpinLock(&deviceExtension->ResetSpinLock, &Irql);
ResetIrp = (PRESET_IRP)de->Flink2;
de aD Flink2: de
while (ResetIrp !=NULL) {
if (ResetIrp->Irp == Irp) {
Æ de = ResetIrp
temp = (PRESET_IRP)de;
tempnext = temp->Flink2;
while (tempnext != ResetIrp) {
temp = tempnext; tempnext = temp->Flink2;
}
temp->Flink2 = ResetIrp->Flink2;
free(ResetIrp);
break;
}
else if (ResetIrp->Flink2 == (PRESET_IRP)de) break;
else ResetIrp = (PRESET_IRP)BusResetIrp->Flink2;
}
typedef struct {
KeReleaseSpinLock(&deviceExtension->ResetSpinLock, Irql);
typedef struct {
RESET_IRP* Flink2;
……
RESET_IRP* Flink2;
Irp;
IoCompleteRequest(Irp, IO_NO_INCREMENT); IRP*
} …
…
} DEVICE_EXTENSION;
} RESET_IRP, *PRESET_IRP;
(de aD Flink2:0)
void XXX_CancelIrp(PDEVICE_OBJECT DeviceObject, PIRP Irp)
{(de a Flink2: x ) * ls (RESET_IRP,Flink2) (x ,0)
D
0
0
………
(de
aD Flink2: XXXResetIrp,temp,tempnext;
x0) * ls (RESET_IRP,Flink2) (x0,de)
de)
PXXX_RESET_IRP
PDEVICE_EXTENSION deviceExtension;
(de
aD Flink2: x0) * ls (RESET_IRP,Flink2) (x0,x1) * (x1aR Irp:Irp)
………
KeAcquireSpinLock(&deviceExtension->ResetSpinLock, &Irql);
ResetIrp = (PRESET_IRP)de->Flink2;
de aD Flink2: de
while (ResetIrp !=NULL) {
if (ResetIrp->Irp == Irp) {
Æ de = ResetIrp
temp = (PRESET_IRP)de;
tempnext = temp->Flink2;
while (tempnext != ResetIrp) {
temp = tempnext; tempnext = temp->Flink2;
}
temp->Flink2 = ResetIrp->Flink2;
free(ResetIrp);
break;
}
else if (ResetIrp->Flink2 == (PRESET_IRP)de) break;
else ResetIrp = (PRESET_IRP)BusResetIrp->Flink2;
}
typedef struct {
KeReleaseSpinLock(&deviceExtension->ResetSpinLock, Irql);
typedef struct {
RESET_IRP* Flink2;
……
RESET_IRP* Flink2;
Irp;
IoCompleteRequest(Irp, IO_NO_INCREMENT); IRP*
} …
…
ERROR: No IRP Field
in DEVICE_EXTENSION
} DEVICE_EXTENSION;
} RESET_IRP, *PRESET_IRP;
Footprint Analysis
list t*;
while (x!=0)
{
t = x;
x = x->next;
free(t);
}
x=aÆemp
Seeding
Footprint
Computation
Footprint Analysis
list t*;
while (x!=0)
{
t = x;
x = x->next;
free(t);
}
x=aÆemp
Seeding
Footprint
Computation
Footprint Analysis
list t*;
while (x!=0)
{
t = x;
x = x->next;
free(t);
}
x=aÆemp
Seeding
Footprint
Computation
P1
P2
P3
{P1}
list t*;
while (x!=0)
{
Footprint Analysis
x=aÆemp
Seeding
t = x;
{I1,I2,I3}
x = x->next;
free(t);
Footprint
Computation
}
{Q1,Q2}
SpaceInvader
{P1}C{Q1ÇQ2}
P1
P2
P3
{P2}
Footprint Analysis
x=aÆemp
list t*;
while (x!=0)
{
Seeding
t ={I
x; 10,I11,I12}
x = x->next;
free(t);
P1
P2
P3
Footprint
Computation
}
{Q10,Q11 ,Q12}
SpaceInvader
{P1}C{Q1ÇQ2}
{P2}C{Q10ÇQ11ÇQ12}
{P3}
list t*;
while (x!=0)
{
t = x; >
x = x->next;
free(t);
Footprint Analysis
x=aÆemp
Seeding
P1
P2
P3
Footprint
Computation
}
>
SpaceInvader
{P1}C{Q1ÇQ2}
{P2}C{Q10ÇQ11ÇQ12}
Footprint Analysis
list t*;
while (x!=0)
{
t = x;
x = x->next;
free(t);
x=aÆemp
Seeding
P1
P2
P3
Footprint
Computation
}
SpaceInvader
{P1}C{Q1ÇQ2}
{P2}C{Q10ÇQ11ÇQ12}
Footprint Analysis
Seeding
Footprint
Computation
SpaceInvader
Safe precondition
Footprint only
Separation Logic
xay,
x
ls (y,z)
y
y
z
xay * ls (y,z),
x
y
9y’. z!=0 Æ v=a Æ
emp
z
xay’ * ls (y’,z)
Variable Convention
• Program variables: x,y,z,t,v,w
• Ghost (or auxiliary) variables: a,b,c,d,….
• Primed variables: x’,y’,z’,t’,v’,w’
9 w’,w’1.
x!=0 Æ z=a Æ w’!=w’1 Æ xaw’ * ls (w’,w’1) * yaw’1
Symbolic Heaps
Separation logic formulas of the form:
(x!=0 Æ z=a Æ w’!=w’1) Æ (xaw’ * ls (w’,w’1) *
yaw’1)
SH = Set of all symbolic heaps
GhoSH = Set of sym. heaps with ghost vars only
Footprint Computation
list t*;
while (x!=0)
{
t = x;
x = x->next;
free(t);
{ (x=aÆemp, x=aÆemp)
}
2 Pfin(GhoSH, SH)
Fixpoint
Computation
}
{ (x=aÆls (a,0), x=0Æemp), 2 P (GhoSH, SH)
fin
(x=0Æemp, x=0Æemp), … }
rearr(x)(F,P)
= { (F,P1), …, (F,Pn) }
if SpInvRearr(x)(P) = {P1, …, Pn}
= { (F*aab, P*aab) } else if P ` x=a
«x=x->next¬ : Pfin(GhoSH x SH) ! Pfin(GhoSH x SH)
= { (false,false) }
otherwise
Footprint Computation
rearr(x) : GhoSH x SH ! Pfin(GhoSH x SH)
exec(x=x->next) : GhoSH x SH ! GhoSH x SH
abs : GhoSH x SH ! CanGhoSH x CanSH
{ (x=aÆls a b, x=aÆls a b), (x=aÆls a b, x=bÆls a b) }
{ (x=aÆls a b, x=aÆaab), (x=aÆls a b, x=aÆaav’*ls v’ b),
(x=aÆls a b*bac, x=bÆls a b*bac) }
Footprint Computation
«x=x->next¬ : Pfin(GhoSH x SH) ! Pfin(GhoSH x SH)
rearr(x) : GhoSH x SH ! Pfin(GhoSH x SH)
exec(x=x->next) : GhoSH x SH ! GhoSH x SH
abs : GhoSH x SH ! CanGhoSH x CanSH
{ (x=aÆls a b, x=aÆls a b), (x=aÆls a b, x=bÆls a b) }
{ (x=aÆls a b, x=aÆaab), (x=aÆls a b, x=aÆaav’*ls v’ b),
(x=aÆls a b*bac, x=bÆls a b*bac) }
{ ………………………………., (x=aÆls a b*bac, x=cÆls a b*bac) }
Footprint Computation
«x=x->next¬ : Pfin(GhoSH x SH) ! Pfin(GhoSH x SH)
rearr(x) : GhoSH x SH ! Pfin(GhoSH x SH)
exec(x=x->next) : GhoSH x SH ! GhoSH x SH
abs : GhoSH x SH ! CanGhoSH x CanSH
{ (x=aÆls a b, x=aÆls a b), (x=aÆls a b, x=bÆls a b) }
{ (x=aÆls a b, x=aÆaab), (x=aÆls a b, x=aÆaav’*ls v’ b),
(x=aÆls a b*bac, x=bÆls a b*bac) }
{ ………………………………., (x=aÆls a c*bac,
b*bac, x=cÆls a c)
b*bac)
}
}
Footprint Computation
«x=x->next¬ : Pfin(GhoSH x SH) ! Pfin(GhoSH x SH)
rearr(x) : GhoSH x SH ! Pfin(GhoSH x SH)
exec(x=x->next) : GhoSH x SH ! GhoSH x SH
abs : GhoSH x SH ! CanGhoSH x CanSH
{ (x=aÆls a b, x=aÆls a b), (x=aÆls a b, x=bÆls a b) }
{ (x=aÆls a b, x=aÆaab), (x=aÆls a b, x=aÆaav’*ls v’ b),
(x=aÆls a b*bac, x=bÆls a b*bac) }
{ ………………………………., (x=aÆls a c*bac,
b*bac, x=cÆls a c)
b*bac)
}
}
List Disposal
list t*;
while (x!=0)
{
t = x;
x = x->next;
free(t);
}
x
0
List Disposal
list t*;
while (x!=0)
{
t = x;
x = x->next;
free(t);
}
x
0
List Disposal
list t*;
while (x!=0)
{
t = x;
x = x->next;
free(t);
}
t
x
0
List Disposal
list t*;
while (x!=0)
{
t = x;
x = x->next;
free(t);
}
t
x
0
List Disposal
list t*;
while (x!=0)
{
t = x;
x = x->next;
free(t);
}
t
x
0
Footprint Computation
list t*;
while (x!=0)
{
t = x;
x = x->next;
free(t);
}
Loop: (x=aÆemp, x=aÆemp)
(x=aÆa!=0Æaab,
x=bÆa!=0Æt=aÆemp)
(x=aÆa!=0Æls
a c,
Discovered
Precondition:
x=cÆt=bÆb!=0Æemp)
x=a
Æ em p
Footprint Computation
list t*;
while (x!=0)
{
t = x;
x = x->next;
free(t);
}
x=a Æ emp
Loop: (x=aÆemp, x=aÆemp)
(x=aÆa!=0Æaab,
x=bÆa!=0Æt=aÆemp)
(x=aÆa!=0Æls
a c,
Discovered
Precondition:
x=cÆt=bÆb!=0Æemp)
x=a Æ a!=0
Æ em p
Footprint Computation
list t*;
while (x!=0)
{
t = x;
x = x->next;
free(t);
}
x=a Æ emp
x=a Æ a!=0 Æ emp
Loop: (x=aÆemp, x=aÆemp)
(x=aÆa!=0Æaab,
x=bÆa!=0Æt=aÆemp)
(x=aÆa!=0Æls
a c,
Discovered
Precondition:
x=cÆt=bÆb!=0Æemp)
x=a Æ a!=0
Æ em p
Footprint Computation
list t*;
while (x!=0)
{
t = x;
x = x->next;
free(t);
}
x=a Æ emp
x=a Æ a!=0 Æ emp
x=a Æ a!=0 Æ t=a Æ emp
Loop: (x=aÆemp, x=aÆemp)
(x=aÆa!=0Æaab,
x=bÆa!=0Æt=aÆemp)
(x=aÆa!=0Æls
a c,
Discovered
Precondition:
x=cÆt=bÆb!=0Æemp)
x=a Æ a!=0
Æ em p * aab
Footprint Computation
list t*;
while (x!=0)
{
t = x;
x = x->next;
free(t);
}
x=a Æ emp
x=a Æ a!=0 Æ emp
x=a Æ a!=0 Æ t=a Æ emp
x=b Æ a!=0 Æ t=a Æ emp * aab
Loop: (x=aÆemp, x=aÆemp)
(x=aÆa!=0Æaab,
x=bÆa!=0Æt=aÆemp)
(x=aÆa!=0Æls
a c,
Discovered
Precondition:
x=cÆt=bÆb!=0Æemp)
x=a Æ a!=0
Æ em p * aab
Footprint Computation
list t*;
while (x!=0)
{
t = x;
x = x->next;
free(t);
}
x=a Æ emp
x=a Æ a!=0 Æ emp
x=a Æ a!=0 Æ t=a Æ emp
x=b Æ a!=0 Æ t=a Æ emp * aab
x=b Æ a!=0 Æ t=a Æ emp
Loop: (x=aÆemp, x=aÆemp)
(x=aÆa!=0Æaab,
x=bÆa!=0Æt=aÆemp)
(x=aÆa!=0Æls
a c,
Discovered
Precondition:
x=cÆt=bÆb!=0Æemp)
x=a Æ a!=0
Æ em p * aab
Footprint Computation
list t*;
while (x!=0)
{
t = x;
x = x->next;
free(t);
}
x=a Æ emp
x=a Æ a!=0 Æ emp
x=a Æ a!=0 Æ t=a Æ emp
x=b Æ a!=0 Æ t=a Æ emp * aab
x=b Æ a!=0 Æ t=a Æ emp
Loop: (x=aÆemp, x=aÆemp)
(x=aÆa!=0Æaab,
x=bÆa!=0Æt=aÆemp)
(x=aÆa!=0Æls
a c,
Discovered
Precondition:
x=cÆt=bÆb!=0Æemp)
x=a Æ a!=0 Æ b!=0
Æ em p * aab
Footprint Computation
list t*;
while (x!=0)
{
t = x;
x = x->next;
free(t);
}
x=a Æ emp
x=a Æ a!=0 Æ t=a
x=b
empÆ b!=0 Æ emp
x=a Æ a!=0 Æ t=a Æ emp
x=b Æ a!=0 Æ t=a Æ emp * aab
x=b Æ a!=0 Æ t=a Æ emp
Loop: (x=aÆemp, x=aÆemp)
(x=aÆa!=0Æaab,
x=bÆa!=0Æt=aÆemp)
(x=aÆa!=0Æls
a c,
Discovered
Precondition:
x=cÆt=bÆb!=0Æemp)
x=a Æ a!=0 Æ b!=0
Æ em p * aab
Footprint Computation
list t*;
while (x!=0)
{
t = x;
x = x->next;
free(t);
}
x=a Æ emp
x=a Æ a!=0 Æ t=a
x=b
empÆ b!=0 Æ emp
x=a Æ a!=0ÆÆt=b
x=b
t=a
t=bÆ
Æ
Æb!=0
emp
b!=0ÆÆemp
emp
x=b Æ a!=0 Æ t=a Æ emp * aab
x=b Æ a!=0 Æ t=a Æ emp
Loop: (x=aÆemp, x=aÆemp)
(x=aÆa!=0Æaab,
x=bÆa!=0Æt=aÆemp)
(x=aÆa!=0Æls
a c,
Discovered
Precondition:
x=cÆt=bÆb!=0Æemp)
x=a Æ a!=0 Æ b!=0
Æ em p * aab
ls a c*a
bac
Footprint Computation
list t*;
while (x!=0)
{
t = x;
x = x->next;
free(t);
}
x=a Æ emp
x=a Æ a!=0 Æ t=a
x=b
empÆ b!=0 Æ emp
x=a Æ a!=0Æ
x=b
Æt=b
t=aÆ
Æ b!=0
emp Æ emp
x=b Æ a!=0
x=c
ÆÆ
t=b
t=a
ÆÆ
b!=0
emp
Æ*emp
aab* bac
x=b Æ a!=0 Æ t=a Æ emp
Loop: (x=aÆemp, x=aÆemp)
(x=aÆa!=0Æaab,
x=bÆa!=0Æt=aÆemp)
(x=aÆa!=0Æls
a c,
Discovered
Precondition:
x=cÆt=bÆb!=0Æemp)
x=a Æ a!=0 Æ b!=0
Æ em p * aab
ls a c*a
bac
Footprint Computation
list t*;
while (x!=0)
{
t = x;
x = x->next;
free(t);
}
x=a Æ emp
x=a Æ a!=0 Æ t=a
x=b
empÆ b!=0 Æ emp
x=a Æ a!=0Æ
x=b
Æt=b
t=aÆ
Æ b!=0
emp Æ emp
x=b Æ a!=0
x=c
ÆÆ
t=b
t=a
ÆÆ
b!=0
emp
Æ*emp
aab* bac
x=b Æ a!=0
x=c
ÆÆ
t=b
t=a
ÆÆ
b!=0
emp
Æ emp
Loop: (x=aÆemp, x=aÆemp)
(x=aÆa!=0Æaab,
x=bÆa!=0Æt=aÆemp)
(x=aÆa!=0Æls
a c,
Discovered
Precondition:
x=cÆt=bÆb!=0Æemp)
x=a Æ a!=0 Æ b!=0
Æ em p * ls
aab
a c* bac
Footprint Computation
list t*;
while (x!=0)
{
t = x;
x = x->next;
free(t);
}
x=a Æ emp
x=a Æ a!=0 Æ t=a
x=b
empÆ b!=0 Æ emp
x=a Æ a!=0
x=b
ÆÆ
t=b
t=a
ÆÆb!=0
empÆ emp
x=b Æ a!=0
x=c
ÆÆ
t=b
t=a
ÆÆ
b!=0
emp
Æ*emp
aab* bac
x=b Æ a!=0Æ
x=c
Æt=b
t=a Æ
Æ b!=0
emp Æ emp
Loop: (x=aÆemp, x=aÆemp)
(x=aÆa!=0Æaab,
x=bÆa!=0Æt=aÆemp)
(x=aÆa!=0Æls
a c,
Discovered
Precondition:
x=cÆt=bÆb!=0Æemp)
x=a Æ a!=0 Æ b!=0
Æ em p * ls
aab
a c*a
bac
Footprint Computation
list t*;
while (x!=0)
{
t = x;
x = x->next;
free(t);
}
x=a Æ emp
x=a Æ a!=0 Æ t=a
x=b
empÆ b!=0 Æ emp
x=a Æ a!=0
x=b
ÆÆ
t=b
t=a
ÆÆb!=0
empÆ emp
x=b Æ a!=0
x=c
ÆÆ
t=b
t=a
ÆÆ
b!=0
emp
Æ*emp
aab* bac
x=b Æ a!=0Æ
x=c
Æt=b
t=a Æ
Æ b!=0
emp Æ emp
Loop: (x=aÆemp, x=aÆemp)
(x=aÆa!=0Æaab,
x=bÆa!=0Æt=aÆemp)
(x=aÆa!=0Æls
a c,
Discovered
Precondition:
x=cÆt=bÆb!=0Æemp)
x=a Æ a!=0 Æ b!=0
Æ em p * ls
aab
a c*a
bac
Footprint Computation
list t*;
x=a Æ emp
while (x!=0)
x=a Æ a!=0 Æ t=a
x=b
empÆ b!=0 Æ emp
{
t = x;
x=a Æ a!=0
x=b
ÆÆ
t=b
t=a
ÆÆb!=0
empÆ emp
x = x->next; x=c
x=b Æ a!=0
ÆÆ
t=b
t=a
ÆÆ
b!=0
emp
Æ*emp
aab* bac
free(t);
x=b Æ a!=0
x=c
Æ
Æt=b
t=a Æ
Æ b!=0
emp Æ emp
Result:
(x=aÆa=0Æemp,
x=aÆa=0Æemp)
}
(x=aÆa!=0Æb=0Æaab, x=bÆa!=0Æt=aÆb=0Æemp)
(x=aÆa!=0Æc=0Æls a c, x=cÆt=bÆb!=0Æc=0Æemp)
Shape Analysis with SpaceInvader
(x=aÆa=0Æemp, x=aÆa=0Æemp)
(x=aÆa!=0Æb=0Æaab,
x=bÆa!=0Æt=aÆb=0Æemp)
list t*; (x=aÆa!=0Æc=0Æls a c,
x=cÆt=bÆb!=0Æc=0Æemp)
while
(x!=0)
{x=a’Æa’!=0Æa’a
{x=a’Æa’=0Æem
{x=a’Æa’!=0Æls a’
p} {
0}
0}
t = x;
x = x->next;
free(t);
}
{ x=0 Æ emp
{ x=0 Æ emp
{ x=0 Æ emp
Footprint Computation,
Ideally
«C¬ : Pfin(GhoSH x SH) ! Pfin(GhoSH x SH)
Supp. «C¬{ (F,P) } = { (G1,Q1), (G2,Q2) }.
Goal:8D, if `SL{F}D{P}, then 9Fi. G=F*Fi and `SL{F*Fi}D;C{Qi}.
F0
G
F
D
P
C
Q
Footprint Computation,
Ideally
«C¬ : Pfin(GhoSH x SH) ! Pfin(GhoSH x SH)
Supp. «C¬{ (F,P) } = { (G1,Q1), (G2,Q2) }.
Goal:8D, if `SL{F}D{P}, then 9Fi. G=F*Fi and `SL{F*Fi}D;C{Qi}.
{t=aÆx=bÆaab} free(t);t=x {t=bÆx=bÆemp}
«x=x->next¬{ (t=aÆx=bÆaab, t=bÆx=bÆemp) }
=
{ (t=aÆx=bÆls
(t=aÆx=bÆaab*bac,
ac
, t=bÆx=cÆbac) }
{t=aÆx=bÆaab*bac}
{t=aÆx=bÆls
ac
} …….;x=x>next{t=bÆx=cÆbac}
Footprint Computation, Actually
«C¬ : Pfin(GhoSH x SH) ! Pfin(GhoSH x SH)
Supp. «C¬{ (F,P) } = { (G1,Q1), (G2,Q2) }.
Goal:8D, if `SL{F}D{P}, then 9Fi. G=F*Fi and `SL{F*Fi}D;C{Qi}.
Actually: for all D,
if `SL {F}D{P}, then 9Pi,Fi. Gi¶F*Fi, `SL{F*Fi}D;C{Pi}, PiµQi.
Fi
Gi
F
Abstraction
abs
D
P
C
Rearrangement
rearr(E)
Pi
Qi
Footprint Computation, Actually
«C¬ : Pfin(GhoSH x SH) ! Pfin(GhoSH x SH)
Supp. «C¬{ (F,P) } = { (G1,Q1), (G2,Q2) }.
Goal:8D, if `SL{F}D{P}, then 9Fi. G=F*Fi and `SL{F*Fi}D;C{Qi}.
Actually: for
all D,only abs and rearr(E)!
But,
if `SL {F}D{P}, then 9Pi,Fi. Gi¶F*Fi, `SL{F*Fi}D;C{Pi}, PiµQi.
Fi
Gi
F
Abstraction
abs
D
P
C
Rearrangement
rearr(E)
Pi
Qi
Footprint Computation, Actually
«C¬ : Pfin(GhoSH x SH) ! Pfin(GhoSH x SH)
Supp. «C¬{ (F,P) } = { (G1,Q1), (G2,Q2) }.
Goal:8D, if `SL{F}D{P}, then 9Fi. G=F*Fi and `SL{F*Fi}D;C{Qi}.
Actually: for
all D,only abs and rearr(E)!
But,
if `SL {F}D{P}, then 9Pi,Fi. Gi¶F*Fi, `SL{F*Fi}D;C{Pi}, PiµQi.
Fi
F
D
P
free(t)
proof rule for free(t) in sep. logic
Pi
Sound
because
of
Frame
Rule
in
sep.
log.
Footprint Computation, Actually
«C¬
: Pfin(GhoSH x SH) ! Pfin(GhoSH x SH)
{F}D{P}
Supp. «C¬{ (F,P) } = { (G1,Q1), (G2,Q2) }.
{F*F
}D{P*F
}
Goal:8D,
if `iSL
{F}D{P},i}then{P*F
9Fi. G=F*F
i}free(t){P
i and `SLi{F*Fi}D;C{Qi}.
Actually: for
all
D,only
But,
abs and rearr(E)!
{P*F
i}D;free(t){Pi}
if `SL {F}D{P}, then 9Pi,Fi. Gi¶F*Fi, `SL{F*Fi}D;C{Pi}, PiµQi.
Fi
F
Fi
D
P
free(t)
proof rule for free(t) in sep. logic
Pi
Backward Footprint
Computation
list t*;
while (x!=0)
{
t = x;
x = x->next;
free(t);
}
Backward:
Forward:
assert(x!=0);
t = x;
x = x->next;
free(t);
assert(x=0);
assert(x!=0);
t = x;
x = x->next;
free(t);
assert(x=0);
Experiments
…
with
Programs
x=a ÆList
y=b Æ
ls a 0
…
append.c
…
x=a Æ y=c Æ ls a b * ls c d
… Mem.
MacBook, 2GH Intel Core 2 Duo. 2GB
merge.c
Experiments with Firewire
t1394Diag_CancelIrp
t1394Diag_CancelIrpFix
t1394_GetAddressData
t1394_GetAddressDataFix
t1394_SetAddressData
t1394_SetAddressDataFix
MacBook, 2GH Intel Core 2 Duo. 2GB Mem.