evmar / retrowin32

windows emulator
https://evmar.github.io/retrowin32/
Apache License 2.0
539 stars 23 forks source link

Support mwcceppc.exe (Metrowerks C/C++ Compiler for Embedded PowerPC) #20

Closed encounter closed 3 weeks ago

encounter commented 1 month ago

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.

evmar commented 1 month ago

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.

evmar commented 1 month ago

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!

encounter commented 1 month ago

This ended up being a few issues:

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!