retrowin32 icon indicating copy to clipboard operation
retrowin32 copied to clipboard

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

Open encounter opened this issue 1 year ago • 3 comments

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.

encounter avatar Jul 23 '24 23:07 encounter

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 avatar Jul 24 '24 20:07 evmar

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!

evmar avatar Jul 24 '24 20:07 evmar

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 environ causes issues.
  • WIN32_FIND_DATAA's definition was wrong, it contained extra fields. This caused some stack corruption in a function that called FindFirstFileA, 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!

encounter avatar Jul 26 '24 00:07 encounter