def __init__(self, proj, name, target, cond, addr): super(CallInstruction, self).__init__(name, addr) # XXX: IDIOM [CALL HL] if hasattr(target, 'value') and target.value == 0x00A0: target = placeholders.HL # XXX: IDIOM [CALL BC] if hasattr(target, 'value') and target.value == 0x0CDA: target = placeholders.BC # XXX: IDIOM [CALL LONG E:HL] if hasattr(target, 'value') and target.value == 0x008A: target = ComputedProcAddress(placeholders.E, placeholders.HL) self.cond = cond if hasattr(target, 'getAddress'): self.targetAddr = target.getAddress() self.target = ProcAddress(self.targetAddr) elif hasattr(target, 'value') and target.value is not None: self.targetAddr = address.fromVirtualAndCurrent(target.value, addr) self.target = ProcAddress(self.targetAddr) else: self.targetAddr = address.fromVirtual(0x4000) # XXX: ambiguous address self.target = target self.target_depset = proj.database.procInfo(self.targetAddr).depset self.returns_used = ALL_REGS self.constant_params = dict()
def __init__(self, inner, postcond, continue_label): self.name = 'do-while' self.addr = address.fromVirtual(0) self.inner = inner self.postcond = postcond self.continue_label = continue_label continue_label.addContinue(self)
def __init__(self, inner, postcond, continue_label): self.name = "do-while" self.addr = address.fromVirtual(0) self.inner = inner self.postcond = postcond self.continue_label = continue_label continue_label.addContinue(self)
def testOffset(self): zero = address.fromVirtual(0) self.assertEquals(str(zero.offset(0)), "0000:0000") self.assertEquals(str(zero.offset(0x3FFF)), "0000:3FFF") self.assertEquals(str(zero.offset(0x4000)), "(A):4000") self.assertEquals(str(zero.offset(0x8000)), "VRAM:8000") first = address.fromPhysical(0x4000) self.assertEquals(str(first.offset(-0x4000)), "0000:0000") self.assertEquals(str(first.offset(0)), "0001:4000") self.assertEquals(str(first.offset(0x3FFF)), "0001:7FFF") self.assertEquals(str(first.offset(0x4000)), "VRAM:8000") high = address.fromVirtual(0x8000) self.assertEquals(str(high.offset(-0x8000)), "0000:0000") self.assertEquals(str(high.offset(-0x1000)), "(A):7000") self.assertEquals(str(high.offset(0)), "VRAM:8000") self.assertEquals(str(high.offset(0x0FFF)), "VRAM:8FFF")
def __init__(self, addr): if not hasattr(addr, 'virtual'): if isinstance(addr, int): #If addr is an int, addr = address.fromVirtual(addr) # code path is unchanged. else: #Else, addr is a string, addr = address.fromConventional(addr) # so it should be processed by fromConventional. super(AddressConstant, self).__init__(addr.virtual()) self.addr = addr self.value = addr.virtual()
def getLimit(proj, addr): if addr.inPhysicalMem(): bank_limit = address.fromVirtualAndBank(0x4000, addr.bank() + 1) else: bank_limit = address.fromVirtual(0xFFFF) next_owned = proj.database.getNextOwnedAddress(addr) if not next_owned or bank_limit < next_owned: return bank_limit else: return next_owned
def getLimit(proj, addr): if addr.inPhysicalMem(): bank_limit = address.fromVirtualAndBank(0x4000, addr.bank()+1) else: bank_limit = address.fromVirtual(0xFFFF) next_owned = proj.database.getNextOwnedAddress(addr) if not next_owned or bank_limit < next_owned: return bank_limit else: return next_owned
def testFromVirtual(self): self.assertEquals(str(address.fromVirtual(0x0000)), "0000:0000") self.assertEquals(str(address.fromVirtual(0x2000)), "0000:2000") self.assertEquals(str(address.fromVirtual(0x4000)), "(A):4000") self.assertEquals(str(address.fromVirtual(0x7FFF)), "(A):7FFF") self.assertEquals(str(address.fromVirtual(0x8000)), "VRAM:8000") self.assertEquals(str(address.fromVirtual(0xFFFF)), "IO:FFFF")
def __init__(self, target, addr=None): self.addr = addr if hasattr(target, "getAddress"): self.target = target elif target.value is not None: if addr is not None: self.target = DataAddress(address.fromVirtualAndCurrent(target.value, addr)) else: self.target = DataAddress(address.fromVirtual(target.value)) else: self.target = target self.childs = (self.target,)
def optimizedWithContext(self, ctx): target = self.target.optimizedWithContext(ctx) if not hasattr(target, 'getAddress') and target.value is not None: target = DataAddress(address.fromVirtual(target.value)).optimizedWithContext(ctx) return Dereference(target, self.addr)
from awake.operand import Constant, Condition, Dereference, Register BC = Register("BC") DE = Register("DE") HL = Register("HL") SP = Register("SP") AF = Register("AF") B = Register("B") C = Register("C") D = Register("D") E = Register("E") H = Register("H") L = Register("L") A = Register("A") deref_HL = Dereference(HL, address.fromVirtual(0)) # XXX: TODO: very very bad FNZ = Condition("FNZ") FZ = Condition("FZ") FNC = Condition("FNC") FC = Condition("FC") ALWAYS = Condition("ALWAYS") ROMBANK = Register('ROMBANK') tab = dict( R=[BC, DE, HL, SP], Q=[BC, DE, HL, AF], S=[B, C, D, E, H, L, deref_HL, A], Z=[B, C, D, E, H, L, deref_HL, A], F=[FNZ, FZ, FNC, FC],
def process(self, x, after, break_target, continue_target, need_label=False): after = self.graph.skipSimpleJumps(after) break_target = self.graph.skipSimpleJumps(break_target) continue_target = self.graph.skipSimpleJumps(continue_target) out = [] while True: x = self.graph.skipSimpleJumps(x) if x is None or x in self._visited: if x == after: pass elif x == break_target: if x is None and None not in self.labels: self.labels[None] = flowcontrol.Label( address.fromVirtual(0)) out.append(flowcontrol.Break(self.labels[x])) elif x == continue_target: out.append(flowcontrol.Continue(self.labels[x])) elif x is None: out.append(flowcontrol.Return()) else: out.append(flowcontrol.Goto(self.labels[x])) return flowcontrol.Block(out) cycle = self.get_unused_cycle(x) if cycle: exits = find_cycle_exits(self.graph, cycle) if exits: exits = set([select_any(exits)]) cascades, next_after = self._process_cascades( exits, after, break_target, continue_target) inner = self.process(x, x, next_after, x, True) continue_label = self.labels[x] out.append(self.make_while(inner, continue_label)) return flowcontrol.Block(out + cascades) self._visited.add(x) childs = self.graph.childs(x) if (len(self.graph.parents(x)) > 1 or need_label) and x not in self.labels: self.labels[x] = flowcontrol.Label(self.graph.block_starts[x]) out.append(self.labels[x]) need_label = False if len(childs) > 1: cascades, next_after = self._process_cascades( self.merges[x], after, break_target, continue_target) prev_contents = self.graph.getContents(x)[:-1] out += prev_contents if self.graph.isSwitch(x): break_target = next_after branches = [] for ch in reversed(childs): branches.append( self.process(ch, next_after, break_target, continue_target)) next_after = ch branches.reverse() out += self.make_switch(x, branches) else: branches = [] for ch in childs: branches.append( self.process(ch, next_after, break_target, continue_target)) out += self.make_if(x, branches[0], branches[1]) return flowcontrol.Block(out + cascades) else: out += self.graph.getContents(x) x = select_any(childs) continue
def process(self, x, after, break_target, continue_target, need_label=False): after = self.graph.skipSimpleJumps(after) break_target = self.graph.skipSimpleJumps(break_target) continue_target = self.graph.skipSimpleJumps(continue_target) out = [] while True: x = self.graph.skipSimpleJumps(x) if x is None or x in self._visited: if x == after: pass elif x == break_target: if x is None and None not in self.labels: self.labels[None] = flowcontrol.Label(address.fromVirtual(0)) out.append(flowcontrol.Break(self.labels[x])) elif x == continue_target: out.append(flowcontrol.Continue(self.labels[x])) elif x is None: out.append(flowcontrol.Return()) else: out.append(flowcontrol.Goto(self.labels[x])) return flowcontrol.Block(out) cycle = self.get_unused_cycle(x) if cycle: exits = find_cycle_exits(self.graph, cycle) if exits: exits = set([select_any(exits)]) cascades, next_after = self._process_cascades(exits, after, break_target, continue_target) inner = self.process(x, x, next_after, x, True) continue_label = self.labels[x] out.append(self.make_while(inner, continue_label)) return flowcontrol.Block(out + cascades) self._visited.add(x) childs = self.graph.childs(x) if (len(self.graph.parents(x)) > 1 or need_label) and x not in self.labels: self.labels[x] = flowcontrol.Label(self.graph.block_starts[x]) out.append(self.labels[x]) need_label = False if len(childs) > 1: cascades, next_after = self._process_cascades(self.merges[x], after, break_target, continue_target) prev_contents = self.graph.getContents(x)[:-1] out += prev_contents if self.graph.isSwitch(x): break_target = next_after branches = [] for ch in reversed(childs): branches.append(self.process(ch, next_after, break_target, continue_target)) next_after = ch branches.reverse() out += self.make_switch(x, branches) else: branches = [] for ch in childs: branches.append(self.process(ch, next_after, break_target, continue_target)) out += self.make_if(x, branches[0], branches[1]) return flowcontrol.Block(out + cascades) else: out += self.graph.getContents(x) x = select_any(childs) continue
def __init__(self, name, addr=None): self.name = name self.addr = addr if not self.addr: self.addr = address.fromVirtual(0)