# Path: awake/address.py
# BANK_SIZE = 0x4000
# class BadAddressException(Exception):
# class Address(object):
#     def __init__(self, addr):
#     def __str__(self):
# def fromVirtual(virtual):
# def fromVirtualAndBank(virtual, bank):
# def fromVirtualAndCurrent(virtual, current):
# def fromPhysical(physical):
# def fromConventional(conventional):
#     def __init__(self, address):
#     def virtual(self):
#     def bank(self):
#     def isAmbiguous(self):
#     def inBankedSpace(self):
#     def inPhysicalMem(self):
#     def physical(self):
#     def offset(self, offset):
#     def withBankSpecified(self, bank):
#     def __lt__(self, other):
#     def __eq__(self, other):
#     def __ne__(self, other):
#     def __hash__(self):
#     def __str__(self):
#     def __repr__(self):
# 
# Path: awake/instruction.py
# class TailCall(CallInstruction):
#     def __init__(self, proj, target):
#         super(TailCall, self).__init__(proj, 'tail-call', target, placeholders.ALWAYS, target.getAddress())
# 
# Path: awake/operand.py
# class ProcAddress(AddressConstant):
#     link_prefix = "/proc/"
#     html_class = "proc-addr"


from collections import defaultdict
from awake import address
from awake.instruction import TailCall
from awake.operand import ProcAddress
        from .flowcontrol import Block
        from .flowcontrol import Block

class ProcedureGraph(object):
    def __init__(self, proj, start_addr, end_addr, block_starts, jumptable_sizes):
        self.start_addr = start_addr
        self.end_addr = end_addr
        self.jumptable_sizes = jumptable_sizes
        block_starts = list(sorted(block_starts))
        self.block_starts = block_starts
        self.block_id_at_addr = dict((block_starts[i], i) for i in range(len(block_starts)))
        self.block_id_at_addr[None] = None
        self._childs = dict()
        self.blocks = [None] * len(block_starts)
        self.addBlocks(proj)
        self._parents = defaultdict(list)
        self._fillParents()

    def addBlocks(self, proj):
        num_blocks = len(self.blocks)
        for i in range(num_blocks):
            start_addr = self.block_starts[i]
            if i+1 < num_blocks:
                end_addr = self.block_starts[i+1]
            else:
                end_addr = self.end_addr
            self.addBlock(proj, i, start_addr, end_addr)

    def addFakeBlock(self, proj, addr):
        pos = len(self.blocks)
        self.block_id_at_addr[addr] = pos


# Path: awake/address.py
# BANK_SIZE = 0x4000
# class BadAddressException(Exception):
# class Address(object):
#     def __init__(self, addr):
#     def __str__(self):
# def fromVirtual(virtual):
# def fromVirtualAndBank(virtual, bank):
# def fromVirtualAndCurrent(virtual, current):
# def fromPhysical(physical):
# def fromConventional(conventional):
#     def __init__(self, address):
#     def virtual(self):
#     def bank(self):
#     def isAmbiguous(self):
#     def inBankedSpace(self):
#     def inPhysicalMem(self):
#     def physical(self):
#     def offset(self, offset):
#     def withBankSpecified(self, bank):
#     def __lt__(self, other):
#     def __eq__(self, other):
#     def __ne__(self, other):
#     def __hash__(self):
#     def __str__(self):
#     def __repr__(self):
# 
# Path: awake/instruction.py
# class TailCall(CallInstruction):
#     def __init__(self, proj, target):
#         super(TailCall, self).__init__(proj, 'tail-call', target, placeholders.ALWAYS, target.getAddress())
# 
# Path: awake/operand.py
# class ProcAddress(AddressConstant):
#     link_prefix = "/proc/"
#     html_class = "proc-addr"


# Path: awake/procedure.py
from collections import defaultdict
from awake import address
from awake.instruction import TailCall
from awake.operand import ProcAddress
        from .flowcontrol import Block
        from .flowcontrol import Block


class ProcedureGraph(object):
    def __init__(self, proj, start_addr, end_addr, block_starts, jumptable_sizes):
        self.start_addr = start_addr
        self.end_addr = end_addr
        self.jumptable_sizes = jumptable_sizes
        block_starts = list(sorted(block_starts))
        self.block_starts = block_starts
        self.block_id_at_addr = dict((block_starts[i], i) for i in range(len(block_starts)))
        self.block_id_at_addr[None] = None
        self._childs = dict()
        self.blocks = [None] * len(block_starts)
        self.addBlocks(proj)
        self._parents = defaultdict(list)
        self._fillParents()

    def addBlocks(self, proj):
        num_blocks = len(self.blocks)
        for i in range(num_blocks):
            start_addr = self.block_starts[i]
            if i+1 < num_blocks:
                end_addr = self.block_starts[i+1]
            else:
                end_addr = self.end_addr
            self.addBlock(proj, i, start_addr, end_addr)

    def addFakeBlock(self, proj, addr):
        pos = len(self.blocks)
        self.block_id_at_addr[addr] = pos


        instr = TailCall(proj, ProcAddress(addr))