NationalSecurityAgency / ghidra

Ghidra is a software reverse engineering (SRE) framework
https://www.nsa.gov/ghidra
Apache License 2.0
51.57k stars 5.87k forks source link

Ghidra fails to create stack frame for HC11 stack pointer #6902

Open GaryOderNichts opened 1 month ago

GaryOderNichts commented 1 month ago

Hey, I'm currently writing a SLEIGH processor spec for the Motorola 68HC11 (HC11) microcontroller. Everything seems to be working so far, besides decompiling stack locals properly. The HC11's SP always points to the next free location on the stack as opposed to the last item that was pushed onto the stack. When writing to the stack, the SP gets transferred to one of the index registers X or Y using the TSX or TSY instruction. These instructions compensate this behavior by transferring SP + 1 into the register.

Quoting the manual:

At any given time, the stack pointer register holds the 16-bit address of the next free location on the stack.

The stack pointer always points at the next free location on the stack as opposed to the last item that was pushed onto the stack.

But this causes ghidra to store stack locals at unaligned stack offsets: image

This seems to cause several unwanted side effects. Pointers to addresses on the stack are getting passed to functions as &stack0xffff or similar. I can manually adjust the stack frame and create the stack locals to fix this. This does not work for the following example though:

asm_test_stack:
    ; make space on stack
    pshx

    ; store value on stack
    tsx ; tsx transfers SP + 1 to register X
    ldd #0xabcd ; load magic value 0xabcd into register D
    std 0x0,x ; store register D on stack at offset 0x0

    ; pass pointer of value to test_call in register D
    xgdx ; exchange register D with X
    bsr test_call

    ; restore stack and return
    pulx
    rts

This results in the following output: image If I attempt to manually create that 16-bit variable at stack offset -1 I get the following error: image

You can find my current processor language here: https://github.com/GaryOderNichts/ghidra-hc11-lang/tree/feature/soft_regs/data/languages Is there any way I can work around this behavior? Am I missing something on my end?

emteere commented 1 month ago

Have you tried changing the alignment of the stack to 1 in the .cspec?

        <pentry minsize="1" maxsize="500" align="1">
          <addr offset="3" space="stack"/>
        </pentry>
GaryOderNichts commented 1 month ago

Thanks for the quick response! Aligning the stack parameters by 2 is necessary since multiple 8-bit parameters are always aligned by 16-bit when passed to the function. Changing it to 1 unfortunately doesn't fix the issue.

I just found this older issue with the same problem for the HCS-08: https://github.com/NationalSecurityAgency/ghidra/issues/2383 The HC(S)-08 has the same stack pointer behavior as the HC-11. Since that issue is still open, I assume this is currently still a limitation in newer versions of ghidra?