qilingframework / qilingframework/qiling

MIPS64 real-ELF (glibc) support depends on upstream unicorn vtlb fixes (unicorn #2272/#2347, #2345/#2346)

Open
#1,645 2 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Python
Stars
6.1k
Forks
798
Avg merge
1d 1h
Merged PRs (30d)
9

Description

Summary

Real-world (glibc / PIE) MIPS64 ELF support in Qiling depends on two upstream unicorn fixes that are not yet in a released unicorn. This issue tracks that cross-repo dependency so the MIPS64 work can rely on it once unicorn ships the fixes.

The MIPS64 shellcode and freestanding (syscall-only) static ELF paths already work on stock pip unicorn. The glibc-ELF paths (dynamic + PIE binaries, TLS setup, pthreads) do not — they trip two bugs in unicorn's virtual-TLB (UC_TLB_VIRTUAL) code path.

Background: why Qiling needs UC_TLB_VIRTUAL for MIPS64

unicorn's MIPS64 CPU-MMU only executes in the low ~2 GB (useg); at/above 0x80000000 it raises an address exception. But real n64 ELFs link at 0x120000000 (~4.8 GB) and PIE binaries load at 0x555555…, and Qiling's 64-bit profile places stack/mmap above 4 GB. The fix (in qiling/arch/mips64.py) is to switch the MIPS64 engine into UC_TLB_VIRTUAL mode with an identity-mapping UC_HOOK_TLB_FILL callback, which bypasses the CPU-MMU segment checks while keeping virtual == physical, so Qiling's flat memory model works unchanged.

Enabling that soft-TLB path is what exposed the two unicorn bugs below.

Blocking unicorn bugs

1. Spurious EXCP_RI after a delay-slot TLB fill — unicorn issue #2272, fix PR #2347.

glibc's __libc_setup_tls scans the program headers for PT_TLS using a bbne "branch-onto-branch" (back-to-back delay slots). Under UC_TLB_VIRTUAL, unicorn_fill_tlb() unconditionally called cpu_restore_state(); on a successful fill this re-injected the branch-delay hflags (MIPS_HFLAG_B|BDS32) into the live env, so the next translation block (the branch target) was generated with BMASK set → spurious Reserved-Instruction exception (intno 20). The RI vectors PC→0 and Qiling dies with UC_ERR_FETCH_UNMAPPED. The fix removes the unconditional restore (the exception path still restores via cpu_loop_exit_restore). (unicorn's own PR #2273 attempted #2272 but only covered the no-hook fallback path; #2347 fixes both the hooked and unhooked cases.)

2. Spurious AdEL on ll/lld from high addresses — unicorn issue #2345, fix PR #2346.

Right after TLS setup, glibc takes an ll/sc spinlock. ll/lld are emitted as helpers that perform the load through the soft-TLB (works), but also call do_translate_address purely to set CP0_LLAddr — and that walks the MIPS segments (xuseg, UX unset for a >2 GB address) → TLBRET_BADADDR → spurious address error (intno 12). The fix skips the segment-walking translate in vtlb mode and records the hook-mapped physical address into CP0_LLAddr instead (alignment check preserved, so a genuinely misaligned ll still faults correctly).

Both are contained to the UC_TLB_VIRTUAL path (not present in upstream QEMU, which has no such mode) and are in the same family.

Impact / CI gating

  • ✅ MIPS64 shellcode and freestanding static ELF tests pass on stock pip unicorn 2.1.3 and are safe for CI today.
  • ⛔ MIPS64 glibc-ELF tests (dynamic + PIE binaries, statx/stat64 end-to-end, multithreading) require the two unicorn fixes above and will fail on stock unicorn / CI until unicorn ships them in a release.

The eventual (reopened) MIPS64 arch PR should keep the glibc-ELF tests gated/held until a unicorn release includes both fixes, then flip them on and reference this issue.

Related Qiling fixes (independent — run on stock unicorn)

These were found while bringing MIPS64 up but are standalone and do not depend on the unicorn fixes: #1633 (statx big-endian), #1635 (getdents alignment), #1638 (clone3), #1640 (MIPS socket options).

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with qiling/arch/mips64.py and the upstream unicorn issues #2272 and #2345 plus fixes #2347 and #2346. Verify whether a unicorn release contains both fixes, then run the MIPS64 glibc-ELF, dynamic/PIE, statx/stat64, and multithreading tests; done means those tests can be enabled without failing on stock unicorn.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
reverse-engineering
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.