Mercurial > projects > ddbg_continued
comparison src/expression/evaluationcontext.d @ 1:4a9dcbd9e54f
-files of 0.13 beta
-fixes so that it now compiles with the current dmd version
author | marton@basel.hu |
---|---|
date | Tue, 05 Apr 2011 20:44:01 +0200 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
0:586e4a649642 | 1:4a9dcbd9e54f |
---|---|
1 /* Ddbg - Win32 Debugger for the D programming language | |
2 * Copyright (c) 2007 Jascha Wetzel | |
3 * All rights reserved. See LICENSE.TXT for details. | |
4 */ | |
5 module expression.evaluationcontext; | |
6 | |
7 import container; | |
8 import codeview.decl; | |
9 import codeview.codeview; | |
10 import minidump; | |
11 import dbgprocess; | |
12 import dbgthread; | |
13 import callstack; | |
14 import util; | |
15 import expression.datahandler; | |
16 | |
17 import std.string; | |
18 | |
19 import win32.winnt; | |
20 | |
21 class EvaluationException : Exception | |
22 { | |
23 this(string m) { super(m); } | |
24 } | |
25 | |
26 /************************************************************************************************** | |
27 | |
28 **************************************************************************************************/ | |
29 class SymbolData | |
30 { | |
31 string type; | |
32 bool defered_load; | |
33 | |
34 union | |
35 { | |
36 ubyte[] data; | |
37 struct { | |
38 size_t len, | |
39 ptr; | |
40 } | |
41 } | |
42 | |
43 /********************************************************************************************** | |
44 | |
45 **********************************************************************************************/ | |
46 ubyte[] getData(EvaluationContext ctx) | |
47 { | |
48 if ( defered_load ) | |
49 { | |
50 debug(eval) DbgIO.println("defered load: ptr=%x len=%d", ptr, len); | |
51 defered_load = false; | |
52 data = ctx.readMemory(ptr, len); | |
53 } | |
54 return data; | |
55 } | |
56 | |
57 /********************************************************************************************** | |
58 | |
59 **********************************************************************************************/ | |
60 bool loadElementSlice(size_t start, size_t end, CodeView cv) | |
61 { | |
62 assert(end>=start); | |
63 size_t size = cv.sizeofMangled(type); | |
64 start *= size; | |
65 end *= size; | |
66 if ( defered_load ) | |
67 { | |
68 if ( end > len ) | |
69 return false; | |
70 ptr += start; | |
71 len = end-start; | |
72 } | |
73 else | |
74 { | |
75 if ( end > data.length ) | |
76 return false; | |
77 data = data[start..end]; | |
78 } | |
79 return true; | |
80 } | |
81 | |
82 /********************************************************************************************** | |
83 | |
84 **********************************************************************************************/ | |
85 bool loadByteSlice(size_t start, size_t end) | |
86 { | |
87 assert(end>=start); | |
88 if ( defered_load ) | |
89 { | |
90 if ( end > len ) | |
91 return false; | |
92 ptr += start; | |
93 len = end-start; | |
94 } | |
95 else | |
96 { | |
97 if ( end > data.length ) | |
98 return false; | |
99 data = data[start..end]; | |
100 } | |
101 return true; | |
102 } | |
103 } | |
104 | |
105 /************************************************************************************************** | |
106 | |
107 **************************************************************************************************/ | |
108 class EvaluationContext | |
109 { | |
110 CodeView codeView; | |
111 MiniDump miniDump; | |
112 DbgProcess process; | |
113 DbgThread thread; | |
114 | |
115 uint frameLevel; | |
116 CallStack stack; | |
117 ScopeSymbol scopeSym; | |
118 | |
119 NamedSymbol[] scopeSymbols; | |
120 | |
121 /********************************************************************************************** | |
122 | |
123 **********************************************************************************************/ | |
124 this(CodeView _cv, | |
125 uint _current_address, | |
126 MiniDump _miniDump, | |
127 DbgProcess _process, | |
128 DbgThread _thread, | |
129 CallStack _stack, | |
130 uint _frame_level=0 | |
131 ) | |
132 { | |
133 miniDump = _miniDump; | |
134 thread = _thread; | |
135 codeView = _cv; | |
136 process = _process; | |
137 stack = _stack; | |
138 frameLevel = _frame_level; | |
139 | |
140 uint segment; | |
141 scopeSym = codeView.findProcedureSymbol(_current_address); | |
142 for ( ; scopeSym !is null; scopeSym = scopeSym.parent_scope ) | |
143 { | |
144 scopeSymbols ~= scopeSym.symbols.named_symbols; | |
145 ProcedureSymbol psym = cast(ProcedureSymbol)scopeSym; | |
146 if ( psym !is null ) | |
147 scopeSymbols ~= psym.arguments.named_symbols; | |
148 } | |
149 } | |
150 | |
151 bool getContext(out CONTEXT ctx, uint context_flags) | |
152 { | |
153 if ( process !is null ) | |
154 return thread.getContext(ctx, context_flags); | |
155 else if ( miniDump !is null ) { | |
156 CONTEXT* ptr = miniDump.getContext; | |
157 if ( ptr !is null ) { | |
158 ctx = *ptr; | |
159 return true; | |
160 } | |
161 } | |
162 return false; | |
163 } | |
164 | |
165 /********************************************************************************************** | |
166 | |
167 **********************************************************************************************/ | |
168 NamedSymbol findSymbol(string name, inout NamedSymbol[] symbols) | |
169 { | |
170 if ( symbols is null ) | |
171 { | |
172 StringWrap sw = new StringWrap(name); | |
173 AVLNode!(NamedSymbol) res; | |
174 if ( codeView.globalNamedSymbols.find(sw, res) ) | |
175 { | |
176 NamedSymbol ns = res.value; | |
177 ScopeSymbol scopesym = cast(ScopeSymbol)ns; | |
178 if ( scopesym is null ) | |
179 return ns; | |
180 symbols = scopesym.symbols.named_symbols; | |
181 return null; | |
182 } | |
183 foreach ( ns; scopeSymbols ) | |
184 { | |
185 if ( name == ns.name_notype ) | |
186 { | |
187 debug(findSymbol) DbgIO.println("%s == %s", name, ns.name_notype); | |
188 ScopeSymbol scopesym = cast(ScopeSymbol)ns; | |
189 if ( scopesym is null ) | |
190 return ns; | |
191 symbols = scopesym.symbols.named_symbols; | |
192 return null; | |
193 } | |
194 } | |
195 } | |
196 else | |
197 { | |
198 foreach ( ns; symbols ) | |
199 { | |
200 if ( name == ns.name_notype ) | |
201 { | |
202 debug(findSymbol) DbgIO.println("%s == %s", name, ns.name_notype); | |
203 ScopeSymbol scopesym = cast(ScopeSymbol)ns; | |
204 if ( scopesym is null ) | |
205 return ns; | |
206 symbols = scopesym.symbols.named_symbols; | |
207 return null; | |
208 } | |
209 } | |
210 } | |
211 return null; | |
212 } | |
213 | |
214 /********************************************************************************************** | |
215 | |
216 **********************************************************************************************/ | |
217 SymbolData loadSymbolData(NamedSymbol symbol) | |
218 { | |
219 StackSymbol stacksym = cast(StackSymbol)symbol; | |
220 SymbolData symdata = new SymbolData; | |
221 if ( stacksym !is null ) | |
222 { | |
223 if ( stacksym.size == 0 ) | |
224 stacksym.size = codeView.sizeofCV(stacksym.cvdata.type); | |
225 debug(eval) DbgIO.println("reading stack symbol size=%d cv type 0x%x", stacksym.size, stacksym.cvdata.type); | |
226 if ( !stack.loadSymbolData(stacksym, symdata, frameLevel) ) | |
227 throw new EvaluationException("Couldn't load stack symbol "~symbol.name_notype); | |
228 } | |
229 else | |
230 { | |
231 DataSymbol datasym = cast(DataSymbol)symbol; | |
232 if ( datasym !is null ) | |
233 { | |
234 if ( datasym.size == 0 ) | |
235 datasym.size = codeView.sizeofCV(datasym.cvdata.type); | |
236 debug(eval) DbgIO.println("reading global symbol size=%d cv type 0x%x", datasym.size, datasym.cvdata.type); | |
237 | |
238 symdata.ptr = codeView.image.getSectionBase(datasym.cvdata.segment)+datasym.cvdata.offset; | |
239 symdata.len = datasym.size; | |
240 symdata.defered_load = true; | |
241 } | |
242 else | |
243 throw new EvaluationException("Can only evaluate Data and Stack Data Symbols, yet"); | |
244 } | |
245 | |
246 symdata.type = codeView.mangleType(symbol); | |
247 if ( symdata.type is null ) | |
248 throw new EvaluationException("Symbol "~symbol.name_notype~" has unknown CV type"); | |
249 return symdata; | |
250 } | |
251 | |
252 /********************************************************************************************** | |
253 | |
254 **********************************************************************************************/ | |
255 bool findMember(string ident, LeafFieldList lfl, inout size_t size, inout size_t offset, inout string type) | |
256 { | |
257 if ( lfl is null ) | |
258 return false; | |
259 foreach ( l; lfl.fields ) | |
260 { | |
261 if ( l.leaf_index == LF_BCLASS_16t ) | |
262 { | |
263 LeafBaseClass lbc = cast(LeafBaseClass)l; | |
264 assert ( lbc !is null ); | |
265 if ( lbc.type-0x1000 >= codeView.type_strings.length ) | |
266 { | |
267 throw new EvaluationException( | |
268 "unknown base class "~format("0x%04x", lbc.type)~" in type information for expression" | |
269 ); | |
270 } | |
271 LeafClassStruc lcs = cast(LeafClassStruc)codeView.type_strings[lbc.type-0x1000][0]; | |
272 assert ( lcs !is null ); | |
273 if ( lcs.field == 0 ) | |
274 continue; | |
275 if ( lcs.field-0x1000 >= codeView.type_strings.length ) | |
276 { | |
277 throw new EvaluationException( | |
278 "unknown field list "~format("0x%04x", lcs.field)~" in type information for expression" | |
279 ); | |
280 } | |
281 Leaf[] fields = codeView.type_strings[lcs.field-0x1000]; | |
282 if ( findMember(ident, cast(LeafFieldList)fields[0], size, offset, type) ) | |
283 return true; | |
284 } | |
285 else if ( l.leaf_index == LF_MEMBER_16t ) | |
286 { | |
287 LeafMember lm = cast(LeafMember)l; | |
288 assert ( lm !is null ); | |
289 if ( lm.name != ident ) | |
290 continue; | |
291 type = codeView.mangleCVtype(lm.type); | |
292 size = codeView.sizeofCV(lm.type); | |
293 offset = lm.offset.getUint; | |
294 return true; | |
295 } | |
296 } | |
297 | |
298 return false; | |
299 } | |
300 | |
301 /********************************************************************************************** | |
302 | |
303 **********************************************************************************************/ | |
304 ubyte[] readMemory(size_t ptr, size_t len) | |
305 { | |
306 if ( miniDump !is null ) | |
307 return miniDump.readMemory(ptr, len); | |
308 | |
309 if ( process is null ) | |
310 return null; | |
311 | |
312 if ( len > process.MEMCHECK_MIN && process.isInvalidMem(ptr, len) ) | |
313 return null; | |
314 ubyte data[] = new ubyte[len]; | |
315 if ( len != process.readProcessMemory(ptr, data.ptr, data.length) ) | |
316 return null; | |
317 return data; | |
318 } | |
319 } | |
320 |