fold/docs/internal/swift-abi-research.md
trvon 18ce5a6050
docs: Swift/C++ ABI, fuzzing, IR, MIR research for multi-language pipeline
- Swift ABI: tagged pointers, garbage-input abort path, ObjC bridging
- C++ fuzz: libFuzzer dlopen coverage limits, AFL++ QEMU mode, vtable seeding
- Cross-language IR: CodeQL/Infer/Joern patterns, Swift SIL gaps in fold IR
- MIR verification: Kani/Prusti/Creusot approaches, BorrowTracker wiring
2026-05-28 10:28:41 -04:00

1.9 KiB

Swift ABI Research for Binary Fuzzing

Generated 2026-05-28. Reference for Swift binary fuzzing.

Calling Convention (ARM64)

  • x0: self parameter (the object reference)
  • x1-x7: additional arguments
  • x21: error return register (for throwing functions)
  • x0 also used for return value

Tagged Pointer Format

Swift uses tagged pointers on ARM64:

  • Small values (integers, bools): stored inline in pointer bits
  • Small objects (strings < 15 bytes): stored inline
  • Regular objects: pointer to heap-allocated metadata

Bits 60-62 discriminate the tag:

  • 0b000 = regular heap pointer
  • 0b001 = small value
  • 0b010 = small object

Garbage Input Behavior

When the fuzzer passes random uint64_t as self:

  1. Swift runtime attempts to dereference the "pointer" as type metadata
  2. If the bit pattern doesn't match valid metadata → swift_unexpectedError()
  3. This calls abort() — SIGABRT, not SIGSEGV
  4. libFuzzer's default signal handler catches SIGABRT but the coverage counters show cov:2 because the abort happens before any real code executes

Tooling

  • swift demangle: demangles Swift symbol names
  • Frida: can hook ObjC methods via ObjC.classes.FuzzMeClass
  • lldb -o "expr": expression evaluation against Swift objects

IRGen Patterns

  • Value witness tables: manage copy/destroy/assign for generic types
  • Existential containers: type-erased protocol values
  • SILGen: Swift AST → SIL lowering pass, then SIL → LLVM IR

Implications for fold

  1. Swift-mangled symbols are unfuzzable via dlopen: need ObjC bridging or Swift-source harness generation
  2. ObjC interop path works: our objc_msgSend harness routes through the ObjC runtime which handles nil receivers gracefully
  3. C-ABI exports work: @_cdecl functions are safe dlopen targets
  4. Future: Swift-source harness generation with swiftc -emit-library could construct valid objects