Skip to content

Commit

Permalink
Add feature to default to using .init_array
Browse files Browse the repository at this point in the history
  • Loading branch information
nspin committed Jan 26, 2024
1 parent 2f9fa4b commit df8cd24
Show file tree
Hide file tree
Showing 3 changed files with 81 additions and 24 deletions.
6 changes: 6 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,19 @@ license = "MIT OR Apache-2.0"
repository = "https://github.com/dtolnay/inventory"
rust-version = "1.62"

[dependencies]
cfg-if = "1.0"

[dev-dependencies]
rustversion = "1.0"
trybuild = { version = "1.0.89", features = ["diff"] }

[lib]
doc-scrape-examples = false

[features]
default-to-init-array-section = []

[package.metadata.docs.rs]
targets = ["x86_64-unknown-linux-gnu"]
rustdoc-args = ["--generate-link-to-definition"]
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,9 @@ registered at the time that dlopen occurs.

Platform support includes Linux, macOS, iOS, FreeBSD, Android, Windows, and a
few others. Beyond this, other platforms will simply find that no plugins have
been registered.
been registered. Alternatively, unsupported platforms may enable the
`default-to-init-array-section` feature to assign constructors to the
`.init_array` section.

For a different approach to plugin registration that *does not* involve
life-before-main, see the [`linkme`] crate.
Expand Down
95 changes: 72 additions & 23 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -433,29 +433,10 @@ macro_rules! __do_submit {
unsafe { $crate::ErasedNode::submit(__INVENTORY.value, &__INVENTORY) }
}

// Linux/ELF: https://www.exploit-db.com/papers/13234
//
// macOS: https://blog.timac.org/2016/0716-constructor-and-destructor-attributes/
//
// Why .CRT$XCU on Windows? https://www.cnblogs.com/sunkang/archive/2011/05/24/2055635.html
// 'I'=C init, 'C'=C++ init, 'P'=Pre-terminators and 'T'=Terminators
$($used)+
#[cfg_attr(
any(
target_os = "linux",
target_os = "android",
target_os = "dragonfly",
target_os = "freebsd",
target_os = "haiku",
target_os = "illumos",
target_os = "netbsd",
target_os = "openbsd",
),
link_section = ".init_array",
)]
#[cfg_attr(any(target_os = "macos", target_os = "ios"), link_section = "__DATA,__mod_init_func")]
#[cfg_attr(windows, link_section = ".CRT$XCU")]
static __CTOR: unsafe extern "C" fn() = __ctor;
$crate::__assign_static_to_section! {
$($used)+
static __CTOR: unsafe extern "C" fn() = __ctor;
}
};
};

Expand All @@ -473,3 +454,71 @@ macro_rules! __do_submit {
}
};
}

// Linux/ELF: https://www.exploit-db.com/papers/13234
//
// macOS: https://blog.timac.org/2016/0716-constructor-and-destructor-attributes/
//
// Why .CRT$XCU on Windows? https://www.cnblogs.com/sunkang/archive/2011/05/24/2055635.html
// 'I'=C init, 'C'=C++ init, 'P'=Pre-terminators and 'T'=Terminators
cfg_if::cfg_if! {
if #[cfg(any(
target_os = "linux",
target_os = "android",
target_os = "dragonfly",
target_os = "freebsd",
target_os = "haiku",
target_os = "illumos",
target_os = "netbsd",
target_os = "openbsd",
))] {
// Not public API.
#[doc(hidden)]
#[macro_export]
macro_rules! __assign_static_to_section {
($item:stmt) => {
#[link_section = ".init_array"]
$item
};
}
} else if #[cfg(any(target_os = "macos", target_os = "ios"))] {
// Not public API.
#[doc(hidden)]
#[macro_export]
macro_rules! __assign_static_to_section {
($item:stmt) => {
#[link_section = "__DATA,__mod_init_func"]
$item
};
}
} else if #[cfg(windows)] {
// Not public API.
#[doc(hidden)]
#[macro_export]
macro_rules! __assign_static_to_section {
($item:stmt) => {
#[link_section = ".CRT$XCU"]
$item
};
}
} else if #[cfg(feature = "default-to-init-array-section")] {
// Not public API.
#[doc(hidden)]
#[macro_export]
macro_rules! __assign_static_to_section {
($item:stmt) => {
#[link_section = ".init_array"]
$item
};
}
} else {
// Not public API.
#[doc(hidden)]
#[macro_export]
macro_rules! __assign_static_to_section {
($item:stmt) => {
$item
};
}
}
}

0 comments on commit df8cd24

Please sign in to comment.