Invalid information for ARM memory operand on next
Quentin01 opened this issue · comments
Hi,
I just checked a bunch of instructions with cstool
and it seems that the some information about a memory operand are broken in next
.
scale
is always 0 instead of being1
or-1
, here are some examples:
0 02 00 11 e7 ldr r0, [r1, -r2]
ID: 4 (ldr)
op_count: 2
operands[0].type: REG = r0
operands[0].access: WRITE
operands[1].type: MEM
operands[1].mem.base: REG = r1
operands[1].mem.index: REG = r2
operands[1].mem.scale: 0
operands[1].access: READ
Registers read: r1 r2
Registers modified: r0
Groups: IsARM
0 02 00 91 e7 ldr r0, [r1, r2]
ID: 4 (ldr)
op_count: 2
operands[0].type: REG = r0
operands[0].access: WRITE
operands[1].type: MEM
operands[1].mem.base: REG = r1
operands[1].mem.index: REG = r2
operands[1].mem.scale: 0
operands[1].access: READ
Registers read: r1 r2
Registers modified: r0
Groups: IsARM
-
disp
is working withsubtracted
being set toTrue
accordingly, but why are you using a field not inarm_op_mem
? e.g in AArch64, the disp will just be negative and there isn't asubtracted
field. -
lshift
is always 0 whatever we are doing (butop->shift.value
is set), here is an example:
0 02 01 91 e7 ldr r0, [r1, r2, lsl #2]
ID: 4 (ldr)
op_count: 2
operands[0].type: REG = r0
operands[0].access: WRITE
operands[1].type: MEM
operands[1].mem.base: REG = r1
operands[1].mem.index: REG = r2
operands[1].mem.scale: 0
operands[1].access: READ
Shift: 2 = 2
Registers read: r1 r2
Registers modified: r0
Groups: IsARM
- what's the point of having
lshift
inarm_op_mem
as we can have a whole lot of other shift that aren't left shift, here is an example:
0 62 01 91 e7 ldr r0, [r1, r2, ror #2]
ID: 4 (ldr)
op_count: 2
operands[0].type: REG = r0
operands[0].access: WRITE
operands[1].type: MEM
operands[1].mem.base: REG = r1
operands[1].mem.index: REG = r2
operands[1].mem.scale: 0
operands[1].access: READ
Shift: 4 = 2
Registers read: r1 r2
Registers modified: r0
Groups: IsARM
- should we always assume that if
op->shift.type
isn'tARM_SFT_INVALID
for a memory operand that it's the offset that should be shifted and not the loaded value? As for regular shift, it's the value that is shifted, here are examples where both shift are represented the same but aren't applied to the same thing:
0 02 01 91 e7 ldr r0, [r1, r2, lsl #2]
ID: 4 (ldr)
op_count: 2
operands[0].type: REG = r0
operands[0].access: WRITE
operands[1].type: MEM
operands[1].mem.base: REG = r1
operands[1].mem.index: REG = r2
operands[1].mem.scale: 0
operands[1].access: READ
Shift: 2 = 2
Registers read: r1 r2
Registers modified: r0
Groups: IsARM
0 01 01 80 e0 add r0, r0, r1, lsl #2
ID: 31 (add)
op_count: 3
operands[0].type: REG = r0
operands[0].access: WRITE
operands[1].type: REG = r0
operands[1].access: READ
operands[2].type: REG = r1
operands[2].access: READ
Shift: 2 = 2
Registers read: r0 r1
Registers modified: r0
Groups: IsARM
I think that the scale
and lshift
issues are probably related to the recent reword on ARM by @Rot127 in #1949, but I'm not sure. I didn't test those instructions on the v5 but as I previously saw some instructions having a correct scale
I think it is working on the v5.
Thanks
Another issue, is that rrx
shift isn't working too, here is an example:
0 61 00 10 e7 ldr r0, [r0, -r1, rrx]
ID: 4 (ldr)
op_count: 2
operands[0].type: REG = r0
operands[0].access: WRITE
operands[1].type: MEM
operands[1].mem.base: REG = r0
operands[1].mem.index: REG = r1
operands[1].mem.scale: 0
operands[1].access: READ
Registers read: r0 r1
Registers modified: r0
Groups: IsARM
Thank you for the report! The underlying problem of it is, that there were and are not many tests for the detail information. This makes issues like yours so valuable.
We work on it for v6
though, see #1984
disp is working with subtracted being set to True accordingly, but why are you using a field not in arm_op_mem? e.g in AArch64, the disp will just be negative and there isn't a subtracted field.
This is because in the ARM
ISA the U
bit indicates explicitly, if an immediate is subtracted or not (see for example ARMv8 ISA (DDI0553B.v) - C2.4.74 LDC, LDC2 (immediate) - Assembler symbols for all encodings
). While in the AArch64
ISA it is not described as such, but the immediate is simply a signed integer.
To be closer to the ARM
ISA, I decided to keep the subtracted flag.
scale is always 0 instead of being 1 or -1, here are some examples:
Thanks, this is probably because I changed the default value to 0 for the mem scale instead of 1. Will be fixed in the PR for this issue.
what's the point of having lshift in arm_op_mem as we can have a whole lot of other shift that aren't left shift, here is an example
Nice catch with all the shifting things. This must have slipped through the todo list in #1949. The memory operand lshift
is not set correctly in v5
either. It is probably still broken, because I copied the behavior.