Closed Ruichka closed 1 year ago
Seems you can workaround it by explicitly slicing the value in the argument passed to le(...)
#ruledef
{
addq a, {val: i32} => le(val`32)
addb a, {val: i8} => le(val`8)
addq_be a, {val: i32} => val
addb_be a, {val: i8} => val
}
outp | addr | data (base 16)
0:0 | 0 | 0f 00 00 00 ; addq a, 0x0f
4:0 | 4 | f1 ff ff ff ; addq a, -0x0f
8:0 | 8 | 0f ; addb a, 0x0f
9:0 | 9 | f1 ; addb a, -0x0f
a:0 | a | 00 00 00 0f ; addq_be a, 0x0f
e:0 | e | ff ff ff f1 ; addq_be a, -0x0f
12:0 | 12 | 0f ; addb_be a, 0x0f
13:0 | 13 | f1 ; addb_be a, -0x0f
which makes no sense to me that this fixes it, but it does.
Concatenating literally nothing no matter the order also fixes it.
#ruledef
{
addq a, {val: i32} => le(val@0`0)
addb a, {val: i8} => le(0`0@val)
addq_be a, {val: i32} => val
addb_be a, {val: i8} => val
}
outp | addr | data (base 16)
0:0 | 0 | 0f 00 00 00 ; addq a, 0x0f
4:0 | 4 | f1 ff ff ff ; addq a, -0x0f
8:0 | 8 | 0f ; addb a, 0x0f
9:0 | 9 | f1 ; addb a, -0x0f
a:0 | a | 00 00 00 0f ; addq_be a, 0x0f
e:0 | e | ff ff ff f1 ; addq_be a, -0x0f
12:0 | 12 | 0f ; addb_be a, 0x0f
13:0 | 13 | f1 ; addb_be a, -0x0f
This is a really good catch, since I overlooked the possibility of creating a "sized negative value" (since le(-0x0f)
errors, for example). But using the automatic slicing feature of typed instruction parameters allows you to create them.
If a negative value is passed onto a le() function, the minus sign gets dropped, causing the end result to be the positive number with a reversed byte order instead of the negative number with a reversed byte order.
This happens even if a reversal can't happen since the size of the value is 1 byte.
Example code that produces the bug: