From 87ed1bb5699cbb75053ddabebd5f086b1d1fdb18 Mon Sep 17 00:00:00 2001 From: Zero Tang Date: Mon, 16 Dec 2024 13:01:52 +0800 Subject: [PATCH] Add eager_init function. Eagerly initialize the iced crate. --- src/rust/iced-x86/README.md | 10 ++++++++++ src/rust/iced-x86/src/decoder.rs | 4 ++++ src/rust/iced-x86/src/encoder.rs | 5 +++++ src/rust/iced-x86/src/formatter/fast.rs | 7 +++++++ .../src/formatter/fast/pseudo_ops_fast.rs | 4 ++++ src/rust/iced-x86/src/formatter/gas.rs | 6 ++++++ src/rust/iced-x86/src/formatter/intel.rs | 5 +++++ src/rust/iced-x86/src/formatter/masm.rs | 5 +++++ src/rust/iced-x86/src/formatter/mod.rs | 18 ++++++++++++++++++ src/rust/iced-x86/src/formatter/nasm.rs | 6 ++++++ src/rust/iced-x86/src/formatter/pseudo_ops.rs | 4 ++++ src/rust/iced-x86/src/lib.rs | 10 ++++++++++ 12 files changed, 84 insertions(+) diff --git a/src/rust/iced-x86/README.md b/src/rust/iced-x86/README.md index 40d386886..65e0974c3 100644 --- a/src/rust/iced-x86/README.md +++ b/src/rust/iced-x86/README.md @@ -1278,6 +1278,16 @@ Output: */ ``` +## Eagerly initialize `iced` crate +This crate depends on `lazy_static` to lazily initialize the library on-demand. However, in some circumstances, memory allocators may become unavailable after initialization stage (e.g.: You cannot call `ExAllocatePool` if `IRQL>DISPATCH_LEVEL`). Therefore, eager initialization may become necessary. \ +To eagerly initialize the `iced` crate, call the `eager_init` function in your initialization routine: +```Rust +use iced_x86; + +iced_x86::eager_init(); +``` +**Caveat:** Unlike decoders, creating formatters will still trigger memory allocations. Therefore, set up your formatter as/inside a global variable. + ## Minimum supported `rustc` version iced-x86 supports `rustc` `1.63.0` or later. diff --git a/src/rust/iced-x86/src/decoder.rs b/src/rust/iced-x86/src/decoder.rs index 6d9f2a107..1b935e393 100644 --- a/src/rust/iced-x86/src/decoder.rs +++ b/src/rust/iced-x86/src/decoder.rs @@ -2652,3 +2652,7 @@ impl<'a, 'b> IntoIterator for &'b mut Decoder<'a> { DecoderIter { decoder: self } } } + +pub(crate) fn eager_init() { + let _ = &handlers::tables::TABLES.handlers_evex_0f[0].0; +} diff --git a/src/rust/iced-x86/src/encoder.rs b/src/rust/iced-x86/src/encoder.rs index 98c10bc2e..c42892fe8 100644 --- a/src/rust/iced-x86/src/encoder.rs +++ b/src/rust/iced-x86/src/encoder.rs @@ -1678,3 +1678,8 @@ impl Encoder { self.bitness } } + +pub(crate) fn eager_init() { + let _ = &handlers_table::HANDLERS_TABLE.as_ptr(); + let _ = &op_code_tbl::OP_CODE_INFO_TBL.as_ptr(); +} diff --git a/src/rust/iced-x86/src/formatter/fast.rs b/src/rust/iced-x86/src/formatter/fast.rs index a4d13eeb0..b7055051d 100644 --- a/src/rust/iced-x86/src/formatter/fast.rs +++ b/src/rust/iced-x86/src/formatter/fast.rs @@ -1844,3 +1844,10 @@ pub type FastFormatter = SpecializedFormatter; pub struct DefaultSpecializedFormatterTraitOptions; impl SpecializedFormatterTraitOptions for DefaultSpecializedFormatterTraitOptions {} + +pub(super) fn eager_init() { + let _ = &fmt_tbl::FMT_DATA.flags; + let _ = &mem_size_tbl::MEM_SIZE_TBL.as_ptr(); + let _ = ®s::REGS_TBL.as_ptr(); + pseudo_ops_fast::eager_init(); +} diff --git a/src/rust/iced-x86/src/formatter/fast/pseudo_ops_fast.rs b/src/rust/iced-x86/src/formatter/fast/pseudo_ops_fast.rs index d1f15960f..305c613b3 100644 --- a/src/rust/iced-x86/src/formatter/fast/pseudo_ops_fast.rs +++ b/src/rust/iced-x86/src/formatter/fast/pseudo_ops_fast.rs @@ -259,3 +259,7 @@ fn create(cc: &[&str], size: usize, prefix: &str, suffix: &str) -> Vec(options: &FormatterOptions, cc_index: u32, mnemonics: &'a debug_assert!(index < mnemonics.len()); &mnemonics[index] } + +pub(crate) fn eager_init() { + let _ = &fmt_consts::FORMATTER_CONSTANTS.a64; + let _ = &fmt_consts::ARRAY_CONSTS.byte_ptr; + let _ = ®s_tbl_ls::REGS_TBL.len(); + // Some static variables are private. Use public functions to eagerly initialize them. + pseudo_ops::eager_init(); + #[cfg(feature = "fast_fmt")] + fast::eager_init(); + #[cfg(feature = "gas")] + gas::eager_init(); + #[cfg(feature = "intel")] + intel::eager_init(); + #[cfg(feature = "masm")] + masm::eager_init(); + #[cfg(feature = "nasm")] + nasm::eager_init(); +} diff --git a/src/rust/iced-x86/src/formatter/nasm.rs b/src/rust/iced-x86/src/formatter/nasm.rs index 5f393d88a..d7cbaf46d 100644 --- a/src/rust/iced-x86/src/formatter/nasm.rs +++ b/src/rust/iced-x86/src/formatter/nasm.rs @@ -1717,3 +1717,9 @@ impl Formatter for NasmFormatter { self.number_formatter.format_u64(&self.d.options, number_options, value) } } + +pub(super) fn eager_init() { + let _ = &fmt_tbl::ALL_INFOS.as_ptr(); + let _ = &mem_size_tbl::MEM_SIZE_TBL.as_ptr(); + let _ = ®s::ALL_REGISTERS.as_ptr(); +} diff --git a/src/rust/iced-x86/src/formatter/pseudo_ops.rs b/src/rust/iced-x86/src/formatter/pseudo_ops.rs index 4d5a0aae2..a334ebe90 100644 --- a/src/rust/iced-x86/src/formatter/pseudo_ops.rs +++ b/src/rust/iced-x86/src/formatter/pseudo_ops.rs @@ -255,3 +255,7 @@ fn create(sb: &mut String, cc: &[&str], size: usize, prefix: &str, suffix: &str) } strings } + +pub(super) fn eager_init() { + let _ = &PSEUDO_OPS.cmppd; +} diff --git a/src/rust/iced-x86/src/lib.rs b/src/rust/iced-x86/src/lib.rs index 2325b5ff5..19e8d98f8 100644 --- a/src/rust/iced-x86/src/lib.rs +++ b/src/rust/iced-x86/src/lib.rs @@ -184,3 +184,13 @@ pub use crate::instruction::*; pub use crate::memory_size::*; pub use crate::mnemonic::*; pub use crate::register::*; + +/// ## eager_init function +/// This routine initializes all static variables inside lazy_static. \ +/// Calling this routine is not required to use iced. The purpose of this routine is to +/// minimalize memory allocations when using iced library. +pub fn eager_init() { + decoder::eager_init(); + encoder::eager_init(); + formatter::eager_init(); +}