Ghidra: ARM:LE:32:v6 Unexpected Exception: 'q0' undefined

Created on 15 Feb 2020  路  10Comments  路  Source: NationalSecurityAgency/ghidra

Describe the bug
The DecompilerInterface is unable to initialize due to q0 being undefined.

To Reproduce
Steps to reproduce the behavior:

  1. Import ARM:LE:32:v6 binary
  2. See exception in log on import
  3. Analyze and go to any function
  4. See Decompiler: Unable to initialize the DecompilerInterface: GHIDRA/decompiler alignment error

Environment (please complete the following information):

  • OS: Microsoft Windows [Version 10.0.18363.657]
  • Java Version: 13.0.2
  • Ghidra Version: 9.2

Additional context
@define VFPv2 is commented out in ARM6_LE.slaspec. According to the ARM1176JZF-S
Technical Reference Manual its VFP11 coprocessor implementsVFPv2. However, uncommenting the define causes the sleigh compile to fail.

Temporarily removing the register_data from ARMt.pspec allows the decompiler to run. This us not correct though and is only a temporary solution. I have confirmed the existence of the q float registers in this processor by running tests using them on actual hardware.

I also did ensure that all my sleigh language files were up to date before reporting this.

ProcessoARM Bug

All 10 comments

As you have stumbled upon there are definite issues with the ARMv6 with the introduction of vector register support. The ARMt.pspec is not suitable for use with v6 with or without the VFPv2 extension. It may be that two different pspecs will be required for v6 (one without VFPv2 and one with VFPv2). Enablement of VFPv2 will likely need to specify the vector register lanes for the d-registers.

Quick question @astrelsky - until we can get a workaround for the v6, have you tried using the arm v7 spec? Does that screw up anything with your binary?

Quick question @astrelsky - until we can get a workaround for the v6, have you tried using the arm v7 spec? Does that screw up anything with your binary?

It doesn't appear to. I'm not sure what the differences are off the top of my head, but if v7 has thumb2 then that would be a difference and a concern if there are instruction conflicts.

Here is a binary that can be used. It's a modified version of micropython for the raspberrypi that I'm optimizing for the ARM1176JZF-S processor. It has a few other things for my own purposes but it should be extensive enough for testing.

I've removed the link. If it is needed I can create another example.

Generally speaking, ARMv7 is backwards compatible with ARMv6, so v6 code can run on v7 devices without issue. Thumb2 would be a problem going the other way (since the ARMv6 processor wouldn't understand the code).

Generally speaking, ARMv7 is backwards compatible with ARMv6, so v6 code can run on v7 devices without issue. Thumb2 would be a problem going the other way (since the ARMv6 processor wouldn't understand the code).

Right, I was just uncertain if there were any instruction conflicts or not. I haven't encountered any issues using v7 yet.

Can you clarify this statement:

Temporarily removing the register_data from ARMt.pspec allows the decompiler to run. This us not correct though and is only a temporary solution. I have confirmed the existence of the q float registers in this processor by running tests using them on actual hardware.

As far as all available ARM documentation is concerned, the Q registers are only available to Advanced SIMD processors, which started with the Cortex. The documentation for the ARM1176JZF-S does not mention Advanced SIMD either.

Can you clarify this statement:

Temporarily removing the register_data from ARMt.pspec allows the decompiler to run. This us not correct though and is only a temporary solution. I have confirmed the existence of the q float registers in this processor by running tests using them on actual hardware.

As far as all available ARM documentation is concerned, the Q registers are only available to Advanced SIMD processors, which started with the Cortex. The documentation for the ARM1176JZF-S does not mention Advanced SIMD either.

I was using -mfpu=vfpv2. I was able to successfully assemble and run code which used the q registers without issue. Disassembling the binary with objdump disassembled the instructions showing the q registers as well. It is possible that this is just "compiler magic" and consecutive 32 bit float registers are being used. I can provide a concrete example later today.

That would be great. I'll try to play around with the compiler options today and see if I can replicate this myself.

That would be great. I'll try to play around with the compiler options today and see if I can replicate this myself.

My mistake, it appears to be converting them to d registers.

    vldm src!, {q0-q3}
    vstm dst!, {q0-q3}

becomes

  3c:   ecb10b10    vldmia  r1!, {d0-d7}
  40:   eca00b10    vstmia  r0!, {d0-d7}

I've attached a full example though just in case though.
mcpy_q_test.tar.gz

I've provided the binaries and the source. I didn't include my libraries so building it may fail.

This issue should now be resolved in master and upcoming 9.2
The binary in question now works with ARM v6
If you still have issues, we can re-open this ticket.
The semantics for vstmia/vldmia were also missing previously ( so bonus fix )

Was this page helpful?
0 / 5 - 0 ratings

Related issues

tambry picture tambry  路  3Comments

lab313ru picture lab313ru  路  3Comments

chibicitiberiu picture chibicitiberiu  路  3Comments

CalcProgrammer1 picture CalcProgrammer1  路  3Comments

huettenhain picture huettenhain  路  3Comments