Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
input_file.seek(0, os.SEEK_END)
file_size = input_file.tell()
input_file.seek(0, os.SEEK_SET)
savefile_id = persistence.read_uint32(input_file)
savefile_version = persistence.read_uint16(input_file)
if savefile_version != 3:
return None
logger.info("Upgrading save-file from version 3 to version 4: Processor id field..")
save_count = persistence.read_uint32(input_file)
output_file = tempfile.TemporaryFile()
persistence.write_uint32(output_file, savefile_id)
persistence.write_uint16(output_file, 4)
persistence.write_uint32(output_file, save_count)
while input_file.tell() < file_size:
# This should be pretty straightforward.
hunk_header_offset = input_file.tell()
hunk_id = persistence.read_uint16(input_file)
hunk_length = persistence.read_uint32(input_file)
hunk_payload_offset = input_file.tell()
actual_hunk_version = persistence.read_uint16(input_file)
expected_hunk_version = SNAPSHOT_HUNK_VERSIONS[hunk_id]
if expected_hunk_version != actual_hunk_version:
logger.error("convert_project_format_3_to_4: hunk %d version mismatch %d != %d", hunk_id, expected_hunk_version, actual_hunk_version)
return None
logger.debug("convert_project_format_3_to_4: file hunk %d", hunk_id)
if block.line_data is None:
line_data_count = 0
else:
line_data_count = len(block.line_data)
s = struct.pack(SEGMENTBLOCK_PACK_FORMAT, block.segment_id, block.segment_offset, block.address, block.length, block.flags, block.line_count, line_data_count)
f.write(s)
if line_data_count > 0:
if get_block_data_type(block) == DATA_TYPE_CODE:
block_offset = 0
for i, (type_id, entry) in enumerate(block.line_data):
persistence.write_uint8(f, type_id)
if type_id == SLD_INSTRUCTION:
if type(entry) is int:
persistence.write_uint16(f, entry)
# The length of this instruction is not stored, so we calculate it relative to the next one.
j = i+1
while j < len(block.line_data):
next_type_id, next_entry = block.line_data[j]
if next_type_id == SLD_INSTRUCTION:
if type(next_entry) is int:
block_offset = next_entry
else:
block_offset = next_entry.pc - pc_offset
break
j += 1
else:
persistence.write_uint16(f, block_offset)
block_offset += entry.num_bytes
elif type_id == SLD_EQU_LOCATION_RELATIVE:
persistence.write_uint32(f, entry) # block offset
# Only these two are likely to have been in use.
if processor_name == "m68k":
processor_id = loaderlib.constants.PROCESSOR_M680x0
elif processor_name == "mips":
processor_id = loaderlib.constants.PROCESSOR_MIPS
else:
logger.error("convert_project_format_3_to_4: unrecognised arch name %s", processor_name)
return None
logger.debug("convert_project_format_3_to_4: arch name %s maps to processor id %d", processor_name, processor_id)
# Write the as yet to be updated header.
persistence.write_uint16(output_file, hunk_id)
output_file_length_offset = output_file.tell()
persistence.write_uint32(output_file, 0)
output_file_payload_offset = output_file.tell()
persistence.write_uint16(output_file, SNAPSHOT_HUNK_VERSIONS[SAVEFILE_HUNK_DISASSEMBLY] + 1)
# Write the payload in the modified format.
persistence.write_dict_uint32_to_set_of_uint32s(output_file, branch_addresses)
persistence.write_dict_uint32_to_set_of_uint32s(output_file, reference_addresses)
persistence.write_dict_uint32_to_string(output_file, symbols_by_address)
persistence.write_dict_uint32_to_list_of_uint32s(output_file, post_segment_addresses)
persistence.write_uint32(output_file, flags)
persistence.write_uint32(output_file, processor_id)
persistence.write_uint32(output_file, num_blocks)
output_file_offset = output_file.tell()
#for block in blocks:
# write_SegmentBlock(output_file, block, program_data.dis_constant_pc_offset)
output_file.write(block_data_string)
if output_file.tell() - output_file_offset != block_data_length:
logger.error("convert_project_format_3_to_4: block length mismatch %d != %d", output_file.tell() - output_file_offset, block_data_length)
if type_id == SLD_INSTRUCTION:
if type(entry) is int:
persistence.write_uint16(f, entry)
# The length of this instruction is not stored, so we calculate it relative to the next one.
j = i+1
while j < len(block.line_data):
next_type_id, next_entry = block.line_data[j]
if next_type_id == SLD_INSTRUCTION:
if type(next_entry) is int:
block_offset = next_entry
else:
block_offset = next_entry.pc - pc_offset
break
j += 1
else:
persistence.write_uint16(f, block_offset)
block_offset += entry.num_bytes
elif type_id == SLD_EQU_LOCATION_RELATIVE:
persistence.write_uint32(f, entry) # block offset
elif type_id in (SLD_COMMENT_TRAILING, SLD_COMMENT_FULL_LINE):
persistence.write_string(f, entry) # string
else:
logger.error("Trying to save a savefile, did not know how to handle entry of type_id: %d, entry value: %s", type_id, entry)
def save_project(f, program_data, save_options):
# type: (io.IOBase, ProgramData, SaveProjectOptions) -> None
f.seek(0, os.SEEK_SET)
persistence.write_uint32(f, SAVEFILE_ID)
persistence.write_uint16(f, SAVEFILE_VERSION)
program_data.save_count += 1
persistence.write_uint32(f, program_data.save_count)
# The input file / source data is saved in the first hunk, so we can skip repersisting it in subsequent saves to the same file.
for hunk_id in (SAVEFILE_HUNK_SOURCEDATA, SAVEFILE_HUNK_SOURCEDATAINFO, SAVEFILE_HUNK_LOADER, SAVEFILE_HUNK_LOADERINTERNAL, SAVEFILE_HUNK_DISASSEMBLY):
if SAVEFILE_HUNK_SOURCEDATA == hunk_id and save_options.input_file is None:
continue
persistence.write_uint16(f, hunk_id)
# Remember the hunk length offset and write a dummy value.
length_offset = f.tell()
persistence.write_uint32(f, 0)
hunk_data_offset = f.tell()
persistence.write_uint16(f, CURRENT_HUNK_VERSIONS[hunk_id])
if SAVEFILE_HUNK_DISASSEMBLY == hunk_id:
save_disassembly_hunk(f, program_data)
elif SAVEFILE_HUNK_LOADER == hunk_id:
save_loader_hunk(f, program_data)
elif SAVEFILE_HUNK_LOADERINTERNAL == hunk_id:
save_loaderinternaldata_hunk(f, program_data)
elif SAVEFILE_HUNK_SOURCEDATAINFO == hunk_id:
save_sourcedatainfo_hunk(f, program_data)
elif SAVEFILE_HUNK_SOURCEDATA == hunk_id:
save_sourcedata_hunk(f, program_data, save_options.input_file)
else:
input_file.seek(0, os.SEEK_END)
file_size = input_file.tell()
input_file.seek(0, os.SEEK_SET)
savefile_id = persistence.read_uint32(input_file)
savefile_version = persistence.read_uint16(input_file)
if savefile_version != 4:
return None
logger.info("Upgrading save-file from version 4 to version 5: symbols by address..")
save_count = persistence.read_uint32(input_file)
output_file = tempfile.TemporaryFile()
persistence.write_uint32(output_file, savefile_id)
persistence.write_uint16(output_file, 5)
persistence.write_uint32(output_file, save_count)
while input_file.tell() < file_size:
# This should be pretty straightforward.
hunk_header_offset = input_file.tell()
hunk_id = persistence.read_uint16(input_file)
hunk_length = persistence.read_uint32(input_file)
hunk_payload_offset = input_file.tell()
actual_hunk_version = persistence.read_uint16(input_file)
expected_hunk_version = SNAPSHOT_HUNK_VERSIONS[hunk_id]
if expected_hunk_version != actual_hunk_version:
logger.error("convert_project_format_4_to_5: hunk %d version mismatch %d != %d", hunk_id, expected_hunk_version, actual_hunk_version)
return None
logger.debug("convert_project_format_4_to_5: file hunk %d", hunk_id)
persistence.write_uint32(f, SAVEFILE_ID)
persistence.write_uint16(f, SAVEFILE_VERSION)
program_data.save_count += 1
persistence.write_uint32(f, program_data.save_count)
# The input file / source data is saved in the first hunk, so we can skip repersisting it in subsequent saves to the same file.
for hunk_id in (SAVEFILE_HUNK_SOURCEDATA, SAVEFILE_HUNK_SOURCEDATAINFO, SAVEFILE_HUNK_LOADER, SAVEFILE_HUNK_LOADERINTERNAL, SAVEFILE_HUNK_DISASSEMBLY):
if SAVEFILE_HUNK_SOURCEDATA == hunk_id and save_options.input_file is None:
continue
persistence.write_uint16(f, hunk_id)
# Remember the hunk length offset and write a dummy value.
length_offset = f.tell()
persistence.write_uint32(f, 0)
hunk_data_offset = f.tell()
persistence.write_uint16(f, CURRENT_HUNK_VERSIONS[hunk_id])
if SAVEFILE_HUNK_DISASSEMBLY == hunk_id:
save_disassembly_hunk(f, program_data)
elif SAVEFILE_HUNK_LOADER == hunk_id:
save_loader_hunk(f, program_data)
elif SAVEFILE_HUNK_LOADERINTERNAL == hunk_id:
save_loaderinternaldata_hunk(f, program_data)
elif SAVEFILE_HUNK_SOURCEDATAINFO == hunk_id:
save_sourcedatainfo_hunk(f, program_data)
elif SAVEFILE_HUNK_SOURCEDATA == hunk_id:
save_sourcedata_hunk(f, program_data, save_options.input_file)
else:
raise RuntimeError("Trying to save a hunk with no handling to do so")
hunk_length = f.tell() - hunk_data_offset
# Go back and fill in the hunk length field.
f.seek(length_offset, os.SEEK_SET)
persistence.write_uint32(f, hunk_length)
actual_hunk_version = persistence.read_uint16(input_file)
expected_hunk_version = SNAPSHOT_HUNK_VERSIONS[hunk_id]
if expected_hunk_version != actual_hunk_version:
logger.error("convert_project_format_4_to_5: hunk %d version mismatch %d != %d", hunk_id, expected_hunk_version, actual_hunk_version)
return None
logger.debug("convert_project_format_4_to_5: file hunk %d", hunk_id)
if SAVEFILE_HUNK_LOADER != hunk_id:
input_file.seek(hunk_header_offset, os.SEEK_SET)
raw_hunk_length = (hunk_payload_offset - hunk_header_offset) + hunk_length
output_file.write(input_file.read(raw_hunk_length))
continue
# Write the as yet to be updated header.
persistence.write_uint16(output_file, hunk_id)
output_file_length_offset = output_file.tell()
persistence.write_uint32(output_file, 0)
output_file_payload_offset = output_file.tell()
persistence.write_uint16(output_file, SNAPSHOT_HUNK_VERSIONS[SAVEFILE_HUNK_LOADER] + 1)
# Transform the hunk from input file to output file.
persistence.write_string(output_file, persistence.read_string(input_file)) # loader_system_name
data_size = persistence.read_uint32(input_file)
persistence.write_uint32(output_file, data_size) # loader_segments
output_file.write(input_file.read(data_size))
set_value = persistence.read_set_of_uint32s(input_file)
persistence.write_dict_uint32_to_list_of_uint32s(output_file, { k: [] for k in set_value }) # loader_relocated_addresses
set_value = persistence.read_set_of_uint32s(input_file)
persistence.write_set_of_uint32s(output_file, set_value) # loader_relocatable_addresses
persistence.write_uint16(output_file, persistence.read_uint16(input_file)) # loader_entrypoint_segment_id
persistence.write_int32(output_file, persistence.read_uint32(input_file)) # loader_entrypoint_offset