Skip to content

How to enable Floating Point Support in ARM 32

Guille Polito edited this page Sep 30, 2020 · 1 revision

To use Floating Point instructions in ARM 32bit simulation, Unicorn needs to enable floating point support. In ARM32 this can be done by executing the following couple of instructions:

mov.w r3, #0xf00000
mcr p15, #0x0, r3, c1, c0, #0x2
isb sy
mov.w r3, #0x40000000
vmsr fpexc, r3

Getting the object code to give to unicorn

To avoid encoding those instructions manually, we can make usage of an assembler. First, we write an assembly file mycode.s with the code above:

.global	_start

.text
_start:
mov.w r3, #0xf00000
mcr p15, #0x0, r3, c1, c0, #0x2
isb sy
mov.w r3, #0x40000000
vmsr fpexc, r3

We then instruct the as assembler to assemble using armv7.

$ as -arch armv7 myfile.s

This will create an object file a.out from which we can then extract the bytes from it using objdump.

$ objdump -disassemble -arch-name=arm

a.out:	file format Mach-O arm

Disassembly of section __TEXT,__text:
_start:
       0:	0f 36 a0 e3 	mov	r3, #15728640
       4:	50 3f 01 ee 	mcr	p15, #0, r3, c1, c0, #2
       8:	6f f0 7f f5  <unknown>
       c:	01 31 a0 e3 	mov	r3, #1073741824
      10:	10 3a e8 ee  <unknown>

Run the instructions

If we take the bytes (and not the mnemonics) of the object dump, we can feed those values to Unicorn.

"The instruction bytes as got by objdump"
bytes := #[ 
	16r0f 16r36 16ra0 16re3
	16r50 16r3f 16r01 16ree
	16r6f 16rf0 16r7f 16rf5
	16r01 16r31 16ra0 16re3
	16r10 16r3a 16re8 16ree ].

"Unicorn accepts memory in multiples of 4KB only. Create one and copy the bytes."
mappedMemory := ByteArray new: 4096.
mappedMemory replaceFrom: 1 to: bytes size with: bytes.

"Create a unicorn instance, map the instructions at address 4096 and execute the 5 instructions"
unicorn := Unicorn arm.
unicorn mapHostMemory: mappedMemory atAddress: 4096 withPermissions: UnicornConstants permissionAll.
unicorn doStartAt: 4096 until: 0 timeout: 0 count: 5 "instructions".

The ARM 32 bits is now able to execute floating point instructions. Be careful of unmapping the memory you mapped, or of not getting your byte array GC'd in case you want to still use it.