Intel MPX

Intel defines their MPX features for x86 on 11 pages starting on physical page 371 here. Gcc plans to use these features. Their comments helped me understand the hardware. useful,
In memory safe languages that I am familiar with code with access to an array A of ints, can call a routine that takes a reference to an int passing access to A[3]. The routine gets a pointer to just A[3]. In C the expectation is that the routine can access A[2] as well. The implication is that three full pointers (3∙64 bits) must be passed. In the safe languages just 64 bits need be passed. This is expensive. To call a routine that takes access to an array, 2∙64 bits, or perhaps 64+32 bits must be passed. Compiled code for safe languages that I familiar with create a dope vector that includes this information. The dope vector includes array origin and index bounds. Only the address of the dope vector is passed. The dope vector is created when the array is allocated, and when its size becomes known.

I am leaning to the view that the MPX feature is an attempt to make C into a safe language. It would be fairer to say “a safer language” for I have seen no claim that MPX was fool-proof.

For the memory safe languages it is assumed that calls across independently compiled units have seen the same function prototypes and declarations of global variables. A loader could enforce this with a little help from the compiler but I don’t know of any attempt to do this. (The loader might demand a secure hash of types of external symbols.)

Figure 16-4 real page 377 of Intel’s manual (q.v.) is a strange diagram describing a structure that given the memory address of the memory address of X is converted to the address of a bound pair that is supposed to bound X. Section 16.4.3 explains the diagram. A pessimistic interpretation of this structure would lead you to think that for every byte of storage devoted to data including pointers, 4 bytes of “Bound Table Entries” are required. It is not nearly that bad because 1MB spans of data memory storing no pointers cost nothing and 1KB spans without pointers cost only virtual memory. There are further economies in the cache. Still such a structure for a modern language such as Scheme, Lisp, OCaml, are likely to need five times as much real data memory.

The problem, as I see it, is that there is no standardized dope vector. The convention is for code to call other code using C conventions, despite the input language to the compiler. Various compilers have their private conventions for messages between independently compiled modules. One argument is whether all index ranges start at 0. Another is how big the range should be. (PL/I had a 16 bit limit early on. That was too small.) I wrote much assembler code to call and be called by compiled code. It was easy. With a suspicious loader, honest assembler code and a bug-free compiler, that would have been memory safe.