capstone-engine / capstone

Capstone disassembly/disassembler framework for ARM, ARM64 (ARMv8), Alpha, BPF, Ethereum VM, HPPA, LoongArch, M68K, M680X, Mips, MOS65XX, PPC, RISC-V(rv32G/rv64G), SH, Sparc, SystemZ, TMS320C64X, TriCore, Webassembly, XCore and X86.
http://www.capstone-engine.org
7.37k stars 1.54k forks source link

Different disasm output in sparc comparing with binutils #653

Closed radare closed 2 years ago

radare commented 8 years ago

bytes: 554889e5 offset: 0 arch: sparc endian: big (because https://github.com/aquynh/capstone/issues/652)

capstone: call 0x15222794 GNU: call 0x55222794

wondering which one is correct

aquynh commented 8 years ago

one way to verify is to run this code inside Unicorn & watch its behavior?

radare commented 8 years ago

using real hardware or reading specs is probably more reliable way to confirm behaviours.

On 26 Apr 2016, at 15:29, Nguyen Anh Quynh notifications@github.com wrote:

one way to verify is to run this code inside Unicorn & watch its behavior?

— You are receiving this because you authored the thread. Reply to this email directly or view it on GitHub https://github.com/aquynh/capstone/issues/653#issuecomment-214744927

aquynh commented 8 years ago

absolutely. but that is a solution when you dont have hardware, or too lazy to ready ISA manual.

jpenalbae commented 8 years ago

I have tested this on a T1000 running solaris 11 and binutils are right.

Also the documentation states the call format is:

sparc-call

So 554889e5 is:

$ calc 0x554889e4
HEX: 0x554889E4
DEC: 1430817252 1430817252
BIN: 0101 0101 0100 1000 1000 1001 1110 0100

Remove the first two bits which indicate call op and we get 01 0101 0100 1000 1000 1001 1110 0100

$ rax2 010101010010001000100111100100b
0x154889e4

Signextend and multiply by 4 as stated in the documentation:

$ calc 4*0x154889e4
HEX: 0x55222790
DEC: 1428301712 1428301712
BIN: 0101 0101 0010 0010 0010 0111 1001 0000

So binutils were right.

My guess is that capstone removed the first 4 bits when calculating the displacement, doing the sign extend over 28 bits instead of 30:

$ calc 0x554889e5
HEX: 0x554889E5
DEC: 1430817253 1430817253
BIN: 0101 0101 0100 1000 1000 1001 1110 0101
$ calc 0x15222794/4
HEX: 0x54889E5
DEC: 88639973 88639973
BIN: 0101 0100 1000 1000 1001 1110 0101
aquynh commented 8 years ago

fixed in the "next" branch now, please confirm. thanks.

jpenalbae commented 8 years ago

Looks like its fixed now.

$ rasm2 -e -b 64 -a sparc.gnu -d `./gen-sparc-call 357075429`
call  0x55222794
$ rasm2 -e -b 64 -a sparc -d `./gen-sparc-call 357075429`
call 0x55222794

The only problem is when when a wraparound happens it prints negative address (all ops are relative to offset 0):

$ rasm2 -e -b 64 -a sparc.gnu -d `./gen-sparc-call 536870912`
call  0xffffffff80000000
$ rasm2 -e -b 64 -a sparc -d `./gen-sparc-call 536870912`
call -0x80000000
$ rasm2 -e -b 64 -a sparc.gnu -d `./gen-sparc-call -1`
call  0xfffffffffffffffc
$ rasm2 -e -b 64 -a sparc -d `./gen-sparc-call -1`
call -4

Anyway this should never happen, so you can ignore it and close this issue.

kabeor commented 2 years ago

Close this issue for now because of legacy, we are preparing to release Capstone 5.0, plz feel free to open a new issue if that still has this issue. thx :)