Exemple #1
0
    def load_project_from_file(self, file_name):
        loaded_variables = dict(qdt.__dict__)

        try:
            execfile(file_name, loaded_variables)
        except Exception as e:
            raise e
        else:
            qproj = None
            for v in loaded_variables.values():
                if isinstance(v, GUIProject):
                    break
                elif qproj is None and isinstance(v, QProject):
                    qproj = v
            else:
                if qproj:
                    v = GUIProject.from_qproject(qproj)
                else:
                    raise Exception("No project object was loaded")

            self.set_project(v)
            self.set_current_file_name(file_name)
            self.saved_operation = self.pht.pos
            self.__check_saved_asterisk__()

            if self._user_settings:
                self._user_settings.account_project(file_name)
                self._update_recent_projects()
Exemple #2
0
    def on_new_project(self):
        if not self.check_unsaved():
            return

        self.set_project(GUIProject())
        self.set_current_file_name()
        """ There is nothing to save in just created project. So declare that
all changes are saved. """
        self.saved_operation = self.pht.pos
        self.__check_saved_asterisk__()
Exemple #3
0
def main():
    parser = ArgumentParser()

    parser.add_argument(
        '--qemu-build',
        '-b',
        default=None,
        type=arg_type_directory,
        metavar='path_to_qemu_build',
    )

    parser.add_argument("script",
                        default="project.py",
                        nargs="?",
                        help="Load project from a script.")

    arguments = parser.parse_args()

    root = QDCGUIWindow()

    try:
        root.load_project_from_file(arguments.script)
    except Exception as e:
        print("Project load failed: " + str(e) + "\n")

        project = GUIProject()

        try:
            variables = {}
            execfile("serialize-test.py", qdt.__dict__, variables)

            for v in variables.values():
                if isinstance(v, MachineNode):
                    mach = v
                    break
            else:
                raise Exception(
                    "No MachineNode instance was found in serialize-test.py")
        except Exception as e:
            print("Machine load failed: " + str(e) + "\n")
            mach = Q35MachineNode_2_6_0()

        project.add_description(mach)

        try:
            layout = load_cPickled(open("layout.p", "rb"))
        except Exception as e:
            print("Layout load failed: " + str(e) + "\n")
        else:
            project.layouts.append((mach.name, layout))

        tmp_p = Q35Project_2_6_0()
        for desc in list(tmp_p.descriptions):
            if not isinstance(desc, MachineNode):
                desc.remove_from_project()
                project.add_description(desc)

        root.set_project(project)
        root.set_current_file_name("project.py")

    if arguments.qemu_build is not None:
        load_build_path_list()
        account_build_path(arguments.qemu_build)
        root.pht.set_build_path(arguments.qemu_build)

    with Settings(expanduser(join("~", ".qdt.py"))) as settings:
        root.set_user_settings(settings)

        root.geometry("1000x750")

        root.mainloop()

    root.save_project_to_file("project.py")
