diff options
author | luckytyphlosion <10688458+luckytyphlosion@users.noreply.github.com> | 2018-07-22 09:20:33 -0400 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-07-22 09:20:33 -0400 |
commit | a586811e197d2a28d3a08dff03548fb69342da96 (patch) | |
tree | d5eec033243b0031afd3a82d47bbe1b7779d1675 /tools/fix_sections.py | |
parent | 5ec276e7c77244befe0b6c9931cda191aa3818b6 (diff) | |
parent | 5b4ef99f4bfec7a1cf41cd3eab601d355bb0fadf (diff) |
Merge pull request #38 from luckytyphlosion/section-reorg
Add linkerscript to replace completely anonymous sections.
Diffstat (limited to 'tools/fix_sections.py')
-rw-r--r-- | tools/fix_sections.py | 137 |
1 files changed, 137 insertions, 0 deletions
diff --git a/tools/fix_sections.py b/tools/fix_sections.py new file mode 100644 index 0000000..dc23f52 --- /dev/null +++ b/tools/fix_sections.py @@ -0,0 +1,137 @@ +import os, errno +import re +import fix_sections_directory + +os.chdir("..") +cwd = os.getcwd() + +debug_lines_startswith = [ + "SECTION ", + "else", + "SECTION ", + "endc" +] + +with open("pokegold-spaceworld-gen.link", "r") as f: + linkerscript = f.read() + +def clean_section(line, file, multiple): + global linkerscript + lines = line.lstrip().split("\"") + if "@" in lines[1] or file == lines[1] or file == "hram.asm" or file == "vram.asm" or file == "sram.asm": + file = lines[1] + else: + file += ("@" + lines[1]) if multiple else "" + + linkerscript = linkerscript.replace("\"" + lines[1] + "\"", "\"" + file + "\"") + if "ROMX" in lines[2]: + return "SECTION \"%s\", ROMX" % file + elif "HRAM" in lines[2]: + return "SECTION \"%s\", HRAM" % file + elif "VRAM" in lines[2]: + return "SECTION \"%s\", VRAM" % file + elif "ROM0" in lines[2]: + return "SECTION \"%s\", ROM0" % file + elif "SRAM" in lines[2]: + return "SECTION \"%s\", SRAM" % file + else: + raise + +TEMP_PATH = fix_sections_directory.TEMP_DIRECTORY + +for root, dirs, files in os.walk(cwd): + for file in files: + rel_root = os.path.relpath(root, cwd) + if not rel_root.startswith("build") and not rel_root.startswith("temp") and file.endswith(".asm") and file != "rst.asm" and file != "wram.asm" and file != "zero_checksum.asm": + canonical_path = os.path.join(root, file) + rel_path = os.path.relpath(canonical_path, cwd) + with open(canonical_path, "r") as f: + contents = f.read() + content_lines = contents.splitlines() + + if "SECTION" in contents: + print(canonical_path) + modify_flag = False + skip_next_line = False + for i, line in enumerate(content_lines): + if not skip_next_line: + if line.lstrip().startswith("SECTION"): + modify_flag = True + content_lines[i] = clean_section(content_lines[i], rel_path, contents.count("SECTION") > 1) + elif "if DEBUG" in line: + debug_content_lines = content_lines[i+1:i+5] + debug_code = False + for debug_content_line, debug_line_startswith in zip(debug_content_lines, debug_lines_startswith): + if not debug_content_line.lstrip().startswith(debug_line_startswith): + break + else: + modify_flag = True + content_lines[i] = "; " + content_lines[i] + content_lines[i+1] = clean_section(content_lines[i+1], rel_path, contents.count("SECTION") > 2) + content_lines[i+2] = "; " + content_lines[i+2] + content_lines[i+3] = "; " + content_lines[i+3] + content_lines[i+4] = "; " + content_lines[i+4] + skip_next_line = True + else: + skip_next_line = False + + if modify_flag: + output = "\n".join(content_lines) + print("rel root: " + rel_root) + try: + os.makedirs(TEMP_PATH + rel_root) + except OSError as e: + if e.errno != errno.EEXIST: + raise + + with open(TEMP_PATH + rel_path, "w+") as f: + f.write(output) + +linkerscript_lines = linkerscript.splitlines() + +i = 0 +clean_wram = False + +while i < len(linkerscript_lines): + line = linkerscript_lines[i] + if clean_wram: + if "org $dfff" not in line: + print(linkerscript_lines.pop(i)) + else: + clean_wram = False + i += 1 + elif "\"Shim for " in line: + no_pop_count = 0 + shim_addr = line.replace(", ", " ; ").split(" ; ")[1] + if linkerscript_lines[i-1] == "\torg " + shim_addr and linkerscript_lines[i-1] != "\torg $4000": + print(linkerscript_lines.pop(i-1)) + else: + no_pop_count += 1 + print(linkerscript_lines.pop(i-1 + no_pop_count)) + + if linkerscript_lines[i-1 + no_pop_count] == "\t; " + shim_addr: + print(linkerscript_lines.pop(i-1 + no_pop_count)) + else: + no_pop_count += 1 + + i -= 3 - no_pop_count + print("") + elif "ROMX" in line and "org $4000" not in linkerscript_lines[i+1]: + linkerscript_lines.insert(i+1, "\torg $4000") + i += 1 + elif line.startswith("WRAM0"): + linkerscript_lines.insert(i+1, "\torg $c000") + i += 1 + elif "\"Map Buffer\"" in line: + clean_wram = True + i += 1 + else: + i += 1 + +for i in range(len(linkerscript_lines)): + linkerscript_lines[i] = linkerscript_lines[i].split(" ; ")[0] + +linkerscript = "\n".join(linkerscript_lines) + "\n" + +with open(TEMP_PATH + "pokegold-spaceworld.link", "w+") as f: + f.write(linkerscript)
\ No newline at end of file |