Skip to main content

radixdb_plugin_abi/
lib.rs

1// Copyright 2026 RadixDB Contributors
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15//! Stable low-level C ABI shared by the RadixDB plugin host and trusted native
16//! plugins.
17//!
18//! This crate deliberately has no dependency on an engine crate and exports no
19//! Rust-owned allocation across the boundary. The safe authoring API lives in
20//! `radixdb-plugin`; this crate is the generated bridge and C-oracle surface.
21
22#![no_std]
23#![forbid(unsafe_op_in_unsafe_fn)]
24
25#[cfg(not(all(
26    any(target_arch = "x86_64", target_arch = "aarch64"),
27    target_os = "linux",
28    target_env = "gnu",
29    target_endian = "little",
30    target_pointer_width = "64"
31)))]
32compile_error!("radixdb-plugin-abi 1.0 supports only x86_64/aarch64 Linux GNU targets");
33
34/// ELF machine identity for native extensions on this target.
35#[cfg(target_arch = "x86_64")]
36pub const NATIVE_ELF_MACHINE: u16 = 62;
37#[cfg(target_arch = "aarch64")]
38pub const NATIVE_ELF_MACHINE: u16 = 183;
39
40mod constants;
41mod descriptor;
42mod raw;
43mod validate;
44
45pub use constants::*;
46pub use descriptor::*;
47pub use raw::*;
48pub use validate::*;
49
50/// Exact entrypoint symbol required from every ABI-major-1 shared library.
51pub const ENTRYPOINT_SYMBOL_V1: &[u8] = b"radixdb_plugin_entry_v1\0";
52
53/// Function type of the only exported plugin symbol.
54pub type RadixPluginEntrypointV1 = unsafe extern "C" fn(
55    host: *const RadixHostApiV1,
56    status: *mut RadixAbiStatusV1,
57) -> *const RadixPluginDescriptorV1;
58
59const _: () = {
60    use core::mem::{align_of, offset_of, size_of};
61
62    assert!(size_of::<RadixAbiHeaderV1>() == 16);
63    assert!(align_of::<RadixAbiHeaderV1>() == 8);
64    assert!(offset_of!(RadixAbiHeaderV1, flags) == 8);
65    assert!(size_of::<RadixAbiSliceV1>() == 16);
66    assert!(align_of::<RadixAbiSliceV1>() == 8);
67    assert!(offset_of!(RadixAbiSliceV1, len) == 8);
68    assert!(size_of::<RadixAbiTypeRefV1>() == 24);
69    assert!(align_of::<RadixAbiTypeRefV1>() == 4);
70    assert!(offset_of!(RadixAbiTypeRefV1, object_id) == 8);
71    assert!(size_of::<RadixAbiValueV1>() == 64);
72    assert!(align_of::<RadixAbiValueV1>() == 8);
73    assert!(offset_of!(RadixAbiValueV1, borrowed_bytes) == 48);
74    assert!(size_of::<RadixAbiColumnViewV1>() == 104);
75    assert!(align_of::<RadixAbiColumnViewV1>() == 8);
76    assert!(offset_of!(RadixAbiColumnViewV1, null_bitmap) == 56);
77    assert!(offset_of!(RadixAbiColumnViewV1, offsets) == 88);
78    assert!(size_of::<RadixAbiBatchViewV1>() == 32);
79    assert!(align_of::<RadixAbiBatchViewV1>() == 8);
80    assert!(offset_of!(RadixAbiBatchViewV1, columns) == 24);
81    assert!(size_of::<RadixAbiResultBuilderV1>() == 48);
82    assert!(align_of::<RadixAbiResultBuilderV1>() == 8);
83    assert!(offset_of!(RadixAbiResultBuilderV1, write) == 32);
84    assert!(size_of::<RadixAbiHashSinkV1>() == 40);
85    assert!(align_of::<RadixAbiHashSinkV1>() == 8);
86    assert!(offset_of!(RadixAbiHashSinkV1, append) == 32);
87    assert!(size_of::<RadixAbiDiagnosticV1>() == 56);
88    assert!(align_of::<RadixAbiDiagnosticV1>() == 8);
89    assert!(offset_of!(RadixAbiDiagnosticV1, detail) == 24);
90    assert!(size_of::<RadixAbiDiagnosticSinkV1>() == 40);
91    assert!(align_of::<RadixAbiDiagnosticSinkV1>() == 8);
92    assert!(offset_of!(RadixAbiDiagnosticSinkV1, write) == 32);
93    assert!(size_of::<RadixAbiCallContextV1>() == 64);
94    assert!(align_of::<RadixAbiCallContextV1>() == 8);
95    assert!(offset_of!(RadixAbiCallContextV1, diagnostics) == 56);
96    assert!(size_of::<RadixHostApiV1>() == 48);
97    assert!(align_of::<RadixHostApiV1>() == 8);
98    assert!(offset_of!(RadixHostApiV1, log) == 40);
99    assert!(size_of::<RadixAbiBindingEntryV1>() == 20);
100    assert!(align_of::<RadixAbiBindingEntryV1>() == 2);
101    assert!(offset_of!(RadixAbiBindingEntryV1, object_id) == 4);
102    assert!(size_of::<RadixAbiExternalTypeDescriptorV1>() == 200);
103    assert!(align_of::<RadixAbiExternalTypeDescriptorV1>() == 8);
104    assert!(offset_of!(RadixAbiExternalTypeDescriptorV1, capabilities) == 88);
105    assert!(offset_of!(RadixAbiExternalTypeDescriptorV1, encode) == 128);
106    assert!(size_of::<RadixAbiScalarFunctionDescriptorV1>() == 136);
107    assert!(align_of::<RadixAbiScalarFunctionDescriptorV1>() == 8);
108    assert!(offset_of!(RadixAbiScalarFunctionDescriptorV1, volatility) == 104);
109    assert!(offset_of!(RadixAbiScalarFunctionDescriptorV1, scalar) == 120);
110    assert!(size_of::<RadixAbiOperatorDescriptorV1>() == 160);
111    assert!(align_of::<RadixAbiOperatorDescriptorV1>() == 8);
112    assert!(offset_of!(RadixAbiOperatorDescriptorV1, function_id) == 144);
113    assert!(size_of::<RadixAbiOperatorClassDescriptorV1>() == 176);
114    assert!(align_of::<RadixAbiOperatorClassDescriptorV1>() == 8);
115    assert!(offset_of!(RadixAbiOperatorClassDescriptorV1, strategies) == 112);
116    assert!(offset_of!(RadixAbiOperatorClassDescriptorV1, encode_key) == 168);
117    assert!(size_of::<RadixAbiPlannerSupportDescriptorV1>() == 136);
118    assert!(align_of::<RadixAbiPlannerSupportDescriptorV1>() == 8);
119    assert!(offset_of!(RadixAbiPlannerSupportDescriptorV1, callback) == 128);
120    assert!(size_of::<RadixPluginDescriptorV1>() == 184);
121    assert!(align_of::<RadixPluginDescriptorV1>() == 8);
122    assert!(offset_of!(RadixPluginDescriptorV1, descriptor_fingerprint) == 72);
123    assert!(offset_of!(RadixPluginDescriptorV1, planner_support) == 176);
124};