コード例 #1
0
def dump_mpt(input_file, target, init_data, arguments):
    """

    :param input_file:
    :type input_file:
    :param target:
    :type target:
    :param init_data:
    :type init_data:
    :param arguments:
    :type arguments:
    """

    input_file_fd = io.open(input_file, 'r')
    contents = input_file_fd.read()

    if six.PY2:
        contents = contents.encode("ascii")
    elif six.PY3:
        pass

    print_info("Parsing input file...")

    var_defs, req_defs, instr_defs = \
        interpret_objdump(contents, target,
                          strict=arguments.get('strict', False),
                          sections=["microprobe.text"])

    print_info("Input file parsed")

    print_info("%d instructions processed from the input file" %
               len(instr_defs))

    if var_defs != []:
        print_info("Variables referenced and detected in the dump: %s" %
                   ','.join([var.name for var in var_defs]))

    if req_defs != []:
        print_warning(
            "Variables referenced and *NOT* detected in the dump: %s" %
            ','.join([var.name for var in req_defs]))
        print_warning("You might need to edit the generated MPT to fix the"
                      " declaration of such variables")

    print_info("Generating the MPT contents...")

    mpt_config = mpt_configuration_factory()

    mpt_config.set_default_code_address(arguments['default_code_address'])
    mpt_config.set_default_data_address(arguments['default_data_address'])

    kwargs = {}
    if "stack_name" in arguments:
        kwargs["stack_name"] = arguments["stack_name"]
    if "stack_address" in arguments:
        kwargs["stack_address"] = Address(
            base_address="code", displacement=arguments["stack_address"])

    variables, instructions = target.elf_abi(arguments["stack_size"],
                                             "c2mpt_function", **kwargs)

    for variable in variables:
        req_defs.append(variable_to_test_definition(variable))

    address = instr_defs[0].address
    for instr in reversed(instructions):
        instr_defs = [instruction_to_definition(instr)] + instr_defs
        address -= instr.architecture_type.format.length

    if address.displacement < 0:
        print_error("Default code address is below zero after"
                    " adding the initialization code.")
        print_error("Check/modify the objdump provided or do not use"
                    " the elf_abi flag.")
        _exit(-1)

    if "end_branch_to_itself" in arguments:
        instr = target.branch_to_itself()
    else:
        instr = target.nop()

    instr.set_label("ELF_ABI_EXIT")
    instr_defs.append(instruction_to_definition(instr))

    mpt_config.set_default_code_address(address.displacement)

    initialized_variables = {}

    mindisplacement = None
    for data in init_data.split('\n'):

        if data.strip() == "":
            continue

        if data.startswith("WARNING"):
            print_warning(data.split(":")[1].strip())
            continue

        name = data.split("=")[0].strip()
        values = ast.literal_eval(data.split("=")[1].strip())
        initialized_variables[name] = values

        if mindisplacement is None:
            mindisplacement = values[2]
            # TODO: this is unsafe. We should compute the real size
            maxdisplacement = values[2] + (values[1] * 8)
        else:
            mindisplacement = min(values[2], mindisplacement)
            maxdisplacement = max(values[2] + (values[1] * 8), maxdisplacement)

    if "host_displacement" in arguments:
        mindisplacement = arguments.get("host_displacement", mindisplacement)

    for name, values in initialized_variables.items():
        values[2] = values[2] - mindisplacement + \
            arguments['default_data_address']

    if 'fix_displacement' in arguments:
        for name, values in initialized_variables.items():
            if "*" in values[0] and isinstance(values[4], list):
                new_values = []
                for value in values[4]:
                    if value <= maxdisplacement and value >= mindisplacement:
                        value = value - mindisplacement + \
                            arguments['default_data_address']
                    new_values.append(value)
                values[4] = new_values
            elif "*" in values[0] and isinstance(values[4], int):
                if (values[4] <= maxdisplacement
                        and values[4] >= mindisplacement):
                    values[4] = values[4] - mindisplacement + \
                        arguments['default_data_address']
            elif values[0] == "uint8_t" and isinstance(values[4], list):
                if len(values[4]) > 8:
                    new_values = "".join(["%02x" % elem for elem in values[4]])

                    # Enable this for testing switched endianness
                    # new_values = [new_values[idx:idx + 2]
                    #              for idx in range(0, len(new_values), 2)]
                    # new_values = new_values[::-1]
                    # new_values = "".join(new_values)

                    new_values = _fix_displacement(new_values, mindisplacement,
                                                   maxdisplacement, arguments)

                    values[4] = [
                        int(new_values[idx:idx + 2], 16)
                        for idx in range(0, len(new_values), 2)
                    ]

    for name, values in initialized_variables.items():

        mpt_config.register_variable_definition(
            MicroprobeTestVariableDefinition(name, *values))
        print_info("Init values for variable '%s' parsed" % name)

    for var in var_defs + req_defs:
        if var.name in list(initialized_variables.keys()):
            continue
        if var.name != arguments["stack_name"]:
            print_warning("Variable '%s' not registered in the C file "
                          "using the macros provided!" % var.name)
        mpt_config.register_variable_definition(var)

    mpt_config.register_instruction_definitions(instr_defs)

    print_info("Dumping MPT to '%s'" % arguments['output_mpt_file'])
    mpt_parser = mpt_parser_factory()
    mpt_parser.dump_mpt_config(mpt_config, arguments['output_mpt_file'])
コード例 #2
0
ファイル: mp_objdump2mpt.py プロジェクト: IBM/microprobe
def dump_mpt(input_file_fd, target, arguments):
    """

    :param input_file_fd:
    :type input_file_fd:
    :param target:
    :type target:
    :param arguments:
    :type arguments:
    """

    try:
        contents = input_file_fd.read()
        if six.PY3 and not isinstance(contents, str):
            contents = contents.decode()
    except KeyboardInterrupt:
        print_info("No input data provided. Exiting...")
        exit(1)

    print_info("Parsing input file...")

    print_info("Sections to parse: %s" % arguments['sections'])

    var_defs, req_defs, instr_defs = \
        interpret_objdump(contents, target,
                          strict=arguments.get('strict', False),
                          sections=arguments['sections'],
                          start_address=arguments['from_address'],
                          end_address=arguments['to_address'])

    print_info("Input file parsed")

    print_info(
        "%d instructions processed from the input file" % len(instr_defs)
    )

    if var_defs != []:
        print_info(
            "Variables referenced and detected in the dump: %s" %
            ','.join([var.name for var in var_defs])
        )

    if req_defs != []:
        print_warning(
            "Variables referenced and *NOT* detected in the dump: %s" %
            ','.join([var.name for var in req_defs])
        )
        print_warning(
            "You might need to edit the generated MPT to fix the"
            " declaration of such variables"
        )

    print_info("Generating the MPT contents...")

    mpt_config = mpt_configuration_factory()

    if 'default_code_address' in arguments:
        mpt_config.set_default_code_address(arguments['default_code_address'])
    else:
        mpt_config.set_default_code_address(instr_defs[0].address.displacement)

    if 'default_data_address' in arguments:
        mpt_config.set_default_data_address(arguments['default_data_address'])
    else:
        mpt_config.set_default_data_address(0)

    if arguments.get('elf_abi', False):

        kwargs = {}
        if "stack_name" in arguments:
            kwargs["stack_name"] = arguments["stack_name"]
        if "stack_address" in arguments:
            kwargs["stack_address"] = Address(
                base_address="code",
                displacement=arguments["stack_address"]
            )

        variables, instructions = target.elf_abi(
            arguments["stack_size"], arguments.get(
                "start_symbol", None
            ), **kwargs
        )

        for variable in variables:
            req_defs.append(variable_to_test_definition(variable))

        address = instr_defs[0].address
        for instr in reversed(instructions):
            instr_defs = [instruction_to_definition(instr)] + instr_defs
            address -= instr.architecture_type.format.length

        if address.displacement < 0:
            print_error(
                "Default code address is below zero after"
                " adding the initialization code."
            )
            print_error(
                "Check/modify the objdump provided or do not use"
                " the elf_abi flag."
            )
            exit(-1)

        mpt_config.set_default_code_address(address.displacement)

    instr = None
    if "end_branch_to_itself" in arguments:
        instr = target.branch_to_itself()
    elif arguments.get('elf_abi', False):
        instr = target.nop()

    if instr is not None:
        instr.set_label("ELF_ABI_EXIT")
        instr_defs.append(instruction_to_definition(instr))

    for var in var_defs + req_defs:
        mpt_config.register_variable_definition(var)

    mpt_config.register_instruction_definitions(instr_defs)

    print_info("Dumping MPT to '%s'" % arguments['output_mpt_file'])
    mpt_parser = mpt_parser_factory()
    mpt_parser.dump_mpt_config(mpt_config, arguments['output_mpt_file'])
