Comments (7)
Ok, I see what's going on here.
Traditional Mac code resources (INITs) use "PC Relative" addressing in their code. This means that all jumps and function calls are stored as relative offsets in the code. Unfortunately, on the 68K, that means 16-bit offsets, hence a 32K limit on code size.
GCC uses 32-bit absolute addresses by default. Once your program/INIT/etc. gets loaded, those addresses are wrong, and RETRO68_RELOCATE() figures out just how wrong they are and patches the code in memory to correct it.
Now, the main routine of Basic Black copies a part of the INIT's code (the part between StartPatchCode
and EndPatchCode
) to a new block in the system heap, so all the carefully patched absolute addresses are wrong again. Hence the crash.
If I was writing this INIT
, I would not do the copying at all, but rather just set the resource attributes to System Heap and Locked, and Not Purgeable. Of course, this means that all the code in main()
stays in memory, so it wastes some memory, but it is much simpler. You get to use global variables and everything.
Just use the function addresses in SetTrapAddress directly, without the offset calculations, and replace PatchGlobals
and associated pointer arithmetic by simple global variables.
Warning: I might be overlooking some other important reason why the original author copied the code to a new block, so as always, there might be unexpected problems.
Theoretically (this means I haven't tested it recently and it might just break everything) gcc
supports 16-bit relative addressing via the -mpcrel
option, as long as your program is below 32KB. You might want to try that first, it might make the code magically work. But you still can't use global variables or any of the modern luxuries in the standard library in this case, because only a minimal part of your code will have been copied into the system heap.
from retro68.
Thanks so much for looking into this and the clear explanation. I'll give both of your suggestions a go and report back with my findings. Thanks again.
from retro68.
I've tried both techniques. Using -mpcrel
unfortunately wasn't the magic solution - it crashed on startup. I didn't spent much time on this though, since I'm certain my resulting code will be greater than 32kb anyway.
I spent a lot more time on your first suggestion - but no matter what I try, my patched toolbox function always crashes with a "No procedure error". It seems as if the address of the function is still not right.
I've attached the simplest of examples which just tries to patch a single toolbox function. If I could get this working then I think I can sort out the rest.
Hoping you can help?
from retro68.
This time, I don't see anything at first glance. I'll try compiling & running it myself later.
from retro68.
I've made some progress. I came across this MacTech Article on writing INITs and it says that you need to call DetachResource on your INIT resource at system startup - otherwise the OS will purge it after it's run.
My test app is no longer crashing into MacsBug with "no procedure name" - but it's still locking up the OS. I think it could simply be that I've written my patched function incorrectly.
I'll keep on chipping away at it, but attached is the updated test app if you happen to spot anything.
from retro68.
Success. The remaining problem was that I wasn't defining the global variable to the existing trap function as pascal:
typedef pascal short(*SEProcPtr) (EventRecord *);
SEProcPtr _oldSystemEvent;
...
from retro68.
Good work!
from retro68.
Related Issues (20)
- Crash when there are more than ten CODE resources when using a custom segmap HOT 1
- Using libraries compiled by CodeWarrior HOT 2
- Include order is wrong
- How do I compile a OpenGL program with this for OS X? HOT 1
- Traditional assembly files
- powerpc-apple-macos-gcc "-g" flag makes app crash
- LaunchAPPLServer crashes if disk is full
- Cannot link against libraries other than InterfaceLib HOT 1
- Failed building Samples
- Add a preprocessor macro to detect Retro68 HOT 1
- Patch: export data from PowerPC code fragments HOT 1
- "Elf2Mac has unexpectedly quit" HOT 1
- Error compiling libelf on latest Arch Linux HOT 1
- Install Fails, can't find make-multiverse.rb HOT 1
- -Wl,--gc-sections on 68k causes crashes when C++ exceptions are thrown HOT 1
- Is this project being maintained? HOT 1
- A5 ignored on asm() register-clobber list HOT 2
- ld warning after updating to latest GCC 12 version HOT 1
- Specifying an output filename HOT 1
- Compiling ResourceFile.cc fails HOT 5
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from retro68.