1 // Copyright 2020 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef V8_TOOLS_V8WINDBG_SRC_V8_DEBUG_HELPER_INTEROP_H_
6 #define V8_TOOLS_V8WINDBG_SRC_V8_DEBUG_HELPER_INTEROP_H_
7 
8 #include <wrl/client.h>
9 
10 #include <DbgModel.h>
11 
12 #include <cstdint>
13 #include <map>
14 #include <string>
15 #include <vector>
16 
17 namespace WRL = Microsoft::WRL;
18 
19 constexpr char kObject[] = "v8::internal::Object";
20 constexpr char16_t kObjectU[] = u"v8::internal::Object";
21 constexpr char kTaggedValue[] = "v8::internal::TaggedValue";
22 constexpr char16_t kTaggedValueU[] = u"v8::internal::TaggedValue";
23 
24 enum class PropertyType {
25   kPointer = 0,
26   kArray = 1,
27   kStruct = 2,
28   kStructArray = kArray | kStruct,
29 };
30 
31 struct StructField {
32   StructField(std::u16string field_name, std::u16string type_name,
33               std::string uncompressed_type_name, uint64_t address,
34               uint8_t num_bits, uint8_t shift_bits);
35   ~StructField();
36   StructField(const StructField&);
37   StructField(StructField&&);
38   StructField& operator=(const StructField&);
39   StructField& operator=(StructField&&);
40 
41   std::u16string name;
42 
43   // Statically-determined type, such as from .tq definition. This type should
44   // be treated as if it were used in the v8::internal namespace; that is, type
45   // "X::Y" can mean any of the following, in order of decreasing preference:
46   // - v8::internal::X::Y
47   // - v8::X::Y
48   // - X::Y
49   std::u16string type_name;
50 
51   // In some cases, |type_name| may be a simple type representing a compressed
52   // pointer such as v8::internal::TaggedValue. In those cases,
53   // |uncompressed_type_name| will contain the type of the object when
54   // decompressed. Otherwise, |uncompressed_type_name| will match |type_name|.
55   // In any case, it is safe to pass the |uncompressed_type_name| value as the
56   // type_hint on a subsequent call to GetObjectProperties.
57   std::string uncompressed_type_name;
58 
59   // Offset, in bytes, from beginning of struct.
60   uint64_t offset;
61 
62   // The number of bits that are present, if this value is a bitfield. Zero
63   // indicates that this value is not a bitfield (the full value is stored).
64   uint8_t num_bits;
65 
66   // The number of bits by which this value has been left-shifted for storage as
67   // a bitfield.
68   uint8_t shift_bits;
69 };
70 
71 struct Property {
72   Property(std::u16string property_name, std::u16string type_name,
73            std::string uncompressed_type_name, uint64_t address,
74            size_t item_size);
75   ~Property();
76   Property(const Property&);
77   Property(Property&&);
78   Property& operator=(const Property&);
79   Property& operator=(Property&&);
80 
81   std::u16string name;
82   PropertyType type;
83 
84   // Statically-determined type, such as from .tq definition. Can be an empty
85   // string if this property is itself a Torque-defined struct; in that case use
86   // |fields| instead. This type should be treated as if it were used in the
87   // v8::internal namespace; that is, type "X::Y" can mean any of the following,
88   // in order of decreasing preference:
89   // - v8::internal::X::Y
90   // - v8::X::Y
91   // - X::Y
92   std::u16string type_name;
93 
94   // In some cases, |type_name| may be a simple type representing a compressed
95   // pointer such as v8::internal::TaggedValue. In those cases,
96   // |uncompressed_type_name| will contain the type of the object when
97   // decompressed. Otherwise, |uncompressed_type_name| will match |type_name|.
98   // In any case, it is safe to pass the |uncompressed_type_name| value as the
99   // type_hint on a subsequent call to GetObjectProperties.
100   std::string uncompressed_type_name;
101 
102   // The address where the property value can be found in the debuggee's address
103   // space, or the address of the first value for an array.
104   uint64_t addr_value;
105 
106   // Size of each array item, if this property is an array.
107   size_t item_size;
108 
109   // Number of array items, if this property is an array.
110   size_t length = 0;
111 
112   // Fields within this property, if this property is a struct, or fields within
113   // each array element, if this property is a struct array.
114   std::vector<StructField> fields;
115 };
116 
117 struct V8HeapObject {
118   V8HeapObject();
119   ~V8HeapObject();
120   V8HeapObject(const V8HeapObject&);
121   V8HeapObject(V8HeapObject&&);
122   V8HeapObject& operator=(const V8HeapObject&);
123   V8HeapObject& operator=(V8HeapObject&&);
124   std::u16string friendly_name;  // String to print in single-line description.
125   std::vector<Property> properties;
126 };
127 
128 V8HeapObject GetHeapObject(WRL::ComPtr<IDebugHostContext> sp_context,
129                            uint64_t address, uint64_t referring_pointer,
130                            const char* type_name, bool is_compressed);
131 
132 // Expand a compressed pointer from 32 bits to the format that
133 // GetObjectProperties expects for compressed pointers.
ExpandCompressedPointer(uint32_t ptr)134 inline uint64_t ExpandCompressedPointer(uint32_t ptr) { return ptr; }
135 
136 std::vector<std::u16string> ListObjectClasses();
137 
138 const char* BitsetName(uint64_t payload);
139 
140 std::vector<Property> GetStackFrame(WRL::ComPtr<IDebugHostContext> sp_context,
141                                     uint64_t frame_pointer);
142 
143 #endif  // V8_TOOLS_V8WINDBG_SRC_V8_DEBUG_HELPER_INTEROP_H_
144