mod bpf;
mod polkadot_wasm;
mod soroban_wasm;
use crate::Target;
use once_cell::sync::Lazy;
use std::ffi::CString;
use std::sync::Mutex;
static LINKER_MUTEX: Lazy<Mutex<i32>> = Lazy::new(|| Mutex::new(0i32));
pub fn link(input: &[u8], name: &str, target: Target) -> Vec<u8> {
let _lock = LINKER_MUTEX.lock().unwrap();
match target {
Target::Solana => bpf::link(input, name),
Target::Soroban => soroban_wasm::link(input, name),
Target::Polkadot {
address_length: _,
value_length: _,
} => polkadot_wasm::link(input, name),
_ => panic!("linker not implemented for target {:?}", target),
}
}
extern "C" {
fn LLDELFLink(args: *const *const libc::c_char, size: libc::size_t) -> libc::c_int;
}
pub fn elf_linker(args: &[CString]) -> bool {
let mut command_line: Vec<*const libc::c_char> = Vec::with_capacity(args.len() + 1);
let executable_name = CString::new("ld.lld").unwrap();
command_line.push(executable_name.as_ptr());
for arg in args {
command_line.push(arg.as_ptr());
}
unsafe { LLDELFLink(command_line.as_ptr(), command_line.len()) == 0 }
}
extern "C" {
fn LLDWasmLink(args: *const *const libc::c_char, size: libc::size_t) -> libc::c_int;
}
pub fn wasm_linker(args: &[CString]) -> bool {
let mut command_line: Vec<*const libc::c_char> = Vec::with_capacity(args.len() + 1);
let executable_name = CString::new("wasm-ld").unwrap();
command_line.push(executable_name.as_ptr());
for arg in args {
command_line.push(arg.as_ptr());
}
unsafe { LLDWasmLink(command_line.as_ptr(), command_line.len()) == 0 }
}