コード例 #3
0
ファイル: mp_coblst2mpt.py プロジェクト: rommelsv/microprobe
def dump_mpt(input_file_fd, target, arguments):
    """

    :param input_file_fd:
    :type input_file_fd:
    :param target:
    :type target:
    :param arguments:
    :type arguments:
    """

    try:
        contents = input_file_fd.read()
    except KeyboardInterrupt:
        print_info("No input data provided. Exiting...")
        exit(1)

    print_info("Parsing input file...")

    skip = True
    data_mode = False

    reg_comment = re.compile("^  [0-9][0-9][0-9][0-9][0-9][0-9]: ")
    reg_label = re.compile(":.*EQU     \\*")
    reg_data = re.compile(" +DC +X'")
    reg_entry = re.compile(" +DS +")

    instruction_definitions = []
    data_definitions = []

    clabel = None
    hlabel = None
    paddress = None
    for line in contents.split("\n"):
        if " PROC " in line:
            skip = False

        if skip:
            continue

        if line.startswith("1PP "):
            continue

        if line.replace(" ", "") == "":
            continue

        if " CONSTANT AREA " in line:
            data_mode = True
            continue

        if "***" in line:
            continue

        if data_mode is True and "|" not in line:
            break

        if line.startswith("0"):
            line = line.replace("0", " ", 1)

        sline = [elem for elem in line.split("|")[0].split(" ") if elem != ""]

        if data_mode:
            if line.startswith("0 0"):
                line = line.replace("0 0", "  0", 1)

            address = int(sline[0], 16)

            if len(data_definitions) > 0 and \
                    (address == data_definitions[-1][0] +
                     len(data_definitions[-1][1]) // 2):
                data_definitions[-1][1] += "".join(sline[2:])
            else:
                data_definitions.append(
                    [address, "".join(sline[2:]), "constant_area"])

            continue

        if reg_comment.search(line):
            continue

        if reg_label.search(line):
            clabel = hlabel + "_" + sline[2].replace(":", "")
            continue

        if sline[2] == "PROC":
            hlabel = sline[3]
            continue

        if sline[2] == "RET":
            continue

        if reg_entry.search(line):
            continue

        if reg_data.search(line):
            address = int(sline[0], 16)
            if len(data_definitions) > 0 and \
                    (address == data_definitions[-1][0] +
                     len(data_definitions[-1][1]) // 2):
                data_definitions[-1][1] += "".join(sline[1:3])
                data_definitions[-1][2] += "".join(sline[4:])
            else:
                data_definitions.append(
                    [address, "".join(sline[1:3]), " ".join(sline[4:])])
            continue

        idx = 1
        value = ""
        while len(sline[idx]) == 4:
            value += sline[idx]
            idx += 1

        address = int(sline[0], 16)
        if address - (len(value) // 2) == paddress:
            address = None

        comment = " ".join(sline[idx + 1:])
        asm = "0x%s" % value
        asm_def = MicroprobeAsmInstructionDefinition(asm, clabel, address,
                                                     None, comment)

        instruction_definitions.append(asm_def)
        clabel = None
        paddress = int(sline[0], 16)

    instr_defs = interpret_asm(instruction_definitions,
                               target, [],
                               show_progress=True)

    var_defs = []
    for idx, data in enumerate(data_definitions):
        address = data[0]
        var_name = "data_%010d" % idx
        len_init_value = len(data[1]) // 2
        init_value = [
            int(data[1][2 * idx:2 * (idx + 1)], 16)
            for idx in range(0, len_init_value)
        ]

        var_defs.append(
            MicroprobeTestVariableDefinition(var_name, "char", len_init_value,
                                             address, None, init_value))

    print_info("Input file parsed")

    print_info("%d instructions processed from the input file" %
               len(instr_defs))

    if var_defs != []:
        print_info("Variables referenced and detected in the dump: %s" %
                   ','.join([var.name for var in var_defs]))

    print_info("Generating the MPT contents...")

    mpt_config = mpt_configuration_factory()

    if 'default_code_address' in arguments:
        mpt_config.set_default_code_address(arguments['default_code_address'])
    else:
        mpt_config.set_default_code_address(instr_defs[0].address.displacement)

    if 'default_data_address' in arguments:
        mpt_config.set_default_data_address(arguments['default_data_address'])
    else:
        mpt_config.set_default_data_address(0)

    for var in var_defs:
        mpt_config.register_variable_definition(var)

    mpt_config.register_instruction_definitions(instr_defs)

    print_info("Dumping MPT to '%s'" % arguments['output_mpt_file'])
    mpt_parser = mpt_parser_factory()
    mpt_parser.dump_mpt_config(mpt_config, arguments['output_mpt_file'])