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

Improve handling of JumpBound truncation constraints #403

Merged
merged 1 commit into from
Jul 24, 2024

Conversation

staslyakhov
Copy link
Contributor

@staslyakhov staslyakhov commented Jul 23, 2024

Background

Given some symbolic value, x, we'd like to compute its possible upper and lower bounds after it is truncated to w bits.

To do this, we first find the bound of x by (recursively) calling exprRangePred. This bound is a statement of the following form (see RangePred for more info): "r bits of x are bounded between low and high".

Then, we check the following:

  • If x has a bound (r, l, h) AND
  • If r is less than or equal to w => Pass-through the bound (r, l, h)

Otherwise, we deem x "unbounded"

Proposal

Declaring x unbounded in the second case seems to throw away useful information that causes many jump tables to remain unclassified. We attempt to improve on that in this commit.

Consider an example where x is bounded by (64, 0, 10) (that is, the 64 bits of x are constrained to be between 0 and 10) and we want to find the bound of truncating x to 8 bits.

With the current logic, since 64 > 8, we'd declare x unbounded. However, the bound (8, 0, 10) should also be valid: if 64 bits of x are bounded to [0, 10], then surely 8 bits of x also lie between 0 and 10.

If the upper bound is instead larger than the largest 8-bit value, we can truncate it to the largest value.
For example, (64, 0, 10000) becomes (8, 0, 255).
Instead of losing the bound completely, we're able to tighten it!

Evaluation

Using Reopt's ground truth evaluation, we found that this change significantly improved jump table classification in coreutil binaries compiled with GCC_O1. Out of 912 total jump tables in the dataset, macaw (launched through Reopt) currently reaches + classifies 109 jump tables. After this change, macaw correctly classifies 857/912 jump tables.

@staslyakhov staslyakhov added the discovery Issues related to the code discovery logic label Jul 23, 2024
@staslyakhov staslyakhov requested a review from RyanGlScott July 23, 2024 21:10
@staslyakhov staslyakhov self-assigned this Jul 23, 2024
@staslyakhov staslyakhov force-pushed the feature/better-jumptable-truncation branch from a36c57e to a8d039b Compare July 23, 2024 23:58
Copy link
Contributor

@RyanGlScott RyanGlScott left a comment

Choose a reason for hiding this comment

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

Thanks!

Given some symbolic value, @x@, we'd like to compute its
possible upper and lower bounds after it is truncated to @w@ bits.

To do this, we first find the bound of x by (recursively) calling `exprRangePred`.
This bound is a statement of the following form (see `RangePred` for more info):
"r bits of x are bounded between @low@ and @high@".

Then, we check the following:
- If x has a bound (r, l, w)
AND
- If r is less than or equal to w
=> Pass-through the bound (r, l, w)
Otherwise, we deem x "unbounded"

Declaring x unbounded in the second case seems to throw away useful
information that causes many jump tables to remain unclassified.
We attempt to improve on that in this commit.

Consider an example where x is bounded by (64, 0, 10)
(that is, the 64 bits of x are constrained to be between 0 and 10)
and we want to find the bound of truncating x to 8 bits.

With the current logic, since 64 > 8, we'd declare x unbounded.
However, the bound (8, 0, 10) should also be valid: if 64 bits of
x are bounded to [0, 10], then surely 8 bits of x also lie between
0 and 10.

If the upper bound is instead larger than the largest 8-bit value, we
can truncate it to the largest value.
For example, (64, 0, 10000) becomes (8, 0, 255).
Instead of losing the bound completely, we're able to tighten it!
@staslyakhov staslyakhov force-pushed the feature/better-jumptable-truncation branch from a8d039b to 75e31f8 Compare July 24, 2024 20:44
@staslyakhov staslyakhov merged commit 82aae49 into master Jul 24, 2024
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
discovery Issues related to the code discovery logic
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants