Support mwcceppc.exe (Metrowerks C/C++ Compiler for Embedded PowerPC)
Currently, this program fails with the following output:
### mwcceppc.exe Compiler Error:
# ### Error: Cannot open main file ###
Errors caused tool to abort.
Test case: mwcc_example.zip
retrowin32 mwcceppc.exe -nodefaults -c in.c -o out.o
(Requires https://github.com/evmar/retrowin32/pull/19)
The included mwcceppc.exe is a version containing CodeView debugging info, so it should be easier to analyze. Here's an exported Ghidra project with many data types already set up: mwcceppc.gzf.zip (extract to .gzf then import)
The error is called @ 43f4a3, after checking for a pointer's validity:
if (cparamblkptr->sourcetext == (char *)0x0) {
// ...
_CError_CannotOpen(); // 43f4a3
If I'm analyzing it correctly, that pointer should have been set via the call @ 41fcbb:
iVar1 = _CWGetMainFileText@12
(param_1,&CompilerLinkerParamBlk_005e3eba.sourcetext,
&CompilerLinkerParamBlk_005e3eba.sourcetextsize);
I think something odd is happening in between.
Also of note is that the included lmgr326b.dll is a stub, each function exported is just return 0;. Hopefully isn't related, but thought it was worth mentioning.
Wow, super detailed repro!
I tried giving it 15 minutes to get it into my debugger but probably my quick stubs to get it to load were too stubby.
In case it helps any (and as a note to myself), the URL I was loading was
http://localhost:8000/debugger.html?dir=local/exe/mwcc_example/&exe=mwcceppc.exe&file=lmgr326b.dll&cmdline=mwcceppc.exe%20-nodefaults%20-c%20in.c%20-o%20out.o
and it was failing with
Assertion (*pb == OS_PATHSEP) failed in "MacSpecs.c" on line 267
exited with code 1
which is probably some of the path stuff not being set up.
My ghidra can't load your gzf file due to being too old, but when I just tried updating it seems my JDK is now too old, and now I'm pulled back into kid stuff, will try again when I next have time!
This ended up being a few issues:
- mwcc doesn't like when there are no environment strings: it tries to allocate 0 bytes to store them, and their malloc impl returns null. Later this null
environcauses issues. -
WIN32_FIND_DATAA's definition was wrong, it contained extra fields. This caused some stack corruption in a function that calledFindFirstFileA, overwriting a few saved registers, and would later misbehave.
Both issues were unfortunately masked by retrowin32 not faulting on zero-page addresses, so I created https://github.com/evmar/retrowin32/issues/23 to track that.
After those were resolved, it was simple to implement the remaining APIs, and now both mwcc and mwld (the associated linker) work great!