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

Using Unicorn with MIPS64 #2109

Closed
OBarronCS opened this issue Feb 16, 2025 · 8 comments
Closed

Using Unicorn with MIPS64 #2109

OBarronCS opened this issue Feb 16, 2025 · 8 comments

Comments

@OBarronCS
Copy link
Contributor

OBarronCS commented Feb 16, 2025

I have been attempting to get Unicorn to execute 64-bit MIPS code, and couldn't find instances of its usage in the codebase. Upon starting the emulator in the MIPS setting with UC_MODE_64, it always throws an UC_ERR_EXCEPTION immediately upon starting the emulator.

Here is a simple program to test this.

#!/usr/bin/env python3
from unicorn import *
from unicorn.mips_const import *

emu = Uc(UC_ARCH_MIPS, UC_MODE_64 | UC_MODE_BIG_ENDIAN)

code = b'\x00\x00\x00\x00' * 2  # NOP instruction in MIPS

ADDRESS = 0x10000
emu.mem_map(ADDRESS, 4 * 1024) 
emu.mem_write(ADDRESS, code)

# emu.reg_write(UC_MIPS_REG_CP0_STATUS, 0b0011_0100_1000_0000_0000_0000_0011_0000)
emu.reg_write(UC_MIPS_REG_PC, ADDRESS)

try:
    emu.emu_start(ADDRESS, 0, count=1)
except Exception as e:
    print(e)

print(f"PC: {hex(emu.reg_read(UC_MIPS_REG_PC))}")

Is there any guidance on setting up 64 bit MIPS in Unicorn?

On a quick search, MIPS seems to have a "Status Register" that has certain bits that enables 64-bit mode in certain scenarios - the flags are outlined in page 91 of this manual https://scc.ustc.edu.cn/_upload/article/files/c6/06/45556c084631b2855f0022175eaf/W020100308600770617815.pdf
Image

However, setting the various bits of CP0_STATUS seem to have no effect.

@wtdcode
Copy link
Member

wtdcode commented Feb 16, 2025

@OBarronCS
Copy link
Contributor Author

OBarronCS commented Feb 16, 2025

I am mapping a memory address that is small enough that it would not be redirected by the MIPS TLB, which is the problem that all the linked issues ran into in the docs you mentioned (they all use 32-bit). The address, 0x10000, should not be changed when mappings from virtual to physical in the MIPS TLB mapping. The code snippet works if you swap UC_MODE_64 to UC_MODE_32.

@OBarronCS
Copy link
Contributor Author

OBarronCS commented Feb 16, 2025

This might be helpful:

When enabling the TLB_VIRTUAL mode, it throws an error and the resulting PC value has a different output address afterwards everytime:

#!/usr/bin/env python3
from unicorn import *
from unicorn.mips_const import *

emu = Uc(UC_ARCH_MIPS, UC_MODE_64 | UC_MODE_BIG_ENDIAN)
emu.ctl_set_tlb_mode(UC_TLB_VIRTUAL)

def hook(uc, vaddr, a, b, c):
    print(hex(vaddr), a, b, c)
    return True
emu.hook_add(UC_HOOK_TLB_FILL, hook)

code = b'\x00\x00\x00\x00' * 2  # NOP instruction in MIPS

ADDRESS =  0x1000
emu.mem_map(ADDRESS, 4 * 1024)
emu.mem_write(ADDRESS, code)

try:
    emu.emu_start(ADDRESS, 0, count=1)
except Exception as e:
    print(e)

print(f"PC: {hex(emu.reg_read(UC_MIPS_REG_PC))}")

Running this script multiple times, the resulting PC has the top portion different each time - might indicate something being cobbled internally.

0x75575f0000001000
0xe4dee70000001000
0x9353f30000001000
0x3529c60000001000
...

This behavior does not appear in MIPS_32

@OBarronCS
Copy link
Contributor Author

OBarronCS commented Feb 16, 2025

I found the culprit -

unicorn/uc.c

Lines 1021 to 1026 in 8d52ece

#ifdef UNICORN_HAS_MIPS
case UC_ARCH_MIPS:
// TODO: MIPS32/MIPS64/BIGENDIAN etc
uc_reg_write(uc, UC_MIPS_REG_PC, &begin_pc32);
break;
#endif

The register width being written for 64-bit is incorrect. Tested a fix that works and made a PR - #2111

@wtdcode
Copy link
Member

wtdcode commented Feb 21, 2025

Anything left for this?

@OBarronCS
Copy link
Contributor Author

OBarronCS commented Feb 22, 2025

MIPS64 now works great with UC_VIRTUAL_TLB enabled. Without this enabled, high addresses will cause incorrect memory address lookups, and I'll make another issue to describe this in case future contributors need more accurate MIPS64 MMU logic.

@OBarronCS
Copy link
Contributor Author

Made the issue here - #2119

@wtdcode
Copy link
Member

wtdcode commented Feb 22, 2025

Thanks for providing the details. I will have a look at the new issue and close this issue.

@wtdcode wtdcode closed this as completed Feb 22, 2025
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

2 participants