DynamoRIO / DynamoRIO/dynamorio
support splitting IT block
- Dominant language
- C
- Stars
- 3.2k
- Forks
- 629
- Avg merge
- 2d 15h
- Merged PRs (30d)
- 31
Description
There are several cases that an IT block might be splited into separated basic block, e.g., a non-ignorable conditional system call in the middle of IT block, or a signal received in an IT block.
Pasting from our design doc discussion:
OP_svc is allowed anywhere in an IT block!
Previously we assumed we never needed to split an IT block, because
branches must be the final instr in an IT block.
If we allow splitting, we run into the issue of another bb targeting that address.
not allowed by arm manual, but app could do it, and if we want to support
that we have to interpret differently if coming from somewhere else.
We already ruled out supporting single addr as both arm and thumb I guess
b/c we threw out the idea of setting LSB on tags themselves.
Can we avoid splitting? what about fault in IT block?
There are 6 problems to consider:
1. App branch targets middle of IT block: illegal according to ARM manual
so maybe we can not support it? Xref our decision to not support the
same bytes as both ARM and Thumb instructions in the same program.
2. Client truncates a bb in the middle of an IT block.
Proposal: illegal! We do not support.
Xref client.truncate: "new idea: have drmgr auto-fix-up IT blocks"
3. Some other length limit makes DR want to truncate: all limits have to be
checked for within 4 whenever see OP_it.
4. Relocation in middle of block due to synchall: consider an unsafe point
if we can identify whether in an IT block: does kernel gives us IT flags
in CPSR just like it does for T flag (all of those are privileged so
can’t read directly)?
Q: Confirm kernel gives us IT flags.
5. App fault in middle of IT block and app signal handler then resumes
there, which DR will treat as a new app entry point.
Q: Is this legal according to ARM manual?
If kernel gives us IT flags, and we preserve IT flags across sigcxt<->mcxt,
we could identify whether going to middle of IT block or not on sigreturn.
Impl and challenges: seems similar to #6.
6. OP_svc: if special-case to only split on OP_svc, becomes kind of
like #5: bb builder knows in middle of IT block. We show client a
predicated instr and add OP_it in mangling.
Impl: still terminate after non-ignorable OP_svc, use multiplexed flag
so when arrive in dispatch know in IT block. Then set flag in dcontext
to survive across do_syscall. Then the next build bb call takes flag
and knows to add OP_it in mangling.
Have to set decode state properly.
Challenges:
A) Recreation: either use stored xl8 instead of recreation, or need FRAG_ flag.
B) Traces: either cannot be in trace, or need FRAG_ flag and update
decode_fragment(). Since prior bb ends in non-ignorable syscall, should
already be a trace ender, so can this be a trace head?
Q: implementing #5 and #6 is 90% of work to support #1-#4? Though
adding #1-#4 will be strict superset of #5 and #6 so for now we will not
support general splitting.
Contributor guide
Assessment
This issue has not been assessed yet.