This introduces a new `address_t` type and two new casts: `pointer_cast` and `address_cast` for casting between an `address_t` and a pointer. These should make it easier to audit the codebase for casts between pointers and integers. In particular, the remaining `reinterpret_cast`s and `pointer_cast`s should be the only places where we could perform invalid pointer arithmetic. Also adds a `pointer_offset` helper that adds an offset (in bytes) to a pointer, preserving its original type. This is a sufficiently common pattern that it seemed worthwhile to centralise it.
43 lines
1.1 KiB
C++
43 lines
1.1 KiB
C++
#pragma once
|
|
#include <cstdint>
|
|
|
|
namespace snmalloc
|
|
{
|
|
/**
|
|
* The type used for an address. Currently, all addresses are assumed to be
|
|
* provenance-carrying values and so it is possible to cast back from the
|
|
* result of arithmetic on an address_t. Eventually, this will want to be
|
|
* separated into two types, one for raw addresses and one for addresses that
|
|
* can be cast back to pointers.
|
|
*/
|
|
typedef uintptr_t address_t;
|
|
|
|
/**
|
|
* Perform pointer arithmetic and return the adjusted pointer.
|
|
*/
|
|
template<typename T>
|
|
inline T* pointer_offset(T* base, size_t diff)
|
|
{
|
|
return reinterpret_cast<T*>(reinterpret_cast<char*>(base) + diff);
|
|
}
|
|
|
|
/**
|
|
* Cast from a pointer type to an address.
|
|
*/
|
|
template<typename T>
|
|
inline address_t address_cast(T* ptr)
|
|
{
|
|
return reinterpret_cast<address_t>(ptr);
|
|
}
|
|
|
|
/**
|
|
* Cast from an address back to a pointer of the specified type. All uses of
|
|
* this will eventually need auditing for CHERI compatibility.
|
|
*/
|
|
template<typename T>
|
|
inline T* pointer_cast(address_t address)
|
|
{
|
|
return reinterpret_cast<T*>(address);
|
|
}
|
|
}
|