Ejemplo n.º 1
0
def run_asm_pprinter_with_outputput(
    ir: gtirb.IR, args: Iterable[str] = ()) -> Tuple[str, str]:
    """
    Runs the pretty-printer to generate an assembly output.
    :param ir: The IR object to print.
    :param args: Any additional arguments for the pretty printer.
    :returns: The assembly string and the contents of stdout/stderr.
    """
    with temp_directory() as tmpdir:
        gtirb_path = os.path.join(tmpdir, "test.gtirb")
        ir.save_protobuf(gtirb_path)

        asm_path = os.path.join(tmpdir, "test.asm")
        proc = subprocess.run(
            (pprinter_binary(), gtirb_path, "--asm", asm_path, *args),
            check=False,
            cwd=tmpdir,
            stdout=subprocess.PIPE,
            stderr=subprocess.STDOUT,
        )

        if should_print_subprocess_output():
            sys.stdout.buffer.write(proc.stdout)
        proc.check_returncode()

        with open(asm_path, "r") as f:
            return f.read(), proc.stdout.decode("ascii")
Ejemplo n.º 2
0
def main():
    ap = argparse.ArgumentParser(description="Show functions in GTIRB")
    ap.add_argument("infile")
    ap.add_argument("-v",
                    "--verbose",
                    action="store_true",
                    help="Verbose output")

    args = ap.parse_args()
    logging.basicConfig(format="%(message)s")
    logger = logging.getLogger("gtirb.functions")
    if args.verbose:
        logger.setLevel(logging.DEBUG)

    logger.info("Loading IR...")
    ir = IR.load_protobuf(args.infile)

    logger.info("Identifying functions...")

    for m in ir.modules:
        fns = Function.build_functions(m)
        fns.sort(key=lambda x: x.get_name())
        if len(fns) > 0:
            print("Module: %s" % m.name)
            for fn in fns:
                print("\tFunction: %s" % fn.get_name())
                print(fn)

    logger.info("Done.")
Ejemplo n.º 3
0
def run_binary_pprinter_mock_out(
    ir: gtirb.IR,
    args: Iterable[str],
    port: Optional[int] = None,
    check_output: bool = False,
) -> subprocess.CompletedProcess:
    with temp_directory() as tmpdir:
        gtirb_path = os.path.join(tmpdir, "test.gtirb")
        ir.save_protobuf(gtirb_path)

        # Put our fake binaries first on PATH so that we can monitor
        # what the pretty-printer is invoking (as long as we have a
        # stub for everything it invokes).
        env = dict(os.environ)
        env["PATH"] = "%s%s%s" % (
            _FAKEBIN_DIR,
            os.pathsep,
            env.get("PATH", ""),
        )
        if port is not None:
            env[fakeprog.PORT_ENV_VAR] = str(port)

        bin_path = os.path.join(tmpdir, "test")

        capture_output_args = {}
        if check_output or not should_print_subprocess_output():
            capture_output_args["stdout"] = subprocess.PIPE
            capture_output_args["stderr"] = subprocess.PIPE

        return subprocess.run(
            (
                pprinter_binary(),
                "--ir",
                gtirb_path,
                "--binary",
                bin_path,
                *args,
            ),
            env=env,
            check=False,
            cwd=tmpdir,
            **capture_output_args,
        )
Ejemplo n.º 4
0
def rewrite_functions(infile,
                      logger=logging.Logger("null"),
                      context=None,
                      fname=None):
    #logger.info("Generating GTIRB IR...")
    #gtirb_protobuf(infile)
    logger.info("Loading IR... " + infile)
    ir = IR.load_protobuf(infile)

    logger.info("Preparing IR for rewriting...")
    ctx = RewritingContext(ir) if context is None else context

    ctx.cp.detail = True

    for m in ctx.ir.modules:
        functions = Function.build_functions(m)
        print("%d functions in binary" % (len(functions)))
        for f in tqdm(functions, desc="Loop over functions"):
            #print("fname %s" %(f.get_name()))
            if fname == None or fname == f.get_name():
                rewrite_function(m, f, ctx, logger=logger)
Ejemplo n.º 5
0
    def test_aux_data(self):
        """Test standard AuxDataTables

        The tests for the standard AuxDataTables check both the type name and
        the type of the contents after reading the tables.

        The standard AuxData Schemata are listed in AuxData.md, and these tests
        should match what is listed there.

        AuxData table entries referring to Nodes are encoded as UUIDs. Codecs
        look up these Nodes in a cache and return the actual object. It is
        legal and possible to not hit a UUID in a cache, but this should be
        detected using these tests.

        Each of the *_items_test checks that all items are of the expected type
        after reading in the aux data.

        """
        test_path = os.path.dirname(os.path.realpath(__file__))

        TableTest = namedtuple("TableTest", ["type_name", "items_test"])

        def alignment_items_test(items):
            for key, alignment in items:
                self.assertIsInstance(key, (CodeBlock, DataBlock, Section))
                self.assertIsInstance(alignment, int)

        def comments_items_test(items):
            for offset, comment in items:
                self.assertIsInstance(offset, Offset)
                self.assertIsInstance(comment, str)

        def function_items_test(items):
            for func_uuid, blocks in items:
                self.assertIsInstance(func_uuid, UUID)
                for block in blocks:
                    self.assertIsInstance(block, CodeBlock)

        def padding_items_test(items):
            for addr, padding in items:
                self.assertIsInstance(addr, int)
                self.assertIsInstance(padding, int)

        def types_items_test(items):
            for data_obj, type_name in items:
                self.assertIsInstance(data_obj, DataBlock)
                self.assertIsInstance(type_name, str)

        def symbolfwd_items_test(items):
            for sym1, sym2 in items:
                self.assertIsInstance(sym1, Symbol)
                self.assertIsInstance(sym2, Symbol)

        standard_table_tests = {
            "alignment":
            TableTest(
                type_name="mapping<UUID,uint64_t>",
                items_test=alignment_items_test,
            ),
            "comments":
            TableTest(
                type_name="mapping<Offset,string>",
                items_test=comments_items_test,
            ),
            "functionBlocks":
            TableTest(
                type_name="mapping<UUID,set<UUID>>",
                items_test=function_items_test,
            ),
            "functionEntries":
            TableTest(
                type_name="mapping<UUID,set<UUID>>",
                items_test=function_items_test,
            ),
            "symbolForwarding":
            TableTest(type_name="mapping<UUID,UUID>",
                      items_test=symbolfwd_items_test),
            "padding":
            TableTest(
                type_name="mapping<Addr,uint64_t>",
                items_test=padding_items_test,
            ),
            "types":
            TableTest(type_name="mapping<UUID,string>",
                      items_test=types_items_test),
        }

        def test_standard_auxdata(aux_data):
            for table, table_test in standard_table_tests.items():
                if table in aux_data:
                    with self.subTest(table):
                        self.assertEqual(aux_data[table].type_name,
                                         table_test.type_name)
                        table_test.items_test(aux_data[table].data.items())

        for ir_file in ("test%s.gtirb" % n for n in range(1, 3)):
            ir = IR.load_protobuf(os.path.join(test_path, ir_file))
            for module in ir.modules:
                test_standard_auxdata(module.aux_data)