I hope here to describe some but not all detail of how an object may be defined at the machine level detail for a conventional machine. The intent is to provide the protection expected by objects and their callers by means of conventional (2018) hardware. Keykos achieves this and these pages describe how in too much detail for some purposes. We strive for some flexibility here.
We presume that the behavior of objects is defined by unexamined machine code and likewise the callers of those objects. This means that some novel trusted runtime code is needed to augment the classic protection hardware to establish such protection.
The conceit is that an object is defined by its behavior and state. The machine version of an object is thus composed of a pointer to code to provide the behavior, broadly shared by objects of the same behavior and some mutable data that provides the state. One of the protection dogmas is that the code of an object is the only program which reads and writes the state of that object. Another dogma is that a flaw discovered in an object’s may not be exploited so as to damage behavior of other objects sharing the same code and behavior.
Relying on conventional hardware the protected code and data reside in pages and one page is often insufficient. Some collection of pages is often arranged to form a larger unit called a segment. If the algebra of segments allows some segment may deliver both the read only program and read write data, and, for that mater, segments possibly shared with other objects. Conventional hardware frequently provides special support for some segment sizes and resulting economy by allocation of address ranges conforming to powers of two.
Programs would presumably like to view object invocation as an instruction which takes some data and returns some data. Many instructions deal exclusively with register data. It is nice to follow this pattern when possible.
The pattern I use to reason about security as provided by capability systems is to imagine the calling of an object as the creation of a ‘message’ which is delivered to the object’s code to be used by that code as it sees fit presumably according to its charter. Much cap history leads to the notion of the invoker being able to choose any capability it holds and including it in a message to another object. These notions result in decreeing that a message include arbitrary capabilities The sender can include any cap he has and the receiver gets that cap which becomes one of his held capabilities at an address of his choice.
In view of the preceding paragraph we propose declaring that a message hold some finite number K of caps along with some bounded amount of data. K is a system design parameter, not a property of the message. Cap systems typically have a null cap conveying no authority which can be:
While the call return pattern remains the dominant dynamic relationship between objects it is not the only one. The continuation pattern seems more convenable to the machine level and is provided by the ‘reply capability’ q.v.. This also relieves the kernel from the obligation of keeping track of many stacks, while expanding available control patterns such as co-routines.
1: The code of an object is the only code which reads and writes the state of that object.
2: A flaw discovered in an object’s may not be exploited so as to damage behavior of other objects sharing the same code and behavior.
3: Dogma 2 is a consequence of a more fundamental dogma: Two objects can influence each other only as allowed by capabilities they hold; even capabilities sharing the same behavior. Such shared state is indeed a useful common pattern easily arranged by providing their state with mutating capabilities to some mutable object with the shared state.
Implicit assumptions such as