def load_file(self, acting_client): self.reset_state(acting_client) # Request a file name to load. result = acting_client.request_load_file() if result is None: return if type(result) is str: self.reset_state(acting_client) return result load_file, file_path = result self.state_id = EditorState.STATE_LOADING file_name = os.path.basename(file_path) is_saved_project = disassembly_persistence.check_is_project_file( load_file) for client in self.clients: client.event_load_start(client is acting_client, file_path) if is_saved_project: disassembly_state = self._prolonged_action( acting_client, "TITLE_LOADING_PROJECT", "TEXT_GENERIC_LOADING", disassembly.load_project_file, load_file, file_name) else: new_options = disassembly.get_new_project_options() identify_result = loaderlib.identify_file(load_file, file_name) # Parameters passed in, to help the client make up it's mind. if identify_result is not None: new_options.is_binary_file = False new_options.loader_load_address = loaderlib.get_load_address( identify_result[0]) new_options.loader_entrypoint_offset = loaderlib.get_entrypoint_address( identify_result[0]) new_options.loader_filetype = identify_result[1]["filetype"] new_options.loader_processor = identify_result[1]["processor"] else: new_options.is_binary_file = True new_options.loader_load_address = 0 new_options.loader_entrypoint_offset = 0 new_options.loader_filetype = loaderlib.constants.FILE_FORMAT_UNKNOWN new_options.loader_processor = "" # Prompt for new project option values. new_option_result = acting_client.request_new_project_option_values( new_options) if new_option_result is None or type(new_option_result) is str: self.reset_state(acting_client) return new_option_result disassembly_state = self._prolonged_action( acting_client, "TITLE_LOADING_FILE", "TEXT_GENERIC_LOADING", disassembly.load_file, load_file, new_option_result, file_name) # Loading was cancelled. if disassembly_state is None: self.reset_state(acting_client) return self.state_id = EditorState.STATE_LOADED self.disassembly_state = disassembly_state # Register our event dispatching callbacks. self.disassembly_state.set_uncertain_reference_modification_func( self._uncertain_reference_modification_callback) self.disassembly_state.set_symbol_insert_func( self._symbol_insert_callback) self.disassembly_state.set_symbol_delete_func( self._symbol_delete_callback) line_count = self.disassembly_state.get_file_line_count() if line_count == 0: self.reset_state(acting_client) return ERRMSG_NOT_SUPPORTED_EXECUTABLE_FILE_FORMAT is_saved_project = disassembly_persistence.check_is_project_file( acting_client.get_load_file()) if is_saved_project: # User may have optionally chosen to not save the input file, as part of the project file. if not self.disassembly_state.is_segment_data_cached(): load_options = disassembly.get_new_project_options() # Parameters passed in, to help the client make up it's mind. load_options.input_file_filesize = self.disassembly_state.get_file_size( ) load_options.input_file_filename = self.disassembly_state.get_file_name( ) load_options.input_file_checksum = self.disassembly_state.get_file_checksum( ) # Parameters received out, our "return values". load_options.loader_file_path = None load_options = acting_client.request_load_project_option_values( load_options) if load_options.loader_file_path is None: self.reset_state(acting_client) return ERRMSG_INPUT_FILE_NOT_FOUND # Verify that the given input file is valid, or error descriptively. with open(load_options.loader_file_path, "rb") as input_data_file: input_data_file.seek(0, os.SEEK_END) errmsg = None if input_data_file.tell( ) != self.disassembly_state.get_file_size(): errmsg = ERRMSG_INPUT_FILE_SIZE_DIFFERS elif util.calculate_file_checksum( input_data_file ) != self.disassembly_state.get_file_checksum(): errmsg = ERRMSG_INPUT_FILE_CHECKSUM_MISMATCH if type(errmsg) is str: self.reset_state(acting_client) return errmsg self.disassembly_state.load_project_file_finalise( input_data_file) entrypoint_address = self.disassembly_state.get_entrypoint_address() line_number = self.disassembly_state.get_line_number_for_address( entrypoint_address) self.set_line_number(acting_client, line_number) def _pre_line_change_callback(line0, line_count): for client in self.clients: client.event_pre_line_change(client is acting_client, line0, line_count) self.disassembly_state.set_pre_line_change_func( _pre_line_change_callback) def _post_line_change_callback(line0, line_count): for client in self.clients: client.event_post_line_change(client is acting_client, line0, line_count) self.disassembly_state.set_post_line_change_func( _post_line_change_callback) for client in self.clients: client.event_load_successful(client is acting_client) return result
def load_file(self, acting_client): self.reset_state(acting_client) # Request a file name to load. result = acting_client.request_load_file() if result is None: return if type(result) is str: self.reset_state(acting_client) return result load_file, file_path = result self.state_id = EditorState.STATE_LOADING file_name = os.path.basename(file_path) is_saved_project = disassembly_persistence.check_is_project_file(load_file) for client in self.clients: client.event_load_start(client is acting_client, file_path) if is_saved_project: disassembly_state = self._prolonged_action(acting_client, "TITLE_LOADING_PROJECT", "TEXT_GENERIC_LOADING", disassembly.load_project_file, load_file, file_name) else: new_options = disassembly.get_new_project_options() identify_result = loaderlib.identify_file(load_file, file_name) # Parameters passed in, to help the client make up it's mind. if identify_result is not None: new_options.is_binary_file = False new_options.loader_load_address = loaderlib.get_load_address(identify_result[0]) new_options.loader_entrypoint_offset = loaderlib.get_entrypoint_address(identify_result[0]) new_options.loader_filetype = identify_result[1]["filetype"] new_options.loader_processor = identify_result[1]["processor"] else: new_options.is_binary_file = True new_options.loader_load_address = 0 new_options.loader_entrypoint_offset = 0 new_options.loader_filetype = loaderlib.constants.FILE_FORMAT_UNKNOWN new_options.loader_processor = "" # Prompt for new project option values. new_option_result = acting_client.request_new_project_option_values(new_options) if new_option_result is None or type(new_option_result) is str: self.reset_state(acting_client) return new_option_result disassembly_state = self._prolonged_action(acting_client, "TITLE_LOADING_FILE", "TEXT_GENERIC_LOADING", disassembly.load_file, load_file, new_option_result, file_name) # Loading was cancelled. if disassembly_state is None: self.reset_state(acting_client) return self.state_id = EditorState.STATE_LOADED self.disassembly_state = disassembly_state # Register our event dispatching callbacks. self.disassembly_state.set_uncertain_reference_modification_func(self._uncertain_reference_modification_callback) self.disassembly_state.set_symbol_insert_func(self._symbol_insert_callback) self.disassembly_state.set_symbol_delete_func(self._symbol_delete_callback) line_count = self.disassembly_state.get_file_line_count() if line_count == 0: self.reset_state(acting_client) return ERRMSG_NOT_SUPPORTED_EXECUTABLE_FILE_FORMAT is_saved_project = disassembly_persistence.check_is_project_file(acting_client.get_load_file()) if is_saved_project: # User may have optionally chosen to not save the input file, as part of the project file. if not self.disassembly_state.is_segment_data_cached(): load_options = disassembly.get_new_project_options() # Parameters passed in, to help the client make up it's mind. load_options.input_file_filesize = self.disassembly_state.get_file_size() load_options.input_file_filename = self.disassembly_state.get_file_name() load_options.input_file_checksum = self.disassembly_state.get_file_checksum() # Parameters received out, our "return values". load_options.loader_file_path = None load_options = acting_client.request_load_project_option_values(load_options) if load_options.loader_file_path is None: self.reset_state(acting_client) return ERRMSG_INPUT_FILE_NOT_FOUND # Verify that the given input file is valid, or error descriptively. with open(load_options.loader_file_path, "rb") as input_data_file: input_data_file.seek(0, os.SEEK_END) errmsg = None if input_data_file.tell() != self.disassembly_state.get_file_size(): errmsg = ERRMSG_INPUT_FILE_SIZE_DIFFERS elif util.calculate_file_checksum(input_data_file) != self.disassembly_state.get_file_checksum(): errmsg = ERRMSG_INPUT_FILE_CHECKSUM_MISMATCH if type(errmsg) is str: self.reset_state(acting_client) return errmsg self.disassembly_state.load_project_file_finalise(input_data_file) entrypoint_address = self.disassembly_state.get_entrypoint_address() line_number = self.disassembly_state.get_line_number_for_address(entrypoint_address) self.set_line_number(acting_client, line_number) def _pre_line_change_callback(line0, line_count): for client in self.clients: client.event_pre_line_change(client is acting_client, line0, line_count) self.disassembly_state.set_pre_line_change_func(_pre_line_change_callback) def _post_line_change_callback(line0, line_count): for client in self.clients: client.event_post_line_change(client is acting_client, line0, line_count) self.disassembly_state.set_post_line_change_func(_post_line_change_callback) for client in self.clients: client.event_load_successful(client is acting_client) return result
def is_project_file(self, acting_client, input_file): return disassembly_persistence.check_is_project_file(input_file)