Renesas M16C #4804
Replies: 10 comments 22 replies
-
The processor is mostly straight-forward I think, just glancing at it for a couple minutes. Take a look at the Ghidra Sleigh Manual in the documentation. One of the biggest hurdles will be the 20-bit registers. Register banking might be a minor gotcha, but since it's only two banks, it should be easy enough to use a swap macro. You might need a context bit to make it easier to model that. These variable length instructions aren't too difficult to tackle. Just remember you'll need different tokens. It's mostly just different sizes of immediates, and they're laid out quite nicely in chapter 4. You'll need to handle them via ellipses. It looks like a fun processor. There are some unusual instructions like Good luck :-) |
Beta Was this translation helpful? Give feedback.
-
Still working on this, just been mostly trying to write out all the instructions, so I can then clean it up, before moving on to the other parts
|
Beta Was this translation helpful? Give feedback.
-
Have some basic things working now, at least. Having some trouble getting the decompiler to understand the stack? But it's progress
|
Beta Was this translation helpful? Give feedback.
-
Any thoughts on how to handle the A0 and A1 registers being zero expanded when used as the destination in byte operations? |
Beta Was this translation helpful? Give feedback.
-
Still having issues with the stack...
void CAN_RX_START(int param_1)
{
undefined *puVar1;
uint uVar2;
uint uVar3;
uint uVar5;
bool bVar6;
undefined auStack_2 [2];
puVar1 = auStack_2;
while( true ) {
uVar2 = *(uint *)(puVar1 + -3);
uVar3 = *(uint *)((int3)&DAT_0c03b0 + (uint3)(uVar2 << 1));
uVar5 = (uint)(byte)puVar1[-1];
bVar6 = uVar5 == uVar3;
if (uVar3 <= uVar5) break;
FUN_0cc96a(uVar5,uVar2);
if (!bVar6) {
FUN_0cd718(uVar2,(uint)(byte)puVar1[-1]);
}
puVar1[-1] = puVar1[-1] + '\x01';
}
return;
} |
Beta Was this translation helpful? Give feedback.
-
Continuing progress on this, updated https://github.com/silverchris/m16c/tree/master/data/languages I am having an issue with Ghidra not combining 16 bit operations into 32bit operations For example 00a
ram:000cd08b a2 dc 07 MOV.w #0x7dc,A0
(register, 0x58, 2) = COPY (const, 0x7dc, 2)
(register, 0x103, 1) = INT_SLESS (register, 0x58, 2), (const, 0x0, 2)
(register, 0x102, 1) = INT_EQUAL (register, 0x58, 2), (const, 0x0, 2)
00a
ram:000cd08e aa 0c 00 MOV.w #0xc,A1
(register, 0x5a, 2) = COPY (const, 0xc, 2)
(register, 0x103, 1) = INT_SLESS (register, 0x5a, 2), (const, 0x0, 2)
(register, 0x102, 1) = INT_EQUAL (register, 0x5a, 2), (const, 0x0, 2)
00a
ram:000cd091 a1 b4 fe ADD.w -0x2[FB],A0
(unique, 0xb00, 2) = INT_SEXT (const, 0xfe, 1)
(unique, 0xc00, 2) = INT_ADD (register, 0x66, 2), (unique, 0xb00, 2)
(unique, 0x1700, 2) = COPY (unique, 0xc00, 2)
(unique, 0x1780, 2) = LOAD (const, 0x211, 4), (unique, 0x1700, 2)
(register, 0x100, 1) = INT_CARRY (register, 0x58, 2), (unique, 0x1780, 2)
(unique, 0x1780, 2) = LOAD (const, 0x211, 4), (unique, 0x1700, 2)
(register, 0x105, 1) = INT_SCARRY (register, 0x58, 2), (unique, 0x1780, 2)
(unique, 0x1780, 2) = LOAD (const, 0x211, 4), (unique, 0x1700, 2)
(register, 0x58, 2) = INT_ADD (register, 0x58, 2), (unique, 0x1780, 2)
(register, 0x102, 1) = INT_EQUAL (register, 0x58, 2), (const, 0x0, 2)
(register, 0x103, 1) = INT_SLESS (register, 0x58, 2), (const, 0x0, 2)
00a
ram:000cd094 77 e5 ADCF.w A1
(unique, 0x9180, 2) = INT_ZEXT (register, 0x100, 1)
(unique, 0x9200, 1) = INT_CARRY (register, 0x5a, 2), (const, 0x0, 2)
(unique, 0x9280, 2) = INT_ADD (const, 0x0, 2), (register, 0x5a, 2)
(unique, 0x9380, 1) = INT_CARRY (unique, 0x9280, 2), (unique, 0x9180, 2)
(register, 0x100, 1) = BOOL_OR (unique, 0x9200, 1), (unique, 0x9380, 1)
(unique, 0x9480, 1) = INT_SCARRY (register, 0x5a, 2), (const, 0x0, 2)
(unique, 0x9500, 2) = INT_ADD (const, 0x0, 2), (register, 0x5a, 2)
(unique, 0x9600, 1) = INT_SCARRY (unique, 0x9500, 2), (unique, 0x9180, 2)
(register, 0x105, 1) = BOOL_OR (unique, 0x9480, 1), (unique, 0x9600, 1)
(unique, 0x9700, 2) = INT_ADD (const, 0x0, 2), (register, 0x5a, 2)
(register, 0x5a, 2) = INT_ADD (unique, 0x9700, 2), (unique, 0x9180, 2)
(register, 0x102, 1) = INT_EQUAL (register, 0x5a, 2), (const, 0x0, 2)
(register, 0x103, 1) = INT_SLESS (register, 0x5a, 2), (const, 0x0, 2)
00a
ram:000cd096 74 a0 LDE.b A1A0,R0L
(register, 0x50, 1) = LOAD (const, 0x1a1, 8), (register, 0x58, 4)
(register, 0x102, 1) = INT_EQUAL (register, 0x50, 1), (const, 0x0, 1)
(register, 0x103, 1) = INT_SLESS (register, 0x50, 1), (const, 0x0, 1) Turning into *CONCAT22((0xf823 < param_1) + 0xc,param_1 + 0x7dc)) Where it would make a lot more sense as *(0xc7dc+param_1) Any tips to get Ghidra to figure that out? |
Beta Was this translation helpful? Give feedback.
-
@silverchris your work is very interesting! |
Beta Was this translation helpful? Give feedback.
-
@GhidorahRex and @astrelsky |
Beta Was this translation helpful? Give feedback.
-
I'm also interested in a Renesas disasm, I saw this plugin https://github.com/redballoonsecurity/rx-proc-ghidra I don't know if this could be of help to you too? It seems to disasm my firmware fine (with Ghidra 9, the plugin wasn't made compatible with more recent versions), but I'm wondering if there would be an easy way to also map out all the interrupts, peripherals, etc from the datasheet? Could someone point me in the right way to do this? |
Beta Was this translation helpful? Give feedback.
-
You need to create an SVD file and feed it to this plugin: https://github.com/leveldown-security/SVD-Loader-Ghidra |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
-
Hi All,
Figured I would ask here before I start to attempt this myself.
Has anyone looked at implementing Renesas M16C instruction set in Ghidra?
I have been trying to wrap my head around it for the last few days, but as a relative noob to the low level implementation of processor, I am not sure if it's a task that I can do, or if it's beyond my skill level.
I think my main hurdle is trying to understand how to handle the variable instruction lengths or addressing modes they are called by Renasas.
If anyone had some pointers, I would also appreciate that.
Here is a link to the instruction set https://www.renesas.com/us/en/document/mah/m16c60-m16c20-m16ctiny-series-software-manual?language=en
Thanks in advance for any advice or help! :)
Beta Was this translation helpful? Give feedback.
All reactions