[CDG5] MPW code mysteries

Elliot Nunn elliotnunn at fastmail.com
Fri Dec 28 12:02:39 AWST 2018


I have to re-learn the AIX-style ABI every time I touch it, so bear with
me.

Apple's docs reveal the implementation detail that every C function
pointer is actually a pointer to a TVector.

(For those following along, a Transition Vector is an 8-byte structure
consisting of a true code pointer and a pointer to the "Table of
Contents" for that code. The TOC is analogous to an old-style 68k A5
world, except that a called function can assume that r2 already points
to the TOC on entry. Therefore functions that call outside their own
code fragment must do so through glue code that sets r2 to the callee's
TOC, and each such bl instruction must be followed by an instruction to
restore r2 to sanity.)

So I'd just cast the function ptr to a TVector pointer and modify it
that way:

(*(unsigned long **)funcPtr)[0] = 0xdeadbeefUL;

> On 28 Dec 2018, at 11:15 am, Max Poliakovski <maximumspatium at googlemail.com> wrote:
> 
> Fellow hackers,
> 
> I'm currently trying to get MPW 3.5 (from EMPW) to generate code closely resembling the original Trampoline.
> 
> While doing so, I immediately stumbled across two issues I cannot resolve. I must admit that my MPW skills are limited. I therefore hope to get some help from you.
> 
> 1) Trampoline's startup code initializes the RTOC as follows:
> 
>     mflr r11
>     bl setup_rtoc
>     DC.L 0x1001E8
> setup_rtoc:
>     mflr RTOC
>     lwz RTOC, 0(RTOC)
> 
> The word in the 3rd line contains the base address of TOC. The value shown above is from Apple's binary. I replaced it with DC.L TOC[TC0] to make PPCAsm/PPCLink to stuff the correct value there. That unfortunately doesn't work. PPCAsm says:
> 
> ### Warning 3171 ### Treating 'TOC[TC0]' as a csect relative offset. Make sure to add it to its csect's TOC entry.
> 
> I don't understand this message. What do I need to put there in order to get the base address of TOC placed there?
> 
> 2) Trampoline's main() initializes the pointer to OF client interface right at the beginning. The code of interest looks like that:
> 
> lwz r9, CIPtr_TC(RTOC)
> lisori r3, 0xdeadbeef
> stw r5, 0(r9)
> stw r3, 4(r9)
> 
> The pointer to the OF client dispatcher is in R5 (3rd argument of main). The TOC pointer is initialized to 0xDEADBEEF. That's exactly what I cannot reproduce. I defined a correct function pointer like that:
> 
> typedef long (*OfCiPtr)(CIArgs *args);
> static OfCIPtr gCIPtr;
> 
> void main(int argc, int arg[], OfCiPtr ciPtr)
> {
>     gCIPtr = ciPtr;
> }
> 
> When I initialize that global pointer gCIPtr with value from ciPtr (3rd argument), only the function address is written while the TOC value remains untouched. The compiled code looks like that:
> 
> lwz r9, CIPtr_TC(RTOC)
> stw r5, 0(r9)
> 
> I wonder how Apple guys managed to put 0xDEADBEEF into TVector's TOC? Do you have any clue?
> _______________________________________________
> cdg5 mailing list
> cdg5 at ucc.asn.au
> https://lists.ucc.gu.uwa.edu.au/mailman/listinfo/cdg5



More information about the cdg5 mailing list