Beispiel #1
0
 def build_hexagon_analysis_h(
     path: str = "./rizin/librz/analysis/arch/hexagon/hexagon_analysis.h",
 ) -> None:
     with open(path, "w+") as f:
         f.write(get_generation_warning_c_code())
         with open("handwritten/hexagon_analysis_h/include.h") as include:
             set_pos_after_license(include)
             f.writelines(include.readlines())
     log("hexagon_analysis.h written to {}".format(path))
Beispiel #2
0
    def copy_tests() -> None:
        with open("handwritten/analysis-tests/hexagon") as f:
            with open("./rizin/test/db/analysis/hexagon", "w+") as g:
                set_pos_after_license(g)
                g.writelines(f.readlines())

        with open("handwritten/asm-tests/hexagon") as f:
            with open("./rizin/test/db/asm/hexagon", "w+") as g:
                set_pos_after_license(g)
                g.writelines(f.readlines())
        log("Copied test files to ./rizin/test/db/")
Beispiel #3
0
    def build_asm_hexagon_c(
            path: str = "rizin/librz/asm/p/asm_hexagon.c") -> None:
        with open(path, "w+") as f:
            f.write(get_generation_warning_c_code())

            with open("handwritten/asm_hexagon_c/include.c") as include:
                set_pos_after_license(include)
                f.writelines(include.readlines())
            with open("handwritten/asm_hexagon_c/initialization.c") as init:
                set_pos_after_license(init)
                f.writelines(init.readlines())
        log("asm_hexagon.c written to {}".format(path))
Beispiel #4
0
    def build_hexagon_disas_c(
            self,
            path: str = "./rizin/librz/asm/arch/hexagon/hexagon_disas.c"
    ) -> None:
        # TODO Clean up this method
        indent = PluginInfo.LINE_INDENT
        var = PluginInfo.HEX_INSTR_VAR_SYNTAX
        with open(path, "w+") as dest:
            dest.write(get_generation_warning_c_code())

            with open("handwritten/hexagon_disas_c/include.c") as include:
                set_pos_after_license(include)
                dest.writelines(include.readlines())

            header = (
                "int hexagon_disasm_instruction(ut32 hi_u32, HexInsn *hi, ut32 addr) {\n"
                + '{}char signed_imm[16] = "";\n'.format(indent) +
                "{}// DUPLEXES\n".format(indent) +
                "{}if ((({} >> 14) & 0x3) == 0) {{\n".format(indent, var) +
                "{}switch (((({} >> 29) & 0xF) << 1) | (({} >> 13) & 1)) {{\n".
                format(indent * 2, var, var))
            dest.write(header)

            # Duplexes
            for c in range(0xF):  # Class 0xf is reserved yet.
                dest.write("{}case 0x{:x}:\n".format(indent * 3, c))
                for d_instr in self.duplex_instructions.values():
                    if d_instr.encoding.get_i_class() == c:
                        dest.write(
                            indent_code_block(
                                d_instr.get_instruction_init_in_c(), 4))
                dest.write("{}break;\n".format(indent * 4))

            # Normal instructions
            # Brackets for switch, if
            dest.write("{}}}\n{}}}\n{}else {{\n".format(
                indent * 2, indent, indent))
            dest.write("{}switch (({} >> 28) & 0xF) {{\n".format(
                indent * 2, var))
            for c in range(0x10):
                dest.write("{}case 0x{:x}:\n".format(indent * 3, c))
                for instr in self.normal_instructions.values():
                    if instr.encoding.get_i_class() == c:
                        dest.write(
                            indent_code_block(
                                instr.get_instruction_init_in_c(), 4))
                dest.write("{}break;\n".format(indent * 4))

            # Closing brackets for switch, else, function
            dest.write("{}}}\n{}}}\n{}return 4;\n}}".format(
                indent * 2, indent, indent))
        log("Hexagon instruction disassembler code written to: {}".format(
            path))
