Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Invalid information for ARM memory operand on next #2281

Open
Quentin01 opened this issue Feb 23, 2024 · 2 comments
Open

Invalid information for ARM memory operand on next #2281

Quentin01 opened this issue Feb 23, 2024 · 2 comments
Labels
Milestone

Comments

@Quentin01
Copy link
Contributor

Quentin01 commented Feb 23, 2024

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 being 1 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 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.

  • lshift is always 0 whatever we are doing (but op->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 in arm_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't ARM_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

@Quentin01
Copy link
Contributor Author

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

@Rot127
Copy link
Collaborator

Rot127 commented Feb 28, 2024

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.

@Rot127 Rot127 added bug ARM Arch labels Mar 19, 2024
@Rot127 Rot127 added this to the v6 milestone Mar 19, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
Status: Todo
Development

No branches or pull requests

2 participants