diff options
Diffstat (limited to 'tools/kamek.py')
-rw-r--r-- | tools/kamek.py | 128 |
1 files changed, 79 insertions, 49 deletions
diff --git a/tools/kamek.py b/tools/kamek.py index 534eac8..ee67a5a 100644 --- a/tools/kamek.py +++ b/tools/kamek.py @@ -162,11 +162,17 @@ class DyLinkCreator(object): VALID_RELOCS = set([1, 4, 5, 6, 10]) - def __init__(self): - self._relocs = [] + def __init__(self, other=None): + if other: + self._relocs = other._relocs[:] - self._targets = [] - self._target_lookups = {} + self._targets = other._targets[:] + self._target_lookups = other._target_lookups.copy() + else: + self._relocs = [] + + self._targets = [] + self._target_lookups = {} self.elf = None @@ -274,36 +280,49 @@ class KamekBuilder(object): print_debug('Temp files for this configuration are in: '+self._configTempDir) if 'dynamic_link' in self._config and self._config['dynamic_link']: - self.dynamic_link = DyLinkCreator() + self.dynamic_link_base = DyLinkCreator() else: - self.dynamic_link = None + self.dynamic_link_base = None self._builtCodeAddr = 0x80001800 if 'code_address' in self.project.data: self._builtCodeAddr = self.project.data['code_address'] - self._patches = [] - self._rel_patches = [] - self._hooks = [] - # hook setup self._hook_contexts = {} for name, hookType in hooks.HookTypes.iteritems(): if hookType.has_context: self._hook_contexts[hookType] = hookType.context_type() - self._create_hooks() self._compile_modules() - self._link() - self._read_symbol_map() - if self.dynamic_link: - self.dynamic_link.set_elf(open(self._outFile, 'rb')) - - for hook in self._hooks: - hook.create_patches() - - self._create_patch() + # figure out how many copies we need to build + # this is a mess! + if 'multi_build' in self._config: + self._multi_build = self._config['multi_build'] + else: + self._multi_build = {self._config['short_name']: self._config['linker_script']} + + for s_name, s_script in self._multi_build.iteritems(): + self.current_build_name = s_name + + self._patches = [] + self._rel_patches = [] + self._hooks = [] + + self._create_hooks() + + self._link(s_name, s_script) + self._read_symbol_map() + + if self.dynamic_link_base: + self.dynamic_link = DyLinkCreator(self.dynamic_link_base) + self.dynamic_link.set_elf(open(self._currentOutFile, 'rb')) + + for hook in self._hooks: + hook.create_patches() + + self._create_patch(s_name) if delete_temp: shutil.rmtree(self._configTempDir) @@ -324,7 +343,10 @@ class KamekBuilder(object): print_debug('Building for configuration: '+config['friendly_name']) self.config_short_name = config['short_name'] - self._rel_area = (config['rel_area_start'], config['rel_area_end']) + if 'rel_area_start' in config: + self._rel_area = (config['rel_area_start'], config['rel_area_end']) + else: + self._rel_area = (-50, -50) def _create_hooks(self): @@ -355,11 +377,12 @@ class KamekBuilder(object): cc_command = ['%smwcceppc.exe' % mw_path, '-I.', '-I-', '-I.', '-nostdinc', '-Cpp_exceptions', 'off', '-Os', '-proc', 'gekko', '-fp', 'hard', '-enum', 'int', '-sdata', '0', '-sdata2', '0', '-g', '-RTTI', 'off', '-use_lmw_stmw', 'on'] as_command = ['%smwasmeppc.exe' % mw_path, '-I.', '-I-', '-I.', '-nostdinc', '-proc', 'gekko', '-d', '__MWERKS__'] - for d in self._config['defines']: - cc_command.append('-d') - cc_command.append(d) - as_command.append('-d') - as_command.append(d) + if 'defines' in self._config: + for d in self._config['defines']: + cc_command.append('-d') + cc_command.append(d) + as_command.append('-d') + as_command.append(d) for i in self._config['include_dirs']: cc_command.append('-I%s' % i) @@ -376,8 +399,9 @@ class KamekBuilder(object): cc_command = ['%s%s-g++' % (gcc_path, gcc_type), '-nodefaultlibs', '-I.', '-fno-builtin', '-Os', '-fno-exceptions', '-fno-rtti', '-mno-sdata'] as_command = cc_command - for d in self._config['defines']: - cc_command.append('-D%s' % d) + if 'defines' in self._config: + for d in self._config['defines']: + cc_command.append('-D%s' % d) for i in self._config['include_dirs']: cc_command.append('-I%s' % i) @@ -419,18 +443,22 @@ class KamekBuilder(object): print_debug('Compilation complete') - def _link(self): + def _link(self, short_name, script_file): print_debug('---') - print_debug('Linking project') - - self._mapFile = '%s/%s_linkmap.map' % (self._outDir, self.config_short_name) - outname = 'object.plf' if self.dynamic_link else 'object.bin' - self._outFile = '%s/%s_%s' % (self._outDir, self.config_short_name, outname) + print_debug('Linking %s (%s)...' % (short_name, script_file)) + + nice_name = '%s_%s' % (self._config['short_name'], short_name) + + print_debug('---') + + self._currentMapFile = '%s/%s_linkmap.map' % (self._outDir, nice_name) + outname = 'object.plf' if self.dynamic_link_base else 'object.bin' + self._currentOutFile = '%s/%s_%s' % (self._outDir, nice_name, outname) ld_command = ['%s%s-ld' % (gcc_path, gcc_type), '-L.'] ld_command.append('-o') - ld_command.append(self._outFile) - if self.dynamic_link: + ld_command.append(self._currentOutFile) + if self.dynamic_link_base: ld_command.append('-r') ld_command.append('--oformat=elf32-powerpc') else: @@ -438,9 +466,9 @@ class KamekBuilder(object): ld_command.append('-Ttext') ld_command.append('0x%08X' % self._builtCodeAddr) ld_command.append('-T') - ld_command.append(self._config['linker_script']) + ld_command.append(script_file) ld_command.append('-Map') - ld_command.append(self._mapFile) + ld_command.append(self._currentMapFile) ld_command.append('--no-demangle') # for debugging #ld_command.append('--verbose') ld_command += self._moduleFiles @@ -454,16 +482,16 @@ class KamekBuilder(object): print 'ld returned %d' % errorVal sys.exit(1) - print_debug('Linked successfully') - - + print_debug('Successfully linked %s' % short_name) + + def _read_symbol_map(self): print_debug('---') print_debug('Reading symbol map') self._symbols = [] - file = open(self._mapFile, 'r') + file = open(self._currentMapFile, 'r') for line in file: if '__text_start' in line: @@ -538,10 +566,12 @@ class KamekBuilder(object): self._patches.append((offset, data)) - def _create_patch(self): + def _create_patch(self, short_name): print_debug('---') print_debug('Creating patch') + nice_name = '%s_%s' % (self._config['short_name'], short_name) + # convert the .rel patches to KamekPatcher format if len(self._rel_patches) > 0: kamekpatch = generate_kamek_patches(self._rel_patches) @@ -550,38 +580,38 @@ class KamekBuilder(object): if self.dynamic_link: # put together the dynamic link files - dlcode = open('%s/%s_dlcode.bin' % (self._outDir, self._config['short_name']), 'wb') + dlcode = open('%s/%s_dlcode.bin' % (self._outDir, nice_name), 'wb') dlcode.write(self.dynamic_link.code) dlcode.close() - dlrelocs = open('%s/%s_dlrelocs.bin' % (self._outDir, self._config['short_name']), 'wb') + dlrelocs = open('%s/%s_dlrelocs.bin' % (self._outDir, nice_name), 'wb') dlrelocs.write(self.dynamic_link.build_reloc_data()) dlrelocs.close() else: # add the outfile as a patch if not using dynamic linking - file = open(self._outFile, 'rb') + file = open(self._currentOutFile, 'rb') patch = (self._codeStart, file.read()) file.close() self._patches.append(patch) # generate a Riivolution patch - riiv = open('%s/%s_riiv.xml' % (self._outDir, self._config['short_name']), 'w') + riiv = open('%s/%s_riiv.xml' % (self._outDir, nice_name), 'w') for patch in self._patches: riiv.write(generate_riiv_mempatch(*patch) + '\n') riiv.close() # generate an Ocarina patch - ocarina = open('%s/%s_ocarina.txt' % (self._outDir, self._config['short_name']), 'w') + ocarina = open('%s/%s_ocarina.txt' % (self._outDir, nice_name), 'w') for patch in self._patches: ocarina.write(generate_ocarina_patch(*patch) + '\n') ocarina.close() # generate a KamekPatcher patch - kpatch = open('%s/%s_loader.bin' % (self._outDir, self._config['short_name']), 'wb') + kpatch = open('%s/%s_loader.bin' % (self._outDir, nice_name), 'wb') kpatch.write(generate_kamek_patches(self._patches)) kpatch.close() |