Skip to content

feat(analysis): implement Golang ABI calling conventions and prologue voting - #6830

Open
doomedraven wants to merge 8 commits into
rizinorg:devfrom
doomedraven:feature/golang-abi-support
Open

doomedraven wants to merge 8 commits into
rizinorg:devfrom
doomedraven:feature/golang-abi-support

Conversation

@doomedraven

@doomedraven doomedraven commented Oct 3, 2026 •

Copy link
Copy Markdown

Your checklist for this pull request

  • I've read the guidelines for contributing to this repository.
  • I made sure to follow the project's coding style.
  • I've documented every RZ_API function and struct this PR changes.
  • I've added tests that prove my changes are effective (required for changes to RZ_API).
  • I've updated the Rizin book with the relevant information (if needed).
  • I've used AI tools to generate fully or partially these code changes and I'm sure the changes are not copyrighted by somebody else.

Detailed description
This PR implements native Go calling convention support and automatic ABI detection for compiled Golang binaries across x86-64, ARM64, and x86-32.

Note: This PR is linked to companion rz-ghidra PR: rizinorg/rz-ghidra#395 for Sleigh decompiler prototype integration.

Problem

Previously, Rizin analyzed Go functions using default host C calling conventions (e.g. System V AMD64 or Microsoft x64 with single RAX return).
Go 1.17+ introduced ABIInternal, a register-based calling convention passing up to 9 integer arguments across registers (RAX, RBX, RCX, RDI, RSI, R8, R9, R10, R11) and returning multiple values across registers. Additionally, Go 1.16 and 1.17 share the same pclntab header magic (0xFFFFFFFA), making it difficult to distinguish stack-based ABI0 from register-based ABIInternal when build information is stripped or obfuscated.

Changes

  1. Calling Conventions in SDB:
    • librz/arch/types/cc-x86-64.sdb.txt: Added golang (RAX–R11, ret=rax, self=r14) and golang_abi0.
    • librz/arch/types/cc-arm-64.sdb.txt: Added golang (X0–X15, ret=x0, self=x28).
    • librz/arch/types/cc-x86-32.sdb.txt: Added golang (stack, ret=eax).
  2. Prologue Voting Heuristic (librz/core/golang.c):
    • Samples the first 24 bytes of recovered Go function prologues to reliably detect active ABI:
      • 49 3B 66 10 / 4D 3B 66 10 (CMPQ SP|R12, 16(R14)): Register ABI (R14 holds g).
      • 65 48|4C 8B /r with SIB 0x25 (MOVQ GS:[disp32], reg): Stack ABI (loads g from TLS).
    • Decisive threshold (>=8 votes, >=90% agreement) resolves the ABI accurately even if build headers are wiped (inspired by heuristics in CAPEmom PR Implement dynamic Go (Golang) stripped symbol recovery and tracing kevoreilly/capemon#181).
  3. Symbol Noise Filtering:
    • Filters out compiler-generated thunk wrappers (.abi0, .abiinternal, ..inittask, type:*) from deep function analysis to keep the symbol table clean.
  4. Automatic Assignment:
    • Automatically sets fcn->cc = "golang" (or "golang_abi0") on all functions discovered via pclntab.

Test plan

  • Ran full test suite: meson test -C build --suite unit -> 138/138 passed.
  • Validated with live Go 1.26 binary: aalg correctly detects Register ABI and tags sym.main.* with call-convention: golang.
  • Added test in test/db/analysis/golang to check golang calling convention detection.

Closing issues

… voting

- Define golang (ABIInternal) and golang_abi0 calling conventions in SDB for x86-64, ARM64, and x86-32
- Implement statistical prologue voting heuristic across sampled Go functions to automatically distinguish ABIInternal from ABI0 on stripped/obfuscated binaries
- Automatically assign detected Go calling convention to recovered sym.go.* functions
- Filter compiler-generated wrapper symbols (.abi0, .abiinternal, ..inittask, type:*) from deep function analysis
- Linked to rz-ghidra PR for SLEIGH decompiler prototype integration
@doomedraven
doomedraven force-pushed the feature/golang-abi-support branch from 61d99c4 to 51c70a1 Compare October 4, 2026 06:37
Comment thread librz/core/golang.c Outdated
Comment thread librz/core/golang.c Outdated
Comment thread librz/core/golang.c Outdated
Comment thread librz/core/golang.c
Comment thread test/db/analysis/golang Outdated
Comment thread librz/core/golang.c Outdated
Comment thread librz/core/golang.c Outdated
@doomedraven

Copy link
Copy Markdown
Author

Addressed the early return comment. Tests pass locally.

@doomedraven

Copy link
Copy Markdown
Author

Addressed the minor review comments: used RZ_STR_ISEMPTY and stripped the Rz prefix from the internal struct names.

@doomedraven

Copy link
Copy Markdown
Author

Removed the // Skip compiler-generated thunk wrappers and runtime metadata comment.

@doomedraven
doomedraven requested a review from wargio October 4, 2026 11:39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants