There was a brief thread on e.g. 'icmp[0] > 0' generating strange
code; I've looked into this a fair amount and want to share what I
have so far.  I've committed a fix that's purely hackery, and only
works for the specific case of "foo > 0" (even "0 < foo" is still
broken).  It fails to optimize away "sub #0", since the optimizer
needs to see the subtraction of the constant in order to put the
0x80000000 back.

The real deal is that the code generator, specifically gen_relation(),
doesn't know when it wants to do signed vs. unsigned comparisons.
If you are comparing with a constant, you probably want an unsigned
comparison.  If you are comparing with another field, however,
unsigned comparisons can give unexpected results; a < b -> a - b < 0
but nothing is < 0 with unsigned math, so libpcap turns it into
a - b > 0x80000000 .

Right now, the optimizer puts the 0x80000000 back if it decides that
one of the values is a constant (which is why you can get different
results with and without the optimizer).  This is because at code
generation time, the code generator doesn't know if a value is a
constant.  However, this is no good, because:

a) The optimizer could optimize away the things that it uses to determine
if it should put the 0x80000000 back, i.e. the "sub #0" that caused
the weird code with 'icmp[0] > 0'.

b) The code should not behave differently before and after optimization.

I'm really not sure how to make the determination whether the user wanted
a signed or an unsigned comparison.  I have some code that allows the
parser and code generator to remember (through combinations of gen_load*
and gen_arth()) what pieces are constants, and make comparisons with
constants unsigned.  However, it's not clear that comparisons with bits of
the packet should always be signed, since the comparison there is really
that the numbers don't differ by more than 0x80000000 (e.g. 0x80000001
< 0 is true).  Perhaps the language should grow an explicit request to
the code generator to generate signed comparisons (or to tag pieces of
expressions as signed, e.g. signed(tcp[4:4]) < 0).

Anyone else have any thoughts?  Anyone want to try out my constants-
are-unsigned patch?

Thanks,
  Bill
-
This is the TCPDUMP workers list. It is archived at
http://www.tcpdump.org/lists/workers/index.html
To unsubscribe use mailto:[EMAIL PROTECTED]?body=unsubscribe

Reply via email to