Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Type inference #14

Merged
merged 28 commits into from
Apr 5, 2019
Merged

Type inference #14

merged 28 commits into from
Apr 5, 2019

Conversation

Enkelmann
Copy link
Contributor

Contains pass that checks which registers hold pointers and which hold data other than pointers. Also tracks values on the stack. Stack access may get reworked when adding pointer target tracking, i.e. tracking to what heap object/function stack frame a pointer is pointing to.

Oh, also contains some unit tests. :-)

@tbarabosch tbarabosch self-requested a review March 29, 2019 14:34
@tbarabosch
Copy link
Contributor

First of all: it already looks very nice! 👍

Some general issues:

  • please add a recipe for type-inference-printer, would be a really nice to have!
  • same behavior of dune as stated by you: some changes require now make clean && make
  • in order to make it work with BAP's opam testing, I had to fix some Map.adds, they are now Map.add_exn (grep for them, but there should be also TODO comments), wrapped up in try-with-blocks. Please have a look at them, just in case that I fixed something. It would be even better if you could preserve the Map.adds and unpack them properly (OK a | Duplicate).
  • regarding the general Makefile: if you run make test it fails because the C samples havent been built yet. We should build them before. Also there should be a make option: "make samples". This could be done in another story.

@tbarabosch
Copy link
Contributor

Once again, let's switch now to BAP testing in this branch, this implies using Core 0.11.0
FYI:
opam repo add bap git://github.com/BinaryAnalysisPlatform/opam-repository#testing
opam update
opam install depext --yes
opam depext --install bap --yes

Copy link
Contributor

@tbarabosch tbarabosch left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Another thing: there is not integration/acceptance test for type inference. Let's discuss whether to try dune for this as well or continue with pytest.

plugins/cwe_type_inference/cwe_type_inference.ml Outdated Show resolved Hide resolved
@@ -0,0 1,14 @@
open Bap.Std
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was just wondering if we can wrap bap -d somehow and add the type information. This would be brilliant! Is this with little work possible?

Copy link
Contributor Author

@Enkelmann Enkelmann Apr 1, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As far as I can see, the -d option prints only terms, not attributes of terms. Also, it does not look like the output of -d is meant to be modified by plugins. So I suppose it would be easier to implement our own version of -d. This should not be too hard, but I would still wait with that until type inference is feature complete.

match mem_region with
| [] -> new_node :: []
| head :: tail ->
if head.pos head.size <= pos then
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

extract a function from the begin end block (line 46 - 59). This would make the function more readable.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I couldn't think of a useful way to extract a function there. I added some comments to improve readability instead.

None
else if head.pos = pos then
match head.data with
| Ok(x) -> Some(Ok(x, head.size))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see this Some(Ok()) wrapping all the time. Is that really idiomatic OCaml?

[@@deriving bin_io, compare, sexp]

let merge reg1 reg2 =
if reg1 = reg2 then Some(Ok(reg1)) else Some(Error(()))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This Some(Ok()) wrapping again.

end
| _ -> None

let parse_dyn_syms project =
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This function could be in module Symbol_utils

let line = ref (String.strip line) in
let str_list = ref [] in
while Option.is_some (String.rsplit2 !line ~on:' ') do
let (left, right) = Option.value_exn (String.rsplit2 !line ~on:' ') in
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That is a general concern and should be applied to the whole pull request (!): there are many Option.value_exn. I think they are never caught when they blow up. To honor the type system, we should unpack them correctly.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, in this particular case I would like to keep the value_exn, since I checked in the previous line that it cannot throw an exception. There is a way of writing this without the value_exn using functional programming style, but I think this would be more verbose and less readable in this case.

let x = Mem_region.add x "Five" ~pos:(bv 3) ~size:(bv 5) in
let x = Mem_region.add x "Seven" ~pos:(bv 9) ~size:(bv 7) in
let x = Mem_region.add x "Three" ~pos:(bv 0) ~size:(bv 3) in
check "add_ok" (Some(Ok("Five", bv 5)) = (Mem_region.get x (bv 3)));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some(Ok()) and Some(Error()), I am really not sure what to think about it. Yet I've never seen it in other OCaml projects.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.


let test_remove () =
let bv num = Bitvector.of_int num ~width:32 in
let x = Mem_region.empty () in
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

these let x = look were tedious. Cann't you use the |> operator??

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I cannot use |> here, because x is not the last argument in the Mem_region.add calls. I could write an add_list function for Mem_region for nicer looking code. But I actually like the current version more, because this way it is very explicit in which order the elements get added.

src/analysis/type_inference.ml Outdated Show resolved Hide resolved
@tbarabosch
Copy link
Contributor

This pull request is HUGE, let's start with the first couple of comments. I will do another iteration once they are fixed.

@tbarabosch
Copy link
Contributor

One more thing: we should prefix EVERY plugin with cwe_checker, i.e. cwe_checker_type_inference for instance!

@tbarabosch
Copy link
Contributor

And another thing: please adjust the Dockerfile to build everything (all the new plugins) for Travis CI!
Adjust the .travis* scripts to run Alcotest etc.

@Enkelmann
Copy link
Contributor Author

  • When we switch to opam-testing for the master branch, we have to document it in the Readme and adjust the docker container.
  • I changed the Map.add_exn to Map.set, because in these use cases the previous value is meant to be overwrittten if it exists.
  • I will check whether prefixing every pass with cwe_checker works.

@Enkelmann
Copy link
Contributor Author

Regarding the Some(Ok(_))-wrappings: I thought about defining a new wrapper type, but I think this way is more idiomatic: Every information during a fixpoint computation has essentially three states:

  • We don't have the information -> None
  • We do have conflicting information (e.g. from a merge) -> Some(Error()). We could also set this to None, but this could lead to infinite loops during fixpoint computation and knowing that there is conflicting infomation could also be useful information
  • We do have non-conflicting information -> Some(Ok(information))

Unless you think we should define a new wrapper type for this I don't know a more idiomatic way.

Regarding Codacy: Didn't we already fix that space problem in changes.md? Did codacy change its mind?

@Enkelmann
Copy link
Contributor Author

TODO: Update readme for use of core 0.11

@tbarabosch tbarabosch merged commit 2db57c4 into master Apr 5, 2019
@tbarabosch tbarabosch deleted the type_inference branch April 5, 2019 11:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants