@@ -89,11 +89,12 @@ module POAnchorCollections = CHCollections.Make
8989let x2p = xpr_formatter#pr_expr
9090let p2s = pretty_to_string
9191let x2s x = p2s (x2p x)
92+ let i2s i = string_of_int i
9293
9394let opti2s (i : int option ) =
9495 if Option. is_some i then string_of_int (Option. get i) else " ?"
9596
96- let _ty2s (ty : btype_t ) =
97+ let ty2s (ty : btype_t ) =
9798 if is_unknown_type ty then " ?" else btype_to_string ty
9899let optty2s (ty : btype_t option ) =
99100 if Option. is_some ty then btype_to_string (Option. get ty) else " ?"
@@ -1379,8 +1380,31 @@ object (self)
13791380 (default () )
13801381 (numerical_to_doubleword n)
13811382 | _ ->
1382- default ()
1383-
1383+ default ()
1384+
1385+ (* Handles the following cases:
1386+ - initial_register_value:
1387+ if the register is a function parameter: get parameter type
1388+ otherwise: Error
1389+
1390+ - initial_memory_value:
1391+ get type of corresponding memory variable
1392+
1393+ - memory_variable:
1394+ separate base from offset
1395+ * global: retrieve type from global-memory-map if addresses match
1396+ otherwise: Error
1397+ Note: this may lead to confusion between type of first field and
1398+ type of struct
1399+
1400+ * basevar:
1401+ if no-offset: type-of *basevar
1402+ otherwise: type dependent on offset
1403+
1404+ - return_value:
1405+ if callsite has a typed var-intro: retrieve type of var-intro
1406+ otherwise: Error (not yet handled)
1407+ *)
13841408 method get_variable_type (v : variable_t ): btype_t traceresult =
13851409 let is_zero (x : xpr_t ) =
13861410 match x with
@@ -1527,14 +1551,52 @@ object (self)
15271551 ^ " at address " ^ loc#i#to_hex_string
15281552 ^ " not yet handled" ])
15291553 (self#f#env#get_call_site v)
1554+ else if self#f#env#is_register_variable v then
1555+ let vrdefs = self#get_variable_rdefs v in
1556+ let fndata = self#f#get_function_data in
1557+ match vrdefs with
1558+ | h :: _ ->
1559+ let optty_r =
1560+ TR. tmap
1561+ (fun r -> fndata#get_reglhs_type r h#getBaseName)
1562+ (self#f#env#get_register v) in
1563+ TR. tfold
1564+ ~ok: (fun optty ->
1565+ match optty with
1566+ | Some ty -> Ok ty
1567+ | _ ->
1568+ Error [
1569+ (elocm __LINE__)
1570+ ^ " No reglhs type assignment found for variable "
1571+ ^ (p2s v#toPretty)
1572+ ^ " at location "
1573+ ^ h#getBaseName])
1574+ ~error: (fun e -> Error ((elocm __LINE__) :: e))
1575+ optty_r
1576+ | _ ->
1577+ Error [
1578+ (elocm __LINE__)
1579+ ^ " Unable to find reachingdefs for variable "
1580+ ^ (p2s v#toPretty)]
15301581 else
15311582 let ty = self#env#get_variable_type v in
15321583 match ty with
15331584 | None -> Error [(elocm __LINE__) ^ " variable: " ^ (x2s (XVar v))]
15341585 | Some t -> Ok t
15351586
1587+ method private get_variable_rdefs (v : variable_t ): symbol_t list =
1588+ let symvar = self#f#env#mk_symbolic_variable v in
1589+ let varinvs = self#varinv#get_var_reaching_defs symvar in
1590+ (match varinvs with
1591+ | [vinv] -> vinv#get_reaching_defs
1592+ | _ ->
1593+ List. concat (List. map (fun vinv -> vinv#get_reaching_defs) varinvs))
1594+
15361595 method xpr_to_cxpr
1537- ?(size =None ) ?(xtype =None ) (x : xpr_t ): xpr_t traceresult =
1596+ ?(arithm =false )
1597+ ?(size =None )
1598+ ?(xtype =None )
1599+ (x : xpr_t ): xpr_t traceresult =
15381600 let _ =
15391601 log_diagnostics_result
15401602 ~msg: (p2s self#l#toPretty)
@@ -1543,14 +1605,45 @@ object (self)
15431605 [" size: " ^ (opti2s size);
15441606 " xtype: " ^ (optty2s xtype);
15451607 " x: " ^ (x2s x)] in
1546- match xtype with
1547- | None -> self#convert_xpr_offsets ~size x
1548- | Some t ->
1549- match x with
1550- | XConst (IntConst n)
1551- when n#equal (mkNumerical 0xffffffff ) && is_int t ->
1552- Ok (int_constant_expr (- 1 ))
1553- | _ -> self#convert_xpr_offsets ~xtype ~size x
1608+ let is_pointer (y : xpr_t ) =
1609+ TR. tfold_default BCHBCTypeUtil. is_pointer false (self#get_xpr_type y) in
1610+ let default () = self#convert_xpr_offsets ~xtype ~size x in
1611+ match x with
1612+ | XOp (XPlus, [y ; XConst (IntConst n )]) when is_pointer y && arithm ->
1613+ let derefty = BCHBCTypeUtil. ptr_deref (TR. tget_ok (self#get_xpr_type y)) in
1614+ let _ =
1615+ log_diagnostics_result
1616+ ~msg: (p2s self#l#toPretty)
1617+ ~tag: " xpr_to_cxpr:pointer expression"
1618+ __FILE__ __LINE__
1619+ [" x: " ^ (x2s x); " *ty: " ^ (ty2s derefty)] in
1620+ TR. tmap2
1621+ ~msg1: (eloc __LINE__)
1622+ ~msg2: (eloc __LINE__)
1623+ (fun cy size ->
1624+ let scaledincr = XConst (IntConst (n#div (mkNumerical size))) in
1625+ let result = XOp (XPlus , [cy; scaledincr]) in
1626+ let _ =
1627+ log_diagnostics_result
1628+ ~msg: (p2s self#l#toPretty)
1629+ ~tag: " xpr_to_cxpr:pointer expression"
1630+ __FILE__ __LINE__
1631+ [" x: " ^ (x2s x);
1632+ " cy: " ^ (x2s cy);
1633+ " size: " ^ (i2s size);
1634+ " result: " ^ (x2s result)] in
1635+ result)
1636+ (self#xpr_to_cxpr y)
1637+ (BCHBCTypeUtil. size_of_btype derefty)
1638+ | _ ->
1639+ match xtype with
1640+ | None -> default ()
1641+ | Some t ->
1642+ match x with
1643+ | XConst (IntConst n)
1644+ when n#equal (mkNumerical 0xffffffff ) && is_int t ->
1645+ Ok (int_constant_expr (- 1 ))
1646+ | _ -> default ()
15541647
15551648 method addr_to_ctgt_xpr
15561649 ?(size =None ) ?(xtype =None ) (a : xpr_t ): xpr_t traceresult =
@@ -1852,6 +1945,7 @@ object (self)
18521945 method get_xpr_type (x : xpr_t ): btype_t traceresult =
18531946 match x with
18541947 | XVar v -> self#get_variable_type v
1948+ | XOp (XPlus, [XVar v ; XConst (IntConst _ )]) -> self#get_variable_type v
18551949 | _ -> Error [(elocm __LINE__) ^ " xpr: " ^ (x2s x)]
18561950
18571951 method decompose_memaddr (x : xpr_t ):
0 commit comments