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;
+    }
+}
+