Exemple #4
0
    def __init__(self, project=None):
        GUITk.__init__(self, wait_msec=1)

        for signame in ["qvc_dirtied", "qvd_failed", "qvc_available"]:
            s = CoSignal()
            s.attach(self.signal_dispatcher)
            setattr(self, "sig_" + signame, s)

        self.title_suffix = _("Qemu device creator GUI")
        self.title_suffix.trace_variable("w", self.__on_title_suffix_write__)

        self.title_not_saved_asterisk = StringVar()
        self.title_not_saved_asterisk.trace_variable(
            "w", self.__on_title_suffix_write__)
        self.saved_operation = None

        self.var_title = StringVar()
        self.title(self.var_title)

        # Hot keys, accelerators
        self.hk = hotkeys = HotKey(self)
        hotkeys.add_bindings([
            HotKeyBinding(
                self.invert_history_window,
                key_code=43,
                description=_("If editing history window is hidden then \
show it else hide it."),
                symbol="H"),
            HotKeyBinding(self.on_load,
                          key_code=32,
                          description=_("Load project from file."),
                          symbol="O"),
            HotKeyBinding(self.on_new_project,
                          key_code=57,
                          description=_("Create new project."),
                          symbol="N"),
            HotKeyBinding(self.on_add_description,
                          key_code=40,
                          description=_("Add description to the project"),
                          symbol="D"),
            HotKeyBinding(self.on_set_qemu_build_path,
                          key_code=56,
                          description=_("Set Qemu build path for the project"),
                          symbol="B"),
            HotKeyBinding(
                self.on_sel_tgt_qemu_version,
                key_code=28,
                description=_("Select target Qemu version for the project"),
                symbol="T"),
            HotKeyBinding(self.on_generate,
                          key_code=42,
                          description=_("Launch code generation"),
                          symbol="G"),
            HotKeyBinding(self.on_delete,
                          key_code=24,
                          description=_("Shutdown the application."),
                          symbol="Q"),
            HotKeyBinding(self.undo,
                          key_code=52,
                          description=_("Revert previous editing."),
                          symbol="Z"),
            HotKeyBinding(self.redo,
                          key_code=29,
                          description=_("Make reverted editing again."),
                          symbol="Y"),
            HotKeyBinding(self.on_save,
                          key_code=39,
                          description=_("Save project."),
                          symbol="S"),
            HotKeyBinding(self.on_reload,
                          key_code=27,
                          description=_("Reload current project from file."),
                          symbol="R")
        ])

        # see `set_user_settings`
        self._user_settings = None

        # Menu bar
        menubar = VarMenu(self)

        self.filemenu = filemenu = VarMenu(menubar, tearoff=False)
        filemenu.add_command(label=_("Add description"),
                             command=self.on_add_description,
                             accelerator=hotkeys.get_keycode_string(
                                 self.on_add_description))
        filemenu.add_command(label=_("Set Qemu build path"),
                             command=self.on_set_qemu_build_path,
                             accelerator=hotkeys.get_keycode_string(
                                 self.on_set_qemu_build_path))
        filemenu.add_command(label=_("Select target Qemu version"),
                             command=self.on_sel_tgt_qemu_version,
                             accelerator=hotkeys.get_keycode_string(
                                 self.on_sel_tgt_qemu_version))
        filemenu.add_command(label=_("Generate"),
                             command=self.on_generate,
                             accelerator=hotkeys.get_keycode_string(
                                 self.on_generate))
        filemenu.add_separator()
        filemenu.add_command(label=_("New project"),
                             command=self.on_new_project,
                             accelerator=hotkeys.get_keycode_string(
                                 self.on_new_project)),
        filemenu.add_command(label=_("Save"),
                             command=self.on_save,
                             accelerator=hotkeys.get_keycode_string(
                                 self.on_save)),
        filemenu.add_command(label=_("Save project as..."),
                             command=self.on_save_as)
        filemenu.add_command(label=_("Load"),
                             command=self.on_load,
                             accelerator=hotkeys.get_keycode_string(
                                 self.on_load)),
        self.reload_idx = filemenu.count
        filemenu.add_command(label=_("Reload"),
                             command=self.on_reload,
                             accelerator=hotkeys.get_keycode_string(
                                 self.on_reload)),
        self.recentmenu = recentmenu = VarMenu(filemenu, tearoff=False)
        filemenu.add_cascade(
            label=_("Recent projects"),
            menu=recentmenu,
            state=DISABLED  # a user settings instance is required
        )

        filemenu.add_separator()
        filemenu.add_command(label=_("Quit"),
                             command=self.quit,
                             accelerator=hotkeys.get_keycode_string(
                                 self.on_delete))
        menubar.add_cascade(label=_("File"), menu=filemenu)

        self.editmenu = editmenu = VarMenu(menubar, tearoff=False)
        editmenu.add_command(label=_("Undo"),
                             command=self.undo,
                             accelerator=hotkeys.get_keycode_string(self.undo))
        self.undo_idx = editmenu.count - 1

        editmenu.add_command(label=_("Redo"),
                             command=self.redo,
                             accelerator=hotkeys.get_keycode_string(self.redo))
        self.redo_idx = editmenu.count - 1

        editmenu.add_separator()

        editmenu.add_command(label=_("Rebuild Cache"),
                             command=self.rebuild_cache,
                             accelerator=hotkeys.get_keycode_string(
                                 self.rebuild_cache))

        editmenu.add_separator()

        v = self.var_history_window = BooleanVar()
        v.set(False)

        self.__on_var_history_window = v.trace_variable(
            "w", self.__on_var_history_window__)

        editmenu.add_checkbutton(label=_("Editing history window"),
                                 variable=v,
                                 accelerator=hotkeys.get_keycode_string(
                                     self.invert_history_window))

        menubar.add_cascade(label=_("Edit"), menu=editmenu)

        self.optionsmenu = optionsmenu = VarMenu(menubar, tearoff=False)

        v = self.var_schedule_generation = BooleanVar()
        v.set(False)

        self.__on_var_schedule_generation = v.trace_variable(
            "w", self.__on_var_schedule_generation__)

        optionsmenu.add_checkbutton(
            label=_("Schedule generation after cache loading"), variable=v)

        v = self.var_gen_chunk_graphs = BooleanVar()
        v.set(False)

        self.__on_var_gen_chunk_graphs = v.trace_variable(
            "w", self.__on_var_gen_chunk_graphs__)

        optionsmenu.add_checkbutton(label=_("Generate chunk graphs"),
                                    variable=v)

        menubar.add_cascade(label=_("Options"), menu=optionsmenu)

        self.config(menu=menubar)

        # Widget layout
        self.grid()
        self.grid_columnconfigure(0, weight=1)
        self.grid_rowconfigure(0, weight=1)

        # Status bar
        self.grid_rowconfigure(1, weight=0)
        self.sb = sb = Statusbar(self)
        sb.grid(row=1, column=0, sticky="NEWS")

        # Target Qemu version in the status bar
        self._target_qemu = Variable(None)

        # This complicated scheme is required because the status must also
        # be updated on language change.
        @as_variable(self._target_qemu, _("No target"), _("Target Qemu: %s"))
        def var_target_qemu(target, no_target, target_qemu):
            if target is None:
                return no_target
            else:
                return target_qemu % target

        sb.left(var_target_qemu)

        # QEMU build path displaying
        self.var_qemu_build_path = StringVar()
        sb.left(self.var_qemu_build_path)

        # Task counters in status bar
        sb.right(_("Background tasks: "))
        sb.repack(CoStatusView(sb), RIGHT)

        self.signal_dispatcher.watch_failed(self.__on_listener_failed)

        self.protocol("WM_DELETE_WINDOW", self.on_delete)

        self.set_project(GUIProject() if project is None else project)

        self.__update_title__()
        self.__check_saved_asterisk__()

        self.qsig_watch("qvc_available", self.__on_qvc_available)
