summaryrefslogtreecommitdiff
path: root/tools
diff options
context:
space:
mode:
authorTreeki <treeki@gmail.com>2012-07-08 02:46:59 +0200
committerTreeki <treeki@gmail.com>2012-07-08 02:46:59 +0200
commit613e30a894cddcdc11c8da140bae35090247c8ec (patch)
tree274cbfccc9e1795d13e1f2fe69d172d4b469877a /tools
parent1c3e5a0b1c62829d78960c4d99e4928ccf73625f (diff)
downloadkamek-613e30a894cddcdc11c8da140bae35090247c8ec.tar.gz
kamek-613e30a894cddcdc11c8da140bae35090247c8ec.zip
added PALv2, made Kamek link all regions at the same time
Diffstat (limited to 'tools')
-rwxr-xr-xtools/hooks.py24
-rw-r--r--tools/kamek.py128
-rwxr-xr-xtools/mapfile_tool.py14
3 files changed, 102 insertions, 64 deletions
diff --git a/tools/hooks.py b/tools/hooks.py
index 388efcb..7252489 100755
--- a/tools/hooks.py
+++ b/tools/hooks.py
@@ -48,10 +48,10 @@ class Hook(object):
self.context.hooks.append(self)
# validate the hook's data
- current_config_name = builder.config_short_name
+ current_build_name = builder.current_build_name
for field in self.required_data:
- field = field.replace('%CONFIG%', current_config_name)
+ field = field.replace('%BUILD%', current_build_name)
if field not in data:
raise ValueError, 'hook %s : %s is missing the field %s' % (module.moduleName, data['name'], field)
@@ -63,13 +63,13 @@ class Hook(object):
class BasicPatchHook(Hook):
"""Hook that simply patches data to an address"""
- required_data = ['addr_%CONFIG%', 'data']
+ required_data = ['addr_%BUILD%', 'data']
def __init__(self, builder, module, data):
Hook.__init__(self, builder, module, data)
def create_patches(self):
- addr = self.data['addr_%s' % self.builder.config_short_name]
+ addr = self.data['addr_%s' % self.builder.current_build_name]
hex_data = self.data['data']
@@ -86,7 +86,7 @@ class BasicPatchHook(Hook):
class BranchInsnHook(Hook):
"""Hook that replaces the instruction at a specific address with a branch"""
- required_data = ['branch_type', 'src_addr_%CONFIG%']
+ required_data = ['branch_type', 'src_addr_%BUILD%']
def __init__(self, builder, module, data):
Hook.__init__(self, builder, module, data)
@@ -95,9 +95,9 @@ class BranchInsnHook(Hook):
try:
target_func = self.data['target_func']
except KeyError:
- target_func = self.data['target_func_%s' % self.builder.config_short_name]
+ target_func = self.data['target_func_%s' % self.builder.current_build_name]
- src_addr = self.data['src_addr_%s' % self.builder.config_short_name]
+ src_addr = self.data['src_addr_%s' % self.builder.current_build_name]
is_symbol_name = isinstance(target_func, str)
if is_symbol_name:
@@ -118,7 +118,7 @@ class BranchInsnHook(Hook):
class AddFunctionPointerHook(Hook):
"""Hook that places a function pointer at an address"""
- required_data = ['src_addr_%CONFIG%']
+ required_data = ['src_addr_%BUILD%']
def __init__(self, builder, module, data):
Hook.__init__(self, builder, module, data)
@@ -127,9 +127,9 @@ class AddFunctionPointerHook(Hook):
try:
target_func = self.data['target_func']
except KeyError:
- target_func = self.data['target_func_%s' % self.builder.config_short_name]
+ target_func = self.data['target_func_%s' % self.builder.current_build_name]
- src_addr = self.data['src_addr_%s' % self.builder.config_short_name]
+ src_addr = self.data['src_addr_%s' % self.builder.current_build_name]
is_symbol_name = isinstance(target_func, str)
if is_symbol_name:
@@ -146,13 +146,13 @@ class AddFunctionPointerHook(Hook):
class NopInsnHook(Hook):
"""Hook that NOPs out the instruction(s) at an address"""
- required_data = ['area_%CONFIG%']
+ required_data = ['area_%BUILD%']
def __init__(self, builder, module, data):
Hook.__init__(self, builder, module, data)
def create_patches(self):
- area = self.data['area_%s' % self.builder.config_short_name]
+ area = self.data['area_%s' % self.builder.current_build_name]
if isinstance(area, list):
addr, end = area
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()
diff --git a/tools/mapfile_tool.py b/tools/mapfile_tool.py
index 3556d0d..41eff5a 100755
--- a/tools/mapfile_tool.py
+++ b/tools/mapfile_tool.py
@@ -9,8 +9,16 @@ def make_hex_offset(offs):
return '0x%08X' % offs
def fix_offs_pal_v2(offs):
- # do this later
- return 0xdeadbeef
+ if offs >= 0x807685A0 and offs <= 0x807AAA70:
+ return offs + 0x40
+
+ if offs >= 0x807AAA74 and offs <= 0x809907FF:
+ return offs + 0x10
+
+ if offs >= 0x80990800:
+ return offs + 0x20
+
+ return offs
def fix_offs_ntsc_v1(offs):
# .text section
@@ -192,7 +200,7 @@ import yaml
original = 'pal'
fix_for = {
- 'pal2': fix_offs_ntsc_v1,
+ 'pal2': fix_offs_pal_v2,
'ntsc': fix_offs_ntsc_v1,
'ntsc2': fix_offs_ntsc_v2,
'jpn': fix_offs_jpn_v1