As a follow-up to one of my previous patch, here's another patch that 
will make --dosimplify more suitable for generating code, better suited 
for software verification.

The patch adds --no-convert-field-offsets option for --dosimplify 
extension.  This option makes CIL not convert structure field access "x-
>p" to, essentially, "(int*)( (int*)x +  8), where "8" (or any other 
similar number) is a machine-dependent offset of a field relative to the 
beginning of the structure.  However, other memory access 
simplifications still work.

Sample file that had this problem is attached as "mem.c".  Try it as 

cilly.asm.exe --printCilAsIs --domakeCFG --dosimplify --no-convert-
field-offsets mem.c


However, in rare cases, there is a problem with arrays and their 
modifiers.  The option requires CIL to generate temporary variables with 
more complex types than previously, and the resultant code is not always 
compilable.  Consider the following file (volatile_fail.c):

struct M {
  unsigned char volatile   completed[46U] ;
} volatile *m;

int main()
{
  return &m->completed;
}


The result of the conversion is:


struct M {
   unsigned char volatile   completed[46U] ;
};
struct M  volatile  *m  ;
int main(void) 
{
  // Compile error here:
  unsigned char volatile   ( volatile  (*__cil_tmp1))[46U] ;

  __cil_tmp1 = (unsigned char volatile   ( volatile  (*))[46U])m;
  return ((int )__cil_tmp1);
}

So,
1) could anyone give me a hint how to fix this?
2) could this patch be added to upstream nevertheless?  I think that the 
benefits to the verification tools, for which the options is useful, are 
much greater than the very rarely encountered issue with "very volatile" 
structs with array fields.  Besides, the behavior without this command-
line option is retained.

-- 
Pavel Shved
website: http://coldattic.info/
e-mail: pavel.sh...@gmail.com
>From 6c3e51e7ae4882beae61e9600b6803414d9c9e23 Mon Sep 17 00:00:00 2001
From: Pavel Shved <sh...@ispras.ru>
Date: Fri, 30 Sep 2011 17:00:46 +0400
Subject: [PATCH] Add --no-convert-field-offset to dosimplify

Field offsets (expressions of the form "&a->f") were converted to
dereference of a's address plus offset in bytes.  This option suppresses
such conversion.  However, certain code will be non-compileable (arrays
of volatile items inside volatile structs).

The aim of this option is to make --dosimplify-generated code better
verifiable by static code checking tools.
---
 src/ext/simplify.ml |   24 +++++++++++++++++++++++-
 1 files changed, 23 insertions(+), 1 deletions(-)

diff --git a/src/ext/simplify.ml b/src/ext/simplify.ml
index 0e3de67..fbb9727 100644
--- a/src/ext/simplify.ml
+++ b/src/ext/simplify.ml
@@ -89,6 +89,12 @@ let simplAddrOf = ref true
  * has been taken somewhere. *)
 let convertDirectCalls = ref true
 
+(* Whether to convert field offsets to offsets by integer.
+ * Static source code verifiers do not need such a conversion *)
+let convertFieldOffsets = ref true
+(* WARN: splitStructs should be set to false, as it won't find the usage of  *)
+
+
 let onlyVariableBasics = ref false
 let noStringConstantsBasics = ref false
 
@@ -116,6 +122,10 @@ let rec makeThreeAddress
       if not(!simplAddrOf) then e else
       match simplifyLval setTemp lv with 
         Mem a, NoOffset -> if !simpleMem then a else AddrOf(Mem a, NoOffset)
+      (* Do not change addrof if we do not convert field offsets *)
+      | Mem a, off when not !convertFieldOffsets -> AddrOf(Mem a, off)
+      (* Do not change addrof if we do not convert field offsets *)
+      | Var v, off when not !convertFieldOffsets -> AddrOf(Var v, off)
       | _ -> (* This is impossible, because we are taking the address 
           * of v and simplifyLval should turn it into a Mem, except if the 
           * sizeof has failed.  *)
@@ -214,7 +224,7 @@ and simplifyLval
     | Field(fi, _) -> E.s (bug "bug in offsetToInt")
   in
   match lv with 
-    Mem a, off -> 
+    Mem a, off when !convertFieldOffsets -> 
       let offidx, restoff = offsetToInt (typeOfLval (Mem a, NoOffset)) off in
       let a' = 
         if offidx <> zero then 
@@ -224,8 +234,13 @@ and simplifyLval
       in
       let a' = if !simpleMem then makeBasic setTemp a' else a' in
       Mem (mkCast a' (typeForCast restoff)), restoff
+  | Mem a, off when not !convertFieldOffsets -> 
+      let a' = if !simpleMem then makeBasic setTemp a else a in
+      Mem a', off
   (* We are taking this variable's address; but suppress simplification if it's a simple function
    * call in no-convert mode*)
+  | Var v, off when v.vaddrof && (not !convertFieldOffsets) && (!convertDirectCalls || not (isFunctionType (typeOfLval lv) ))  ->
+      (Var v, off)
   | Var v, off when v.vaddrof && (!convertDirectCalls || not (isFunctionType (typeOfLval lv) ))  ->
       let offidx, restoff = offsetToInt v.vtype off in
       (* We cannot call makeBasic recursively here, so we must do it 
@@ -722,6 +737,13 @@ let feature : featureDescr =
       ("--no-convert-direct-calls", Arg.Clear convertDirectCalls,
                     " do not convert direct function calls to function pointer \
                       calls if the address of the function was taken");
+      ("--no-convert-field-offsets", Arg.Unit ( fun () ->
+                      convertFieldOffsets := false;
+                      (* do not split structs in function calls *)
+                      splitStructs := false
+                    ),
+                    " do not convert field offsets to offsets by integer, and \
+                    do not split structures into fields in function calls");
     ];
     fd_doit = (function f -> iterGlobals f doGlobal);
     fd_post_check = true;
-- 
1.7.3.4

struct X{
	int dummy;
	struct {
		int q;
	} *p;
};

int main()
{
	struct X *r;
	return r->p->q;
}
struct M {
	unsigned char volatile   completed[46U] ;
} volatile *m;

int main()
{
	return &m->completed;
}
------------------------------------------------------------------------------
The demand for IT networking professionals continues to grow, and the
demand for specialized networking skills is growing even more rapidly.
Take a complimentary Learning@Cisco Self-Assessment and learn 
about Cisco certifications, training, and career opportunities. 
http://p.sf.net/sfu/cisco-dev2dev
_______________________________________________
CIL-users mailing list
CIL-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/cil-users

Reply via email to