Exemple #5
0
    def __init__(self, project=None):
        GUITk.__init__(self, wait_msec=1)

        for signame in ["qvc_dirtied", "qvd_failed", "qvc_available"]:
            s = CoSignal()
            s.attach(self.signal_dispatcher)
            setattr(self, "sig_" + signame, s)

        self.title_suffix = _("Qemu device creator GUI")
        self.title_suffix.trace_variable("w", self.__on_title_suffix_write__)

        self.title_not_saved_asterisk = StringVar()
        self.title_not_saved_asterisk.trace_variable(
            "w", self.__on_title_suffix_write__)
        self.saved_operation = None

        self.var_title = StringVar()
        self.title(self.var_title)

        # Hot keys, accelerators
        self.hk = hotkeys = HotKey(self)
        hotkeys.add_bindings([
            HotKeyBinding(
                self.invert_history_window,
                key_code=43,  # H
                description=_("If editing history window is hidden then \
show it else hide it.")),
            HotKeyBinding(
                self.on_load,
                key_code=32,  # O
                description=_("Load project from file.")),
            HotKeyBinding(
                self.on_new_project,
                key_code=57,  # N
                description=_("Create new project.")),
            HotKeyBinding(
                self.on_add_description,
                key_code=40,  # D
                description=_("Add description to the project")),
            HotKeyBinding(
                self.on_set_qemu_build_path,
                key_code=56,  # B
                description=_("Set Qemu build path for the project")),
            HotKeyBinding(
                self.on_generate,
                key_code=42,  # G
                description=_("Launch code generation")),
            HotKeyBinding(
                self.on_delete,
                key_code=24,  # Q
                description=_("Shutdown the application.")),
            HotKeyBinding(
                self.undo,
                key_code=52,  # Z
                description=_("Revert previous editing.")),
            HotKeyBinding(
                self.redo,
                key_code=29,  # Y
                description=_("Make reverted editing again.")),
            HotKeyBinding(
                self.on_save,
                key_code=39,  # S
                description=_("Save project.")),
            HotKeyBinding(
                self.rebuild_cache,
                key_code=27,  # R
                description=_("Rebuild Cache."))
        ])

        hotkeys.add_key_symbols({
            27: "R",
            43: "H",
            32: "O",
            57: "N",
            40: "D",
            56: "B",
            42: "G",
            24: "Q",
            52: "Z",
            29: "Y",
            39: "S"
        })

        # Menu bar
        menubar = VarMenu(self)

        filemenu = VarMenu(menubar, tearoff=False)
        filemenu.add_command(label=_("Add description"),
                             command=self.on_add_description,
                             accelerator=hotkeys.get_keycode_string(
                                 self.on_add_description))
        filemenu.add_command(label=_("Set Qemu build path"),
                             command=self.on_set_qemu_build_path,
                             accelerator=hotkeys.get_keycode_string(
                                 self.on_set_qemu_build_path))
        filemenu.add_command(label=_("Generate"),
                             command=self.on_generate,
                             accelerator=hotkeys.get_keycode_string(
                                 self.on_generate))
        filemenu.add_separator()
        filemenu.add_command(label=_("New project"),
                             command=self.on_new_project,
                             accelerator=hotkeys.get_keycode_string(
                                 self.on_new_project)),
        filemenu.add_command(label=_("Save"),
                             command=self.on_save,
                             accelerator=hotkeys.get_keycode_string(
                                 self.on_save)),
        filemenu.add_command(label=_("Save project as..."),
                             command=self.on_save_as)
        filemenu.add_command(label=_("Load"),
                             command=self.on_load,
                             accelerator=hotkeys.get_keycode_string(
                                 self.on_load)),
        filemenu.add_separator()
        filemenu.add_command(label=_("Quit"),
                             command=self.quit,
                             accelerator=hotkeys.get_keycode_string(
                                 self.on_delete))
        menubar.add_cascade(label=_("File"), menu=filemenu)

        self.editmenu = editmenu = VarMenu(menubar, tearoff=False)
        editmenu.add_command(label=_("Undo"),
                             command=self.undo,
                             accelerator=hotkeys.get_keycode_string(self.undo))
        self.undo_idx = editmenu.count - 1

        editmenu.add_command(label=_("Redo"),
                             command=self.redo,
                             accelerator=hotkeys.get_keycode_string(self.redo))
        self.redo_idx = editmenu.count - 1

        editmenu.add_separator()

        editmenu.add_command(label=_("Rebuild Cache"),
                             command=self.rebuild_cache,
                             accelerator=hotkeys.get_keycode_string(
                                 self.rebuild_cache))

        editmenu.add_separator()

        v = self.var_history_window = BooleanVar()
        v.set(False)

        self.__on_var_history_window = v.trace_variable(
            "w", self.__on_var_history_window__)

        editmenu.add_checkbutton(label=_("Editing history window"),
                                 variable=v,
                                 accelerator=hotkeys.get_keycode_string(
                                     self.invert_history_window))

        menubar.add_cascade(label=_("Edit"), menu=editmenu)

        self.config(menu=menubar)

        # Widget layout
        self.grid()
        self.grid_columnconfigure(0, weight=1)
        self.grid_rowconfigure(0, weight=1)

        # Status bar
        self.grid_rowconfigure(1, weight=0)
        self.sb = sb = Statusbar(self)
        sb.grid(row=1, column=0, sticky="NEWS")

        # QEMU build path displaying
        self.var_qemu_build_path = StringVar()
        sb.left(self.var_qemu_build_path)

        # Task counters in status bar
        self.var_tasks = vt = IntVar()
        self.var_callers = vc = IntVar()
        self.var_active_tasks = vat = IntVar()
        self.var_finished_tasks = vft = IntVar()
        sb.right(_("Background tasks: "))
        sb.right(FormatVar(value="%u") % vt, fg="red")
        sb.right(FormatVar(value="%u") % vc, fg="orange")
        sb.right(FormatVar(value="%u") % vat)
        sb.right(FormatVar(value="%u") % vft, fg="grey")

        self.task_manager.watch_activated(self.__on_task_state_changed)
        self.task_manager.watch_finished(self.__on_task_state_changed)
        self.task_manager.watch_failed(self.__on_task_state_changed)
        self.task_manager.watch_removed(self.__on_task_state_changed)

        self.protocol("WM_DELETE_WINDOW", self.on_delete)

        self.set_project(GUIProject() if project is None else project)

        self.__update_title__()
        self.__check_saved_asterisk__()
