[security][CVE-2022-27809] Builtins should always take int64_t, not int
[hiphop-php.git] / hphp / runtime / vm / pc-filter.h
blob52f6b30b367065613a75bd5236ceed868b0867e4
1 /*
2 +----------------------------------------------------------------------+
3 | HipHop for PHP |
4 +----------------------------------------------------------------------+
5 | Copyright (c) 2010-2013 Facebook, Inc. (http://www.facebook.com) |
6 | Copyright (c) 1997-2010 The PHP Group |
7 +----------------------------------------------------------------------+
8 | This source file is subject to version 3.01 of the PHP license, |
9 | that is bundled with this package in the file LICENSE, and is |
10 | available through the world-wide-web at the following url: |
11 | http://www.php.net/license/3_01.txt |
12 | If you did not receive a copy of the PHP license and are unable to |
13 | obtain it through the world-wide-web, please send a note to |
14 | license@php.net so we can mail you a copy immediately. |
15 +----------------------------------------------------------------------+
18 #pragma once
20 #include "hphp/runtime/vm/func.h"
22 namespace HPHP {
23 ////////////////////////////////////////////////////////////////////////////////
25 // Map which holds a set of PCs and supports reasonably fast addition and
26 // lookup. Used to decide if a given PC falls within an interesting area, e.g.,
27 // for breakpoints and stepping.
28 struct PCFilter {
29 static constexpr auto PTRMAP_PTR_SIZE = sizeof(void*) * 8;
30 static constexpr auto PTRMAP_LEVEL_BITS = 8LL;
31 static constexpr auto PTRMAP_LEVEL_ENTRIES = 1LL << PTRMAP_LEVEL_BITS;
32 static constexpr auto PTRMAP_LEVEL_MASK = PTRMAP_LEVEL_ENTRIES - 1LL;
33 private:
34 // Radix-tree implementation of pointer map
35 struct PtrMapNode {
36 union {
37 PtrMapNode* m_entries;
38 void* m_value;
40 void clearImpl(unsigned short bits);
42 struct PtrMap {
43 PtrMap() {
44 static_assert(PTRMAP_PTR_SIZE % PTRMAP_LEVEL_BITS == 0,
45 "PTRMAP_PTR_SIZE must be a multiple of PTRMAP_LEVEL_BITS");
46 m_root.m_entries = nullptr;
48 ~PtrMap() { clear(); }
49 PtrMap(const PtrMap&) = delete;
50 PtrMap& operator=(const PtrMap&) = delete;
52 static PtrMapNode makeNode();
53 void setPointer(void* ptr, void* val);
54 void* getPointer(void* ptr) const {
55 if (!m_root.m_entries) return nullptr;
56 return getPointerImpl(ptr);
58 void clear();
59 void swap(PtrMap& other) {
60 std::swap(m_root, other.m_root);
62 bool isNull() { return m_root.m_entries == nullptr; }
63 private:
64 void* getPointerImpl(void* ptr) const;
65 PtrMapNode m_root;
66 TYPE_SCAN_IGNORE_FIELD(m_root); // points to a malloc'd radix tree node
69 PtrMap m_map;
71 public:
72 PCFilter() {}
74 // Filter function to exclude opcodes when adding ranges.
75 using OpcodeFilter = std::function<bool(Op)>;
77 // Add/remove offsets, either individually or by range. By default allow all
78 // opcodes.
79 void addRanges(const OffsetFuncRangeVec& offsets,
80 OpcodeFilter isOpcodeAllowed = [] (Op) { return true; });
81 void removeRanges(const OffsetFuncRangeVec& offsets,
82 OpcodeFilter isOpcodeAllowed = [] (Op) { return true; });
83 void removeOffset(const Func* func, Offset offset);
85 // Add/remove/check explicit PCs.
86 void addPC(const unsigned char* pc) {
87 m_map.setPointer((void*)pc, (void*)pc);
89 void removePC(const unsigned char* pc) {
90 m_map.setPointer((void*)pc, nullptr);
92 bool checkPC(const unsigned char* pc) {
93 return m_map.getPointer((void*)pc) == (void*)pc;
96 bool isNull() { return m_map.isNull(); }
98 void swap(PCFilter& other) {
99 m_map.swap(other.m_map);
102 void clear() {
103 m_map.clear();
107 ///////////////////////////////////////////////////////////////////////////////