Skip to content

Invalid ELF Headers when precompiling components #11300

@anlavandier

Description

@anlavandier

Test Case

Wasm Component bytecode
Wasm Component source code
All the relevant code I used is in this repo

Steps to Reproduce

  • (Optional) Build the component from source using cargo-component build.
$ cargo-component --version
cargo-component 0.21.1
  • First precompile the component using cranelift : wasmtime = { version = "34.0.1", default-features = false, features = ["runtime", "component-model", "pulley", "cranelift"] }
fn main() -> Result<()> {
    let mut config = Config::new();
    if let Err(error) = config.target("pulley32") {
        eprintln!(
            "this Wasmtime was not built with the correct compiler backend \
             enabled: {error:?}",
        );
        return Ok(());
    }

    // Create an `Engine` with that configuration.
    let engine = match Engine::new(&config) {
        Ok(engine) => engine,
        Err(error) => {
            println!("Wasmtime build is incompatible with config: {error:?}");
            return Ok(());
        }
    };

    // Pre-compile a Wasm program.
    let wasm = include_bytes!("../../add/target/wasm32-wasip1/release/add.wasm");

    let precompiled = engine.precompile_component(wasm)?;

    // Write the pre-compiled program to a file.
    //
    // Note that the `.cwasm` extension is conventional for these files, and is
    // what the Wasmtime CLI will use by default, for example.
    std::fs::write("add_wasm32-wasip1.cwasm", &precompiled)?;

    // And we are done -- now a different Wasmtime embedding can load and run
    // the pre-compiled Wasm program from that `add.cwasm` file!
    Ok(())
}
  • Second try to parse the Precompiled Component in another instance. wasmtime = { version = "34.0.2", default-features = false, features = ["runtime", "component-model", "pulley"] }
use wasmtime::{component::Component, *};

fn main () {
    if let Err(e) = run_wasmtime() {
        println!("{:?}", defmt::Debug2Format(&e))
    }
}


fn run_wasmtime() -> wasmtime::Result<()> {
    let mut config = Config::default();

    config.target("pulley32")?;
    let engine = Engine::new(&config)?;
    let component_bytes  = include_bytes!("../../component-add/add_wasm32-wasip1.cwasm");

    let _component = match unsafe { Component::deserialize_raw(&engine, component_bytes.as_slice().into()) } {
        Ok(comp) => comp,
        Err(error) => {
            println!("failed to deserialize pre-compiled module: {:?}", defmt::Debug2Format(&error));
            return Ok(());
        }
    };
    println!("Deserialized Component");
    Ok(())
}

Expected Results

See Deserialized Component on stdout

Actual Results

failed to deserialize pre-compiled module: failed to parse precompiled artifact as an ELF

Caused by:
    Invalid ELF header size or alignment

Versions and Environment

Wasmtime version or commit: 34.0.1

Operating system: Ubuntu 22.04 LTS

Architecture: x86_64

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugIncorrect behavior in the current implementation that needs fixing

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions