ghidra icon indicating copy to clipboard operation
ghidra copied to clipboard

Support delay slots with a fixed number of instructions for ISAs with multiple instruction sizes

Open cyrozap opened this issue 2 years ago • 3 comments

Is your feature request related to a problem? Please describe. I have an out-of-tree processor module for a CPU whose instruction set has mixed four-byte/two-byte instructions (similar to 32-bit ARM/Thumb-2 and several other ISAs) and includes instructions that can delay by two instructions (for example, j16.d2, do.d2). The existing delayslot(N) function can only delay by a fixed number of bytes, but unlike ARM/Thumb-2 there's no mode-switching, so any instruction can be followed by an instruction of either size, not just the same size. So while for instructions that only delay by one a delayslot(2) will suffice (since the smallest instructions only have two bytes), a delayslot(4) will fail to delay by two instructions if the first instruction to be delayed by is four bytes long, and a delayslot(8) might delay by three or even four instructions depending on their sizes.

Describe the solution you'd like A new function that enables delaying by a fixed number of instructions, regardless of the sizes of the instructions that follow. So if we were to call this function delayinst(N), delayinst(1) would always delay by one instruction, delayinst(2) would delay by two instructions, delayinst(3) by three instructions, and so on.

Describe alternatives you've considered One possible solution I tried was to use a single delay slot for the two-delay-slot instructions, and then add some context on the next instruction so that it'll add another delay slot, but this caused even greater issues. It's been a while since I did that test so I don't remember exactly what those issues were, but it was either because instructions in a delay slot cannot themselves have any delay slots or because it resulted in the instructions being arranged in the wrong order (e.g., instead of one.d2; two; three becoming two; three; one, it became two; one; three). I also thought that maybe it'd be possible to use some kind of post-processing script to set the size of the delay slot for delay-by-two instructions based on the sizes of the instructions that follow them, but I wasn't sure if that was practical or even possible.

Additional context #1314 describes a similar issue but was closed, presumably because the instructions were all the same size and the user discovered they could just set the number of delay slot bytes to the product of the instruction size and the number of instructions in the delay slot. Unfortunately, the instructions I'm dealing with are not all the same size, so this solution won't work for me.

cyrozap avatar Jan 30 '22 01:01 cyrozap

The delay slot value indicates the minimum-number of bytes consumed. Frequently a value of 1 is used to consume 1 instruction of any length in the delay slot. This byte consumption value could be an issue, for more than 1 instruction in delay slot, if the instruction count is known but not the lengths. This sounds like your case.

Do you have a link to the processor manual you can share?

ghidra1 avatar Feb 01 '22 20:02 ghidra1

Do you have a link to the processor manual you can share?

Unfortunately, I'm not sure a manual even exists for this architecture. As far as I've been able to determine, MD32 is a MediaTek-designed ISA and they haven't released any documentation on it publicly.

The processor module I've been writing is the result of feeding arbitrary instructions into a closed-source disassembler for the architecture (that was released publicly by one of MediaTek's customers) to identify instruction mnemonics and encodings, then testing assumptions about instruction semantics by executing instructions on real hardware and using the processor module with Ghidra to disassemble real-world binaries. So if you'd like to read a manual for this architecture, the ghidra-md32 processor module is unfortunately the closest thing you'll get to one.

cyrozap avatar Feb 02 '22 21:02 cyrozap

I've been thinking about this issue again recently, and I had an idea on how to approach this. Would it be possible to manipulate the delay slot byte lengths in Java code? That is, during the disassembly process, some Java hooks into the disassembler, and if the current instruction has a two-instruction delay slot, the code checks the byte length of the next instruction, and if the instruction is four bytes long it sets the delay slot length to six bytes? Perhaps this would be possible with a P-code injection/override? I found a guide on P-code injection here, but I'm not entirely sure how to apply it to this problem (assuming it's possible).

cyrozap avatar Apr 03 '24 01:04 cyrozap