[][src]Module ckb_std::dynamic_loading

This module supports dynamic loading a library from an on-chain cell.

Pre-requirement

Example

Shared library(C)

typedef unsigned long size_t;

__attribute__((visibility("default"))) int
plus_42(size_t num) {
  return 42 + num;
}

__attribute__((visibility("default"))) char *
foo() {
  return "foo";
}

Rust contract

use ckb_std::dynamic_loading::{CKBDLContext, Symbol};

/// code hash of the shared library
pub const CODE_HASH_SHARED_LIB: [u8; 32] = [235, 179, 185, 44, 159, 213, 242, 94, 42, 196, 68, 5, 213, 248, 71, 106, 136, 183, 99, 125, 37, 214, 63, 59, 57, 87, 65, 80, 177, 92, 23, 255];

// create a dynamic loading context instance
// we use [u8; 64 * 1024] as the buffer to receive the code, the size of the buffer must be
// aligned to PAGE_SIZE 4096, otherwise will return an error.
//
// NOTICE: CKB-VM using a W^X memory model, after loading code into memory pages, these pages can't
// be deallocated, which means we should never drop a CKBDLContext instance, otherwise a
// InvalidPermission error will occuer to terminate our script.
//
// [W^X memory model](https://github.com/nervosnetwork/rfcs/blob/master/rfcs/0003-ckb-vm/0003-ckb-vm.md#wx-memory)
let mut context = CKBDLContext::<[u8; 64 * 1024]>::new();

// load a shared library from dep cells
let lib = context.load(&CODE_HASH_SHARED_LIB).expect("load shared lib");

unsafe {
    type Plus42 = unsafe extern "C" fn(n: usize) -> usize;
    let plus_42: Symbol<Plus42> = lib.get(b"plus_42").expect("find plus_42");
    assert_eq!(plus_42(13), 13 + 42);

    type Foo = unsafe extern "C" fn() -> *const u8;
    let foo: Symbol<Foo> = lib.get(b"foo").expect("find foo");
    let ptr = foo();
    let mut buf = [0u8; 3];
    buf.as_mut_ptr().copy_from(ptr, buf.len());
    assert_eq!(&buf[..], b"foo");
}

The core part of this module is inspired from https://github.com/nervosnetwork/ckb-c-stdlib/blob/eae8c4c974ce68ca8062521747a16e8e59de755f/ckb_dlfcn.h

The ELF parsing code is inspired from https://github.com/riscv/riscv-pk/blob/master/pk/elf.h original code is in BSD license.

Structs

CKBDLContext

Dynamic loading context T represent a buffer type, for example: [u8; 64 * 1024], the size of T must aligned with PAGE_SIZE 4096.

Library

Dynamic loaded library

Symbol

Wrapper of dynamic loaded symbols

Enums

Error

Dynamic loading errors