native: export generated FFI symbols
ober
705393265c765b733ea4c0b04ec29c24195f0bc2
--- a/jerboa-native-rs/src/aproc.rs +++ b/jerboa-native-rs/src/aproc.rs @@ -1024,6 +1024,7 @@ pub extern "C" fn jerboa_aproc_spawn_pty( } /// dup(2) — returns the new fd, or -1 on error. +#[no_mangle] pub extern "C" fn jerboa_aproc_dup(fd: i32) -> i32 { ffi_wrap(|| { // SAFETY: dup(2) validates the descriptor number; errors are surfaced @@ -1041,6 +1042,7 @@ pub extern "C" fn jerboa_aproc_dup(fd: i32) -> i32 { } /// close(2) — returns 0 on success, -1 on error. +#[no_mangle] pub extern "C" fn jerboa_aproc_close(fd: i32) -> i32 { // SAFETY: close(2) validates the descriptor number. Ownership is governed // by the Scheme caller; this wrapper forwards the syscall result. --- a/jerboa-native-rs/src/crypto.rs +++ b/jerboa-native-rs/src/crypto.rs @@ -55,6 +55,7 @@ fn digest_impl( }) } +#[no_mangle] pub extern "C" fn jerboa_md5( _input: *const u8, _input_len: usize, @@ -113,6 +114,7 @@ fn next_sha256_context() -> u64 { } /// Allocate an opaque incremental SHA-256 context handle. +#[no_mangle] pub extern "C" fn jerboa_sha256_ctx_new() -> u64 { match std::panic::catch_unwind(|| { let handle = next_sha256_context(); @@ -128,6 +130,7 @@ pub extern "C" fn jerboa_sha256_ctx_new() -> u64 { } /// Add one chunk to an incremental SHA-256 context. +#[no_mangle] pub extern "C" fn jerboa_sha256_ctx_update(handle: u64, input: *const u8, input_len: usize) -> i32 { ffi_wrap(|| { if input.is_null() && input_len > 0 { @@ -152,6 +155,7 @@ pub extern "C" fn jerboa_sha256_ctx_update(handle: u64, input: *const u8, input_ } /// Finalize and consume an incremental SHA-256 context. +#[no_mangle] pub extern "C" fn jerboa_sha256_ctx_final(handle: u64, output: *mut u8, output_len: usize) -> i32 { ffi_wrap(|| { if output.is_null() || output_len < digest::SHA256_OUTPUT_LEN { @@ -176,6 +180,7 @@ pub extern "C" fn jerboa_sha256_ctx_final(handle: u64, output: *mut u8, output_l } /// Drop an unfinished incremental SHA-256 context. Idempotent for cleanup. +#[no_mangle] pub extern "C" fn jerboa_sha256_ctx_free(handle: u64) { let _ = std::panic::catch_unwind(|| lock_sha256_contexts().remove(&handle)); } --- a/jerboa-native-rs/src/process_ctl.rs +++ b/jerboa-native-rs/src/process_ctl.rs @@ -2,6 +2,7 @@ use crate::panic::{ffi_wrap, set_last_error}; /// Set the process name via prctl(PR_SET_NAME) on Linux. /// name: UTF-8 bytes, max 15 bytes (will be truncated). +#[no_mangle] pub extern "C" fn jerboa_prctl_set_name(name: *const u8, name_len: usize) -> i32 { ffi_wrap(|| { if name.is_null() { @@ -36,6 +37,7 @@ pub extern "C" fn jerboa_prctl_set_name(name: *const u8, name_len: usize) -> i32 } /// Lock all current and future memory pages (prevent swapping). +#[no_mangle] pub extern "C" fn jerboa_mlockall() -> i32 { ffi_wrap(|| { #[cfg(any(target_os = "linux", target_os = "freebsd"))] @@ -59,6 +61,7 @@ pub extern "C" fn jerboa_mlockall() -> i32 { /// Probe whether a process exists using kill(pid, 0). /// Returns: 1 = exists, 0 = does not exist, -1 = error. +#[no_mangle] pub extern "C" fn jerboa_kill_probe(pid: u32) -> i32 { ffi_wrap(|| { // SAFETY: kill(pid, 0) performs permission/existence probing without @@ -103,6 +106,7 @@ fn errno() -> i32 { /// Check if the current process is being traced (debugged) on FreeBSD. /// Uses sysctl kern.proc.pid to read kinfo_proc and check ki_flag for P_TRACED. /// Returns: 1 = traced, 0 = not traced, -1 = error. +#[no_mangle] pub extern "C" fn jerboa_freebsd_is_traced() -> i32 { ffi_wrap(|| { #[cfg(target_os = "freebsd")] @@ -150,6 +154,7 @@ pub extern "C" fn jerboa_freebsd_is_traced() -> i32 { /// Count total number of processes on FreeBSD via sysctl kern.proc.all. /// Returns the count, or -1 on error. +#[no_mangle] pub extern "C" fn jerboa_freebsd_process_count() -> i32 { ffi_wrap(|| { #[cfg(target_os = "freebsd")] @@ -191,6 +196,7 @@ pub extern "C" fn jerboa_freebsd_process_count() -> i32 { /// Takes a plain string (not a format string) — we call setproctitle("%s", name). /// name: UTF-8 bytes, name_len: length. /// Returns 0 on success, -1 on error. +#[no_mangle] pub extern "C" fn jerboa_setproctitle(name: *const u8, name_len: usize) -> i32 { ffi_wrap(|| { if name.is_null() { @@ -241,6 +247,7 @@ pub extern "C" fn jerboa_setproctitle(name: *const u8, name_len: usize) -> i32 { /// Read the path of the current executable. /// On Linux: /proc/self/exe /// On FreeBSD: sysctl KERN_PROC_PATHNAME +#[no_mangle] pub extern "C" fn jerboa_proc_self_exe( output: *mut u8, output_len: usize, --- a/jerboa-native-rs/src/regex_native.rs +++ b/jerboa-native-rs/src/regex_native.rs @@ -295,6 +295,7 @@ pub extern "C" fn jerboa_regex_free(handle: u64) -> i32 { /// Compile with PCRE2-compatible flags bitmask. /// Flags: 0x8=CASELESS, 0x20=DOTALL, 0x400=MULTILINE, 0x80000=UTF (ignored, always UTF-8) /// Returns 0 on success, -1 on error. +#[no_mangle] pub extern "C" fn jerboa_regex_compile_ex( pattern: *const u8, pattern_len: usize, --- a/jerboa-native-rs/src/socks5_server.rs +++ b/jerboa-native-rs/src/socks5_server.rs @@ -118,6 +118,7 @@ struct ServerConfig { /// Returns handle (>0) on success, 0 on error. /// /// `username`/`password` pointers may be null for no-auth mode. +#[no_mangle] pub extern "C" fn jerboa_socks5_server_start( bind_addr: *const u8, bind_addr_len: usize, @@ -260,6 +261,7 @@ pub extern "C" fn jerboa_socks5_server_start( /// Stop a running SOCKS5 proxy server. /// Returns 0 on success, -1 on error. +#[no_mangle] pub extern "C" fn jerboa_socks5_server_stop(handle: u64) -> i32 { match std::panic::catch_unwind(|| { let Some(mut map) = lock_servers() else { @@ -288,6 +290,7 @@ pub extern "C" fn jerboa_socks5_server_stop(handle: u64) -> i32 { /// Get the actual bound port of a SOCKS5 server. /// Returns port (>0) on success, 0 on error. +#[no_mangle] pub extern "C" fn jerboa_socks5_server_port(handle: u64) -> u16 { match std::panic::catch_unwind(|| { let Some(map) = lock_servers() else { @@ -309,6 +312,7 @@ pub extern "C" fn jerboa_socks5_server_port(handle: u64) -> u16 { /// Get stats: active connections and total connections. /// Writes "active:N total:N" to buf. /// Returns bytes written (>0) or -1 on error. +#[no_mangle] pub extern "C" fn jerboa_socks5_server_stats(handle: u64, buf: *mut u8, buf_len: usize) -> i32 { match std::panic::catch_unwind(|| { if buf.is_null() || buf_len == 0 { --- a/jerboa-native-rs/src/tls.rs +++ b/jerboa-native-rs/src/tls.rs @@ -737,6 +737,7 @@ pub extern "C" fn jerboa_tls_server_new( /// Create a TLS server context from in-memory PEM cert and key data. /// Same as jerboa_tls_server_new but reads from byte buffers instead of files. /// Returns context handle (>0) on success, 0 on error. +#[no_mangle] pub extern "C" fn jerboa_tls_server_new_pem( cert_pem: *const u8, cert_pem_len: usize, @@ -869,6 +870,7 @@ pub extern "C" fn jerboa_tls_accept(server_ctx: u64, fd: i32) -> u64 { /// client_ca_pem: CA cert PEM bytes used to verify client certificates. /// Clients without a valid cert signed by this CA are rejected at the TLS handshake. /// Returns context handle (>0) on success, 0 on error. +#[no_mangle] pub extern "C" fn jerboa_tls_server_new_mtls_pem( cert_pem: *const u8, cert_pem_len: usize, @@ -1285,6 +1287,7 @@ pub extern "C" fn jerboa_tls_connect_mtls( /// The server's cert is chain-verified against ca_pem. The client /// presents cert_pem/key_pem as its identity. Returns handle ID (>0) on /// success, 0 on error. +#[no_mangle] pub extern "C" fn jerboa_tls_connect_mtls_pem_ca( host: *const u8, host_len: usize, @@ -1417,6 +1420,7 @@ pub extern "C" fn jerboa_tls_connect_mtls_pem_ca( /// mTLS connect using in-memory cert/key data (no file paths). /// Avoids /proc/self/fd/ which Android SELinux may block. /// Returns handle ID (>0) on success, 0 on error. +#[no_mangle] pub extern "C" fn jerboa_tls_connect_mtls_mem( host: *const u8, host_len: usize, --- a/jerboa-native-rs/src/wasm.rs +++ b/jerboa-native-rs/src/wasm.rs @@ -306,6 +306,7 @@ pub extern "C" fn jerboa_wasm_instance_free(handle: u64) { /// /// SAFETY: `fd` must be a valid, owned UDP socket file descriptor. /// Returns 0 on success, -1 on error. +#[no_mangle] pub extern "C" fn jerboa_wasm_set_socket(instance_handle: u64, fd: i32) -> i32 { ffi_wrap(|| { let mut instances = match lock_instances() { @@ -347,6 +348,7 @@ pub extern "C" fn jerboa_wasm_set_socket(instance_handle: u64, fd: i32) -> i32 { /// The WASM guest can only open CDB files under these directories. /// path_ptr/path_len: UTF-8 directory path. /// Returns 0 on success, -1 on error. +#[no_mangle] pub extern "C" fn jerboa_wasm_allow_cdb_dir( instance_handle: u64, path_ptr: *const u8, --- a/jerboa-native-rs/src/wasm_sm.rs +++ b/jerboa-native-rs/src/wasm_sm.rs @@ -1122,6 +1122,7 @@ pub extern "C" fn jerboa_sm_call( // FFI: Memory access (stubs — full impl requires persistent instance) // ============================================================ +#[no_mangle] pub extern "C" fn jerboa_sm_memory_read( _handle: u64, _offset: u32, @@ -1131,6 +1132,7 @@ pub extern "C" fn jerboa_sm_memory_read( -1 } +#[no_mangle] pub extern "C" fn jerboa_sm_memory_write( _handle: u64, _offset: u32, @@ -1140,6 +1142,7 @@ pub extern "C" fn jerboa_sm_memory_write( -1 } +#[no_mangle] pub extern "C" fn jerboa_sm_memory_size(_handle: u64) -> i64 { -1 } @@ -1153,6 +1156,7 @@ pub extern "C" fn jerboa_sm_add_fuel(_handle: u64, _fuel: u64) -> i32 { 0 } +#[no_mangle] pub extern "C" fn jerboa_sm_fuel_remaining(_handle: u64) -> i64 { 0 } --- a/jerboa-native-rs/src/x25519.rs +++ b/jerboa-native-rs/src/x25519.rs @@ -6,6 +6,7 @@ use x25519_dalek::{PublicKey, StaticSecret}; /// Generate an X25519 keypair using ring's CSPRNG. /// private_out: 32-byte buffer for the private key /// public_out: 32-byte buffer for the public key +#[no_mangle] pub extern "C" fn jerboa_x25519_generate_keypair(private_out: *mut u8, public_out: *mut u8) -> i32 { ffi_wrap(|| { if private_out.is_null() || public_out.is_null() { @@ -33,6 +34,7 @@ pub extern "C" fn jerboa_x25519_generate_keypair(private_out: *mut u8, public_ou /// Compute public key from a private key. /// private_key: 32-byte private key /// public_out: 32-byte buffer for the public key +#[no_mangle] pub extern "C" fn jerboa_x25519_public_from_private( private_key: *const u8, private_len: usize, @@ -62,6 +64,7 @@ pub extern "C" fn jerboa_x25519_public_from_private( /// our_private: 32-byte private key /// their_public: 32-byte public key /// shared_out: 32-byte buffer for the shared secret +#[no_mangle] pub extern "C" fn jerboa_x25519_diffie_hellman( our_private: *const u8, priv_len: usize, @@ -104,6 +107,7 @@ pub extern "C" fn jerboa_x25519_diffie_hellman( /// salt: salt bytes (can be NULL with salt_len=0 for no salt) /// info: context/application info /// output: buffer for derived key material +#[no_mangle] pub extern "C" fn jerboa_hkdf_sha256( ikm: *const u8, ikm_len: usize, --- a/jerboa-native-rs/src/x509.rs +++ b/jerboa-native-rs/src/x509.rs @@ -350,6 +350,7 @@ pub extern "C" fn jerboa_x509_generate_self_signed( /// caller-provided buffers instead of files. /// /// Returns 0 on success, -1 on error. +#[no_mangle] pub extern "C" fn jerboa_x509_generate_self_signed_mem( ip_addrs_csv: *const u8, ip_addrs_len: usize, @@ -457,6 +458,7 @@ pub extern "C" fn jerboa_x509_generate_self_signed_mem( /// here. The lengths actually written are stored in cert_out_len / key_out_len. /// /// Returns 0 on success, -1 on error (call jerboa_last_error for details). +#[no_mangle] pub extern "C" fn jerboa_x509_generate_signed_by_ca_mem( ca_cert_pem: *const u8, ca_cert_pem_len: usize,