-
Notifications
You must be signed in to change notification settings - Fork 54
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Using libraries compiled by CodeWarrior #197
Comments
I have not gone down the standalone code resource path yet because it seems like it would have many drawbacks so I consider it a last resort. And I'm not really looking at PPC yet because I understand 68K better. To convert the MPW 68K libraries (which look like they're just object files), interfaces-and-libraries.sh uses Retro68's ConvertObj to convert an MPW object file into a rudimentary assembly representation, sends that to m68k-apple-macos-as to make a gcc-compatible object file, and then runs m68k-apple-macos-ar on it to make a gcc-compatible archive out of it. The assembly is rudimentary in that it represents everything just as bytes; it doesn't attempt to show the instructions that those bytes represent. ConvertObj doesn't appear to be designed to read CodeWarrior object files. (I found one CW object decoder—mwobdec—but I don't know if it works, it was only designed for the Metrowerks PowerPC compiler on BeOS, and it is written in C# using Microsoft Visual Studio, neither of which I know anything about. This converter claims to be based on documentation of the CW object format; I've requested a copy of this documentation.) CodeWarrior Pro 5 and earlier does come with the MPW tools MWDump68K/MWDumpPPC to convert CW objects and libraries to assembly. (In CW Pro 6, this functionality has moved to MWLink68K/MWLinkPPC with the Distressingly, even a simple tiny function seems to involve the use of CW library functions. This simple C function: int answer(void)
{
int a = 6;
int b = 7;
return a * b;
} compiled with MWC68K with optimizations off and disassembled with MWDump68K becomes: Hunk: Kind=HUNK_GLOBAL_CODE Name="answer"(1) Size=38
00000000: 4E56 0000 link a6,#0
00000004: 2F04 move.l d4,-(a7)
00000006: 2F03 move.l d3,-(a7)
00000008: 7606 moveq #6,d3
0000000A: 7807 moveq #7,d4
0000000C: 2003 move.l d3,d0
0000000E: 2204 move.l d4,d1
00000010: 4EAD 0000 jsr __lmul__
00000014: 261F move.l (a7)+,d3
00000016: 281F move.l (a7)+,d4
00000018: 4E5E unlk a6
0000001A: 4E75 rts
0000001C: 8661 6E73 7765 dc.b 0x86,'answer',0x00
7200
00000024: 0000
XRef: Kind=HUNK_XREF_CODE16BIT Name="__lmul__"(2) #Pairs=1
Offset=$00000012 Value=$00000000 In other words, multiplication is handled by a CW library function |
Just another progress update...
MWDump68K outputs only the first 0x30 bytes of data hunks: Hunk: Kind=HUNK_GLOBAL_IDATA Name="Curl_easyopts"(315) Size=3780
00000000: 00 00 00 00 28 18 04 00 00 00 00 00 00 00 00 00 '....(...........'
00000010: 00 D4 00 00 00 00 00 00 00 00 00 00 27 76 04 00 '.‘..........'v..'
00000020: 00 00 00 00 00 00 00 00 00 AB 00 00 00 00 00 00 '.........´......'
...
00000EC0: 00 00 00 00 '....' That's the literal output, including the A tool to convert MW objects to MPW objects, or an MW compiler/linker flag to generate MPW objects in the first place, seems like a thing that should already exist but I haven't found it yet. MW tools can read MPW objects, but I haven't found a way to make them write them.
When a library or object is linked into a program with MWLink68K, Segment "Main" size=$054A rsrcid=1 JTindex=$0000 #JTEnts=$0000
__Startup__ $000004 size=$00010A extern file="__RuntimeModule__"
__decomp_data__ $00010E size=$000104 local
__reloc_compr__ $000212 size=$000074 local
__relocate__ $000286 size=$00002C local
__unrelocate__ $0002B2 size=$000032 local
__A5WorldCheck__ $0002E4 size=$000036 local
__A5WorldSetup__ $000312 size=$000036 local
__PatchSegmentMap__ $00031A size=$000010 local
__LOADSEG__ $00032A size=$0000C6 extern
__UNLOADSEG__ $0003F0 size=$000098 local
__PreInit__ $000488 size=$000002 extern
exit $00048A size=$000008 extern
__TrapUnpatch__ $000492 size=$000024 extern
__destroy_global_chain $0004B6 size=$000024 extern
__lmul__ $0004DA size=$000032 extern
__InitCode__ $00050C size=$000002 extern
answer $00050E size=$000026 extern file="answer.c"
main $000534 size=$000016 extern file="main.c"
I have begun looking into this, but as anticipated it is a bit of work. For one thing, every public API function will need a glue function that calls the code resource. There is some complication with the functions that have variadic arguments. The code resource will end up containing the entire library, even functions the application doesn't use; no opportunity for dead code stripping. So that'll make the final application larger than it needs to be. I could manually keep track of which library functions I use in my app and only include those in the code resource. And for a 68K code resource to work at all, it has to reference its global data via A4 not A5. I can of course compile the library with the flags to do that, but the library depends on GUSI which comes with pre-compiled libraries built for A5. It also comes with build scripts so I will have to see if I can get those working and then modified to build for A4. I'm hopeful that the code resource path will not be necessary for PPC and that and I can find a way to convert a PPC MW library/object to an MPW library/object. The library does not currently compile with Apple's MPW compilers SC and MrC, though getting that to work is another avenue I may pursue. |
I'm developing an app with Retro68 and I would like to call a third-party library that cannot be compiled with Retro68 but which can be compiled with CodeWarrior.
Is there a way to convert the compiled 68K and PPC libraries that CodeWarrior creates into a form that I can link my app with when using Retro68? I had hoped I could use a method similar to what interfaces-and-libraries.sh does, but I suspect that was designed for MPW's object format, not CodeWarrior's.
If I cannot convert them, I think I will have to have CodeWarrior compile them into a standalone code resource which my Retro68 app can then load and call, but this will involve a bit of work in wrapping the interface.
The text was updated successfully, but these errors were encountered: