wasmerio/wasmer · error

Unsupported libcall

Error message

Unsupported libcall

What it means

irlibcall_to_libcall converts Cranelift's internal ir::LibCall values into the compiler-agnostic LibCall representation used for relocations. Any LibCall not explicitly mapped (mostly float intrinsics beyond floor/trunc/nearest) hits the `_ => panic!("Unsupported libcall")` arm. It runs during relocation processing (mach_reloc_to_reloc), so it surfaces at the end of compilation when externalized calls are being resolved.

Source

Thrown at lib/compiler-cranelift/src/translator/translation_utils.rs:101

        Type::ExternRef | Type::FuncRef => reference_type(target_config),
        Type::ExceptionRef => Ok(EXN_REF_TYPE),
        // ty => Err(wasm_unsupported!("type_to_type: wasm type {:?}", ty)),
    }
}

/// Transform Cranelift LibCall into runtime LibCall
pub fn irlibcall_to_libcall(libcall: ir::LibCall) -> LibCall {
    match libcall {
        ir::LibCall::Probestack => LibCall::Probestack,
        ir::LibCall::CeilF32 => LibCall::CeilF32,
        ir::LibCall::CeilF64 => LibCall::CeilF64,
        ir::LibCall::FloorF32 => LibCall::FloorF32,
        ir::LibCall::FloorF64 => LibCall::FloorF64,
        ir::LibCall::TruncF32 => LibCall::TruncF32,
        ir::LibCall::TruncF64 => LibCall::TruncF64,
        ir::LibCall::NearestF32 => LibCall::NearestF32,
        ir::LibCall::NearestF64 => LibCall::NearestF64,
        _ => panic!("Unsupported libcall"),
    }
}

/// Transform Cranelift Reloc to compiler Relocation
pub fn irreloc_to_relocationkind(reloc: Reloc) -> RelocationKind {
    match reloc {
        Reloc::Abs4 => RelocationKind::Abs4,
        Reloc::Abs8 => RelocationKind::Abs8,
        Reloc::X86PCRel4 => RelocationKind::PCRel4,
        Reloc::X86CallPCRel4 => RelocationKind::X86CallPCRel4,
        Reloc::X86CallPLTRel4 => RelocationKind::X86CallPLTRel4,
        Reloc::X86GOTPCRel4 => RelocationKind::X86GOTPCRel4,
        Reloc::Arm64Call => RelocationKind::Arm64Call,
        Reloc::RiscvCallPlt => RelocationKind::RiscvCall,
        _ => panic!("The relocation {reloc} is not yet supported."),
    }
}

View on GitHub (pinned to 8c4b9ee9d3)

Solutions

  1. Upgrade Wasmer (and its cranelift dependency) so newly added LibCall variants are mapped.
  2. Compile with a target CPU that has native float instructions (enable SSE2/softfloat disabled) to avoid libcalls.
  3. Change compiler flags/backends so the failing operation is lowered inline rather than to a libcall.
  4. If reproducible, file an issue including the target triple and the operation that triggers the missing libcall.

Example fix

// before
let target = Target::new(triple, EnumSet::new()); // soft-float-ish, no FP features
// after
let mut feats = EnumSet::new();
feats.insert(CpuFeature::SSE2);
let target = Target::new(triple, feats); // float ops lowered inline, no libcall reloc
Defensive patterns

Strategy: fallback

Validate before calling

// Avoid soft-float targets that force unmapped libcalls:
fn target_needs_native_float(feats: &EnumSet<CpuFeature>, triple: &Triple) -> bool {
    matches!(triple.architecture, Architecture::X86_64) && !feats.contains(CpuFeature::SSE2)
}

Prevention

When it happens

Trigger: Compilation where the Cranelift backend emits a machine relocation referencing an ir::LibCall variant with no mapping in irlibcall_to_libcall (called from mach_reloc_to_reloc) — e.g. an unmapped math intrinsic like powi, memset, or sqrt variant on a target that lowered an operation to a libcall.

Common situations: Soft-float targets (no native FP instructions) that lower float ops to libcalls not covered by the mapping; newer Cranelift versions adding LibCall variants before Wasmer's mapping is updated; unusual compiler flag combinations enabling float ops on targets lacking them.

Related errors


AI-assisted analysis of wasmerio/wasmer@8c4b9ee9d3 (2026-09-01). Data as JSON: /api/errors/690947ceb1512a47. Report an issue: GitHub.