#ifndef V8_SANDBOX_TRUSTED_POINTER_TABLE_H_
#define V8_SANDBOX_TRUSTED_POINTER_TABLE_H_
#include "include/v8config.h"
#include "src/base/atomicops.h"
#include "src/base/memory.h"
#include "src/common/globals.h"
#include "src/sandbox/external-entity-table.h"
#include "src/sandbox/indirect-pointer-tag.h"
#include "src/sandbox/tagged-payload.h"
#ifdef V8_ENABLE_SANDBOX
namespace v8 {
namespace internal {
class Counters;
class Isolate;
class TrustedPointerPublishingScope;
* The entries of a TrustedPointerTable.
*
* Each entry contains an (absolute) pointer to a TrustedObject.
*/
struct TrustedPointerTableEntry {
inline void MakeTrustedPointerEntry(Address pointer, IndirectPointerTag tag,
bool mark_as_alive);
inline void MakeFreelistEntry(uint32_t next_entry_index);
inline void MakeZappedEntry();
inline Address GetPointer(IndirectPointerTag tag) const;
inline void SetPointer(Address pointer, IndirectPointerTag tag);
inline bool HasPointer(IndirectPointerTag tag) const;
inline void Unpublish();
inline void Publish(IndirectPointerTag tag);
inline bool IsFreelistEntry() const;
inline uint32_t GetNextFreelistEntryIndex() const;
inline void Mark();
inline void Unmark();
inline bool IsMarked() const;
static constexpr bool IsWriteProtected = false;
private:
friend class TrustedPointerTable;
inline Address GetPointerUnchecked() const;
struct TrustedPointerTaggingScheme {
using TagType = IndirectPointerTag;
static constexpr uint64_t kMarkBit = kTrustedPointerTableMarkBit;
static constexpr uint64_t kTagMask = kIndirectPointerTagMask;
static constexpr TagType kFreeEntryTag = kFreeTrustedPointerTableEntryTag;
static constexpr bool kSupportsEvacuation = false;
static constexpr bool kSupportsZapping = false;
};
struct Payload : TaggedPayload<TrustedPointerTaggingScheme> {
static Payload ForTrustedPointerEntry(Address pointer,
IndirectPointerTag tag) {
DCHECK_EQ(pointer & kHeapObjectTag, kHeapObjectTag);
DCHECK_EQ(pointer & kTrustedPointerTableMarkBit, 0);
DCHECK_EQ(pointer & kIndirectPointerTagMask, 0);
return Payload(pointer, tag);
}
static Payload ForFreelistEntry(uint32_t next_entry) {
return Payload(next_entry, kFreeTrustedPointerTableEntryTag);
}
static Payload ForZappedEntry() {
return Payload(0, kIndirectPointerNullTag);
}
private:
Payload(Address pointer, IndirectPointerTag tag)
: TaggedPayload(pointer, tag) {}
};
std::atomic<Payload> payload_;
};
static_assert(sizeof(TrustedPointerTableEntry) ==
kTrustedPointerTableEntrySize);
* A table containing (full) pointers to TrustedObjects.
*
* When the sandbox is enabled, a trusted pointer table (TPT) is used to safely
* reference trusted heap objects located in one of the trusted spaces outside
* of the sandbox. The TPT guarantees that every access to an object via a
* trusted pointer (an index into the table) either results in an invalid
* pointer or a valid pointer to a valid (live) object of the expected type.
*
* The TPT is very similar to the external pointer table (EPT), but is used to
* reference V8 HeapObjects (located inside a V8 heap) rather than C++ objects
* (typically located on one of the system heaps). As such, the garbage
* collector needs to be aware of the table indirection.
*/
class V8_EXPORT_PRIVATE TrustedPointerTable
: public ExternalEntityTable<TrustedPointerTableEntry,
kTrustedPointerTableReservationSize> {
public:
static_assert(kMaxTrustedPointers == kMaxCapacity);
static_assert(!kSupportsCompaction);
TrustedPointerTable() = default;
TrustedPointerTable(const TrustedPointerTable&) = delete;
TrustedPointerTable& operator=(const TrustedPointerTable&) = delete;
using Space = ExternalEntityTable<TrustedPointerTableEntry,
kTrustedPointerTableReservationSize>::Space;
inline Address Get(TrustedPointerHandle handle, IndirectPointerTag tag) const;
inline Address GetMaybeUnpublished(TrustedPointerHandle handle,
IndirectPointerTag tag) const;
inline void Set(TrustedPointerHandle handle, Address pointer,
IndirectPointerTag tag);
inline TrustedPointerHandle AllocateAndInitializeEntry(
Space* space, Address pointer, IndirectPointerTag tag,
TrustedPointerPublishingScope* scope);
inline void Mark(Space* space, TrustedPointerHandle handle);
uint32_t Sweep(Space* space, Counters* counters);
inline void Zap(TrustedPointerHandle handle);
inline void Publish(TrustedPointerHandle handle, IndirectPointerTag tag);
inline bool IsUnpublished(TrustedPointerHandle handle) const;
template <typename Callback>
void IterateActiveEntriesIn(Space* space, Callback callback);
Address base_address() const { return base(); }
private:
inline uint32_t HandleToIndex(TrustedPointerHandle handle) const;
inline TrustedPointerHandle IndexToHandle(uint32_t index) const;
inline void Validate(Address pointer, IndirectPointerTag tag);
};
}
}
#endif
#endif