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
64pub mod arch;
65pub mod dynamic;
66mod format;
67mod loader;
68mod macros;
69pub mod mmap;
70pub mod object;
71mod os;
72mod relocation;
73pub mod segment;
74mod symbol;
75#[cfg(feature = "version")]
76mod version;
77
78use alloc::{
79 boxed::Box,
80 string::{String, ToString},
81};
82use core::{
83 any::Any,
84 fmt::{Debug, Display},
85};
86use object::*;
87use relocation::{ElfRelocation, GLOBAL_SCOPE};
88use segment::ELFRelro;
89
90pub use elf::abi;
91pub use format::dylib::{ElfDylib, RelocatedDylib, Symbol};
92pub use format::exec::{ElfExec, RelocatedExec};
93pub use format::{CoreComponent, CoreComponentRef, Elf, UserData};
94pub use loader::Loader;
95pub use relocation::find_symdef;
96
97#[derive(Debug)]
99pub enum Error {
100 IOError { msg: String },
102 MmapError { msg: String },
104 RelocateError {
106 msg: String,
107 custom_err: Box<dyn Any + Send + Sync>,
108 },
109 ParseDynamicError { msg: &'static str },
111 ParseEhdrError { msg: String },
113 ParsePhdrError {
115 msg: String,
116 custom_err: Box<dyn Any + Send + Sync>,
117 },
118}
119
120impl Display for Error {
121 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
122 match self {
123 Error::IOError { msg } => write!(f, "{msg}"),
124 Error::MmapError { msg } => write!(f, "{msg}"),
125 Error::RelocateError { msg, .. } => write!(f, "{msg}"),
126 Error::ParseDynamicError { msg } => write!(f, "{msg}"),
127 Error::ParseEhdrError { msg } => write!(f, "{msg}"),
128 Error::ParsePhdrError { msg, .. } => write!(f, "{msg}"),
129 }
130 }
131}
132
133impl core::error::Error for Error {}
134
135#[cold]
136#[inline(never)]
137#[allow(unused)]
138fn io_error(msg: impl ToString) -> Error {
139 Error::IOError {
140 msg: msg.to_string(),
141 }
142}
143
144#[cold]
145#[inline(never)]
146fn relocate_error(msg: impl ToString, custom_err: Box<dyn Any + Send + Sync>) -> Error {
147 Error::RelocateError {
148 msg: msg.to_string(),
149 custom_err,
150 }
151}
152
153#[cold]
154#[inline(never)]
155fn parse_dynamic_error(msg: &'static str) -> Error {
156 Error::ParseDynamicError { msg }
157}
158
159#[cold]
160#[inline(never)]
161fn parse_ehdr_error(msg: impl ToString) -> Error {
162 Error::ParseEhdrError {
163 msg: msg.to_string(),
164 }
165}
166
167#[cold]
168#[inline(never)]
169fn parse_phdr_error(msg: impl ToString, custom_err: Box<dyn Any + Send + Sync>) -> Error {
170 Error::ParsePhdrError {
171 msg: msg.to_string(),
172 custom_err,
173 }
174}
175
176pub unsafe fn set_global_scope(f: fn(&str) -> Option<*const ()>) {
191 GLOBAL_SCOPE.store(f as usize, core::sync::atomic::Ordering::Release);
192}
193
194pub type Result<T> = core::result::Result<T, Error>;