5 // Created by James McIlree on 10/25/12.
6 // Copyright (c) 2014 Apple. All rights reserved.
9 template <typename SIZE> class KDEventFields {};
12 class KDEventFields<Kernel32> {
14 static const uint64_t K32_TIMESTAMP_MASK = 0x00ffffffffffffffULL;
15 static const uint64_t K32_CPU_MASK = 0xff00000000000000ULL;
16 static const uint32_t K32_CPU_SHIFT = 56;
27 int cpu() const { return (int) ((_timestamp & K32_CPU_MASK) >> K32_CPU_SHIFT); }
28 uint64_t timestamp() const { return _timestamp & K32_TIMESTAMP_MASK; }
30 uint64_t unused() const { THROW("Calling method for field that does not exist"); }
34 class KDEventFields<Kernel64> {
44 uint64_t _unused; // Defined as uintptr in orignal header
46 int cpu() const { return (int)_cpuid; }
47 uint64_t timestamp() const { return _timestamp; }
49 uint64_t unused() const { return _unused; }
52 /* The debug code consists of the following
54 * ----------------------------------------------------------------------
56 *| Class (8) | SubClass (8) | Code (14) |Qual(2)|
57 * ----------------------------------------------------------------------
58 * The class specifies the higher level
61 template <typename SIZE>
64 KDEventFields<SIZE> _fields;
66 static const uint32_t DBG_CLASS_MASK = 0xFF000000;
67 static const uint32_t DBG_CLASS_MASK_SHIFT = 24;
68 static const uint32_t DBG_SUBCLASS_MASK = 0x00FF0000;
69 static const uint32_t DBG_SUBCLASS_MASK_SHIFT = 16;
70 static const uint32_t DBG_CODE_MASK = 0x0000FFFC;
71 static const uint32_t DBG_CODE_MASK_SHIFT = 2;
72 static const uint32_t DBG_FUNC_MASK = DBG_FUNC_START | DBG_FUNC_END;
76 // Provided only for lower_bounds/upper_bounds binary searches of event buffers
79 KDEvent(AbsTime timestamp) { _fields._timestamp = timestamp.value(); }
81 // Sort by time operator for lower_bounds/upper_bounds
82 bool operator<(const KDEvent& rhs) const { return this->timestamp() < rhs.timestamp(); }
84 AbsTime timestamp() const { return AbsTime(_fields.timestamp()); }
85 typename SIZE::ptr_t tid() const { return _fields._thread; }
86 int cpu() const { return _fields.cpu(); }
88 uint32_t dbg_class() const { return (_fields._debugid & DBG_CLASS_MASK) >> DBG_CLASS_MASK_SHIFT; }
89 uint32_t dbg_subclass() const { return (_fields._debugid & DBG_SUBCLASS_MASK) >> DBG_SUBCLASS_MASK_SHIFT; }
90 uint32_t dbg_code() const { return (_fields._debugid & DBG_CODE_MASK) >> DBG_CODE_MASK_SHIFT; }
91 uint32_t dbg_cooked() const { return _fields._debugid & ~DBG_FUNC_MASK; }
92 uint32_t dbg_raw() const { return _fields._debugid; }
94 typename SIZE::ptr_t arg1() const { return _fields._arg1; }
95 typename SIZE::ptr_t arg2() const { return _fields._arg2; }
96 typename SIZE::ptr_t arg3() const { return _fields._arg3; }
97 typename SIZE::ptr_t arg4() const { return _fields._arg4; }
99 uint8_t* arg1_as_pointer() const { return (uint8_t*)&_fields._arg1; }
100 std::string arg1_as_string() const;
101 std::string all_args_as_string() const;
103 bool is_func_start() const { return (_fields._debugid & DBG_FUNC_MASK) == DBG_FUNC_START; }
104 bool is_func_end() const { return (_fields._debugid & DBG_FUNC_MASK) == DBG_FUNC_END; }
105 bool is_func_none() const { return (_fields._debugid & DBG_FUNC_MASK) == DBG_FUNC_NONE; }
107 uint64_t unused() const { return _fields.unused(); }
110 // Must have a code set to be valid, no codes are 0x00
114 // Legal values are NONE, START, and END.
115 if ((_fields._debugid & DBG_FUNC_MASK) == DBG_FUNC_MASK)
121 std::string to_string() const;
124 template <typename SIZE>
125 std::string KDEvent<SIZE>::arg1_as_string() const {
126 // We can't count on the arg being NULL terminated, we have to copy.
127 // Using a uint32_t/uint64_t instead of a char[] guarantees alignment.
128 decltype(_fields._arg1) buf[2];
130 buf[0] = _fields._arg1;
133 return std::string(reinterpret_cast<char*>(buf));
136 template <typename SIZE>
137 std::string KDEvent<SIZE>::all_args_as_string() const {
138 // We can't count on the arg being NULL terminated, we have to copy.
139 // Using a uint32_t/uint64_t instead of a char[] guarantees alignment.
140 decltype(_fields._arg1) buf[5];
142 buf[0] = _fields._arg1;
143 buf[1] = _fields._arg2;
144 buf[2] = _fields._arg3;
145 buf[3] = _fields._arg4;
148 return std::string(reinterpret_cast<char*>(buf));