Mercurial > projects > ddbg_continued
view 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 source
/* 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; } }