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

[WIP] Opportunistic state merging for Manticore #1351

Open
wants to merge 16 commits into
base: master
from

Conversation

6 participants
@vaibhavbsharma
Copy link

vaibhavbsharma commented Jan 15, 2019

This PR is a work-in-progress as of now. The central idea is to merge states that happen to be at the same program location. This requires us to implement a is_merge_possible predicate that compares two states and a merge method that creates a merged State from two mergeable State objects.

I am still working on finishing the implementation of is_merge_possible by adding checks for the array of byte values in various Map objects that describe the state's memory. The next step is to implement the merge method by merging just the CPU and copy everything else from one of the two states.

So far, the changes affect the main loop in Executor. But, I am waiting for 3 APIs to be implemented that will allow me to move my code out of Executor and into a separate state-merging plugin. The design of the APIs is as follows:

  1. load_state loads a state given a state_id without deleting it.
  2. delete_state deletes a state given a state_id
  3. replace_state replaces the state with a value state_id in its workspace with another state given in its argument
    All three APIs return an error if the state with state_id does not exist in Executor's workspace. @feliam is currently working on implementing these APIs.

With these APIs implemented, I plan to create a state-merging plugin that adds a callback for will_load_state. The callback would merge the state that is about to be executed with other states if any happen to be at the same program location. To figure out which states are at the same program location without loading all the states into memory, the plugin would add a handler for did_enqueue_state and maintain a global dictionary that maps state_id values to that state's program counter.


This change is Reviewable

vaibhavbsharma added some commits Jan 11, 2019

Skeleton implementation for state merging in Manticore
This commit introduces a new attribute -- cpu_stateid_dict -- in Executor that keeps track of the Program Counter register of each state and maps PC values to a list of state ids. States that are at the same PC are checked for mergeability.

** Warning: The is_merge_possible and merge methods in state_merging.py have not been implemented. However, this commit should not affect current exploration of Manticore
Implementing input, output sockets comparison for states + adding an …
…example to test state merging

1. Building the constraint that can be used to check if the solver thinks that the buffers in input and output sockets are equal when comparing states for merging
2. Puttng the state merging example in that runs into 3 opportunities for state merging when the Random policy is seeded with the seed = 2 (not sure how to set it up from the Python script)
Adding initial implementation of memory comparison for state merging
**caution: I am in the process of finishing the memory maps comparison
@yan

This comment has been minimized.

Copy link
Member

yan commented on manticore/core/state_merging.py in 317042d Jan 15, 2019

If you're okay including name in comparisons, this can just be if m1 != m2:

This comment has been minimized.

Copy link
Author

vaibhavbsharma replied Jan 15, 2019

Yes, I didn't realize most of this check is already implemented in Map.__eq__. I've changed my implementation to just use m1 != m2.

@yan

This comment has been minimized.

Copy link
Member

yan commented on manticore/core/state_merging.py in 317042d Jan 15, 2019

Map.__lt__ uses start to sort by default (and then end, perms and name, in that order)

This comment has been minimized.

Copy link
Author

vaibhavbsharma replied Jan 15, 2019

I didn't realize that. Thanks for letting me know. I've dropped the key parameter from these sorted calls.

@disconnect3d

This comment has been minimized.

Copy link
Contributor

disconnect3d commented on manticore/core/state_merging.py in 317042d Jan 15, 2019

Or just for i, j in zip(buffer1, buffer2):

This comment has been minimized.

Copy link
Member

yan replied Jan 15, 2019

This also only checks the first len(buffer1) bytes (or min(len1,len2) bytes in the updated case); is that by design?

This comment has been minimized.

Copy link
Author

vaibhavbsharma replied Jan 15, 2019

Thanks for catching this. I was planning on adding the check for the two buffer lengths to be equal but I forgot about it when looking at other parts of the State. I've changed the implementation to check the lengths for equality and using zip.

@CLAassistant

This comment has been minimized.

Copy link

CLAassistant commented Jan 15, 2019

CLA assistant check
All committers have signed the CLA.

vaibhavbsharma and others added some commits Jan 15, 2019

Finishing the `is_merge_possible` predicate's implementation by finis…
…hing comparison of memory in the two states
Finishing off a basic implementation of opportunistic state merging b…
…y implementing the `merge` method that merges the CPU canonical registers between states
Setting the merged constraint in the merged state
The merged constraint is simply a logical OR of the constraints in the states being merged.
Dev state merging loadsave (#1357)
* load/save/replace as needed by state merging

* WIP Move merging to a plugin
Integrating @feliam's changes in so that the basic_statemerging.py ex…
…ample is now using the Merge plugin

1. Using Merge plugin and the newly added APIs in Executor to load, delete, replace states
2. Completing the memory objects comparison by comparing both memory object's symbolic writes instead of only comparing the first memory object against the second
3. Adding documentation for all of the newly introduced methods in state_merging.py
Minor changes to get both Manticore CLI and script-based example via …
…basic_statemerging.py to work + moving Merger Plugin to plugin.py

These changes now allow state merging to correctly merge two states in basic_statemerging.c
Avoid unnecessary CPU register merging using the solver + explaining …
…my hack to avoid importing SMemory into state_merging.py

@vaibhavbsharma vaibhavbsharma requested review from feliam , yan , disconnect3d and mossberg Jan 18, 2019

vaibhavbsharma added some commits Jan 18, 2019

Updating the description in basic_statemerging.c and .py which is the…
… example I've been using to test state merging

@ehennenfent ehennenfent added this to In progress in Manticore Releases Jan 22, 2019

@ehennenfent ehennenfent moved this from In progress to Review Needed in Manticore Releases Jan 22, 2019

print("loaded state_id = " + str(state_id) + " at cpu = " + hex(state.cpu.PC))

m.subscribe('will_load_state', will_load_state_callback)
m.subscribe('did_load_state', did_load_state_callback)

This comment has been minimized.

@disconnect3d

disconnect3d Jan 25, 2019

Contributor

Loud thinking: do we want users to directly subscribe for events? @feliam


@sync
def _replace_state(self, state_id, state):
# self._workspace.rm_state(state_id)

This comment has been minimized.

@disconnect3d

disconnect3d Jan 25, 2019

Contributor

Delete comment?

@ehennenfent ehennenfent added this to the Validate Existing issues milestone Feb 5, 2019

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment