instr_is_predicated for setcc

21 views
Skip to first unread message

Byron Hawkins

unread,
Sep 24, 2022, 8:40:11 PM9/24/22
to DynamoRIO Users
What is the reason for excluding the setcc instructions from instr_is_predicated()? It seems to me that these instructions follow the same cc scheme as cmovcc and jcc, so why would they not be similarly predicated? I have an easy workaround, but I would still like to understand the logic here. Thanks if anyone can explain!

Byron

Derek Bruening

unread,
Sep 26, 2022, 11:13:29 AM9/26/22
to Byron Hawkins, DynamoRIO Users
I think the logic is that SETCC is just a copy: it unconditionally copies a flag bit from the eflags register to a destination.  From that point of view there is no conditional or predicated behavior.  If copying the flags were to be considered predicated because it depends on the flags, then LAHF and PUSHF would be predicated.

On Sat, Sep 24, 2022 at 8:40 PM Byron Hawkins <byron.c...@gmail.com> wrote:
What is the reason for excluding the setcc instructions from instr_is_predicated()? It seems to me that these instructions follow the same cc scheme as cmovcc and jcc, so why would they not be similarly predicated? I have an easy workaround, but I would still like to understand the logic here. Thanks if anyone can explain!

Byron

--
You received this message because you are subscribed to the Google Groups "DynamoRIO Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to dynamorio-use...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/dynamorio-users/9d8ee8b3-ee36-48ec-9bf9-45442fa8880dn%40googlegroups.com.

Byron Hawkins

unread,
Sep 26, 2022, 12:50:03 PM9/26/22
to DynamoRIO Users
Do you know of use cases where a typical compiler might generate a setcc without a preceding flag assignment within the basic block, as is conventional for jcc? In the binary analysis that I'm working on, for any instruction that reads specific flags (jcc, cmovcc, setcc), it expects the basic block to contain some prior instruction that writes (at least) those flags. The analysis won't crash if that's not the case, but the logic of the analysis is "not so smart" if those flags are set across the block boundary (i.e., earlier). More to the point, my analysis looks for a preceding predicate when it encounters a setcc. Based only on casual observation of gcc, this usage seems to be universal for the setcc group. If you know of important cases where setcc is used differently, I'd appreciate a tip!'

Byron Hawkins

unread,
Sep 28, 2022, 9:21:45 PM9/28/22
to DynamoRIO Users
Now that I look more closely, I'm not sure how to see the setcc group as a set of copy operations. It may be that in some instances of setcc, a flag is copied directly into the dst--for example SETO. But in other cases, a predicate is evaluated, and the result of the predicate is copied into the dst. For example, SETL evaluates (SF == OF) and puts that result into the dst byte--it doesn't copy either SF or OF, only the result of the predicate. So from this standpoint, it seems to be a predicated instruction group.

Instructions like LAHF and PUSHF are different in that they perform the same copy operation regardless of the flag states. So by this logic, LAHF and PUSHF would not be predicated.

Am I missing something here?

On Monday, September 26, 2022 at 5:13:29 PM UTC+2 Derek Bruening wrote:

Derek Bruening

unread,
Sep 29, 2022, 11:14:28 AM9/29/22
to Byron Hawkins, DynamoRIO Users
On Wed, Sep 28, 2022 at 9:21 PM Byron Hawkins <byron.c...@gmail.com> wrote:
Now that I look more closely, I'm not sure how to see the setcc group as a set of copy operations. It may be that in some instances of setcc, a flag is copied directly into the dst--for example SETO. But in other cases, a predicate is evaluated, and the result of the predicate is copied into the dst. For example, SETL evaluates (SF == OF) and puts that result into the dst byte--it doesn't copy either SF or OF, only the result of the predicate. So from this standpoint, it seems to be a predicated instruction group.

Our definition of "predicated" is that the instruction's behavior varies in whether it does anything or in which operands it examines, not in the value of the data it deals with.  SETCC never varies its behavior: regardless of the values of the flags, it blindly copies them.  Your example of the SF==OF doesn't change this.  It's just like ADC: it does a computation that combines a flag with something else; but it does that same operation every time.  Only the data values change.

This definition of predicated is what we think analysis tools want to know.  A taint propagation tool wants to know which instructions vary in whether taint will flow from sources to destinations: a predicated instruction that might turn into a NOP if its predicate doesn't match is critical to pay special attention to for taint propagation.  But SETCC does not need any special treatment for taint propagation: tainted flags source bits will always flow to the destination because the insruction's behavior never changes.
 


Instructions like LAHF and PUSHF are different in that they perform the same copy operation regardless of the flag states. So by this logic, LAHF and PUSHF would not be predicated.

Am I missing something here?

On Monday, September 26, 2022 at 5:13:29 PM UTC+2 Derek Bruening wrote:
I think the logic is that SETCC is just a copy: it unconditionally copies a flag bit from the eflags register to a destination.  From that point of view there is no conditional or predicated behavior.  If copying the flags were to be considered predicated because it depends on the flags, then LAHF and PUSHF would be predicated.

On Sat, Sep 24, 2022 at 8:40 PM Byron Hawkins <byron.c...@gmail.com> wrote:
What is the reason for excluding the setcc instructions from instr_is_predicated()? It seems to me that these instructions follow the same cc scheme as cmovcc and jcc, so why would they not be similarly predicated? I have an easy workaround, but I would still like to understand the logic here. Thanks if anyone can explain!

Byron

--
You received this message because you are subscribed to the Google Groups "DynamoRIO Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to dynamorio-use...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/dynamorio-users/9d8ee8b3-ee36-48ec-9bf9-45442fa8880dn%40googlegroups.com.

--
You received this message because you are subscribed to the Google Groups "DynamoRIO Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to dynamorio-use...@googlegroups.com.

sharma...@google.com

unread,
Sep 29, 2022, 11:38:56 AM9/29/22
to DynamoRIO Users
Hi,

> for any instruction that reads specific flags (jcc, cmovcc, setcc), it expects the basic block to contain some prior instruction that writes (at least) those flags

I don't have examples of compiler-generated code, but I can say DynamoRIO doesn't make this assumption (DR saves and restores arithmetic flags when transitioning to a new fragment).

For setcc, I agree with Derek that it is not predicated. If the condition is false, setcc would still take some action (set the destination to zero).

Abhinav

Byron Hawkins

unread,
Sep 29, 2022, 11:59:24 AM9/29/22
to Derek Bruening, DynamoRIO Users
Thanks Derek, I get it now! My analysis is more value-oriented, for example discovering potential switch table targets, so it's normal that it doesn't fit the typical case of taint analysis. The API adjustment is easily done within my framework.
Reply all
Reply to author
Forward
0 new messages