def execute_CTR(state, reason): state.reason = reason value = state.header[syntax.Field('CTR')] value.value = 1 state.label = syntax.Label('') return state
def execute_OP(state, destination, left_source, operator, right_source): left_value = None ''' Lookup left_source operand ''' if isinstance(left_source, O.Value): left_value = left_source.value elif isinstance(left_source, O.Field): left_value = state.header[left_source.field] else: raise RuntimeError() right_value = None ''' Lookup right_source operand ''' if isinstance(right_source, O.Value): right_value = right_source.value elif isinstance(right_source, O.Field): right_value = state.header[right_source.field] else: raise RuntimeError() ''' Operate on the values ''' value = operate(left_value, operator, right_value) ''' Lookup destination operand ''' if isinstance(destination, O.Field): state.header[destination.field] = value else: raise RuntimeError() state.label = syntax.Label('') return state
def execute_PUSH(state, location, source): value = None ''' Lookup source operand ''' if isinstance(source, O.Value): value = source.value elif isinstance(source, O.Field): value = state.header[source.field] else: raise RuntimeError() if isinstance(location, O.Location): ''' Lookup offset ''' offset = location.location.offset if isinstance(offset, O.Value): offset_value = offset.value elif isinstance(offset, O.Field): offset_value = state.header[offset.field] else: raise RuntimeError() state.packet.insert(BitArray(length=value.size), offset_value.value) state.packet[offset_value.value:(offset_value.value + value.size)] = value.value else: raise RuntimeError() state.label = syntax.Label('') return state
def execute_BR(state, left_source, operator, right_source, label): left_value = None ''' Lookup left_source operand ''' if isinstance(left_source, O.Value): left_value = left_source.value elif isinstance(left_source, O.Field): left_value = state.header[left_source.field] else: raise RuntimeError() right_value = None ''' Lookup right_source operand ''' if isinstance(right_source, O.Value): right_value = right_source.value elif isinstance(right_source, O.Field): right_value = state.header[right_source.field] else: raise RuntimeError() ''' Update program counter ''' if compare(left_value, operator, right_value): state.label = label else: state.label = syntax.Label('') return state
def execute_POP(state, destination, location): size = None ''' Validate destination operand ''' if isinstance(destination, O.Field): size = state.header[destination.field].size else: raise RuntimeError() if isinstance(location, O.Location): ''' Lookup offset ''' offset = location.location.offset if isinstance(offset, O.Value): offset_value = offset.value elif isinstance(offset, O.Field): offset_value = state.header[offset.field] else: raise RuntimeError() state.header[destination.field].value = int(state.packet[offset_value.value:(offset_value.value + size)].uint) del state.packet[offset_value.value:(offset_value.value + size)] else: raise RuntimeError() state.label = syntax.Label('') return state
def execute_ST(state, location, source): value = None ''' Lookup source operand ''' if isinstance(source, O.Value): value = source.value elif isinstance(source, O.Field): value = state.header[source.field] else: raise RuntimeError() ''' Store in the packet ''' if isinstance(location, O.Location): offset = location.location.offset if isinstance(offset, O.Value): offset_value = offset.value elif isinstance(offset, O.Field): offset_value = state.header[offset.field] else: raise RuntimeError() state.packet[offset_value.value:(offset_value.value + value.size)] = value.value else: raise RuntimeError() state.label = syntax.Label('') return state
def _next_label(instruction): if isinstance(instruction, I.LBL): return instruction.label elif isinstance(instruction, I.Instruction): return syntax.Label('$' + str(uuid.uuid1().hex)) else: raise RuntimeError
def type_check_BR(context, left_source, operator, right_source, label): pass ''' Lookup left_source operand ''' if isinstance(left_source, O.Value): pass elif isinstance(left_source, O.Field): if not is_special_field(left_source.field): if left_source.field in context.header: pass else: raise TypeError( "left source field (%s) is not present in the header." % str(left_source.field)) else: raise TypeError("left source field (%s) is a special field." % str(left_source.field)) else: raise TypeError( "invalid %s of left source (%s). Should be either %s or %s." % (type(left_source), left_source, O.Value, O.Field)) ''' Lookup right_source operand ''' if isinstance(right_source, O.Value): pass elif isinstance(right_source, O.Field): if not is_special_field(right_source.field): if right_source.field in context.header: pass else: raise TypeError( "right source field (%s) is not present in the header." % str(right_source.field)) else: raise TypeError("right source field (%s) is a special field." % str(right_source.field)) else: raise TypeError( "invalid %s of right source (%s). Should be either %s or %s." % (type(right_source), right_source, O.Value, O.Field)) if isinstance(operator, Op.ComparisonOperator): pass else: raise TypeError("invalid %s of operator (%s). Should be %s." % (type(operator), operator, Op.ComparisonOperator)) ''' Update program counter ''' if not isinstance(label, syntax.Label): raise TypeError("invalid %s of label (%s). Should be %s." % (type(label), label, syntax.Label)) # TODO: check this using the forwards and backwards label check # if label in labels: # pass # else: # raise TypeError("TypeError(%s): label (%s) doesn't exist" % ("BR", str(label))) context.labels = Labels(label, syntax.Label(''))
def generate(instructions): flow_graph = {} basic_blocks = bb.generate(instructions) entry_label = syntax.Label('$entry') first_label = current_label = syntax.Label('$' + str(uuid.uuid1().hex)) exit_label = syntax.Label('$exit') last_label = None flow_graph[entry_label] = Node([Entry()], [], [first_label]) flow_graph[exit_label] = Node([Exit()], [], []) for basic_block in basic_blocks: instruction = basic_block[-1] next_label = _next_label(instruction) flow_graph[current_label] = Node(basic_block, [], _successors(instruction, next_label)) if isinstance(instruction, I.HLT): last_label = current_label current_label = next_label flow_graph[last_label].successors.append(exit_label) # Remove redundant label instructions label_list = [] for label, node in flow_graph.iteritems(): instruction_list = [] for instruction in node.basic_block: if isinstance(instruction, I.LBL): instruction_list.append(instruction) for instruction in instruction_list: node.basic_block.remove(instruction) if len(node.basic_block) == 0: label_list.append(label) for label in label_list: del flow_graph[label] for label, node in flow_graph.iteritems(): for successor_label in node.successors: flow_graph[successor_label].predecessors.append(label) return flow_graph
def type_check_PUSH(context, location, source): source_size = None ''' Lookup source operand ''' if isinstance(source, O.Value): source_size = source.value.size elif isinstance(source, O.Field): if not is_special_field(source.field): if source.field in context.header: source_size = context.header[source.field] else: raise TypeError( "source field (%s) is not present in the header." % str(source.field)) else: raise TypeError("source field (%s) is a special field." % str(source.field)) else: raise TypeError( "invalid %s of source (%s). Should be either %s or %s." % (type(source), source, O.Value, O.Field)) ''' lookup location operand ''' location_size = None if isinstance(location, O.Location): offset = location.location.offset if isinstance(offset, O.Value): pass elif isinstance(offset, O.Field): if not is_special_field(offset.field): if offset.field in context.header: pass else: raise TypeError( "location's offset field (%s) is not present in the header." % str(offset.field)) else: raise TypeError( "location's offset field (%s) is a special field." % str(offset.field)) else: raise TypeError( "invalid %s of location's offset (%s). Should be either %s or %s." % (type(offset), offset, O.Value, O.Field)) location_size = source_size else: raise TypeError("invalid %s of location (%s). Should be %s." % (type(location), location, O.Location)) ''' Compare sizes ''' if source_size <= location_size: pass else: raise TypeError( "source (%s) size (%s) should be less than location (%s) size (%s)." % (source, source_size, location, location_size)) context.labels = Labels(syntax.Label(''))
def type_check_RMV(context, field): if not is_reserved_field(field.field): if field.field in context.header: del context.header[field.field] else: raise TypeError("field (%s) is not present in the header." % str(field.field)) else: raise TypeError("field (%s) is a reserved field." % str(field.field)) context.labels = Labels(syntax.Label(''))
def type_check_ADD(context, field, size): if not is_reserved_field(field.field): if field.field not in context.header: context.header[field.field] = size else: raise TypeError("field (%s) is already present in the header." % str(field.field)) else: raise TypeError("field (%s) is a reserved field." % str(field.field)) context.labels = Labels(syntax.Label(''))
def type_check_LBL(context, label): if not isinstance(label, syntax.Label): raise TypeError("invalid %s of label (%s). Should be %s." % (type(label), label, syntax.Label)) # TODO: check this using the forwards and backwards label check # if label in labels: # pass # else: # raise TypeError("TypeError(%s): label (%s) doesn't exist" % ("JMP", str(label))) context.labels = Labels(syntax.Label(''))
def type_check_POP(context, destination, location): destination_size = None ''' Lookup destination operand ''' if isinstance(destination, O.Field): if not is_special_field(destination.field): if destination.field in context.header: destination_size = context.header[destination.field] else: raise TypeError( "destination field (%s) is not present in the header." % str(destination.field)) else: raise TypeError("destination field (%s) is a special field." % str(destination.field)) else: raise TypeError("invalid %s of destination (%s). Should be %s." % (type(destination), destination, O.Field)) location_size = None ''' Lookup source operand ''' if isinstance(location, O.Location): offset = location.location.offset if isinstance(offset, O.Value): pass elif isinstance(offset, O.Field): if not is_special_field(offset.field): if offset.field in context.header: pass else: raise TypeError( "location's offset field (%s) is not present in the header." % str(offset.field)) else: raise TypeError( "location's offset field (%s) is a special field." % str(offset.field)) else: raise TypeError( "invalid %s of location's offset (%s). Should be either %s or %s." % (type(offset), offset, O.Value, O.Location)) location_size = destination_size else: raise TypeError("invalid %s of location (%s). Should be %s." % (type(location), location, O.Location)) ''' Compare sizes ''' if location_size <= destination_size: pass else: raise TypeError( "location (%s) size (%s) should be less than destination (%s) size (%s)." % (location, location_size, destination, destination_size)) context.labels = Labels(syntax.Label(''))
def type_check_CTR(context, reason): if isinstance(reason, syntax.Reason): pass else: raise TypeError("invalid %s of reason (%s). Should be %s." % (type(reason), reason, syntax.Reason)) if syntax.Field('CTR') in context.header: # if context.header[syntax.Field('CTR')] == syntax.Size(1): # pass # else: # raise TypeError("TypeError(%s): invalid '%s' field size (%i), should be of size (1)." % # ("CTR", "CTR", context.header[syntax.Field('CTR')])) pass else: raise TypeError("field (%s) is not present in the header." % "CTR") context.labels = Labels(syntax.Label(''))
def execute_CRC(state, destination, sources): offset = 0 ba = BitArray() for source in sources: ''' Lookup source ''' if isinstance(source, O.Value): value = source.value elif isinstance(source, O.Field): value = state.header[source.field] else: raise RuntimeError() length = value.size ba[offset:(offset + length)] = value.value offset += length ''' Compute CRC and store it in the destination ''' if isinstance(destination, O.Field): state.header[destination.field].value = crc16(ba.bytes) state.label = syntax.Label('') return state
def type_check_Instruction(instructions, tables, context): # Read instruction at program counter instruction = instructions[context.pc] # Check if HLT instruction if isinstance(instruction, I.HLT): type_check_HLT(context) else: next_Instruction(instructions, tables, context) if len(context.labels) == 1: if context.labels[0] == syntax.Label(''): context.pc += 1 else: context.pc, _ = get_label(instructions, context.labels[0]) type_check_Instruction(instructions, tables, context) elif len(context.labels) == 2: if context.labels[0] != '': pass else: raise TypeError("taken-branch label (%s) can't be empty." % (context.labels[0])) if context.labels[1] == '': pass else: raise TypeError("not-taken-branch label (%s) must be empty." % (context.labels[1])) # type check taken-branch contextT = deepcopy(context) contextT.pc, _ = get_label(instructions, context.labels[0]) type_check_Instruction(instructions, tables, contextT) # type check not-taken-branch context.pc += 1 type_check_Instruction(instructions, tables, context) else: raise TypeError("invalid labels (%s) count." % context.labels)
def execute_HSH(state, destination, sources): value = None offset = 0 ba = BitArray() for source in sources: if isinstance(source, O.Value): value = source.value elif isinstance(source, O.Field): value = state.header[source.field] else: raise RuntimeError() length = value.size ba[offset:(offset + length)] = value.value offset += length ''' Compute hash and store it in the destination ''' if isinstance(destination, O.Field): state.header[destination.field].value = hash(ba.uint) else: raise RuntimeError() state.label = syntax.Label('') return state
def type_check_OP(context, destination, left_source, operator, right_source): left_size = None ''' Lookup left_source operand ''' if isinstance(left_source, O.Value): left_size = left_source.value.size elif isinstance(left_source, O.Field): if not is_special_field(left_source.field): if left_source.field in context.header: left_size = context.header[left_source.field] else: raise TypeError( "left source field (%s) is not present in the header." % str(left_source.field)) else: raise TypeError("left source field (%s) is a special field." % str(left_source.field)) else: raise TypeError("invalid %s of left source (%s). Should be %s or %s." % (type(left_source), left_source, O.Value, O.Field)) ''' Lookup right_source operand ''' right_size = None if isinstance(right_source, O.Value): right_size = right_source.value.size elif isinstance(right_source, O.Field): if not is_special_field(right_source.field): if right_source.field in context.header: right_size = context.header[right_source.field] else: raise TypeError( "right source field (%s) is not present in the header." % str(right_source.field)) else: raise TypeError("right source field (%s) is a special field." % str(right_source.field)) else: raise TypeError( "invalid %s of right source (%s). Should be %s or %s." % (type(right_source), right_source, O.Value, O.Field)) ''' Operate on the values ''' if isinstance(operator, Op.ArithmeticBitwiseOperator): pass else: raise TypeError( "invalid %s of operator (%s). Should be %s." % (type(operator), operator, Op.ArithmeticBitwiseOperator)) ''' Lookup destination operand ''' destination_size = None if isinstance(destination, O.Field): if not is_special_field(destination.field): if destination.field in context.header: destination_size = context.header[destination.field] else: raise TypeError( "destination field (%s) is not present in the header." % str(destination.field)) else: raise TypeError("destination field (%s) is a special field." % str(destination.field)) else: raise TypeError("invalid %s of destination (%s). Should be %s." % (type(destination), destination, O.Field)) # TODO: make proper comparisons using the operator types (i.e., mul operator requires double desintation size) ''' Compare sizes ''' if left_size <= destination_size: pass else: raise TypeError( "left source (%s) size (%s) should be less than destination (%s) size (%s)." % (left_source, left_size, destination, destination_size)) if right_size <= destination_size: pass else: raise TypeError( "right source (%s) size (%s) should be less than destination (%s) size (%s)." % (right_source, right_size, destination, destination_size)) context.labels = Labels(syntax.Label(''))
def type_check_HLT(context): context.labels = Labels(syntax.Label(''))
def execute_ADD(state, field, size): state.header[field.field] = syntax.Value(0, size) state.label = syntax.Label('') return state
def execute_RMV(state, field): del state.header[field.field] state.label = syntax.Label('') return state
def execute_HLT(state): state.label = syntax.Label('') return state
def __init__(self, header, packet, reason=syntax.Reason('', ''), label=syntax.Label(''), extra=None): self.header = header self.packet = packet self.reason = reason self.label = label self.extra = extra