Beispiel #5
0
    def build_hexagon_c(
            self,
            path: str = "./rizin/librz/asm/arch/hexagon/hexagon.c") -> None:
        indent = PluginInfo.LINE_INDENT

        with open(path, "w+") as dest:
            dest.write(get_generation_warning_c_code())
            with open("handwritten/hexagon_c/include.c") as include:
                set_pos_after_license(include)
                dest.writelines(include.readlines())
            dest.write("\n")

            reg_class: str
            for reg_class in self.hardware_regs:
                func_name = HardwareRegister.get_func_name_of_class(reg_class)
                function = "char* {}(int opcode_reg)".format(func_name)
                self.reg_resolve_decl.append(function + ";")
                dest.write("\n{} {{\n".format(function))

                parsing_code = HardwareRegister.get_parse_code_reg_bits(
                    reg_class, "opcode_reg")
                parsing_code = indent_code_block(parsing_code, 1)
                if parsing_code != "":
                    dest.write("{}\n".format(parsing_code))

                dest.write("{}switch (opcode_reg) {{\n".format(indent))
                dest.write(
                    '{}default:\n{}rz_warn_if_reached();\n{}return "<err>";\n'.
                    format(indent * 2, indent * 3, indent * 3))

                hw_reg: HardwareRegister
                for hw_reg in self.hardware_regs[reg_class].values():
                    dest.write('{}case {}:\n{}return "{}";\n'.format(
                        indent * 2,
                        hw_reg.enum_name,
                        indent * 3,
                        hw_reg.asm_name.upper(),
                    ))
                dest.write("{}}}\n}}\n".format(indent))

            with open("handwritten/hexagon_c/functions.c") as func:
                set_pos_after_license(func)
                dest.writelines(func.readlines())
            dest.write("\n")

        log("hexagon.c written to: {}".format(path))
Beispiel #6
0
    def build_hexagon_h(
            self,
            path: str = "./rizin/librz/asm/arch/hexagon/hexagon.h") -> None:
        indent = PluginInfo.LINE_INDENT
        general_prefix = PluginInfo.GENERAL_ENUM_PREFIX

        with open(path, "w+") as dest:
            dest.write(get_generation_warning_c_code())
            dest.write("\n")
            dest.write(get_include_guard("hexagon.h"))

            with open("handwritten/hexagon_h/typedefs.h") as typedefs:
                set_pos_after_license(typedefs)
                dest.writelines(typedefs.readlines())

            reg_class: str
            for reg_class in self.hardware_regs:
                dest.write("\ntypedef enum {\n")

                hw_reg: HardwareRegister
                for hw_reg in sorted(self.hardware_regs[reg_class].values(),
                                     key=lambda x: x.hw_encoding):
                    alias = ",".join(hw_reg.alias)
                    dest.write("{}{} = {},{}\n".format(
                        indent,
                        hw_reg.enum_name,
                        hw_reg.hw_encoding,
                        " // " + alias if alias != "" else "",
                    ))
                dest.write("}} {}{}; // {}\n".format(
                    general_prefix,
                    HardwareRegister.register_class_name_to_upper(reg_class),
                    reg_class,
                ))

            with open("handwritten/hexagon_h/macros.h") as macros:
                set_pos_after_license(macros)
                dest.writelines(macros.readlines())
            dest.write("\n")
            if len(self.reg_resolve_decl) == 0:
                raise ImplementationException(
                    "Register resolve declarations missing"
                    "(They get generated together with hexagon.c)."
                    "Please generate hexagon.c before hexagon.h")
            for decl in self.reg_resolve_decl:
                dest.write(decl + "\n")
            with open("handwritten/hexagon_h/declarations.h") as decl:
                set_pos_after_license(decl)
                dest.writelines(decl.readlines())

            dest.write("#endif")

        log("hexagon.h written to: {}".format(path))
Beispiel #7
0
    def build_hexagon_regs(
            self,
            path: str = "rizin/librz/analysis/p/analysis_hexagon.c") -> None:
        profile = self.get_alias_profile().splitlines(keepends=True)
        offset = 0

        for hw_reg_classes in self.hardware_regs:
            if hw_reg_classes in [
                    "IntRegsLow8",
                    "GeneralSubRegs",
                    "GeneralDoubleLow8Regs",
                    "ModRegs",
            ]:
                continue  # Those registers would only be duplicates.
            hw_reg: HardwareRegister
            for hw_reg in self.hardware_regs[hw_reg_classes].values():
                profile.append(hw_reg.get_reg_profile(offset) + "\n")
                offset += int((hw_reg.size / 8))
            profile.append("\n")
        profile = profile[:-1]  # Remove line breaks
        profile[-1] = profile[-1][:-1] + ";\n"  # [:-1] to remove line break.

        with open(path, "w+") as f:
            f.write(get_generation_warning_c_code())

            with open("handwritten/analysis_hexagon_c/include.c") as include:
                set_pos_after_license(include)
                f.writelines(include.readlines())
            with open(
                    "handwritten/analysis_hexagon_c/functions.c") as functions:
                set_pos_after_license(functions)
                f.writelines(functions.readlines())
            f.write("\n")

            tmp = list()
            tmp.append("const char *p =\n")
            tmp += profile
            tmp = make_c_block(
                lines=tmp,
                begin="static bool set_reg_profile(RzAnalysis *analysis)",
                ret="return rz_reg_set_profile_string(analysis->reg, p);\n",
            )
            f.writelines(tmp)
            f.write("\n")

            with open("handwritten/analysis_hexagon_c/initialization.c"
                      ) as initialization:
                set_pos_after_license(initialization)
                f.writelines(initialization.readlines())
            f.write("\n")
