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