Mercurial > projects > ddbg_continued
diff 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 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/expression/evaluationcontext.d Tue Apr 05 20:44:01 2011 +0200 @@ -0,0 +1,320 @@ +/* Ddbg - Win32 Debugger for the D programming language + * Copyright (c) 2007 Jascha Wetzel + * All rights reserved. See LICENSE.TXT for details. + */ +module expression.evaluationcontext; + +import container; +import codeview.decl; +import codeview.codeview; +import minidump; +import dbgprocess; +import dbgthread; +import callstack; +import util; +import expression.datahandler; + +import std.string; + +import win32.winnt; + +class EvaluationException : Exception +{ + this(string m) { super(m); } +} + +/************************************************************************************************** + +**************************************************************************************************/ +class SymbolData +{ + string type; + bool defered_load; + + union + { + ubyte[] data; + struct { + size_t len, + ptr; + } + } + + /********************************************************************************************** + + **********************************************************************************************/ + ubyte[] getData(EvaluationContext ctx) + { + if ( defered_load ) + { + debug(eval) DbgIO.println("defered load: ptr=%x len=%d", ptr, len); + defered_load = false; + data = ctx.readMemory(ptr, len); + } + return data; + } + + /********************************************************************************************** + + **********************************************************************************************/ + bool loadElementSlice(size_t start, size_t end, CodeView cv) + { + assert(end>=start); + size_t size = cv.sizeofMangled(type); + start *= size; + end *= size; + if ( defered_load ) + { + if ( end > len ) + return false; + ptr += start; + len = end-start; + } + else + { + if ( end > data.length ) + return false; + data = data[start..end]; + } + return true; + } + + /********************************************************************************************** + + **********************************************************************************************/ + bool loadByteSlice(size_t start, size_t end) + { + assert(end>=start); + if ( defered_load ) + { + if ( end > len ) + return false; + ptr += start; + len = end-start; + } + else + { + if ( end > data.length ) + return false; + data = data[start..end]; + } + return true; + } +} + +/************************************************************************************************** + +**************************************************************************************************/ +class EvaluationContext +{ + CodeView codeView; + MiniDump miniDump; + DbgProcess process; + DbgThread thread; + + uint frameLevel; + CallStack stack; + ScopeSymbol scopeSym; + + NamedSymbol[] scopeSymbols; + + /********************************************************************************************** + + **********************************************************************************************/ + this(CodeView _cv, + uint _current_address, + MiniDump _miniDump, + DbgProcess _process, + DbgThread _thread, + CallStack _stack, + uint _frame_level=0 + ) + { + miniDump = _miniDump; + thread = _thread; + codeView = _cv; + process = _process; + stack = _stack; + frameLevel = _frame_level; + + uint segment; + scopeSym = codeView.findProcedureSymbol(_current_address); + for ( ; scopeSym !is null; scopeSym = scopeSym.parent_scope ) + { + scopeSymbols ~= scopeSym.symbols.named_symbols; + ProcedureSymbol psym = cast(ProcedureSymbol)scopeSym; + if ( psym !is null ) + scopeSymbols ~= psym.arguments.named_symbols; + } + } + + bool getContext(out CONTEXT ctx, uint context_flags) + { + if ( process !is null ) + return thread.getContext(ctx, context_flags); + else if ( miniDump !is null ) { + CONTEXT* ptr = miniDump.getContext; + if ( ptr !is null ) { + ctx = *ptr; + return true; + } + } + return false; + } + + /********************************************************************************************** + + **********************************************************************************************/ + NamedSymbol findSymbol(string name, inout NamedSymbol[] symbols) + { + if ( symbols is null ) + { + StringWrap sw = new StringWrap(name); + AVLNode!(NamedSymbol) res; + if ( codeView.globalNamedSymbols.find(sw, res) ) + { + NamedSymbol ns = res.value; + ScopeSymbol scopesym = cast(ScopeSymbol)ns; + if ( scopesym is null ) + return ns; + symbols = scopesym.symbols.named_symbols; + return null; + } + foreach ( ns; scopeSymbols ) + { + if ( name == ns.name_notype ) + { + debug(findSymbol) DbgIO.println("%s == %s", name, ns.name_notype); + ScopeSymbol scopesym = cast(ScopeSymbol)ns; + if ( scopesym is null ) + return ns; + symbols = scopesym.symbols.named_symbols; + return null; + } + } + } + else + { + foreach ( ns; symbols ) + { + if ( name == ns.name_notype ) + { + debug(findSymbol) DbgIO.println("%s == %s", name, ns.name_notype); + ScopeSymbol scopesym = cast(ScopeSymbol)ns; + if ( scopesym is null ) + return ns; + symbols = scopesym.symbols.named_symbols; + return null; + } + } + } + return null; + } + + /********************************************************************************************** + + **********************************************************************************************/ + SymbolData loadSymbolData(NamedSymbol symbol) + { + StackSymbol stacksym = cast(StackSymbol)symbol; + SymbolData symdata = new SymbolData; + if ( stacksym !is null ) + { + if ( stacksym.size == 0 ) + stacksym.size = codeView.sizeofCV(stacksym.cvdata.type); + debug(eval) DbgIO.println("reading stack symbol size=%d cv type 0x%x", stacksym.size, stacksym.cvdata.type); + if ( !stack.loadSymbolData(stacksym, symdata, frameLevel) ) + throw new EvaluationException("Couldn't load stack symbol "~symbol.name_notype); + } + else + { + DataSymbol datasym = cast(DataSymbol)symbol; + if ( datasym !is null ) + { + if ( datasym.size == 0 ) + datasym.size = codeView.sizeofCV(datasym.cvdata.type); + debug(eval) DbgIO.println("reading global symbol size=%d cv type 0x%x", datasym.size, datasym.cvdata.type); + + symdata.ptr = codeView.image.getSectionBase(datasym.cvdata.segment)+datasym.cvdata.offset; + symdata.len = datasym.size; + symdata.defered_load = true; + } + else + throw new EvaluationException("Can only evaluate Data and Stack Data Symbols, yet"); + } + + symdata.type = codeView.mangleType(symbol); + if ( symdata.type is null ) + throw new EvaluationException("Symbol "~symbol.name_notype~" has unknown CV type"); + return symdata; + } + + /********************************************************************************************** + + **********************************************************************************************/ + bool findMember(string ident, LeafFieldList lfl, inout size_t size, inout size_t offset, inout string type) + { + if ( lfl is null ) + return false; + foreach ( l; lfl.fields ) + { + if ( l.leaf_index == LF_BCLASS_16t ) + { + LeafBaseClass lbc = cast(LeafBaseClass)l; + assert ( lbc !is null ); + if ( lbc.type-0x1000 >= codeView.type_strings.length ) + { + throw new EvaluationException( + "unknown base class "~format("0x%04x", lbc.type)~" in type information for expression" + ); + } + LeafClassStruc lcs = cast(LeafClassStruc)codeView.type_strings[lbc.type-0x1000][0]; + assert ( lcs !is null ); + if ( lcs.field == 0 ) + continue; + if ( lcs.field-0x1000 >= codeView.type_strings.length ) + { + throw new EvaluationException( + "unknown field list "~format("0x%04x", lcs.field)~" in type information for expression" + ); + } + Leaf[] fields = codeView.type_strings[lcs.field-0x1000]; + if ( findMember(ident, cast(LeafFieldList)fields[0], size, offset, type) ) + return true; + } + else if ( l.leaf_index == LF_MEMBER_16t ) + { + LeafMember lm = cast(LeafMember)l; + assert ( lm !is null ); + if ( lm.name != ident ) + continue; + type = codeView.mangleCVtype(lm.type); + size = codeView.sizeofCV(lm.type); + offset = lm.offset.getUint; + return true; + } + } + + return false; + } + + /********************************************************************************************** + + **********************************************************************************************/ + ubyte[] readMemory(size_t ptr, size_t len) + { + if ( miniDump !is null ) + return miniDump.readMemory(ptr, len); + + if ( process is null ) + return null; + + if ( len > process.MEMCHECK_MIN && process.isInvalidMem(ptr, len) ) + return null; + ubyte data[] = new ubyte[len]; + if ( len != process.readProcessMemory(ptr, data.ptr, data.length) ) + return null; + return data; + } +} +