Beispiel #8
0
    def build_hexagon_analysis_c(
        self,
        path: str = "./rizin/librz/analysis/arch/hexagon/hexagon_analysis.c"
    ) -> None:
        indent = PluginInfo.LINE_INDENT

        with open(path, "w+") as f:
            f.write(get_generation_warning_c_code())

            with open("handwritten/hexagon_analysis_c/include.c") as include:
                set_pos_after_license(include)
                f.writelines(include.readlines())
            f.write("\n")

            f.write(
                "int hexagon_analysis_instruction(HexInsn *hi, RzAnalysisOp *op) {\n"
            )
            f.write("{}static ut32 hw_loop0_start = 0;\n".format(indent))
            f.write("{}static ut32 hw_loop1_start = 0;\n\n".format(indent))
            f.write("{}switch (hi->instruction) {{\n".format(indent))

            default = "{}default:\n".format(indent * 2)
            default += (
                "{}if (is_endloop01_instr(hi) && hi->pkt_info.last_insn) {{\n".
                format(indent * 3) +
                "{}op->type = RZ_ANALYSIS_OP_TYPE_CJMP;\n".format(indent * 4) +
                "{}op->fail = hw_loop0_start;\n".format(indent * 4) +
                "{}op->jump = hw_loop1_start;\n".format(indent * 4) +
                "{}hw_loop1_start = 0;\n".format(indent * 4) +
                "{}hw_loop0_start = 0;\n{}}}\n".format(indent * 4, indent * 3))
            default += (
                "{}else if (is_endloop0_instr(hi) && hi->pkt_info.last_insn) {{\n"
                .format(indent * 3) +
                "{}op->type = RZ_ANALYSIS_OP_TYPE_CJMP;\n".format(indent * 4) +
                "{}op->jump = hw_loop0_start;\n".format(indent * 4) +
                "{}hw_loop0_start = 0;\n{}}}\n".format(indent * 4, indent * 3))
            default += (
                "{}else if (is_endloop1_instr(hi) && hi->pkt_info.last_insn) {{\n"
                .format(indent * 3) +
                "{}op->type = RZ_ANALYSIS_OP_TYPE_CJMP;\n".format(indent * 4) +
                "{}op->jump = hw_loop1_start;\n".format(indent * 4) +
                "{}hw_loop1_start = 0;\n{}}}\n".format(indent * 4, indent * 3))
            default += "{}break;\n".format(indent * 3)

            f.write(default)

            all_instr = [i for i in self.normal_instructions.values()]
            for i in self.duplex_instructions.values():
                all_instr.append(i)

            i: Instruction
            for i in all_instr:
                if i.has_jump_target:
                    f.write("{}case {}:\n".format(indent * 2, i.plugin_name))
                    f.write("{}// {}\n".format(indent * 3, i.syntax))
                    f.write("{}{}\n".format(indent * 3, i.get_rizin_op_type()))
                    if i.has_imm_jmp_target():
                        index = i.get_jmp_operand_syntax_index()
                        if index < 0:
                            raise ImplementationException(
                                "Not PC relative operand given. But the jump needs one."
                                "{}".format(i.llvm_syntax))

                        f.write(
                            "{}op->jump = op->addr + (st32) hi->ops[{}].op.imm;\n"
                            .format(indent * 3, index))
                        if i.predicated:
                            f.write(
                                "{}op->fail = op->addr + op->size;\n".format(
                                    indent * 3))
                        if i.is_loop_begin:
                            f.write("{}if (is_loop0_begin(hi)) {{\n".format(
                                indent * 3) +
                                    "{}hw_loop0_start = op->jump;\n{}}}\n".
                                    format(indent * 4, indent * 3))
                            f.write("{}else if (is_loop1_begin(hi)) {{\n".
                                    format(indent * 3) +
                                    "{}hw_loop1_start = op->jump;\n{}}}\n".
                                    format(indent * 4, indent * 3))
                    f.write("{}break;\n".format(indent * 3, indent * 2))

            f.write("{i}}}\n{i}return op->size;\n}}".format(i=indent))
        log("hexagon_analysis.c written to: {}".format(path))