This repository was archived by the owner on Oct 21, 2020. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 24
/
Copy pathdmadata.py
93 lines (80 loc) · 3.92 KB
/
dmadata.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
#!/usr/bin/env python3
import os, struct, sys, ast, argparse
from elftools.elf.elffile import ELFFile
def align_up(base, align_to):
return ((base + align_to - 1) // align_to) * align_to
if __name__ == "__main__":
parser = argparse.ArgumentParser()
parser.add_argument('files', help='file list')
parser.add_argument('out', help='output file')
parser.add_argument('-l', '--linkscript', help='output linker script for file VROM addresses', metavar='filename')
parser.add_argument('-u', '--uncompressed', help='build dmadata from only uncompressed files', action='store_true', default=False)
parser.add_argument('-e', '--elf', help='Override files with sections of an ELF, if it contains them')
args = parser.parse_args()
raw_elffile = None
elffile = None
if args.elf is not None:
raw_elffile = open(args.elf, 'rb')
elffile = ELFFile(raw_elffile)
with open(args.out, 'wb') as dmadata, open(args.files, 'r') as files:
curr_vrom = 0
curr_phys = 0
dmadata_table = ast.literal_eval(files.read())
linker_info = list()
for base_file, comp_file, alignment, size_if_missing in dmadata_table:
try:
file_name = base_file.split('/')[-1]
uncompressed = comp_file == ''
missing = base_file == '' and comp_file == ''
blank = missing and size_if_missing == 0
is_dmadata = base_file.endswith('dmadata')
is_in_elf = file_name != '' and (elffile is not None) and (elffile.get_section_by_name(file_name) is not None)
alignment = max(alignment, 0x10)
if missing:
vrom_size = size_if_missing
phys_size = 0
elif is_dmadata:
vrom_size = len(dmadata_table) * 0x10
phys_size = vrom_size
elif is_in_elf:
vrom_size = elffile.get_section_by_name(file_name)['sh_size']
phys_size = vrom_size
else:
vrom_size = os.path.getsize(base_file)
if uncompressed or args.uncompressed:
phys_size = vrom_size
else:
phys_size = os.path.getsize(comp_file)
if blank:
vrom_start = 0
vrom_end = 0
else:
vrom_start = align_up(curr_vrom, alignment)
vrom_end = vrom_start + vrom_size
if blank:
phys_start = 0
phys_end = 0
elif missing:
phys_start = 0xFFFFFFFF
phys_end = 0xFFFFFFFF
else:
phys_start = align_up(curr_phys, 0x10)
phys_end = 0 if uncompressed else phys_start + phys_size
curr_vrom = align_up(curr_vrom, alignment) + vrom_size
curr_phys = align_up(curr_phys, 0x10) + phys_size
dmadata.write(vrom_start.to_bytes(4, 'big'))
dmadata.write(vrom_end.to_bytes(4, 'big'))
dmadata.write(phys_start.to_bytes(4, 'big'))
dmadata.write(phys_end.to_bytes(4, 'big'))
if base_file != '':
linker_info.append((os.path.basename(base_file), vrom_start, vrom_end))
except:
print('Error when processing entry ' + base_file)
sys.exit(1)
if args.linkscript:
with open(args.linkscript, 'w') as file:
for name, vrom_start, vrom_end in linker_info:
formatted_name = '_' + name if name[0].isdigit() else name
file.write('{}_vrom_start = 0x{:08X};\n'.format(formatted_name, vrom_start))
file.write('{}_vrom_end = 0x{:08X};\n'.format(formatted_name, vrom_end))
file.write('\n')