Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Can we get support for loading gameboy SYM symbol files via a script or feature of the plugin? #11

Open
ILOVEPIE opened this issue Jan 29, 2023 · 1 comment

Comments

@ILOVEPIE
Copy link

Being able to load symbol files would be very helpful.

@ILOVEPIE
Copy link
Author

ILOVEPIE commented Jan 30, 2023

This works, but for this script to work the xram needs to be correctly banked.

##
# Imports a text file containing symbol definitions for Gameboy.
# @author ILOVEPIE <patrick.martin.r@gmail.com>
# @category Data
#

from ghidra.program.model.symbol.SourceType import *
import string

globalsyms = {}

def normalGetPrefix(bank,address,name):
    endoffset = 0
    if name.lower().endswith("end"):
        endoffset = 1
    if address <= 0x3fff+endoffset:
        return "rom0",address
    if address >= 0x4000 and address <= 0x7FFF+endoffset:
        return "rom"+str(max(1,bank)),address
    if address >=0x8000 and address <= 0x9FFF+endoffset:
        return "vram",address
    if address >=0xA000 and address <= 0xBFFF+endoffset:
        return "xram"+str(bank),address
    if address >=0xC000 and address <= 0xCFFF+endoffset:
        return "wram0",address
    if address >=0xD000 and address <= 0xDFFF+endoffset:
        return "wram"+str(max(1,bank)),address
    if address >=0xE000 and address <= 0xFDFF+endoffset:
        # TODO: figgure echo ram out later.
        return "eram",address
    if address >= 0xFE00 and address <= 0xFE9F+endoffset:
        return "oam",address
    if address >= 0xFEA0 and address <= 0xFEFF+endoffset:
        return "unk",address
    if address >= 0xFF00 and address <= 0xFF7F+endoffset:
        return "io",address
    if address >= 0xFF80 and address <= 0xFFFE+endoffset:
        return "hram",address
    if address >= 0xFFFF and address <= 0xFFFF+endoffset:
        return "ie",address
    raise Exception("Unrecongnized address 0x"+hex(address)+" for symbol '"+name+"'.")

def getPrefix(bank,address,name):
    result = ("undef",address)
    globalsym = name
    if "." in name:
        (globalsym,name) = name.split('.',1)
        (globalsymbank,globalsymaddress,globalsymprefix) = globalsyms[globalsym]
        if globalsymaddress is not None:
            if globalsymaddress <= address:
                if globalsymbank is None and bank is None:
                    result = (None,address)
                elif globalsymbank is not None and bank is not None:
                    result = (globalsymprefix,address)
                else:
                    raise Exception("local symbol '"+globalsym+"."+name+"has no global parent.")
            else:
                raise Exception("local symbol '"+globalsym+"."+name+"has no global parent.")
        else:
            raise Exception("local symbol '"+globalsym+"."+name+"has no global parent.")
    else:
        result = normalGetPrefix(bank,address,name)
    if name == globalsym:
        (prefix,address) = result
        globalsyms[name] = (bank,address,prefix)
    return result
        
    

functionManager = currentProgram.getFunctionManager()

f = askFile("Please select a .SYM file", "Import")

for line in file(f.absolutePath): 
    pieces = line.split()

    name = pieces[1]
    (bank,address) = pieces[0].split(':')
    if address is None:
        address = int(bank,16)
        bank = None
        address = toAddr(address)
    elif bank == "BOOT":
        # what do we do if it's the boot rom?
        continue
    else:
        bank = int(bank,16)
        address = int(address,16)
        prefix,address = getPrefix(bank,address,name)
        if prefix is not None:
            address = prefix+":"+hex(address)
        address = toAddr(address)
	

    if address is not None:
        func = functionManager.getFunctionAt(address)
        if func is not None:
            old_name = func.getName()
            func.setName(name, USER_DEFINED)
            print("Renamed function {} to {} at address {}".format(old_name, name, address))
        else:
            print("Created label {} at address {}".format(name, address))
            createLabel(address, name, False)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant