summaryrefslogtreecommitdiff
path: root/tools/kamek.py
diff options
context:
space:
mode:
Diffstat (limited to 'tools/kamek.py')
-rw-r--r--tools/kamek.py128
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()