Subject: Questions about SVR4 ABI
To: None <port-macppc@netbsd.org>
From: Tim Kelly <hockey@dialectronics.com>
List: port-macppc
Date: 10/18/2004 09:28:46
Hi All,
I've found a copy of the System V Application Binary Interface PowerPC
Processor Supplemental and I've been reading through it. In order for me
to be sure I understand some of the terminology/concepts, I had a couple
questions:

In the MacOS Preferred Executable Format (PEF), which is sort of
related to XCOFF, there were segments of executable code that would be
grouped as "code fragments." I vaguely recall that there was a limit to
how much executable code could be contained in a single fragment, and it
would not surprise me to learn that it 32 or 64M, similiar to what is
mentioned in SVR4 ABI (as a limitation of the bl* instructions). The
compiler was responsible for determining the size of the code fragments.
If a function call was outside of the local code fragment, and all
"MacOS Toolbox" calls were outside of the local code fragment, the
compiler had to put in "cross-RTOC glue." This glue consisted of a
prologue and epilog that sandwiched a jump to a transition vector,
which is what pointed to the actual location of the function call. The
transition vector was a symbol in the TOC (Table of Contents,
and the register containing it is the RTOC) that was resolved by the
MacOS Code Fragment Manager (CFM) at the time the executable was loaded
into memory. An unresolved symbol could either result in a termination
exception or be handled properly if the programmer checks for proper
resolution of symbols before calling them.

1) In the SVR4 ABI, there are references to the dynamic linker. Is this
the same as the CFM of MacOS?

2) Is the Global Offset Table (GOT) the same as the TOC in MacOS?

3) Or is the Procedure Linkage Table (PLT) the equivalent of TOC? I'm
not sure that there is an equivalent function in MacOS to PLT. 

As I referenced above, MacOS Toolbox calls were cross-RTOC and resolved
only during the loading of the particular code fragment (which had
overhead entry and exit functions). Subsequent code written into memory
did not get Toolbox calls resolved, to the best of my knowledge (I'm
familiar with calling libraries dynamically from a master application). 

4) Is is possible to enforce lazy linking, as the SVR4 ABI calls it,
being off?

In MacOS, almost all of the operating system executed at user level in
the PowerPC. There was a small portion, which Apple referred to as a
"nanokernel," that I believe ran in supervisor mode (this is from 8.6
on). As such, the PowerPC instruction "sc" (System Call) had almost no
effect. Obviously this is not the case with *BSD.

5) Is it possible to create a "wrapper" for sc in *BSD in which the
wrapper is dynamically linked to instead of sc, and the wrapper creates
the environment the kernel expects to see at the time of the call? The
goal would be to create a "canary" value at the time the wrapper is
resolved during loading and if the canary is not present during
subsequent execution that calls sc, an exception is generated. By
enforcing lazy linking being off, any code written into memory after the
executable is loaded would not resolve the wrapper and therefore the
canary would not be present.

6) If it is possible, would such a wrapper be completely contained
within libc, or are there other places it would need to go?

(My initial thought would be that the canary value would be contained
somewhere accessible only through the linker and while in supervisor
mode, so as not be gleaned within the executable itself.)

7, and last for now) Has anyone examined the possibility of taking an
alternative approach from Mac-On-Linux's rooted window to using MacOS
applications, by utilizing the TOC of a Mac application to dynamically
resolve MacOS Toolbox TOC symbols to X graphics routines and make the
Mac apps rootless?

thanks in advance,
tim