1#![no_std]
32#![warn(
33 clippy::unnecessary_wraps,
34 clippy::unnecessary_lazy_evaluations,
35 clippy::collapsible_if,
36 clippy::cast_lossless,
37 clippy::explicit_iter_loop,
38 clippy::manual_assert,
39 clippy::needless_question_mark,
40 clippy::needless_return,
41 clippy::needless_update,
42 clippy::redundant_clone,
43 clippy::redundant_else,
44 clippy::redundant_static_lifetimes
45)]
46#![allow(
47 clippy::len_without_is_empty,
48 clippy::unnecessary_cast,
49 clippy::uninit_vec
50)]
51extern crate alloc;
52
53#[cfg(not(any(
54 target_arch = "x86_64",
55 target_arch = "aarch64",
56 target_arch = "riscv64",
57 target_arch = "riscv32",
58 target_arch = "loongarch64",
59 target_arch = "x86",
60 target_arch = "arm",
61)))]
62compile_error!("unsupport arch");
63
64#[cfg(all(
65 any(feature = "fs", feature = "mmap"),
66 not(any(feature = "use-libc", feature = "use-syscall"))
67))]
68compile_error!("use at least one of libc and syscall");
69
70#[cfg(all(feature = "use-libc", feature = "use-syscall"))]
71compile_error!("only one of use-libc and use-syscall can be used");
72
73pub mod arch;
74pub mod dynamic;
75mod format;
76mod loader;
77mod macros;
78pub mod mmap;
79pub mod object;
80mod relocation;
81pub mod segment;
82mod symbol;
83#[cfg(feature = "version")]
84mod version;
85
86use alloc::{
87 boxed::Box,
88 string::{String, ToString},
89};
90use core::{
91 any::Any,
92 fmt::{Debug, Display},
93};
94use object::*;
95use relocation::{ElfRelocation, GLOBAL_SCOPE};
96use segment::ELFRelro;
97
98pub use elf::abi;
99pub use format::dylib::{ElfDylib, RelocatedDylib, Symbol};
100pub use format::exec::{ElfExec, RelocatedExec};
101pub use format::{CoreComponent, CoreComponentRef, Elf, UserData};
102pub use loader::Loader;
103pub use relocation::find_symdef;
104
105#[derive(Debug)]
107pub enum Error {
108 #[cfg(feature = "fs")]
110 IOError { msg: String },
111 MmapError { msg: String },
113 RelocateError {
115 msg: String,
116 custom_err: Box<dyn Any + Send + Sync>,
117 },
118 ParseDynamicError { msg: &'static str },
120 ParseEhdrError { msg: String },
122 ParsePhdrError {
124 msg: String,
125 custom_err: Box<dyn Any + Send + Sync>,
126 },
127}
128
129impl Display for Error {
130 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
131 match self {
132 #[cfg(feature = "fs")]
133 Error::IOError { msg } => write!(f, "{msg}"),
134 Error::MmapError { msg } => write!(f, "{msg}"),
135 Error::RelocateError { msg, .. } => write!(f, "{msg}"),
136 Error::ParseDynamicError { msg } => write!(f, "{msg}"),
137 Error::ParseEhdrError { msg } => write!(f, "{msg}"),
138 Error::ParsePhdrError { msg, .. } => write!(f, "{msg}"),
139 }
140 }
141}
142
143impl core::error::Error for Error {}
144
145#[cfg(feature = "fs")]
146#[cold]
147#[inline(never)]
148fn io_error(msg: impl ToString) -> Error {
149 Error::IOError {
150 msg: msg.to_string(),
151 }
152}
153
154#[cold]
155#[inline(never)]
156fn relocate_error(msg: impl ToString, custom_err: Box<dyn Any + Send + Sync>) -> Error {
157 Error::RelocateError {
158 msg: msg.to_string(),
159 custom_err,
160 }
161}
162
163#[cold]
164#[inline(never)]
165fn parse_dynamic_error(msg: &'static str) -> Error {
166 Error::ParseDynamicError { msg }
167}
168
169#[cold]
170#[inline(never)]
171fn parse_ehdr_error(msg: impl ToString) -> Error {
172 Error::ParseEhdrError {
173 msg: msg.to_string(),
174 }
175}
176
177#[cold]
178#[inline(never)]
179fn parse_phdr_error(msg: impl ToString, custom_err: Box<dyn Any + Send + Sync>) -> Error {
180 Error::ParsePhdrError {
181 msg: msg.to_string(),
182 custom_err,
183 }
184}
185
186pub unsafe fn set_global_scope(f: fn(&str) -> Option<*const ()>) {
201 GLOBAL_SCOPE.store(f as usize, core::sync::atomic::Ordering::Release);
202}
203
204pub type Result<T> = core::result::Result<T, Error>;