OLD | NEW |
| (Empty) |
1 // Copyright 2009 The Native Client Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can | |
3 // be found in the LICENSE file. | |
4 | |
5 #include <gcroot.h> | |
6 | |
7 #include "dwarf_reader/dwarf_vm.h" | |
8 #include "elf_reader/elf_object.h" | |
9 | |
10 #include "src/NaClVsx.DebugHelpers/DwarfParser.h" | |
11 | |
12 | |
13 using System::IntPtr; | |
14 using System::Runtime::InteropServices::GCHandle; | |
15 using System::Runtime::InteropServices::GCHandleType; | |
16 using System::Runtime::InteropServices::Marshal; | |
17 | |
18 namespace NaClVsx { | |
19 | |
20 class DwarfParserImpl : public dwarf_reader::IDwarfReader { | |
21 public: | |
22 | |
23 explicit DwarfParserImpl(gcroot<NaClVsx::IDwarfReader^> target) | |
24 : target_(target) {} | |
25 | |
26 // | |
27 // Implementation of IDwarfReader | |
28 // | |
29 virtual void *StartCompilationUnit( | |
30 uint64 offset, | |
31 uint8 address_size, | |
32 uint8 offset_size, | |
33 uint64 cu_length, | |
34 uint8 dwarf_version) { | |
35 target_->StartCompilationUnit(); | |
36 return NULL; | |
37 } | |
38 | |
39 virtual void EndCompilationUnit(void *ctx, uint64 offset) { | |
40 target_->EndCompilationUnit(); | |
41 } | |
42 | |
43 virtual void *StartDIE(void *ctx, | |
44 uint64 parent, | |
45 uint64 offset, | |
46 dwarf2reader::DwarfTag tag) { | |
47 target_->StartDIE(parent, offset, static_cast<DwarfTag>(tag)); | |
48 | |
49 return NULL; | |
50 } | |
51 | |
52 virtual void EndDIE(void *ctx, uint64 offset) { | |
53 target_->EndDIE(offset); | |
54 } | |
55 | |
56 virtual void ProcessAttributeUnsigned(void *ctx, | |
57 uint64 offset, | |
58 uint64 parent, | |
59 dwarf2reader::DwarfAttribute attr, | |
60 dwarf2reader::DwarfForm form, | |
61 uint64 data) { | |
62 target_->ProcessAttribute( | |
63 offset, | |
64 parent, | |
65 static_cast<DwarfAttribute>(attr), | |
66 data); | |
67 } | |
68 | |
69 virtual void ProcessAttributeSigned(void *ctx, | |
70 uint64 offset, | |
71 uint64 parent, | |
72 dwarf2reader::DwarfAttribute attr, | |
73 dwarf2reader::DwarfForm form, | |
74 int64 data) { | |
75 target_->ProcessAttribute( | |
76 offset, | |
77 parent, | |
78 static_cast<DwarfAttribute>(attr), | |
79 data); | |
80 } | |
81 | |
82 virtual void ProcessAttributeReference(void *ctx, | |
83 uint64 offset, | |
84 uint64 parent, | |
85 dwarf2reader::DwarfAttribute attr, | |
86 dwarf2reader::DwarfForm form, | |
87 uint64 data) { | |
88 target_->ProcessAttribute( | |
89 offset, | |
90 parent, | |
91 static_cast<DwarfAttribute>(attr), | |
92 gcnew DwarfReference(data)); | |
93 } | |
94 | |
95 virtual void ProcessAttributeBuffer(void *ctx, | |
96 uint64 offset, | |
97 uint64 parent, | |
98 dwarf2reader::DwarfAttribute attr, | |
99 dwarf2reader::DwarfForm form, | |
100 const char* data, | |
101 uint64 len) { | |
102 array<System::Byte>^ arr = | |
103 gcnew array<System::Byte>(static_cast<int>(len)); | |
104 // NOTE: using const_cast because Marshal doesn't support const ptrs. | |
105 Marshal::Copy( | |
106 IntPtr(const_cast<char*>(data)), arr, 0, static_cast<int>(len)); | |
107 | |
108 target_->ProcessAttribute( | |
109 offset, | |
110 parent, | |
111 static_cast<DwarfAttribute>(attr), | |
112 arr); | |
113 } | |
114 | |
115 virtual void ProcessAttributeString(void *ctx, | |
116 uint64 offset, | |
117 uint64 parent, | |
118 dwarf2reader::DwarfAttribute attr, | |
119 dwarf2reader::DwarfForm form, | |
120 const char* data) { | |
121 // NOTE: using const_cast because Marshal doesn't support const ptrs. | |
122 System::String^ str = | |
123 Marshal::PtrToStringAnsi(IntPtr(const_cast<char*>(data))); | |
124 | |
125 target_->ProcessAttribute( | |
126 offset, | |
127 parent, | |
128 static_cast<DwarfAttribute>(attr), | |
129 str); | |
130 } | |
131 | |
132 virtual void DefineDir(void *ctx, const char *name, uint32 dir_num) { | |
133 // NOTE: using const_cast because Marshal doesn't support const ptrs. | |
134 target_->DefineDir( | |
135 Marshal::PtrToStringAnsi(IntPtr(const_cast<char*>(name))), | |
136 dir_num); | |
137 } | |
138 | |
139 virtual void DefineFile(void *ctx, const char *name, int32 file_num, | |
140 uint32 dir_num, uint64 mod_time, | |
141 uint64 length) { | |
142 // NOTE: using const_cast because Marshal doesn't support const ptrs. | |
143 target_->DefineFile( | |
144 Marshal::PtrToStringAnsi(IntPtr(const_cast<char*>(name))), | |
145 file_num, | |
146 dir_num); | |
147 } | |
148 | |
149 virtual void AddLine(void *ctx, | |
150 uint64 address, | |
151 uint64 length, | |
152 uint32 file_num, | |
153 uint32 line_num, | |
154 uint32 column_num) { | |
155 target_->AddLine(address, length, file_num, line_num, column_num); | |
156 } | |
157 | |
158 virtual void AddLocListEntry(uint64 offset, | |
159 bool is_first_entry, | |
160 uint64 lowPc, | |
161 uint64 highPc, | |
162 const void* data, | |
163 size_t dataSize) { | |
164 array<System::Byte>^ arr = | |
165 gcnew array<System::Byte>(static_cast<int>(dataSize)); | |
166 // NOTE: using const_cast because Marshal doesn't support const ptrs. | |
167 Marshal::Copy( | |
168 IntPtr(const_cast<void*>(data)), arr, 0, static_cast<int>(dataSize)); | |
169 | |
170 target_->AddLocListEntry(offset, is_first_entry, lowPc, highPc, arr); | |
171 } | |
172 | |
173 virtual bool BeginCfiEntry( | |
174 size_t offset, | |
175 uint64 address, | |
176 uint64 length, | |
177 uint8 version, | |
178 const char* augmentation, | |
179 unsigned return_address) { | |
180 return target_->BeginCfiEntry( | |
181 address); | |
182 } | |
183 | |
184 virtual bool AddCfiRule( | |
185 uint64 address, | |
186 int reg, | |
187 CFI_RuleType ruleType, | |
188 int base_register, | |
189 int32 offset, | |
190 const void* data, | |
191 uint32_t len) { | |
192 // NOTE: using const_cast because Marshal doesn't support const ptrs. | |
193 void* void_data = const_cast<void*>(data); | |
194 array<System::Byte>^ arr = nullptr; | |
195 if (data && len) { | |
196 gcnew array<System::Byte>(static_cast<int>(len)); | |
197 Marshal::Copy(IntPtr(void_data), arr, 0, static_cast<int>(len)); | |
198 } | |
199 | |
200 return target_->AddCfiRule( | |
201 address, | |
202 reg, | |
203 (NaClVsx::IDwarfReader::CfiRuleType)ruleType, | |
204 base_register, | |
205 offset, | |
206 arr); | |
207 } | |
208 | |
209 virtual bool EndCfiEntry() { | |
210 return target_->EndCfiEntry(); | |
211 } | |
212 | |
213 virtual void AddRangeListEntry(uint64 offset, | |
214 uint64 base_address, | |
215 uint64 low_pc, | |
216 uint64 high_pc) { | |
217 target_->AddRangeListEntry(offset, base_address, low_pc, high_pc); | |
218 } | |
219 | |
220 private: | |
221 gcroot<NaClVsx::IDwarfReader^> target_; | |
222 }; | |
223 | |
224 class DwarfVmImpl : public dwarf_reader::IDwarfVM { | |
225 public: | |
226 explicit DwarfVmImpl(gcroot<NaClVsx::IDwarfVM^> vm) : target_(vm) {} | |
227 | |
228 virtual uint32_t BitWidth() { | |
229 return target_->BitWidth(); | |
230 } | |
231 | |
232 virtual bool IsLSB() { | |
233 return target_->IsLSB(); | |
234 } | |
235 | |
236 virtual void ErrorString(const char *str) { | |
237 target_->ErrorString( | |
238 Marshal::PtrToStringAnsi(IntPtr(const_cast<char*>(str)))); | |
239 } | |
240 | |
241 virtual uint64_t ReadRegister(int reg_number) { | |
242 return target_->ReadRegister(reg_number); | |
243 } | |
244 | |
245 virtual uint64_t ReadMemory(uint64_t address, int count) { | |
246 return target_->ReadMemory(address, count); | |
247 } | |
248 | |
249 virtual uint64_t ReadFrameBase() { | |
250 return target_->ReadFrameBase(); | |
251 } | |
252 | |
253 private: | |
254 gcroot<NaClVsx::IDwarfVM^> target_; | |
255 }; | |
256 | |
257 | |
258 | |
259 | |
260 void DwarfParser::DwarfParseElf( | |
261 System::String^ filename, | |
262 IDwarfReader^ reader ) { | |
263 elf_reader::ElfObject elf; | |
264 DwarfParserImpl parse = DwarfParserImpl(gcroot<IDwarfReader^>(reader)); | |
265 | |
266 IntPtr hString = Marshal::StringToHGlobalAnsi(filename); | |
267 bool result = elf.Load(reinterpret_cast<char*>(hString.ToPointer())); | |
268 Marshal::FreeHGlobal(hString); | |
269 | |
270 if (result) { | |
271 dwarf_reader::DwarfParseElf(&elf, &parse); | |
272 } else { | |
273 throw gcnew System::IO::FileLoadException("Could not load " + filename); | |
274 } | |
275 } | |
276 | |
277 uint64_t DwarfParser::DwarfParseVM( | |
278 IDwarfVM^ vm, | |
279 array<System::Byte>^ data) { | |
280 DwarfVmImpl vmImpl = DwarfVmImpl(gcroot<IDwarfVM^>(vm)); | |
281 GCHandle^ hData = GCHandle::Alloc(data, GCHandleType::Pinned); | |
282 IntPtr pData = hData->AddrOfPinnedObject(); | |
283 | |
284 uint64_t result = dwarf_reader::DwarfParseVM( | |
285 &vmImpl, | |
286 reinterpret_cast<uint8_t*>(pData.ToPointer()), | |
287 data->Length); | |
288 | |
289 hData->Free(); | |
290 return result; | |
291 } | |
292 } // namespace NaClVsx | |
293 | |
OLD | NEW |