summary history branches tags files
commit:9b9f392892699593ed13e32a4435191e56b86a71
author:mrmekon
committer:mrmekon
date:Fri Nov 9 11:32:13 2012 -0500
parents:edd8cb4dd0a1e911763e4898965c997716127ccf
Step, Next, and Stepi implemented.  Beginning ability to list source code.  Beginning ability to print symbols.
diff --git a/mdb/picdebugger.py b/mdb/picdebugger.py
line changes: +67/-4
index 02dba28..f9f5751
--- a/mdb/picdebugger.py
+++ b/mdb/picdebugger.py
@@ -1,5 +1,7 @@
 import sys
 import time
+import struct
+import jarray
 import java.lang.String
 import java.lang.System as System
 import com.microchip.mplab.util.observers
@@ -15,8 +17,11 @@ from com.microchip.mplab.mdbcore.translator.interfaces import ITranslator
 from com.microchip.mplab.mdbcore.translator.exceptions import TranslatorException
 from com.microchip.mplab.mdbcore.disasm import DisAsm
 from com.microchip.mplab.mdbcore.memory.memorytypes import ProgramMemory
+from com.microchip.mplab.mdbcore.memory.memorytypes import FileRegisters
 from com.microchip.mplab.mdbcore.objectfileparsing.exception import ProgramFileParsingException
 from com.microchip.mplab.mdbcore.platformtool import PlatformToolMetaManager
+from com.microchip.mplab.mdbcore.symbolview.interfaces import SymbolViewProvider
+from com.microchip.mplab.mdbcore.common.debug.SymbolType import eFundamentalType as VarType
 
 from com.microchip.mplab.mdbcore.ControlPointMediator.ControlPoint import BreakType
 from com.microchip.mplab.mdbcore.ControlPointMediator import ControlPointMediator
@@ -24,6 +29,11 @@ from com.microchip.mplab.mdbcore.ControlPointMediator import ControlPointMediato
 System.setProperty("crownking.stream.verbosity", "quiet")
 
 class picdebugger(com.microchip.mplab.util.observers.Observer):
+    class StepType:
+        IN = 0
+        OVER = 1
+        INSTR = 2
+    
     def __init__(self):
         self.mdb = None
         self._breakpoints = []
@@ -160,16 +170,69 @@ class picdebugger(com.microchip.mplab.util.observers.Observer):
         bits = assembly.GetDevice().getFamilyCode()
         return assembly.GetDevice().getSubFamily()
 
-    def addressToSourceLine(self, addr):
+    def getMemoryContents(self, addr, length, virtual=False):
+        fr = self.assembly.getLookup().lookup(FileRegisters)
+        data = jarray.zeros(length, "b")
+        if virtual:
+            mem = fr.GetVirtualMemory()
+        else:
+            mem = fr.GetPhysicalMemory()
+        mem.RefreshFromTarget(addr, length)
+        if mem.Read(addr, length, data) == length:
+            return data        
+        return None
+
+    def getSymbolValue(self, symbol):
+        sv = self.assembly.getLookup().lookup(SymbolViewProvider)
+        info = sv.getRawSymbol(symbol)
+        if not info:
+            return None
+        vartype = info.Type()
+        varlength = info.ByteLength()
+        data = self.getMemoryContents(info.Address(), varlength, virtual=True)
+        if not data:
+            return None
+
+        # Unpack array into variable based on type
+        fmtMap = {1: "b", 2: "h", 4: "i", 8: "q"}
+        # TODO: fill out map of types and their signedness
+        signMap = {VarType.ST_ULONG.value(): False,
+                   VarType.ST_LONG.value(): True,
+                   }
+        if varlength > 8:
+            # TODO: Handle complex symbols.  Struct or string or something.
+            print "Symbol type not handled!"
+            return None
+        fmt = fmtMap[varlength]
+        if vartype in signMap:
+            fmt = fmt.lower() if signMap[vartype] else fmt.upper()
+        # Special cases:
+        if vartype == VarType.ST_FLOAT:
+            fmt = "f"
+        elif vartype == VarType.ST_DOUBLE:
+            fmt = "d"
+        return struct.unpack(fmt, data.tostring())[0]
+        
+        
+
+    def addressToSourceLine(self, addr, stripdir=True):
         try:
             info = self.translator.addressToSourceLine(addr)
-            return (info.file.split("/")[-1], info.lLine)
+            f = info.file
+            if stripdir:
+                f = info.file.split("/")[-1]                
+            return (f, info.lLine)
         except TranslatorException:
             return ("unknown",0)
 
-    def step(self):
+    def step(self, type=StepType.OVER):
         try:
-            self.mdb.StepOver()
+            if type == self.StepType.OVER:
+                self.mdb.StepOver()
+            elif type == self.StepType.IN:
+                self.mdb.StepIn()
+            else:
+                self.mdb.StepInstr()
         except DebugException:
             print "Lost communication with debugger or target!"
             return

diff --git a/picdb.py b/picdb.py
line changes: +44/-6
index 2031334..01872c1
--- a/picdb.py
+++ b/picdb.py
@@ -16,16 +16,19 @@ class CommandHandler:
         self._commandMap = {
         "connect": {'fn': self.cmdConnect, 'help': "Conects to a PIC target."},
         "load": {'fn': self.cmdLoad, 'help': "Load ELF file onto target."},
-        "step": {'fn': self.cmdStep, 'help': "Step over next source line."},
+        "step": {'fn': self.cmdStep, 'help': "Step to next source line."},
+        "stepi": {'fn': self.cmdStepi, 'help': "Step to next assembly instruction."},
+        "next": {'fn': self.cmdNext, 'help': "Step to next source line, over functions."},
         "quit": {'fn': self.cmdQuit, 'help': "Quits this program."},
         "help": {'fn': self.cmdHelp, 'help': "Displays this help."},
         "debug": {'fn': self.cmdDebug, 'help': "Drop to Python console."},
         "break": {'fn': self.cmdBreak, 'help': "Set breakpoint."},
         "continue": {'fn': self.cmdContinue, 'help': "Continue running target."},
-        "print": {'fn': self.cmdPrint, 'help': "Print variable."},
+        "print": {'fn': self.cmdPrint, 'help': "Display variable."},
         "breakpoints": {'fn': self.cmdBreakpoints, 'help': "List breakpoints."},
+        "list": {'fn': self.cmdList, 'help': "Display source code listing."},
         }
-        
+
     def cmdConnect(self, args):
         '''
 Connects to a PIC target.
@@ -47,6 +50,12 @@ Usage: print <variable or register>
 Supported registers:
  * $pc
 '''
+        if args[0] != "$":
+            data = self.dbg.getSymbolValue(args)
+            if data is not None:
+                print data
+            else:
+                print "Symbol not found."
         if args.lower() == "$pc":
             print "PC: 0x%X" % self.dbg.getPC()
 
@@ -104,13 +113,42 @@ Usage: continue
         print "%sStopped at 0x%X (%s:%d)" % ("" if bp < 0 else "Breakpoint %d: " % bp,
                                              pc,file,line)
 
+    def cmdList(self, args):
+        pc = self.dbg.getPC()
+        fname,line = self.dbg.addressToSourceLine(pc, stripdir=False)
+        print "Listing from: %s" % fname
+        f = open(fname, "r")
+        for _ in range(line-1):
+            f.readline()
+        for i in range(10):
+            print "%.3d: %s" % (line+i, f.readline())
+
+
     def cmdStep(self, args):
         '''
-Step target over one line of source.
+Step target over one line of source.  Descends into functions.
 Usage: step
 '''
-        self.dbg.step()
-        
+        self.dbg.step(self.dbg.StepType.IN)
+
+
+    def cmdStepi(self, args):
+        '''
+Step target over one single instruction.
+Usage: stepi
+'''
+        self.dbg.step(self.dbg.StepType.INSTR)
+
+
+    def cmdNext(self, args):
+        '''
+Step target over one line of source.  If line is a function call, does not
+descend into it.
+Usage: step
+'''
+        self.dbg.step(self.dbg.StepType.OVER)
+
+
     def cmdQuit(self, args):
         '''
 Quit debugger.