-
Notifications
You must be signed in to change notification settings - Fork 6
Displaying Capabilities
When CHERI capabilities are used in pointers in C, it is helpful for developers to provide a human-friendly format for properties of pointers beyond the address such as bounds and permissions. This document defines a few different formats for displaying capabilities as well as contexts for displaying them.
Different contexts may use different formats.
The simplest format for displaying a capability is to display the raw contents of the capability as a hexadecimal value. This may or may not include the tag (TBD?).
An example use of this format is p/x of a capability in CHERI GDB.
Format:
<capability>
Fields:
-
capability: Hex value of capability bytes.
Another simple format for displaying a capability is to display the address of a capability as a hexadecimal value. This should generally match the existing format used with integer pointers.
An example use of this format is the printf(3) %p format when used in pure-capability CHERI C.
Format:
<address>
Fields:
-
address: Virtual address of capability.
Initially, CHERI projects used a verbose format which displayed all possible fields of capabilities as separate hex values. However, this format had a couple of disadvantages. First, it was quite broad (over 80 characters for a single pointer). Secondly, it still required manual decoding of fields such as permission bits and object types. The simplified format aims to provide a more concise format which provides details that are generally applicable to most developers using CHERI C such as basic permissions. It does omit some details such as more obscure permissions and most object types. In addition, for null-derived capabilities (capabilities where the tag and upper attribute word are all zero), only the address is displayed (the Basic Format).
An example use of this format is the printf(3) %#p format when used in pure-capability CHERI C.
Format:
<address> [<permissions>,<base>-<top>] (<attr>)
-
address: Virtual address of capability displayed as a hexadecimal value with a0xprefix. -
permissions: Zero or more of the following characters:-
r: LOAD permission -
w: STORE permission -
x: EXECUTE permission -
R: LOAD_CAP permission -
W: STORE_CAP permission -
E: EXECUTIVE permission (Morello only)- Could be
Xinstead so we haverwxRWX, though we may wantXfor ASR instead
- Could be
-
-
base: Lower bound of capability displayed as a hexadecimal value with a0xprefix. -
top: Upper bound of capability plus 1 displayed as a hexadecimal value with a0xprefix. -
attr: Zero or more of the following comma-separated attributes. If none of the attributes are present, this field is omitted (along with the enclosing parentheses/brackets).-
invalid: Capability's tag is clear. -
sentry: Capability is a sealed entry. -
sealed: Capability is sealed with a type other than the sealed entry object type.
-
In some cases, all of the details of a capability may be desired (for example, when working with code that uses sealed capabilities). For these cases, a verbose (but readable) format should be defined. Ideally such a format would retain human-friendly display of fields such as permissions when possible while providing details of all of the fields of a capability.
Ideally, displaying capabilities in this format would be provided in debuggers.
Format:
TBD
Both pure-capability and hybrid CHERI C implementations should permit the display of capabilities via printf(3) via the p format specifier.
By default, the p specifier should print the address of the capability (the Basic Format) matching the format used for integer pointers in plain C for the given platform. Different environments display pointers differently (for example BSD kernels and C libraries display integer pointers as hexadecimal values with a 0x prefix, whereas the Linux kernel displays integer pointers as hexadecimal without a 0x prefix), and p should match a platform's existing format.
In addition, the following additional format specifiers are defined in CHERI C:
-
The
lmodifier can be used with thepspecifier to indicate that the argument is avoid * __capabilityrather than avoid *.For hybrid CHERI C,
paccepts integer pointer arguments by default (void *). This modifier allows a capability to be passed instead. To ease portability between hybrid and pure-capability CHERI C, pure-capability CHERI C also accepts (but ignores) this modifier. In pure-capability CHERI C,void *is already a capability. -
The
#modifier can be used with thepspecifier to request that a capability be displayed using the Simplified Format.To ease portability, this modifier is ignored if it is used with an integer pointer in hybrid CHERI C.
-
An optional precision can be used with the
pspecifier.If given, the precision is used to determine the width of addresses (address, base, and top) displayed in the Simplified Format. Each address should be zero-padded if necessary to meet the desired precision. Note that the precision applies to the hexadecimal digits displayed for each address and does not include the
0xprefix.
If a field width is provided for the p specifier, that field width should be applied to the result of the entire output string generated by the Simplified Format when used with the # modifier.
-
EvsXpermission (see above) - Should absent permissions be denoted by a
-similar tols -loutput? When used with precision, this would provide a fixed-width format which is nice for dumping tables of registers. - Other permissions? ASR could be useful and is likely to stick around. S and U are useful but in an otype-less world with just sentries those would no longer be needed.
- ASR may make sense as
X: just as LOAD_CAP gates access to specific types of loads, ASR gates access to specific types of instructions. - We may also want to show flags (e.g. cap mode for risc-v)
- For RV{32,64}Y,
cshould be used instead ofRandW