Flutter Engine
The Flutter Engine
dwarf.h
Go to the documentation of this file.
1// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
2// for details. All rights reserved. Use of this source code is governed by a
3// BSD-style license that can be found in the LICENSE file.
4
5#ifndef RUNTIME_VM_DWARF_H_
6#define RUNTIME_VM_DWARF_H_
7
8#include "vm/allocation.h"
9#include "vm/hash.h"
10#include "vm/hash_map.h"
11#include "vm/image_snapshot.h"
12#include "vm/object.h"
13#include "vm/zone.h"
14
15namespace dart {
16
17#ifdef DART_PRECOMPILER
18
19class InliningNode;
20class LineNumberProgramWriter;
21
22struct ScriptIndexPair {
23 // Typedefs needed for the DirectChainedHashMap template.
24 typedef const Script* Key;
25 typedef intptr_t Value;
26 typedef ScriptIndexPair Pair;
27
28 static Key KeyOf(Pair kv) { return kv.script_; }
29
30 static Value ValueOf(Pair kv) { return kv.index_; }
31
32 static inline uword Hash(Key key) {
33 return String::Handle(key->url()).Hash();
34 }
35
36 static inline bool IsKeyEqual(Pair pair, Key key) {
37 return pair.script_->ptr() == key->ptr();
38 }
39
40 ScriptIndexPair(const Script* s, intptr_t index) : script_(s), index_(index) {
41 ASSERT(!s->IsNull());
42 DEBUG_ASSERT(s->IsNotTemporaryScopedHandle());
43 }
44
45 ScriptIndexPair() : script_(nullptr), index_(-1) {}
46
47 void Print() const;
48
49 const Script* script_;
50 intptr_t index_;
51};
52
53typedef DirectChainedHashMap<ScriptIndexPair> ScriptIndexMap;
54
55struct FunctionIndexPair {
56 // Typedefs needed for the DirectChainedHashMap template.
57 typedef const Function* Key;
58 typedef intptr_t Value;
59 typedef FunctionIndexPair Pair;
60
61 static Key KeyOf(Pair kv) { return kv.function_; }
62
63 static Value ValueOf(Pair kv) { return kv.index_; }
64
65 static inline uword Hash(Key key) { return key->token_pos().Hash(); }
66
67 static inline bool IsKeyEqual(Pair pair, Key key) {
68 return pair.function_->ptr() == key->ptr();
69 }
70
71 FunctionIndexPair(const Function* f, intptr_t index)
72 : function_(f), index_(index) {
73 ASSERT(!f->IsNull());
74 DEBUG_ASSERT(f->IsNotTemporaryScopedHandle());
75 }
76
77 FunctionIndexPair() : function_(nullptr), index_(-1) {}
78
79 void Print() const;
80
81 const Function* function_;
82 intptr_t index_;
83};
84
85typedef DirectChainedHashMap<FunctionIndexPair> FunctionIndexMap;
86
87// Assumes T has a copy constructor and is CopyAssignable.
88template <typename T>
89struct DwarfCodeKeyValueTrait {
90 // Typedefs needed for the DirectChainedHashMap template.
91 typedef const Code* Key;
92 typedef T Value;
93
94 struct Pair {
95 Pair(const Code* c, const T v) : code(c), value(v) {
96 ASSERT(c != nullptr);
97 ASSERT(!c->IsNull());
98 DEBUG_ASSERT(c->IsNotTemporaryScopedHandle());
99 }
100 Pair() : code(nullptr), value{} {}
101
102 // Don't implicitly delete copy and copy assignment constructors.
103 Pair(const Pair& other) = default;
104 Pair& operator=(const Pair& other) = default;
105
106 const Code* code;
107 T value;
108 };
109
110 static Key KeyOf(Pair kv) { return kv.code; }
111
112 static Value ValueOf(Pair kv) { return kv.value; }
113
114 static inline uword Hash(Key key) {
115 // Instructions are always allocated in old space, so they don't move.
116 return Utils::WordHash(key->PayloadStart());
117 }
118
119 static inline bool IsKeyEqual(Pair pair, Key key) {
120 // Code objects are always allocated in old space, so they don't move.
121 return pair.code->ptr() == key->ptr();
122 }
123};
124
125template <typename T>
126using DwarfCodeMap = DirectChainedHashMap<DwarfCodeKeyValueTrait<T>>;
127
128class DwarfWriteStream : public ValueObject {
129 public:
130 DwarfWriteStream() {}
131 virtual ~DwarfWriteStream() {}
132
133 virtual void sleb128(intptr_t value) = 0;
134 virtual void uleb128(uintptr_t value) = 0;
135 virtual void u1(uint8_t value) = 0;
136 virtual void u2(uint16_t value) = 0;
137 virtual void u4(uint32_t value) = 0;
138 virtual void u8(uint64_t value) = 0;
139 virtual void string(const char* cstr) = 0; // NOLINT
140
141 // Prefixes the content added by body with its length.
142 //
143 // symbol_prefix is used when a local symbol is created for the length.
144 virtual void WritePrefixedLength(const char* symbol_prefix,
145 std::function<void()> body) = 0;
146
147 virtual void OffsetFromSymbol(intptr_t label, intptr_t offset) = 0;
148
149 virtual void InitializeAbstractOrigins(intptr_t size) = 0;
150 virtual void RegisterAbstractOrigin(intptr_t index) = 0;
151 virtual void AbstractOrigin(intptr_t index) = 0;
152
153 DISALLOW_COPY_AND_ASSIGN(DwarfWriteStream);
154};
155
156class Dwarf : public ZoneAllocated {
157 public:
158 explicit Dwarf(Zone* zone, const Trie<const char>* deobfuscation_trie);
159
160 const ZoneGrowableArray<const Code*>& codes() const { return codes_; }
161
162 // Stores the code object for later creating the line number program.
163 void AddCode(const Code& code, intptr_t label);
164
165 intptr_t AddFunction(const Function& function);
166 intptr_t AddScript(const Script& script);
167 intptr_t LookupFunction(const Function& function);
168 intptr_t LookupScript(const Script& script);
169
170 void WriteAbbreviations(DwarfWriteStream* stream);
171 void WriteDebugInfo(DwarfWriteStream* stream);
172 void WriteLineNumberProgram(DwarfWriteStream* stream);
173
174 private:
175 friend class LineNumberProgramWriter;
176
177 static constexpr intptr_t DW_TAG_compile_unit = 0x11;
178 static constexpr intptr_t DW_TAG_inlined_subroutine = 0x1d;
179 static constexpr intptr_t DW_TAG_subprogram = 0x2e;
180
181 static constexpr intptr_t DW_CHILDREN_no = 0x0;
182 static constexpr intptr_t DW_CHILDREN_yes = 0x1;
183
184 static constexpr intptr_t DW_AT_sibling = 0x1;
185 static constexpr intptr_t DW_AT_name = 0x3;
186 static constexpr intptr_t DW_AT_stmt_list = 0x10;
187 static constexpr intptr_t DW_AT_low_pc = 0x11;
188 static constexpr intptr_t DW_AT_high_pc = 0x12;
189 static constexpr intptr_t DW_AT_comp_dir = 0x1b;
190 static constexpr intptr_t DW_AT_inline = 0x20;
191 static constexpr intptr_t DW_AT_producer = 0x25;
192 static constexpr intptr_t DW_AT_abstract_origin = 0x31;
193 static constexpr intptr_t DW_AT_artificial = 0x34;
194 static constexpr intptr_t DW_AT_decl_column = 0x39;
195 static constexpr intptr_t DW_AT_decl_file = 0x3a;
196 static constexpr intptr_t DW_AT_decl_line = 0x3b;
197 static constexpr intptr_t DW_AT_call_column = 0x57;
198 static constexpr intptr_t DW_AT_call_file = 0x58;
199 static constexpr intptr_t DW_AT_call_line = 0x59;
200
201 static constexpr intptr_t DW_FORM_addr = 0x01;
202 static constexpr intptr_t DW_FORM_string = 0x08;
203 static constexpr intptr_t DW_FORM_flag = 0x0c;
204 static constexpr intptr_t DW_FORM_udata = 0x0f;
205 static constexpr intptr_t DW_FORM_ref4 = 0x13;
206 static constexpr intptr_t DW_FORM_ref_udata = 0x15;
207 static constexpr intptr_t DW_FORM_sec_offset = 0x17;
208
209 static constexpr intptr_t DW_INL_not_inlined = 0x0;
210 static constexpr intptr_t DW_INL_inlined = 0x1;
211
212 static constexpr intptr_t DW_LNS_copy = 0x1;
213 static constexpr intptr_t DW_LNS_advance_pc = 0x2;
214 static constexpr intptr_t DW_LNS_advance_line = 0x3;
215 static constexpr intptr_t DW_LNS_set_file = 0x4;
216 static constexpr intptr_t DW_LNS_set_column = 0x5;
217
218 static constexpr intptr_t DW_LNE_end_sequence = 0x01;
219 static constexpr intptr_t DW_LNE_set_address = 0x02;
220
221 public:
222 // Public because they're also used in constructing .eh_frame ELF sections.
223 static constexpr intptr_t DW_CFA_offset = 0x80;
224 static constexpr intptr_t DW_CFA_val_offset = 0x14;
225 static constexpr intptr_t DW_CFA_def_cfa = 0x0c;
226
227 private:
228 enum {
229 kCompilationUnit = 1,
230 kAbstractFunction,
231 kConcreteFunction,
232 kInlinedFunction,
233 };
234
235 void WriteAbstractFunctions(DwarfWriteStream* stream);
236 void WriteConcreteFunctions(DwarfWriteStream* stream);
237 InliningNode* ExpandInliningTree(const Code& code);
238 void WriteInliningNode(DwarfWriteStream* stream,
239 InliningNode* node,
240 intptr_t root_label,
241 const Script& parent_script);
242
243 void WriteSyntheticLineNumberProgram(LineNumberProgramWriter* writer);
244 void WriteLineNumberProgramFromCodeSourceMaps(
245 LineNumberProgramWriter* writer);
246
247 Zone* const zone_;
248 const Trie<const char>* const deobfuscation_trie_;
249 ZoneGrowableArray<const Code*> codes_;
250 DwarfCodeMap<intptr_t> code_to_label_;
251 ZoneGrowableArray<const Function*> functions_;
252 FunctionIndexMap function_to_index_;
253 ZoneGrowableArray<const Script*> scripts_;
254 ScriptIndexMap script_to_index_;
255};
256
257#endif // DART_PRECOMPILER
258
259} // namespace dart
260
261#endif // RUNTIME_VM_DWARF_H_
TArray< uint32_t > Key
#define DEBUG_ASSERT(cond)
Definition: assert.h:321
static Object & Handle()
Definition: object.h:407
static uint32_t WordHash(intptr_t key)
Definition: utils.cc:217
#define ASSERT(E)
struct MyStruct s
uint8_t value
Dart_NativeFunction function
Definition: fuchsia.cc:51
Definition: dart_vm.cc:33
uintptr_t uword
Definition: globals.h:501
static uint32_t Hash(uint32_t key)
Definition: hashmap_test.cc:65
it will be possible to load the file into Perfetto s trace viewer disable asset Prevents usage of any non test fonts unless they were explicitly Loaded via prefetched default font Indicates whether the embedding started a prefetch of the default font manager before creating the engine run In non interactive keep the shell running after the Dart script has completed enable serial On low power devices with low core running concurrent GC tasks on threads can cause them to contend with the UI thread which could potentially lead to jank This option turns off all concurrent GC activities domain network JSON encoded network policy per domain This overrides the DisallowInsecureConnections switch Embedder can specify whether to allow or disallow insecure connections at a domain level old gen heap size
Definition: switches.h:259
#define DISALLOW_COPY_AND_ASSIGN(TypeName)
Definition: globals.h:581
#define T
Definition: precompiler.cc:65
SeparatedVector2 offset