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
