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

prevents delay slots from becoming a basic block start #1170

Merged
merged 3 commits into from
Jul 8, 2020

Conversation

ivg
Copy link
Member

@ivg ivg commented Jul 2, 2020

Our control-flow graph representation is unable to handle cases when a
delay slot of some branching instruction becomes a target of a call or
a jump, because we do not allow the same instruction to belong to
several basic blocks (aka instruction sharing). When we encounter such a
case, our control-flow invariants are broken which leads to failures
downstream (e.g., we have duplicating term identifiers).

While it is possible that a delay slot might become a target of a
jump, in reality compilers are not generating such code (well, at
least we are not aware of such compilers) and the main source of calls
that target delays slots is Byteweight, which false positively
identifies them as function starts.

Since we don't have an option to represent such graphs right now, to
preserve our invariants, we cancel all disassembling chains that end
up in classifying some delay slots as function starts or targets of
a jump or call. To implement this, we remember each task that lead to
a creating of a new basic block. When we discover a new basic block we
check if its start is a known delay slot, and if it is , we cancel the
chain. If later we discover jump whose delay slot is a start of a
basic block we cancel all chains that were responsible for the
creation of that basic block and continue. To summarize, the invariant
is that a delay slot may never be a start of a basic block.

Another change, which is more of an optimization, that bundled with
this commit, is that we now track the function starts and use them
as the starting points to build the whole program CFG. Before we were
using all basic blocks, when we build the whole program CFG which
ended up in lots of unreachable code, which was ignored by
the subroutine partitoning algorithm, so there is no need to
disassemble them anyways.

ivg added 3 commits July 2, 2020 15:29
Our control-flow graph representation is unable to handle cases when a
delay slot of some branching instruction becomes a target of a call or
a jump, because we do not allow the same instruction to belong to
several basic blocks (aka instruction sharing). When we encounter such a
case, our control-flow invariants are broken which leads to failures
downstream (e.g., we have duplicating term identifiers).

While it is possible that a delay slot might become a target of a
jump, in reality compilers are not generating such code (well, at
least we are not aware of such compilers) and the main source of calls
that target delays slots is Byteweight, which false positively
identifies them as function starts.

Since we don't have an option to represent such graphs right now, to
preserve our invariants, we cancel all disassembling chains that end
up in classifying some delay slots as function starts or targets of
a jump or call. To implement this, we remember each task that lead to
a creating of a new basic block. When we discover a new basic block we
check if its start is a known delay slot, and if it is , we cancel the
chain. If later we discover jump whose delay slot is a start of a
basic block we cancel all chains that were responsible for the
creation of that basic block and continue. To summarize, the invariant
is that a delay slot may never be a start of a basic block.

Another change, which is more of an optimization, that bundled with
this commit, is that we now track the function starts and use them
as the starting points to build the whole program CFG. Before we were
using all basic blocks, when we build the whole program CFG which
ended up in lots of unreachable code, which was ignored by
the subroutine partitoning algorithm, so there is no need to
disassemble them anyways.
i.e., it will scan through all basic blocks if no entry is specified.
@ivg ivg merged commit 20c9000 into BinaryAnalysisPlatform:master Jul 8, 2020
@ivg ivg deleted the protects-delay-slots branch December 1, 2021 19:13
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.

1 participant