Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to run a custom ELF file #1881

Open
Subway2023 opened this issue Dec 20, 2024 · 0 comments
Open

How to run a custom ELF file #1881

Subway2023 opened this issue Dec 20, 2024 · 0 comments

Comments

@Subway2023
Copy link

Component

sp1-zkvm

Describe the feature you would like

I want to write an ELF program to verify a LOAD bug. However, I find that the custom ELF program cannot be executed properly.

poc.s

.section .data
value:  .word 0x12345678    # Define a value in memory

.section .text
.globl _start
_start:
    # Initialize registers and stack
    li t0, 0x0            # Clear the t0 register
    li t1, 0x0            # Clear the t1 register

    # Load the value from memory into register t0
    la t2, value          # Load the address of value into t2 register
    lw t0, 0(t2)          # Load the memory value at address t2 into t0

    # Here you can insert an "invalid" modification to simulate a load error
    # Assume a bug where we directly modify the register's value, simulating a failed load
    li t0, 0xdeadbeef     # Forcefully set t0 to an erroneous value

    # Load the value from memory into t1 again, which should be 0x12345678
    lw t1, 0(t2)          # Normally load the memory value into t1

    # Compare the values of t0 and t1 to check if they are equal
    # At this point, t0 should be 0xdeadbeef while t1 should be 0x12345678
    beq t0, t1, _success  # If t0 == t1, jump to _success

_failure:
    # Output an error flag; the program will jump here
    li a0, 1              # Error return value 1
    ecall                 # System call, return 1 indicating an error
    j _end                # Jump to end

_success:
    # The program executes successfully, jumping here
    li a0, 0              # Normal return value 0
    ecall                 # System call, return 0 indicating success

_end:
    # Program execution finished, returning to the operating system
    li a7, 93             # Linux syscall number for exit
    ecall                 # System call to exit, returning the value in a0
riscv32-unknown-elf-as -o poc.o poc.s
riscv32-unknown-elf-ld -o poc.elf poc.o

main.rs. The test program is adapted from the example generated by cargo prove new --bare fibonacci.

//! An end-to-end example of using the SP1 SDK to generate a proof of a program that can be executed
//! or have a core proof generated.
//!
//! You can run this script using the following command:
//! ```shell
//! RUST_LOG=info cargo run --release -- --execute
//! ```
//! or
//! ```shell
//! RUST_LOG=info cargo run --release -- --prove
//! ```

use alloy_sol_types::SolType;
use clap::Parser;
use fibonacci_lib::PublicValuesStruct;
use sp1_sdk::{include_elf, ProverClient, SP1Stdin};

/// The ELF (executable and linkable format) file for the Succinct RISC-V zkVM.
pub const FIBONACCI_ELF: &[u8] = include_elf!("fibonacci-program");
pub const POC_ELF: &[u8] = include_bytes!("/mnt/sdd1/zkvm/poc/poc.elf");


/// The arguments for the command.
#[derive(Parser, Debug)]
#[clap(author, version, about, long_about = None)]
struct Args {
    #[clap(long)]
    execute: bool,

    #[clap(long)]
    prove: bool,

    #[clap(long, default_value = "20")]
    n: u32,
}

fn main() {
    // Setup the logger.
    sp1_sdk::utils::setup_logger();

    // Parse the command line arguments.
    let args = Args::parse();

    if args.execute == args.prove {
        eprintln!("Error: You must specify either --execute or --prove");
        std::process::exit(1);
    }

    // Setup the prover client.
    let client = ProverClient::new();

    // Setup the inputs.
    let mut stdin = SP1Stdin::new();
    stdin.write(&args.n);

    println!("n: {}", args.n);

    if args.execute {
        // Execute the program
        // let (output, report) = client.execute(FIBONACCI_ELF, stdin).run().unwrap();
        let (output, report) = client.execute(POC_ELF, SP1Stdin::new()).run().unwrap();
        println!("Program executed successfully.");
    } 
}

The execution result is as follows:

thread 'main' panicked at /root/.cargo/registry/src/mirrors.tuna.tsinghua.edu.cn-df7c3c540f42cdbd/sp1-core-executor-3.0.0/src/disassembler/rrs.rs:394:82:
called `Option::unwrap()` on a `None` value
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
2024-12-20T12:57:05.446853Z  INFO execute: close time.busy=170µs time.idle=3.56µs

May I ask where the problem lies, and how to run a custom ELF file?

Additional context

No response

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant