Author Topic: The Trampoline (Inside booting the Mac with a microscope)  (Read 31879 times)

Offline powermax

  • Enthusiast Member
  • ***
  • Posts: 80
  • Hobbyist programmer
Re: The Trampoline (Inside booting the Mac with a microscope)
« Reply #40 on: August 23, 2017, 07:36:48 AM »
What on earth is "deadbeef"? ???

0xDEADBEEF is often chosen as bogus value for unused variables or structure members. It hexspeaks for yourself - looking at it you know that's bogus. Plus, an access to this address will cause an exception.

Offline powermax

  • Enthusiast Member
  • ***
  • Posts: 80
  • Hobbyist programmer
Re: The Trampoline (Inside booting the Mac with a microscope)
« Reply #41 on: August 23, 2017, 07:49:47 AM »
Code: [Select]
CIcall: 1198c8 finddevice deadbeef
001198b0: 00 00 00 00 00 00 00 00 ff 80 a2 90 de ad be ef |................|

Two values shown in your snippet builds the content of the OpenFirmware TVector. This internal MacOS structure looks like that:

Code: [Select]
typedef struct TVector {
    ProcPtr    fProcPtr;
    void        *fTOC;
};

0xff80a290 is therefore the address of the client interface procedure inside OpenFirmware and 0xdeadbeef is the TOC pointer. The latter contains a bogus value because TOC isn't used in OpenFirmware.

It raises the question why does Trampoline use TVector - the mandatory structure to make inter-procedural calls in the classic Mac OS - at all? BootX doesn't do that. I assume Apple simple used a standard Mac OS compiler (MPW oder Metrowerks CodeWarrior) to produce Trampolin's binary. Calling any function via pointer will cause these compiler to generate TVecs + ptr_glue code.

Offline MacOS Plus

  • Gold Member
  • *****
  • Posts: 418
  • The 9serve Lives!
Re: The Trampoline (Inside booting the Mac with a microscope)
« Reply #42 on: August 23, 2017, 07:52:49 AM »
What on earth is "deadbeef"? ???

0xDEADBEEF is often chosen as bogus value for unused variables or structure members. It hexspeaks for yourself - looking at it you know that's bogus. Plus, an access to this address will cause an exception.

  Thanks, that context explains it's usage here quite well.

Offline Daniel

  • Gold Member
  • *****
  • Posts: 300
  • Programmer, Hacker, Thinker
Re: The Trampoline (Inside booting the Mac with a microscope)
« Reply #43 on: August 23, 2017, 12:45:06 PM »
Code: [Select]
CIcall: 1198c8 finddevice deadbeef
001198b0: 00 00 00 00 00 00 00 00 ff 80 a2 90 de ad be ef |................|

Two values shown in your snippet builds the content of the OpenFirmware TVector. This internal MacOS structure looks like that:

Code: [Select]
typedef struct TVector {
    ProcPtr    fProcPtr;
    void        *fTOC;
};

0xff80a290 is therefore the address of the client interface procedure inside OpenFirmware and 0xdeadbeef is the TOC pointer. The latter contains a bogus value because TOC isn't used in OpenFirmware.

It raises the question why does Trampoline use TVector - the mandatory structure to make inter-procedural calls in the classic Mac OS - at all? BootX doesn't do that. I assume Apple simple used a standard Mac OS compiler (MPW oder Metrowerks CodeWarrior) to produce Trampolin's binary. Calling any function via pointer will cause these compiler to generate TVecs + ptr_glue code.

Ok. This means that some code in the Trampoline (probably written in assembly) makes a TVector out of the client interface address. Then it can be called by normal c code. That explains it.

Offline Daniel

  • Gold Member
  • *****
  • Posts: 300
  • Programmer, Hacker, Thinker
Re: The Trampoline (Inside booting the Mac with a microscope)
« Reply #44 on: August 23, 2017, 01:47:59 PM »
I figured out what the 1198c8 is. It is the argument array that is passed to the client interface in r3. The Trampoline appears to always use the same location for the argument array. This lets us do some pretty neat stuff.
Code: [Select]
dev /openprom/client-services
: read-cstring 0 begin 2dup + c@ 0= if true else 1+ false then until ;
: finddevice ." finding " 1198d4 @ read-cstring type ."  . It's phandle is " finddevice 1198d8 @ 8 u.r cr ;
: open ." opening " 1198d4 @ read-cstring type ."  . It's ihandle is " open 1198d8 @ 8 u.r cr ;
: close ." closing " 1198d4 @ 8 u.r cr close ;
mac-boot

Code: [Select]
finding /chosen . It's phandle is 00000000
finding / . It's phandle is 00102519
finding /options . It's phandle is 00102557
finding /pci@f2000000/mac-io@17/ata-4@1f000/disk . It's phandle is 00106f58
finding /rtas . It's phandle is 001025d9
finding /chosen . It's phandle is 00180000
finding /cpus/@0 . It's phandle is 000000c0
finding /cpus/@0/l2-cache . It's phandle is 0010183c
finding /cpus/@0/l2-cache/l2-cache . It's phandle is 001016d8
finding /aliases . It's phandle is ffffffff
opening /pseudo-hid/keyboard . It's ihandle is 00100740
finding / . It's phandle is 00000000
finding /rom/macos . It's phandle is 00100f88
opening /nvram@fff04000 . It's ihandle is 00116960
opening /nvram@fff04000 . It's ihandle is 00116998
finding /aliases . It's phandle is 000031e9
opening /pci@f0000000/ATY,RageM3pParent@10/ATY,RageM3pB:0 . It's ihandle is 0010ff34
finding /aliases . It's phandle is 000002c4
finding /pci@f0000000/ATY,RageM3pParent@10/ATY,RageM3pA . It's phandle is 001058cc
opening /pci@f2000000/mac-io@17/via-pmu@16000/power-mgt . It's ihandle is 001166f0

This technique can be extended to any client interface service. I am pretty sure I can also make it drop into the open firmware prompt when certain conditions are met. So we can breakpoint the Trampoline at any client interface call, provided we know what values will be in the argument array beforehand.

Offline nanopico

  • Moderator
  • Platinum Member
  • *****
  • Posts: 767
Re: The Trampoline (Inside booting the Mac with a microscope)
« Reply #45 on: August 24, 2017, 06:43:20 AM »
I figured out what the 1198c8 is. It is the argument array that is passed to the client interface in r3. The Trampoline appears to always use the same location for the argument array. This lets us do some pretty neat stuff.
Code: [Select]
dev /openprom/client-services
: read-cstring 0 begin 2dup + c@ 0= if true else 1+ false then until ;
: finddevice ." finding " 1198d4 @ read-cstring type ."  . It's phandle is " finddevice 1198d8 @ 8 u.r cr ;
: open ." opening " 1198d4 @ read-cstring type ."  . It's ihandle is " open 1198d8 @ 8 u.r cr ;
: close ." closing " 1198d4 @ 8 u.r cr close ;
mac-boot

Code: [Select]
finding /chosen . It's phandle is 00000000
finding / . It's phandle is 00102519
finding /options . It's phandle is 00102557
finding /pci@f2000000/mac-io@17/ata-4@1f000/disk . It's phandle is 00106f58
finding /rtas . It's phandle is 001025d9
finding /chosen . It's phandle is 00180000
finding /cpus/@0 . It's phandle is 000000c0
finding /cpus/@0/l2-cache . It's phandle is 0010183c
finding /cpus/@0/l2-cache/l2-cache . It's phandle is 001016d8
finding /aliases . It's phandle is ffffffff
opening /pseudo-hid/keyboard . It's ihandle is 00100740
finding / . It's phandle is 00000000
finding /rom/macos . It's phandle is 00100f88
opening /nvram@fff04000 . It's ihandle is 00116960
opening /nvram@fff04000 . It's ihandle is 00116998
finding /aliases . It's phandle is 000031e9
opening /pci@f0000000/ATY,RageM3pParent@10/ATY,RageM3pB:0 . It's ihandle is 0010ff34
finding /aliases . It's phandle is 000002c4
finding /pci@f0000000/ATY,RageM3pParent@10/ATY,RageM3pA . It's phandle is 001058cc
opening /pci@f2000000/mac-io@17/via-pmu@16000/power-mgt . It's ihandle is 001166f0

This technique can be extended to any client interface service. I am pretty sure I can also make it drop into the open firmware prompt when certain conditions are met. So we can breakpoint the Trampoline at any client interface call, provided we know what values will be in the argument array beforehand.

I have seen 1198c8 in the trampoline sort of often for the parts I've gotten through. (not very much yet)
If it ain't broke, don't fix it, or break it so you can fix it!

Offline Daniel

  • Gold Member
  • *****
  • Posts: 300
  • Programmer, Hacker, Thinker
Re: The Trampoline (Inside booting the Mac with a microscope)
« Reply #46 on: August 24, 2017, 07:35:27 AM »
I figured out what the 1198c8 is. It is the argument array that is passed to the client interface in r3. The Trampoline appears to always use the same location for the argument array. This lets us do some pretty neat stuff.
Code: [Select]
dev /openprom/client-services
: read-cstring 0 begin 2dup + c@ 0= if true else 1+ false then until ;
: finddevice ." finding " 1198d4 @ read-cstring type ."  . It's phandle is " finddevice 1198d8 @ 8 u.r cr ;
: open ." opening " 1198d4 @ read-cstring type ."  . It's ihandle is " open 1198d8 @ 8 u.r cr ;
: close ." closing " 1198d4 @ 8 u.r cr close ;
mac-boot

Code: [Select]
finding /chosen . It's phandle is 00000000
finding / . It's phandle is 00102519
finding /options . It's phandle is 00102557
finding /pci@f2000000/mac-io@17/ata-4@1f000/disk . It's phandle is 00106f58
finding /rtas . It's phandle is 001025d9
finding /chosen . It's phandle is 00180000
finding /cpus/@0 . It's phandle is 000000c0
finding /cpus/@0/l2-cache . It's phandle is 0010183c
finding /cpus/@0/l2-cache/l2-cache . It's phandle is 001016d8
finding /aliases . It's phandle is ffffffff
opening /pseudo-hid/keyboard . It's ihandle is 00100740
finding / . It's phandle is 00000000
finding /rom/macos . It's phandle is 00100f88
opening /nvram@fff04000 . It's ihandle is 00116960
opening /nvram@fff04000 . It's ihandle is 00116998
finding /aliases . It's phandle is 000031e9
opening /pci@f0000000/ATY,RageM3pParent@10/ATY,RageM3pB:0 . It's ihandle is 0010ff34
finding /aliases . It's phandle is 000002c4
finding /pci@f0000000/ATY,RageM3pParent@10/ATY,RageM3pA . It's phandle is 001058cc
opening /pci@f2000000/mac-io@17/via-pmu@16000/power-mgt . It's ihandle is 001166f0

This technique can be extended to any client interface service. I am pretty sure I can also make it drop into the open firmware prompt when certain conditions are met. So we can breakpoint the Trampoline at any client interface call, provided we know what values will be in the argument array beforehand.

I have seen 1198c8 in the trampoline sort of often for the parts I've gotten through. (not very much yet)
It is safe to say that any reference to 1198c8 through 1198f4 or so has something to do with the client interface. These values will either be all over the place or will be in functions that are called from very many places. I am not sure which method is used in the Trampoline.

Offline nanopico

  • Moderator
  • Platinum Member
  • *****
  • Posts: 767
Re: The Trampoline (Inside booting the Mac with a microscope)
« Reply #47 on: August 24, 2017, 08:14:34 AM »
There is space near there too that is commonly used for other stack items.
Now that I think of it and if I am remembering right (sorry at work don't have notes or anything here).
That parameter region is the first item setup. Or the second maybe. But extremely early on.
If it ain't broke, don't fix it, or break it so you can fix it!

Offline powermax

  • Enthusiast Member
  • ***
  • Posts: 80
  • Hobbyist programmer
Re: The Trampoline (Inside booting the Mac with a microscope)
« Reply #48 on: August 24, 2017, 08:19:52 AM »
Sounds like the same thing I am doing, but most of the work after the disassembler is manual. I would say tedious is an understatement no mater which way you go. A boot loader like this is more difficult than other programs as there are no external libraries linked to help aid in identifying what is making external calls and there are no debug symbols.

Yes and no. That boot loader is actually much easier to analyze than any other program because
  • it's pretty small comparing to full-fledged applications
  • it's written in C - no classes, no virtual function calls, no callback hell
  • low-level assembly is tiny compared to said NK
  • there is no floating-point arithmetic inside, no other fancy stuff like hand crafted Altivec asm

Oh god debug symbols would be the best thing in the world for this.

Yeah, we got the booxtX code to compare with and I'm currently preparing a list of functions, their prototypes and descriptions for you to grab.
« Last Edit: August 24, 2017, 01:21:17 PM by powermax »

Offline DieHard

  • Global Moderator
  • Platinum Member
  • *****
  • Posts: 2368
Re: The Trampoline (Inside booting the Mac with a microscope)
« Reply #49 on: August 24, 2017, 08:41:24 AM »
I will not say much as I do not want to "taint" this amazing thread; I just wanted to say that you guys are truly the "Dream Team" and our heroes;  I read this one almost everyday and when there are no new responses, I usually re-read it from the top, just to get the old brain flowing again.  I have not coded assembler or C or Pascal in over 25 years, but the excitement of tracing out tight, well written code and finding a better way to "skin a cat" without introducing some bugs has always appealed to me. 

You guys are great, keep up the good work, feels like the progress is accelerating on all fronts. I doubt that anyone, even at Apple, could imagine that their secret box of treasures would be exposed to light all these years later !

Offline nanopico

  • Moderator
  • Platinum Member
  • *****
  • Posts: 767
Re: The Trampoline (Inside booting the Mac with a microscope)
« Reply #50 on: August 24, 2017, 08:55:45 AM »
Sounds like the same thing I am doing, but most of the work after the disassembler is manual. I would say tedious is an understatement no mater which way you go. A boot loader like this is more difficult than other programs as there are no external libraries linked to help aid in identifying what is making external calls and there are no debug symbols.

Yes and no. That boot loader is actually much easier to analyze than any other program because
Probably doesn't help that I am still not completely versed in ppc asm and I have this sadistic obsession with going through the code just to get a better grasp at ASM.  I figured out early on it is all written in C, but again I'm just a bit sadistic in this regard.

  • it's pretty small comparing to full-fledged applications
  • it's written in C - no classes, to virtual function calls, no callback hell
  • low-level assembly is tiny compared to said NK
  • there is no floating-point arithmetic inside, no other fancy stuff like hand crafted Altivec asm

Oh god debug symbols would be the best thing in the world for this.

Yeah, we got the booxtX code to compare with and I'm currently preparing a list of functions, their prototypes and descriptions for you to grab.

Agreed on all yes.  I guess my point of more difficult is it's interaction with the parcels.  Probably is more effort to me as I have very little time to go through it right now. Everything seems difficult at this point right now. A little overloaded at work make me kind of not want to touch any code at the moment at home. 

I will not say much as I do not want to "taint" this amazing thread; I just wanted to say that you guys are truly the "Dream Team" and our heroes;  I read this one almost everyday and when there are no new responses, I usually re-read it from the top, just to get the old brain flowing again.  I have not coded assembler or C or Pascal in over 25 years, but the excitement of tracing out tight, well written code and finding a better way to "skin a cat" without introducing some bugs has always appealed to me. 

You guys are great, keep up the good work, feels like the progress is accelerating on all fronts. I doubt that anyone, even at Apple, could imagine that their secret box of treasures would be exposed to light all these years later !

I'm sure all of use appreciate the sentiment.
If it ain't broke, don't fix it, or break it so you can fix it!