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

Add support for HC08 SKIP1 and SKIP2 optimizations #6396

Open
guillaume-dorczynski opened this issue Apr 9, 2024 · 2 comments
Open

Add support for HC08 SKIP1 and SKIP2 optimizations #6396

guillaume-dorczynski opened this issue Apr 9, 2024 · 2 comments
Assignees
Labels
Feature: Processor/HCS08 Status: Triage Information is being gathered

Comments

@guillaume-dorczynski
Copy link

Hello, I'm a new user of Ghidra, trying to reverse engineer a Freescale HC08 program.

I encountered a few illogical CPHX instructions (opcode 0x65), and I was told these were branch optimizations called SKIP2. There are SKIP1 optimizations too, that I never encountered yet. See HC08 Compiler manual ( https://ece-classes.usc.edu/ee459/library/documents/Compiler_HC08.pdf )

I think I know how to make Ghidra decompiler understand these optimizations, by manually setting the fallthrough address of the previous instruction as in the following screenshot :

ghidra652

I was wondering if you could make Ghidra a bit smarter, to automatically set the fallthrough address when it sees these optimizations. I suppose it is possible as I've seen a similar issue #4241 but it's for another microcontroller, however I have no clue about what they are discussing.

@pjsoberoi
Copy link
Contributor

Not sure how to handle this. I was thinking we can just define a SKIP1 instruction as a 0x65 NOP. However 0x65 is the opcode for the 3-byte CPHX instruction.

@if  defined(HCS08) || defined(HC08)
:CPHX iopr16i       is (op=0x65); iopr16i
{ 
	op1:2 = iopr16i;
	tmp:2 = HIX - op1;
	$(Z) = (tmp == 0);
	$(N) = (tmp s< 0);
	$(C) = (op1 > HIX);
	V_CPHX_flag(op1, tmp);
}
@endif

Is the instruction at 0xc9a2 valid? What happens if you clear it and assemble from 0xc9a1?

@GhidorahRex
Copy link
Collaborator

It looks like the code at 0xc9a2 is valid and the instruction at 0xc9a1 is supposed to skip it by consuming the bytes as part of a useless CPHX instruction. From a sleigh standpoint, there's no way to separate a skip2 from a valid cphx since the optimization is only " if no flags are needed afterwards," which sleigh has no method of knowing.

There may be a way through an analyzer with context to implement a skip2 instruction. The analyzer would check if the opcode at the current address is 0x65, and if there's a reference to the following address, clear the instruction, set the skip context to 1 and disassemble. This would be similar for skip1 except checking for the opcode 0x21.

define register offset=0x100 size=4 contextreg;
define context contextreg
skip=(0,0)
;

:SKIP2 is skip=1 & op=65 {
    addr = inst_start + 3;
    goto [addr];
}

:SKIP1 is skip=1 & op=21 {
  addr = inst_start + 2;
  goto [addr];

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Feature: Processor/HCS08 Status: Triage Information is being gathered
Projects
None yet
Development

No branches or pull requests

4 participants