[−][src]Module ckb_std::dynamic_loading
This module supports dynamic loading a library from an on-chain cell.
Pre-requirement
- Shared library: a standard ELF shared library, usually with a
.so
file extension (example of how to create a shared library). - Shared library cell: deploy the shared library to the chain.
- Transaction: use the CellDep field reference to the shared library cell.
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 |