Skip to main content

libsla_sys/
sys.rs

1pub use default::*;
2
3use super::rust::*;
4
5#[cxx::bridge]
6mod default {
7    #[repr(i32)]
8    #[derive(Debug)]
9    #[namespace = "ghidra"]
10    enum spacetype {
11        /// Special space to represent constants
12        IPTR_CONSTANT = 0,
13        /// Normal spaces modelled by processor
14        IPTR_PROCESSOR = 1,
15        /// addresses = offsets off of base register
16        IPTR_SPACEBASE = 2,
17        /// Internally managed temporary space
18        IPTR_INTERNAL = 3,
19        /// Special internal FuncCallSpecs reference
20        IPTR_FSPEC = 4,
21        /// Special internal PcodeOp reference
22        IPTR_IOP = 5,
23        /// Special virtual space to represent split variables
24        IPTR_JOIN = 6,
25    }
26
27    #[repr(i32)]
28    #[derive(Debug)]
29    #[namespace = "ghidra"]
30    enum OpCode {
31        /// Copy one operand to another
32        CPUI_COPY = 1,
33        /// Load from a pointer into a specified address space
34        CPUI_LOAD = 2,
35        /// Store at a pointer into a specified address space
36        CPUI_STORE = 3,
37
38        /// Always branch
39        CPUI_BRANCH = 4,
40        /// Conditional branch
41        CPUI_CBRANCH = 5,
42        /// Indirect branch (jumptable)
43        CPUI_BRANCHIND = 6,
44
45        /// Call to an absolute address
46        CPUI_CALL = 7,
47        /// Call through an indirect address
48        CPUI_CALLIND = 8,
49        /// User-defined operation
50        CPUI_CALLOTHER = 9,
51        /// Return from subroutine
52        CPUI_RETURN = 10,
53
54        // Integer/bit operations
55        /// Integer comparison, equality (==)
56        CPUI_INT_EQUAL = 11,
57        /// Integer comparison, in-equality (!=)
58        CPUI_INT_NOTEQUAL = 12,
59        /// Integer comparison, signed less-than (<)
60        CPUI_INT_SLESS = 13,
61        /// Integer comparison, signed less-than-or-equal (<=)
62        CPUI_INT_SLESSEQUAL = 14,
63        /// Integer comparison, unsigned less-than (<)
64        /// This also indicates a borrow on unsigned substraction
65        CPUI_INT_LESS = 15,
66        /// Integer comparison, unsigned less-than-or-equal (<=)
67        CPUI_INT_LESSEQUAL = 16,
68        /// Zero extension
69        CPUI_INT_ZEXT = 17,
70        /// Sign extension
71        CPUI_INT_SEXT = 18,
72        /// Addition, signed or unsigned (+)
73        CPUI_INT_ADD = 19,
74        /// Subtraction, signed or unsigned (-)
75        CPUI_INT_SUB = 20,
76        /// Test for unsigned carry
77        CPUI_INT_CARRY = 21,
78        /// Test for signed carry
79        CPUI_INT_SCARRY = 22,
80        /// Test for signed borrow
81        CPUI_INT_SBORROW = 23,
82        /// Twos complement
83        CPUI_INT_2COMP = 24,
84        /// Logical/bitwise negation (~)
85        CPUI_INT_NEGATE = 25,
86        /// Logical/bitwise exclusive-or (^)
87        CPUI_INT_XOR = 26,
88        /// Logical/bitwise and (&)
89        CPUI_INT_AND = 27,
90        /// Logical/bitwise or (|)
91        CPUI_INT_OR = 28,
92        /// Left shift (<<)
93        CPUI_INT_LEFT = 29,
94        /// Right shift, logical (>>)
95        CPUI_INT_RIGHT = 30,
96        /// Right shift, arithmetic (>>)
97        CPUI_INT_SRIGHT = 31,
98        /// Integer multiplication, signed and unsigned (*)
99        CPUI_INT_MULT = 32,
100        /// Integer division, unsigned (/)
101        CPUI_INT_DIV = 33,
102        /// Integer division, signed (/)
103        CPUI_INT_SDIV = 34,
104        /// Remainder/modulo, unsigned (%)
105        CPUI_INT_REM = 35,
106        /// Remainder/modulo, signed (%)
107        CPUI_INT_SREM = 36,
108
109        /// Boolean negate (!)
110        CPUI_BOOL_NEGATE = 37,
111        /// Boolean exclusive-or (^^)
112        CPUI_BOOL_XOR = 38,
113        /// Boolean and (&&)
114        CPUI_BOOL_AND = 39,
115        /// Boolean or (||)
116        CPUI_BOOL_OR = 40,
117
118        // Floating point operations
119        /// Floating-point comparison, equality (==)
120        CPUI_FLOAT_EQUAL = 41,
121        /// Floating-point comparison, in-equality (!=)
122        CPUI_FLOAT_NOTEQUAL = 42,
123        /// Floating-point comparison, less-than (<)
124        CPUI_FLOAT_LESS = 43,
125        /// Floating-point comparison, less-than-or-equal (<=)
126        CPUI_FLOAT_LESSEQUAL = 44,
127        // Slot 45 is currently unused
128        /// Not-a-number test (NaN)
129        CPUI_FLOAT_NAN = 46,
130
131        /// Floating-point addition (+)
132        CPUI_FLOAT_ADD = 47,
133        /// Floating-point division (/)
134        CPUI_FLOAT_DIV = 48,
135        /// Floating-point multiplication (*)
136        CPUI_FLOAT_MULT = 49,
137        /// Floating-point subtraction (-)
138        CPUI_FLOAT_SUB = 50,
139        /// Floating-point negation (-)
140        CPUI_FLOAT_NEG = 51,
141        /// Floating-point absolute value (abs)
142        CPUI_FLOAT_ABS = 52,
143        /// Floating-point square root (sqrt)
144        CPUI_FLOAT_SQRT = 53,
145
146        /// Convert an integer to a floating-point
147        CPUI_FLOAT_INT2FLOAT = 54,
148        /// Convert between different floating-point sizes
149        CPUI_FLOAT_FLOAT2FLOAT = 55,
150        /// Round towards zero
151        CPUI_FLOAT_TRUNC = 56,
152        /// Round towards +infinity
153        CPUI_FLOAT_CEIL = 57,
154        /// Round towards -infinity
155        CPUI_FLOAT_FLOOR = 58,
156        /// Round towards nearest
157        CPUI_FLOAT_ROUND = 59,
158
159        // Internal opcodes for simplification. Not
160        // typically generated in a direct translation.
161
162        // Data-flow operations
163        /// Phi-node operator
164        CPUI_MULTIEQUAL = 60,
165        /// Copy with an indirect effect
166        CPUI_INDIRECT = 61,
167        /// Concatenate
168        CPUI_PIECE = 62,
169        /// Truncate
170        CPUI_SUBPIECE = 63,
171
172        /// Cast from one data-type to another
173        CPUI_CAST = 64,
174        /// Index into an array ([])
175        CPUI_PTRADD = 65,
176        /// Drill down to a sub-field  (->)
177        CPUI_PTRSUB = 66,
178        /// Look-up a \e segmented address
179        CPUI_SEGMENTOP = 67,
180        /// Recover a value from the \e constant \e pool
181        CPUI_CPOOLREF = 68,
182        /// Allocate a new object (new)
183        CPUI_NEW = 69,
184        /// Insert a bit-range
185        CPUI_INSERT = 70,
186        /// Extract a bit-range
187        CPUI_EXTRACT = 71,
188        /// Count the 1-bits
189        CPUI_POPCOUNT = 72,
190        /// Count the leading 0-bits
191        CPUI_LZCOUNT = 73,
192        /// Value indicating the end of the op-code values
193        CPUI_MAX = 74,
194    }
195
196    extern "Rust" {
197        type RustPcodeEmit<'a>;
198        unsafe fn dump(
199            self: &mut RustPcodeEmit,
200            addr: &Address,
201            op_code: OpCode,
202            output: *mut VarnodeData,
203            inputs: &CxxVector<VarnodeData>,
204        );
205
206        type RustLoadImage<'a>;
207        unsafe fn load_fill(
208            self: &RustLoadImage,
209            ptr: *mut u8,
210            size: i32,
211            addr: &Address,
212        ) -> Result<()>;
213
214        type RustAssemblyEmit<'a>;
215        fn dump(
216            self: &mut RustAssemblyEmit,
217            addr: &Address,
218            mnemonic: &CxxString,
219            body: &CxxString,
220        );
221    }
222
223    unsafe extern "C++" {
224        include!("libsla-sys/src/cpp/bridge.hh");
225
226        #[namespace = "ghidra"]
227        type OpCode;
228
229        #[namespace = "ghidra"]
230        type spacetype;
231
232        #[namespace = "ghidra"]
233        type Address;
234
235        #[rust_name = "new_address"]
236        unsafe fn construct_new(address_space: *mut AddrSpace, offset: u64) -> UniquePtr<Address>;
237
238        #[rust_name = "offset"]
239        fn getOffset(self: &Address) -> u64;
240        #[rust_name = "address_space"]
241        fn getSpace(self: &Address) -> *mut AddrSpace;
242
243        #[namespace = "ghidra"]
244        type AddrSpace;
245        #[rust_name = "name"]
246        fn getName(self: &AddrSpace) -> &CxxString;
247        #[rust_name = "word_size"]
248        fn getWordSize(self: &AddrSpace) -> u32;
249        #[rust_name = "address_size"]
250        fn getAddrSize(self: &AddrSpace) -> u32;
251        #[rust_name = "space_type"]
252        fn getType(self: &AddrSpace) -> spacetype;
253        #[rust_name = "big_endian"]
254        fn isBigEndian(self: &AddrSpace) -> bool;
255
256        #[namespace = "ghidra"]
257        type LoadImage;
258
259        #[namespace = "ghidra"]
260        type ContextInternal;
261
262        #[namespace = "ghidra"]
263        type PcodeEmit;
264
265        #[namespace = "ghidra"]
266        type VarnodeData;
267
268        #[rust_name = "varnode_address"]
269        fn getAddress(data: &VarnodeData) -> UniquePtr<Address>;
270        #[rust_name = "varnode_size"]
271        fn getSize(data: &VarnodeData) -> u32;
272
273        #[namespace = "ghidra"]
274        type ContextDatabase;
275        #[rust_name = "new_context_internal"]
276        fn construct_new_context() -> UniquePtr<ContextDatabase>;
277
278        #[namespace = "ghidra"]
279        type Element;
280        fn initialize_element_id();
281        fn initialize_attribute_id();
282
283        #[namespace = "ghidra"]
284        type Document;
285        #[rust_name = "root"]
286        fn getRoot(self: &Document) -> *mut Element;
287        #[rust_name = "document_root"]
288        fn getDocumentRoot(doc: &Document) -> &Element;
289
290        #[namespace = "ghidra"]
291        type DocumentStorage;
292        #[rust_name = "new_document_storage"]
293        fn construct_new() -> UniquePtr<DocumentStorage>;
294        #[rust_name = "docstore_parse_document"]
295        fn parseDocumentIntoStore<'a>(
296            store: Pin<&'a mut DocumentStorage>,
297            data: &CxxString,
298        ) -> Result<&'a Document>;
299
300        /// # Safety
301        ///
302        /// `element` must be a valid pointer.
303        #[rust_name = "register_tag"]
304        unsafe fn registerTag(self: Pin<&mut DocumentStorage>, element: *const Element);
305
306        // Register varnode
307        type RegisterVarnodeName;
308        #[rust_name = "register"]
309        fn getVarnode(self: &RegisterVarnodeName) -> &VarnodeData;
310        #[rust_name = "name"]
311        fn getName(self: &RegisterVarnodeName) -> &CxxString;
312
313        // The Sleigh
314        type SleighProxy;
315        #[rust_name = "new_sleigh"]
316        fn construct_new_sleigh(context: UniquePtr<ContextDatabase>) -> UniquePtr<SleighProxy>;
317        fn initialize(self: Pin<&mut SleighProxy>, store: Pin<&mut DocumentStorage>) -> Result<()>;
318        #[rust_name = "initialize_from_sla"]
319        fn initializeFromSla(self: Pin<&mut SleighProxy>, sla: &CxxString) -> Result<()>;
320        #[rust_name = "initialize_from_raw_sla"]
321        fn initializeFromRawSla(self: Pin<&mut SleighProxy>, sla: &CxxString) -> Result<()>;
322        #[rust_name = "num_spaces"]
323        fn numSpaces(self: &SleighProxy) -> i32;
324        #[rust_name = "address_space"]
325        fn getSpace(self: &SleighProxy, index: i32) -> *mut AddrSpace;
326        #[rust_name = "default_code_space"]
327        fn getDefaultCodeSpace(self: &SleighProxy) -> *mut AddrSpace;
328        /// Throws an exception if the name does not correspond to an existing context variable
329        #[rust_name = "set_context_default"]
330        fn setContextDefault(
331            self: Pin<&mut SleighProxy>,
332            name: &CxxString,
333            value: u32,
334        ) -> Result<()>;
335        #[rust_name = "parse_document_and_register_root"]
336        fn parseDocumentAndRegisterRootElement(
337            store: Pin<&mut DocumentStorage>,
338            data: &CxxString,
339        ) -> Result<()>;
340
341        #[rust_name = "register_from_name"]
342        fn getRegister<'a>(self: &'a SleighProxy, name: &CxxString) -> Result<&'a VarnodeData>;
343
344        // This will return an empty string on failure
345        #[rust_name = "register_name"]
346        unsafe fn getRegisterNameProxy(
347            self: &SleighProxy,
348            base: *mut AddrSpace,
349            offset: u64,
350            size: i32,
351        ) -> UniquePtr<CxxString>;
352
353        // Need to proxy this because the C++ API interfaces with std::map. However as of now the
354        // cxx crate does not expose std::map. So the FFI layer builds a vector of the map
355        // key-value pairs instead in a custom class. The custom layer is necessary since the pair
356        // API cannot be easily exposed through FFI either.
357        #[rust_name = "all_register_names"]
358        fn getAllRegistersProxy(self: &SleighProxy) -> UniquePtr<CxxVector<RegisterVarnodeName>>;
359
360        #[rust_name = "parse_processor_config"]
361        fn parseProcessorConfig(self: Pin<&mut SleighProxy>, store: &DocumentStorage)
362        -> Result<()>;
363
364        // TODO Can throw UnimplError from C++ which has lots of useful info that is lost here
365        #[rust_name = "disassemble_pcode"]
366        fn disassemblePcode(
367            self: &SleighProxy,
368            loadImage: &RustLoadImage,
369            emit: &mut RustPcodeEmit,
370            address: &Address,
371        ) -> Result<i32>;
372
373        #[rust_name = "disassemble_native"]
374        fn disassembleNative(
375            self: &SleighProxy,
376            loadImage: &RustLoadImage,
377            emit: &mut RustAssemblyEmit,
378            address: &Address,
379        ) -> Result<i32>;
380    }
381}