Complete rewrite

This commit is contained in:
Elliot Nunn 2020-09-20 16:40:34 +08:00
parent 6007b23086
commit 1cf462dd0a
4 changed files with 10455 additions and 687 deletions

View File

@ -1,34 +1,33 @@
Everything I know about the obscure "linked patch" system
programming/binary interface in System 7.1-??
The "Linked Patches" are an unusual 68k code format in the System
resource fork of Mac OS 7-9. They contain initialization code to run at
boot and runtime code for installation in RAM-based vector tables.
The idea was to provide a macro-based interface that a 68k assembly
programmer could use to create RAM-based "patches" for a newly booted
MacOS system. Similar patches were needed even in the original Macintosh
System Software to fix bugs in the shipping ROM. Runtime patching also
came to be used to add new software features to old Mac models. But
writing a patch in pure 68k assembly, especially a "come-from" patch,
was very tedious and usually required self-modifying code.
The first Linked Patches shipped in the interdependent 'lpch' resources
of System 7.0.
The linked patches incrementally improved that situation. Here is a
summary of the design decisions made:
From System 7.5, 'gpch' resources contained groups of functionally
related 'lpch' resources. A group could be loaded or not according to
the host machine. This was controlled by one 'gusd' and multiple 'gtbl'
resource.
- A library of 68k macros provided a nearly-declarative way to describe
to installation process for a given patch.
- The runtime RAM usage was minimised by separating installation from
runtime code, and by segmenting each code module at build time
according to its target ROM releases.
- Advantage was taken of the huge commonality carefully between
Macintosh ROM releases, which was painstakingly maintained by binary
patching and "overpatching".
- Object files containing patches woulod be linked into resources by a
full linker, making dead code elimination available and allowing the
direct inclusion of code originally meant for a ROM build.
- Runtime self-modification of code was done almost entirely by a
generic runtime loader, instead of allowing each patch writer to come
up with a unique and uniquely buggy solution.
- Special assembly facilities were made available to ease the writing of
come-from patches (patches that wrested control from a buggy segment
of ROM by hijacking a possibly unrelated trap in the vicinity).
Specifically, it was easy to describe the address of the target trap
and to produce code that would test that the trap was indeed being
called from that address.
`patch_rip.py` is a Python 3 script to dump a group of 'lpch' resources
(or a single 'gpch' resource) to text.
## Usage
First, `pip3 install macresources` to get the `rfx` command-line tool,
which exposes the resources inside a resource fork like regular files.
Then point `patch_rip.py` at the System file of interest:
rfx ./patch_rip.py System/..namedfork/rsrc//lpch/ # macOS 10's kernel resource fork support
rfx ./patch_rip.py System.hqx//lpch/ # BinHex file
rfx ./patch_rip.py System//lpch/ # Rez file named "System.rdump"
To dump a numbered 'gpch' file instead, replace `//lpch/`, which expands
to a path for each lpch resource, with `//gpch/NNN`, which expands to a
single path.
The output is not disassembled, but it is annotated with the known
locations of specialised "jsr" instructions, etc.

View File

@ -1,25 +0,0 @@
#!/bin/bash
cd "$(dirname $BASH_SOURCE)"
VANILLA=~/Documents/mac/primary/Sys710x.rdump
SUPERMARIO=~/Documents/mac/supermario/worktree/cube-e
BUILT=$SUPERMARIO/BuildResults/System/System.rdump
RH="-rh $SUPERMARIO/BuildResults/System/Lib/LinkedPatches.lib"
SH="-sh $SUPERMARIO/BuildResults/System/Text/LinkPatchJumpTbl"
COMMON="-w 16 $RH $SH"
for MODE in pt pm pr pj pjh pp; do
(
./patch_rip.py -$MODE $COMMON $BUILT >/tmp/elliot-$MODE-lpch
./patch_rip.py -$MODE $COMMON $VANILLA >/tmp/apple-$MODE-lpch; echo >>/tmp/apple-$MODE-lpch
git diff --no-index -U999999999 /tmp/elliot-$MODE-lpch /tmp/apple-$MODE-lpch >lpch-$MODE.patch
true
) &
done
for job in `jobs -p`; do
wait $job
done

View File

@ -1,137 +0,0 @@
# This is a manually compiled file showing the layout of the "linked patches" in System 7.1.0
# patch_rip.py is used to grab the code from each 'lpch' resource, which is then fed into IDA and
# compared to the SuperMario sources.
# The idea is to get the linked patches building to a byte-perfect System 7.1
# (This is one of the last steps to a perfect 7.1 from the SuperMario sources!!!!!)
# Unhappy suspicion: the Power Manager will be very hard to restore to its old state
# Format:
# <hex offset> <file> <symbol>
lpch 1 1614b(1432b) Plus
0 SCSILinkPatch.a SCSIBusyPlusInstall
C FileMgrPatches.a SaveD1AcrossBTDelete
1E FileMgrPatches.a SaveD3AcrossBTSearch
30 FileMgrPatches.a SaveD1AcrossBTInsert
42 FileMgrPatches.a SaveD3AcrossBTGetRecord
54 FileMgrPatches.a KillCheckRemountSickestWay
8C LaterFileMgrPatches.a MountVolPatch
BA LaterFileMgrPatches.a MFSRenamePatch
E4 ???
F0 AllB&WQDPatch.a PatchStdRgnPlus
150 AllB&WQDPatch.a MyPutRgn
1B2 DrawPicturePlusSE.a FixPStdBits
1BC DrawPciture32Patch.a FixStdGetPicInGetPicData
1C6 ???
2EA Mouse.a MouseMapping
49A ResourceMgrPatches.a UpdateResFileNewHandleFailure
4D0 ResourceMgrPatches.a UpdateResFileDisposeHandleCleanup
512 ResourceMgrPatches.a FixSuperLoadEquates
540 ResourceMgrPatches.a BadMapCheckInCheckMap
57E ???
lpch 2 208b(172b) SE
0 ???
24 SonyPatches.a SetupDCDDriveNumberForSE
2E BrightnessPatches.a ClassicBrightPatch
90 BrightnessPatches.a csCodeCheck
lpch 3 9443b(9056b) Plus,SE
lpch 4 9594b(9220b) II
0 MMUPatches.a SwapHMMU
5A MMUPatches.a InstallSwapPMMU
90 MMUPatches.a SwapPMMU
178 MenuMgrPatch.a SetClipForCallDrawMDEF
1AC MenuMgrPatchII.a IIDeleteMenu
1EC MenuMgrPatchII.a IIGetMHandle
214 MenuMgrPatchII.a IIBothMenuSelects
530 MenuMgrPatchII.a IIMenuSelect
692 MenuMgrPatchII.a IIHiliteMenuFix
6A6 MenuMgrPatchII.a IIMenuSelectFix
6F2 MenuMgrPatchII.a IIMenuMgrSysErrors
720 MenuMgrPatchII.a IIGetItemCmd
728 MenuMgrPatchII.a IISetItemCmd
730 MenuMgrPatchII.a IIInsertMenu
7E4 MenuMgrPatchII.a IICountMItems
822 MenuMgrPatchII.a IIDrawMenuBar
834 MenuMgrPatchII.a IIDelMenuItem
864 MenuMgrPatchII.a IICalcMenuSize
880 MenuMgrPatchII.a IISetMenuBar
88A MenuMgrPatchII.a IIAppendOrInsertItem
990 MenuMgrPatchII.a IIDelMCEntries
9E2 MenuMgrPatchII.a AfterLoadResourceInGetTheMProc
A22 SlotMgrPatch.a InstallSlot
A74 SlotMgrPatch.a CopyBlock
A94 SlotMgrPatch.a RestartSlotMgr
AC0 SlotMgrPatch.a sInfoMerge
... C8E EOF
?????
C7A SlotMgrInit.a InitJmpTbl
1214 SlotMgrInit.a Secondary_Init
1332 SlotMgr.a SlotMgr
... 21E6 EOF
21E6 DialogMgrPatches.a DrawItemSetPort
2214 DialogMgrPatches.a DisposDialogFix
2236 DialogMgrPatches.a NoIctbDisposeInCloseDialog
2250 DialogMgrPatches.a NoDetachResourceInDoColor
2264 DialogMgrPatches.a DuplicateColorTableInNewDialog
228A QuickDrawPatches.a CharExtraFixDiv
22BC QuickDrawPatches.a RgnOpStackSpace
232C WindowMgrPatches.a NoChangeInGrowWindow
234A WindowMgrPatches.a DoActivatePalette
2368 WindowMgrPatches.a MoveWindowActivatePalette
... 23EA EOF
?????
lpch 6 1883b(1806b) SE,II
lpch 7 1170b(962b) Plus,SE,II
lpch 8 5638b(5528b) Portable
0 AllB&WQDPatch.a PortablePatchStdPoly
24 DrawPicturePortable.a PortableDrawPicture
...A20 EOF
A20 ??? PowerMgrPatch that has since disappeared
???
1172 PowerMgrPatches.a SCCWakeFix
11AE PowerMgrPatches.a SndWatch
???
12B0 PowerMgr.a MPPOpen (this one goes to 13DE)
13DA PowerMgrPatches.a InitializeStrings
1440 PowerMgrPatches.a LoadString
1450 PowerMgrPatches.a GetDetachRes
1460 SonyPatches.a RecalPatch
14BE backlightpatch.a BklightInstall
lpch 10 69b(36b) SE,Portable
lpch 11 21849b(21094b) Plus,SE,Portable
lpch 15 19949b(19750b) Plus,SE,II,Portable
lpch 16 25488b(24488b) IIci
lpch 20 25282b(24986b) II,IIci
lpch 22 219b(166b) SE,II,IIci
lpch 23 32b(16b) Plus,SE,II,IIci
lpch 24 767b(640b) Portable,IIci
lpch 27 23b(0b) Plus,SE,Portable,IIci
lpch 28 842b(688b) II,Portable,IIci
lpch 30 168b(96b) SE,II,Portable,IIci
lpch 31 254504b(247434b) Plus,SE,II,Portable,IIci
lpch 32 13b(0b) SuperMario
lpch 63 2746b(0b) Plus,SE,II,Portable,IIci,SuperMario

11009
patch_rip.py

File diff suppressed because it is too large Load Diff