Exemple #6
0
def main():
    ap = QArgumentParser(formatter_class=ArgumentDefaultsHelpFormatter,
                         description="QEMU runtime introspection tool")
    ap.add_argument("-q", dest="qsrc", help="QEMU src directory.")
    ap.add_argument(
        "-c",
        "--connect",
        nargs="?",
        metavar="HOST",
        const="127.0.0.1",  # default if `-c` is given without a value
        # Suppress reasons:
        # 1. do not print incorrect default in help by
        #    `ArgumentDefaultsHelpFormatter` (correct is `const`)
        # 2. do not add the attribute to parsed args if the arg is missed
        default=SUPPRESS,
        help="connect to existing gdbstub (default: %(const)s)")
    ap.add_argument("-p",
                    "--port",
                    type=int,
                    metavar="PORT",
                    default=4321,
                    help="start search for unused port from this number")
    ap.add_argument(
        "qarg",
        nargs="+",
        help="QEMU executable and arguments to it. Prefix them with `--`.")
    args = ap.parse_args()

    # executable
    qemu_cmd_args = args.qarg

    # src directory
    qemu_src_dir = args.qsrc

    # debug info
    qemu_debug = qemu_cmd_args[0]

    elf = InMemoryELFFile(qemu_debug)
    if not elf.has_dwarf_info():
        stderr("%s does not have DWARF info. Provide a debug QEMU build\n" %
               (qemu_debug))
        return -1

    di = elf.get_dwarf_info()

    if not di.debug_pubnames_sec:
        print("%s does not contain .debug_pubtypes section. Provide"
              " -gpubnames flag to the compiler" % qemu_debug)

    dic = DWARFInfoCache(di, symtab=elf.get_section_by_name(".symtab"))

    if qemu_src_dir:
        gvl_adptr = GitLineVersionAdapter(qemu_src_dir)
    else:
        gvl_adptr = None

    qomtr = QOMTreeReverser(dic,
                            interrupt=False,
                            verbose=True,
                            line_adapter=gvl_adptr)

    if "-i386" in qemu_debug or "-x86_64" in qemu_debug:
        MWClass = PCMachineWatcher
    else:
        MWClass = MachineWatcher

    mw = MWClass(dic, qomtr.tree, interrupt=True, line_adapter=gvl_adptr)

    proj = GUIProject()
    pht = GUIProjectHistoryTracker(proj, proj.history)

    MachineReverser(mw, pht)

    try:
        qemu_debug_addr_fmt = args.connect + ":%u"
    except AttributeError:  # no -c/--connect option
        # auto select free port for gdb-server
        port = find_free_port(args.port)

        qemu_debug_addr = "localhost:%u" % port

        qemu_proc = Popen(["gdbserver", qemu_debug_addr] + qemu_cmd_args)
    else:
        port = args.port
        qemu_debug_addr = qemu_debug_addr_fmt % port
        qemu_proc = None

    if not wait_for_tcp_port(port):
        raise RuntimeError("gdbserver does not listen %u" % port)

    qemu_debugger = AMD64(str(port), noack=True)

    rt = Runtime(qemu_debugger, dic)

    qomtr.init_runtime(rt)
    mw.init_runtime(rt)

    # Because pyrsp (with machine reconstruction suite) works in a separate
    # thread, tracker's "changed" notifications are racing with GUI. So, GUI
    # must not watch those notifications. To maintain GUI consistency
    # other project and tracker are created with same history. The GUI is
    # watching this second tracker. A special coroutine working in GUI thread
    # will poll first (master) tracker position and adjust second (slave)
    # tracker updating the GUI without races.
    proj2 = GUIProject()
    # different context (project) but same history
    slave_pht = GUIProjectHistoryTracker(proj2, proj.history)

    def co_syncronizer():
        while True:
            if slave_pht.pos != pht.pos:
                yield True
                slave_pht.do()
            else:
                yield False

    tk = QEmuWatcherGUI(slave_pht, rt)

    tk.task_manager.enqueue(co_syncronizer())

    tk.geometry("1024x1024")
    tk.mainloop()

    qomtr.to_file("qom-by-q.i.dot")

    if qemu_proc is not None:
        qemu_proc.wait()

    if gvl_adptr is not None:
        gvl_adptr.cm.store_cache()