Age | Commit message (Collapse) | Author | Files | Lines |
|
Initial detection of Arm Morello architecture from the HWCAP2 bit and CPU
identification from MIDR_EL0.
TODO: not needed?
- lp64 does not have to detect
- purecap can assume morello
|
|
Assembly prologue code with mcount call for gprof instrumentation.
TODO: untested, likely needs further runtime updates too.
|
|
This is needed now to avoid referencing abort in ld.so.
TODO: Fixing shared library profiling for capabilities requires
type fixes so capabilities are not stored into shared memory
(maybe purecap layout can match the lp64 one and then no file format
and external tooling change is required.)
TODO: Proper fix also depends on _dl_runtime_profile plt entry
|
|
Required for LD_AUDIT PLT hooks and shared library profiling.
incomplete, untested.
TODO: needs La_aarch64* layout definition for morello
TODO: needs to save c9 for vararg abi
|
|
Adjust types in the E(*) structs to support capabilities.
TODO: purecap pldd should refuse to deal with lp64 and ELF32 processes.
the code for the 32bit case should be disabled.
TODO: a correct fix requires support for all abis that can run on the
same system (purecap, lp64 and ELF32 too).
|
|
Updates libc.abilist files for getauxptr to version 2.37.
|
|
|
|
New function to return values from the auxiliary vector as
capabilities. This is the same as implemented by other C libraries.
TODO: agree about exact semantics across libcs
|
|
TODO: the value will change
|
|
TEST_COMPARE should allow comparison between two capability values.
|
|
This adds a new modifier %#p for printing capability information
according to the CHERI C Programming guide:
https://github.com/CTSRD-CHERI/cheri-c-programming/wiki/Displaying-Capabilities
A %#p option in printf will display:
<address> [<permissions>,<base>-<top>] (<attr>)
* address: Virtual address of capability displayed as a hexadecimal
value with a 0x prefix.
* 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)
* base: Lower bound of capability displayed as a hexadecimal value
with a 0x prefix.
* top: Upper bound of capability plus 1 displayed as a hexadecimal
value with a 0x prefix.
* 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.
A %p option in printf will display the capability value (address) normally.
|
|
In pthread_attr_setstack fail with EINVAL if the input stack does not
meet the PCS constraints.
|
|
TODO: depends on kernel sigevent definition update.
|
|
We need to distinguish timerids that are small integers returned by
the kernel and timerids that are pointers to struct timer. The existing
pointer tagging does not work for CHERI because of the pointer shift.
Simply use the top bit without shift to tag pointers. This still relies
on the top byte ignore of aarch64 (the top byte does not affect the
capability representation) and that pointers are not tagged for other
reasons (like HWASAN).
TODO: this is morello specific and does not work for generic cheri.
|
|
TODO: needs agreement across cheri libcs
|
|
TODO: depends on l_addr design
|
|
Add morello specific dl-machine.h.
Add morello dynamic relocation processing support for purecap ABI.
Only support R_AARCH64_NONE, R_AARCH64_ABS64 and R_AARCH64_RELATIVE
dynamic relocs from the lp64 abi. This required several APIs to
change ElfW(Addr) to uintptr_t including in generic code (where
elfptr_t used to cover both traditional and capability abis).
RELATIVE and IRELATIVE relocs use a helper function to construct a
capability. Also fixed the IRELATIVE handling for static linking.
Use new machine routines on morello for load address computation so it
is a valid capability:
void *elf_machine_runtime_dynamic (void)
uintptr_t elf_machine_load_address_from_args (void *)
The ld.so load address is either AT_BASE or if it is invoked as a
command then derived from AT_PHDR or _DYNAMIC (pcc).
ELF_MACHINE_START_ADDRESS is updated to turn the ElfW(Addr) user entry
into a capability based on l_addr.
TODO: __tls_get_addr should return a bounded pointer.
(in case traditional tls is defined for morello)
note: tls_index struct that is used for trad tls is changed for morello.
(this is abi once trad tls is defined for morello)
arguably _dl_make_tlsdesc_dynamic should set up tlsinfo.ti_size too.
(but it's better to avoid changing the generic code)
TODO: use cheri auxv entries to derive ld.so capabilities, this will
require separate RW and RX base pointers instead of single l_addr.
AT_BASE will not be a capability covering ld.so.
|
|
Prevent lp64 ld.so loading purecap binaries.
|
|
|
|
Ensure map_end is derived from map_start.
Use stricter mmap bounds when using MAP_FIXED:
c->mapend is aligned up to pagesize, but the capability representing
the mapping has bounds that are not page aligned, so use c->dataend
that is the actual end bound of the loaded segment.
TODO: l_addr of a pde is 0 but it should cover the exe.
this will have to be fixed. (and must not use morello asm)
|
|
TODO: requires follwup patches to make sure all usage of the fields
preserve capabilities.
|
|
|
|
Functions returning a pointer to the user entry need to use an int type
that can represent pointers.
|
|
The purecap version of aarch64 dl-start.S. Note: self relocation of
ld.so is handled by the rtld bootstrap code.
|
|
The dynamic section cannot be relocated to hold pointers in place.
|
|
Add purecap ld cache flag. Add the purecap ld.so name to known names.
Handle lib64c system library paths. And set the purecap abi flag on
cache entries.
|
|
The asm code of the test is for lp64 ABI only.
|
|
Adjust ucontext layout for purecap ABI and add make/get/set/swapcontext
implementations accordingly.
Note: mcontext layout follows the linux sigcontext struct, in userspace
*context functions rely on the c registers stored in the extension area
and ignore the mcontext fields for x registers.
|
|
Similar to lp64 setjmp/longjmp, but handles capability registers.
Save q regs instead of d regs to simplify the offset computation.
|
|
We should use a type that guarantees to represent all address bits.
In CHERI C this would be ptraddr_t, but we use unsigned long for now
not to cause regressions on other targets where this type is missing.
|
|
If sizeof(ptrdiff_t) < sizeof(void*) the alignment logic was wrong
(incorrectly assumed that base was already sufficiently aligned).
Use more robust alignment logic: this one should work on any target.
Note: this is an installed header so it must be namespace clean and
portable.
|
|
This is the right type as the values hold pointers.
|
|
|
|
Such arithmetic invalidates capabilities so this security measure does
not work for CHERI.
Note: the architecture makes it hard to corrupt pointers in malloc
metadata, but not impossible: current allocation bounds include the
metadata and capabilities are not revoked after free. These issues can
be fixed by a capability aware malloc.
|
|
Avoid integer casts and arithmetics that invalidates capabilities.
|
|
This code updates pointers to a reallocated buffer to point to the new
buffer. It is not conforming (does arithmetics with freed pointers),
but it also creates invalid capabilities because the provenance is
derived from the original freed pointers instead of the new buffer.
Change the arithmetics so provenance is derived from the new buffer.
The conformance issue is not fixed.
|
|
USE_MALLOC_LOW_BIT should work for capabilities too, but we need to
ensure that pointer provenance is right: the red/black flag is
computed as uintptr_t, but with uintptr_t | uintptr_t it's not clear
which side provides the provenance.
So use unsigned int type for the flag (which is the type used in case
of !USE_MALLOC_LOW_BIT anyway), then unsigned int | uintptr_t works.
The type of RED is corrected too to match unsigned int.
|
|
On capability targets avoid copying pointers via unsigned long.
|
|
Make wctype_t a pointer so dereferencing it works. wctrans_t is already
a pointer and used the same way.
Existing targets are not affected, only capability targets where this
is necessary.
|
|
Using const on the definition does not work for a pure capability ABI:
the capability permissions when accessing the object will be read only.
Use a hack to hide the public declaration in the TU where the const
objects are initialized. (This should work on non-capability targets
too, but to err on the safe side only enable the hack on capability
targets.)
|
|
|
|
|
|
Alignment of the public definition did not match the internal layout.
Ensure that the type is at least pointer aligned.
|
|
|
|
Arm Morello requires 128-bit atomics.
|
|
start/end should be capabilities now that l_addr is a capability.
|
|
According to the ELF spec:
"Each element of this array is a pointer to a function to be executed
by the dynamic linker."
"Note that the address of a function need not be the same as a pointer
to a function as defined by the processor supplement."
so these should be accessed via uintptr_t type instead of ElfW(Addr).
|
|
The base should be 0, but also a valid capability. Initialize to a zero
capability instead of relying on AT_BASE.
TODO: this is a hack. we will need stricter bounds and possibly separate
l_addr and bounds info.
|
|
|
|
The Elf64_auxv_t needs to be adjusted for the new capability size.
|