Package envi :: Package memcanvas
[hide private]
[frames] | no frames]

Source Code for Package envi.memcanvas

  1  ''' 
  2  The envi.memcanvas module is the home of the base MemoryRenderer object and 
  3  MemoryCanvas objects. 
  4  ''' 
  5   
  6  import sys 
  7  import traceback 
  8   
  9  import envi 
 10  import envi.memory as e_mem 
 11  import envi.resolver as e_resolv 
 12   
13 -class MemoryRenderer:
14 """ 15 A top level object for all memory renderers 16 """ 17
18 - def rendSymbol(self, mcanv, va):
19 """ 20 If there is a symbolic name for the current va, print it... 21 """ 22 sym = mcanv.syms.getSymByAddr(va) 23 if sym != None: 24 mcanv.addVaText("%s:\n" % repr(sym), va)
25
26 - def rendVa(self, mcanv, va):
27 tag = mcanv.getVaTag(va) 28 mcanv.addText("%.8x:" % va, tag=tag)
29
30 - def rendChars(self, mcanv, bytes):
31 for b in bytes: 32 val = ord(b) 33 bstr = "%.2x" % val 34 if val < 0x20 or val > 0x7e: 35 b = "." 36 mcanv.addNameText(b, bstr)
37
38 - def render(self, mcanv, va):
39 """ 40 Render one "unit" and return the size you ate. 41 mcanv will be a MemoryCanvas extender and va 42 is the virtual address you are expected to render. 43 """ 44 raise Exception("Implement render!")
45
46 -class MemoryCanvas:
47 """ 48 A memory canvas is a place where the textual representation 49 of memory will be displayed. The methods implemented here show 50 how a memory canvas which simply prints would be implemented. 51 """
52 - def __init__(self, mem, syms=None):
53 if syms == None: 54 syms = e_resolv.SymbolResolver() 55 self.mem = mem 56 self.syms = syms 57 self.currend = None 58 self.renderers = {} 59 self._canv_scrolled = False 60 self._canv_navcallback = None 61 62 # A few things for tracking renders. 63 self._canv_beginva = None 64 self._canv_endva = None 65 self._canv_rendvas = []
66
67 - def setScrolledCanvas(self, scroll):
68 self._canv_scrolled = scroll
69
70 - def write(self, msg):
71 # So a canvas can act like simple standard out 72 self.addText(msg)
73
74 - def setNavCallback(self, callback):
75 ''' 76 Set a navigation "callback" that will be called with 77 a memory expression as it's first argument anytime the 78 canvas recieves user input which desires nav... 79 ''' 80 self._canv_navcallback = callback
81
82 - def addRenderer(self, name, rend):
83 self.renderers[name] = rend 84 self.currend = rend
85
86 - def getRenderer(self, name):
87 return self.renderers.get(name)
88
89 - def getRendererNames(self):
90 ret = self.renderers.keys() 91 ret.sort() 92 return ret
93
94 - def setRenderer(self, name):
95 rend = self.renderers.get(name) 96 if rend == None: 97 raise Exception("Unknown renderer: %s" % name) 98 self.currend = rend
99
100 - def getTag(self, typename):
101 """ 102 Retrieve a non-named tag (doesn't highlight or do 103 anything particularly special, but allows color 104 by typename). 105 """ 106 return None
107
108 - def getNameTag(self, name, typename=None):
109 """ 110 Retrieve a "tag" object for a name. "Name" tags will 111 (if possible) be highlighted in the rendered interface 112 """ 113 return None # No highlighting in plain text
114
115 - def getVaTag(self, va):
116 """ 117 Retrieve a tag object suitable for showing that the text 118 added with this tag should link through to the specified 119 virtual address in the memory canvas. 120 """ 121 return None # No linking in plain text
122
123 - def addText(self, text, tag=None):
124 """ 125 Add text to the canvas with a specified tag. 126 127 NOTE: Implementors should probably check _canv_scrolled to 128 decide if they should scroll to the end of the view... 129 """ 130 sys.stdout.write(text.encode(sys.stdout.encoding,'replace'))
131
132 - def addNameText(self, text, name=None, typename=None):
133 if name == None: 134 name = text 135 tag = self.getNameTag(name, typename=typename) 136 self.addText(text, tag=tag)
137
138 - def addVaText(self, text, va):
139 tag = self.getVaTag(va) 140 self.addText(text, tag=tag)
141
142 - def render(self, va, size, rend=None):
143 raise Exception('Depricated! use renderMemory!')
144
145 - def clearCanvas(self):
146 pass
147
148 - def _beginRenderMemory(self, va, size, rend):
149 pass
150
151 - def _endRenderMemory(self, va, size, rend):
152 pass
153
154 - def _beginRenderVa(self, va):
155 pass
156
157 - def _endRenderVa(self, va):
158 pass
159
160 - def _beginUpdateVas(self, valist):
161 raise Exception('Default canvas cant update!')
162
163 - def _endUpdateVas(self):
164 pass
165
166 - def _beginRenderAppend(self):
167 raise Exception('Default canvas cant append!')
168
169 - def _endRenderAppend(self):
170 pass
171
172 - def _beginRenderPrepend(self):
173 raise Exception('Default canvas cant prepend!')
174
175 - def _endRenderPrepend(self):
176 pass
177
178 - def _isRendered(self, va, maxva):
179 ''' 180 Returns true if any part of the current render overlaps 181 with the specified region. 182 ''' 183 if self._canv_beginva == None: 184 return False 185 186 if self._canv_endva == None: 187 return False 188 189 if va > self._canv_endva: 190 return False 191 192 if maxva < self._canv_beginva: 193 return False 194 195 return True
196
197 - def renderMemoryUpdate(self, va, size):
198 199 maxva = va + size 200 if not self._isRendered(va, maxva): 201 return 202 203 # Find the index of the first and last change 204 iend = None 205 ibegin = None 206 for i,(rendva,rendsize) in enumerate(self._canv_rendvas): 207 208 if ibegin == None and va <= rendva: 209 ibegin = i 210 211 if iend == None and maxva <= rendva: 212 iend = i 213 214 if ibegin != None and iend != None: 215 break 216 217 saved_last = self._canv_rendvas[iend:] 218 saved_first = self._canv_rendvas[:ibegin] 219 updatedvas = self._canv_rendvas[ibegin:iend] 220 #print 'IBEGIN',hex(ibegin) 221 #print 'IEND',hex(iend) 222 #print 'FIRST',repr([hex(va) for va in saved_first]) 223 #print 'UPDATED',repr([hex(va) for va in updatedvas]) 224 #print 'LAST',repr([hex(va) for va in saved_last]) 225 226 # We must actually start rendering from the beginning 227 # of the first updated VA index 228 startva = updatedvas[0][0] 229 endva = self._canv_endva 230 if saved_last: 231 endva = saved_last[0][0] 232 233 newrendvas = [] 234 235 self._beginUpdateVas(updatedvas) 236 try: 237 238 while startva < endva: 239 self._beginRenderVa(startva) 240 rsize = self.currend.render(self, startva) 241 newrendvas.append((startva,rsize)) 242 self._endRenderVa(startva) 243 startva += rsize 244 245 except Exception, e: 246 s = traceback.format_exc() 247 self.addText("\nException At %s: %s\n" % (hex(va),s)) 248 249 self._canv_rendvas = saved_first + newrendvas + saved_last 250 251 self._endUpdateVas()
252
253 - def renderMemoryPrepend(self, size):
254 firstva, firstsize = self._canv_rendvas[0] 255 256 va = firstva - size 257 258 self._beginRenderPrepend() 259 260 savedrendvas = self._canv_rendvas 261 self._canv_rendvas = [] 262 self._canv_beginva = va 263 264 rend = self.currend 265 266 try: 267 268 while va < firstva: 269 self._beginRenderVa(va) 270 rsize = rend.render(self, va) 271 self._canv_rendvas.append((va,rsize)) 272 self._endRenderVa(va) 273 va += rsize 274 275 self._canv_rendvas.extend(savedrendvas) 276 277 except Exception, e: 278 s = traceback.format_exc() 279 self.addText("\nException At %s: %s\n" % (hex(va),s)) 280 281 self._endRenderPrepend()
282
283 - def renderMemoryAppend(self, size):
284 lastva, lastsize = self._canv_rendvas[-1] 285 286 va = lastva + lastsize 287 288 self._beginRenderAppend() 289 290 rend = self.currend 291 try: 292 maxva = va + size 293 while va < maxva: 294 self._beginRenderVa(va) 295 rsize = rend.render(self, va) 296 self._canv_rendvas.append((va,rsize)) 297 self._endRenderVa(va) 298 va += rsize 299 300 self._canv_endva = maxva 301 302 except Exception, e: 303 s = traceback.format_exc() 304 self.addText("\nException At %s: %s\n" % (hex(va),s)) 305 306 self._endRenderAppend()
307
308 - def renderMemory(self, va, size, rend=None):
309 310 # if this is not a "scrolled" canvas, clear it. 311 if not self._canv_scrolled: 312 self.clearCanvas() 313 314 if rend == None: 315 rend = self.currend 316 317 self.currend = rend 318 319 # Set our canvas render tracking variables. 320 self._canv_beginva = va 321 self._canv_endva = va + size 322 self._canv_rendvas = [] 323 324 # A callback for "bulk" rendering (let the canvas cache...) 325 self._beginRenderMemory(va, size, rend) 326 try: 327 maxva = va + size 328 while va < maxva: 329 self._beginRenderVa(va) 330 rsize = rend.render(self, va) 331 self._canv_rendvas.append((va,rsize)) 332 self._endRenderVa(va) 333 va += rsize 334 335 except Exception, e: 336 s = traceback.format_exc() 337 self.addText("\nException At %s: %s\n" % (hex(va),s)) 338 339 # Canvas callback for render completion (or error...) 340 self._endRenderMemory(va, size, rend)
341
342 -class StringMemoryCanvas(MemoryCanvas):
343
344 - def __init__(self, mem, syms=None):
345 MemoryCanvas.__init__(self, mem, syms=None) 346 self.strval = ""
347
348 - def addText(self, text, tag=None):
349 self.strval += text
350
351 - def __str__(self):
352 return self.strval
353