Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 14 additions & 7 deletions link-section/src/platform/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ pub const fn validate_section_name(name: &str) {

/// Launder a pointer's provenance so it appears as an "exposed" pointer.
pub fn launder_pointer_provenance<T>(ptr: *const T) -> *const T {
#[cfg(not(windows))]
#[cfg(any(not(windows), miri))]
{
core::ptr::with_exposed_provenance(ptr.expose_provenance())
}
Expand All @@ -48,20 +48,27 @@ pub fn launder_pointer_provenance<T>(ptr: *const T) -> *const T {
// exposed provenance and reverts it, which it then traces to the marker allocation which
// it then believes all slice loads come from.
//
// Treating this provenance round-trip as a no-op is arguably an LLVM optimization issue
// somewhere between Rust and LLVM.
#[cfg(windows)]
// Treating this provenance round-trip as a no-op is arguably an LLVM optimization issue.
#[cfg(all(windows, not(miri)))]
{
core::hint::black_box(core::ptr::with_exposed_provenance(ptr.expose_provenance()))
unsafe extern "C" {
#[link_name = crate::__ls_provenance_symbol!()]
static LS_PROVENANCE_DONOR: u8;
}

// Copy provenance from a non-Rust symbol ineligible for many
// optimizations to the pointer. It is far less likely for early optimization
// passes to fold the pointer into the marker's allocation.
(&raw const LS_PROVENANCE_DONOR).with_addr(ptr.addr()) as *const T
}
}

/// Constant bounds for a pointer-based section.
pub struct PtrBounds {
/// Section start address.
pub start: *const (),
start: *const (),
/// One byte past the last section byte.
pub end: *const (),
end: *const (),
}

impl PtrBounds {
Expand Down
38 changes: 38 additions & 0 deletions link-section/src/platform/windows.rs
Original file line number Diff line number Diff line change
Expand Up @@ -150,3 +150,41 @@ crate::__def_section_name! {
HASH_LENGTH = 10;
VALID_SECTION_CHARS = "_ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
}

/// Linker-visible provenance donor for Windows.
#[doc(hidden)]
#[macro_export]
macro_rules! __ls_provenance_symbol {
() => {
concat!(
"__ls_prov_",
env!("CARGO_CRATE_NAME"),
"_",
env!("CARGO_PKG_VERSION_MAJOR"),
"_",
env!("CARGO_PKG_VERSION_MINOR"),
"_",
env!("CARGO_PKG_VERSION_PATCH"),
)
};
}

// Linker-visible provenance donor for Windows.
#[cfg(all(target_os = "windows", not(miri)))]
core::arch::global_asm!(core::concat!(
// read-only
".pushsection .rdata$",
__ls_provenance_symbol!(),
// ..."d" = initialized, "r" = read-only
// "discard" = "duplicates OK"
",\"dr\",discard,",
__ls_provenance_symbol!(),
"\n",
".globl ",
__ls_provenance_symbol!(),
"\n",
__ls_provenance_symbol!(),
":\n",
".byte 0\n",
".popsection\n",
));
8 changes: 4 additions & 4 deletions link-section/tests/expand-darwin/link_section.expanded.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,22 +19,22 @@ impl FOO {
{
#[allow(missing_unsafe_on_extern)]
extern "C" {
#[link_name = "\u{1}section$start$__DATA$FOO74oV7cnUspp"]
#[link_name = "\u{1}section$start$__DATA$FOO6jQ6HDNgQqM"]
static __SYMBOL: u8;
}
unsafe { &raw const __SYMBOL as *const () }
},
{
#[allow(missing_unsafe_on_extern)]
extern "C" {
#[link_name = "\u{1}section$end$__DATA$FOO74oV7cnUspp"]
#[link_name = "\u{1}section$end$__DATA$FOO6jQ6HDNgQqM"]
static __SYMBOL: u8;
}
unsafe { &raw const __SYMBOL as *const () }
},
)
};
let name = "__DATA,FOO74oV7cnUspp";
let name = "__DATA,FOO6jQ6HDNgQqM";
::link_section::__support::validate_section_name(name);
unsafe { <TypedSection<fn()>>::new(name, section) }
};
Expand Down Expand Up @@ -76,7 +76,7 @@ fn foo() {
type __InSecStoredTy = <FOO as ::link_section::__support::SectionItemType>::Item;
const __LINK_SECTION_CONST_ITEM_VALUE: __InSecStoredTy = foo;
#[used]
#[link_section = "__DATA,FOO74oV7cnUspp,regular,no_dead_strip"]
#[link_section = "__DATA,FOO6jQ6HDNgQqM,regular,no_dead_strip"]
static __LINK_SECTION_CONST_ITEM: __InSecStoredTy = __LINK_SECTION_CONST_ITEM_VALUE;
__LINK_SECTION_CONST_ITEM_VALUE
};
Expand Down
8 changes: 4 additions & 4 deletions link-section/tests/expand-linux/link_section.expanded.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,22 +20,22 @@ impl FOO {
{
#[allow(missing_unsafe_on_extern)]
extern "C" {
#[link_name = "__start__data_link_section_FOO74oV7cnUspp"]
#[link_name = "__start__data_link_section_FOO6jQ6HDNgQqM"]
static __SYMBOL: u8;
}
unsafe { &raw const __SYMBOL as *const () }
},
{
#[allow(missing_unsafe_on_extern)]
extern "C" {
#[link_name = "__stop__data_link_section_FOO74oV7cnUspp"]
#[link_name = "__stop__data_link_section_FOO6jQ6HDNgQqM"]
static __SYMBOL: u8;
}
unsafe { &raw const __SYMBOL as *const () }
},
)
};
let name = "_data_link_section_FOO74oV7cnUspp";
let name = "_data_link_section_FOO6jQ6HDNgQqM";
::link_section::__support::validate_section_name(name);
unsafe { <TypedSection<fn()>>::new(name, section) }
};
Expand Down Expand Up @@ -77,7 +77,7 @@ fn foo() {
type __InSecStoredTy = <FOO as ::link_section::__support::SectionItemType>::Item;
const __LINK_SECTION_CONST_ITEM_VALUE: __InSecStoredTy = foo;
#[used]
#[link_section = "_data_link_section_FOO74oV7cnUspp"]
#[link_section = "_data_link_section_FOO6jQ6HDNgQqM"]
static __LINK_SECTION_CONST_ITEM: __InSecStoredTy = __LINK_SECTION_CONST_ITEM_VALUE;
__LINK_SECTION_CONST_ITEM_VALUE
};
Expand Down
15 changes: 3 additions & 12 deletions tests/link_section/copied/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,13 +1,6 @@
[package]
name = "tests"
version = "0.1.0"
edition = "2021"
publish = false

[dependencies]
ctor = { path = "../../../ctor" }
link-section = { path = "../../../link-section" }
libc-print = "0.5"
[workspace]
members = ["copied", "copied-types", "register-a", "register-b"]
resolver = "2"

[profile.dev]
opt-level = 3
Expand All @@ -18,5 +11,3 @@ codegen-units = 1
opt-level = 3
lto = "fat"
codegen-units = 1

[workspace]
8 changes: 8 additions & 0 deletions tests/link_section/copied/copied-types/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
[package]
name = "copied-types"
version = "0.1.0"
edition = "2021"
publish = false

[dependencies]
link-section = { path = "../../../../link-section" }
27 changes: 27 additions & 0 deletions tests/link_section/copied/copied-types/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
//! Shared types and link sections for the `copied` integration test.

use link_section::section;

#[derive(Debug, Copy, Clone, Ord, PartialOrd, Eq, PartialEq)]
pub struct ComplexType {
pub static_string: &'static str,
pub static_ptr: &'static OtherType,
}

#[derive(Debug, Copy, Clone, Ord, PartialOrd, Eq, PartialEq)]
pub struct OtherType {
pub u32: u32,
pub u64: u64,
}

pub static OTHER_TYPE: OtherType = OtherType { u32: 1, u64: 2 };
pub static OTHER_TYPE_2: OtherType = OtherType { u32: 3, u64: 4 };

#[section(typed)]
pub static VALUES: link_section::TypedSection<&'static u64>;

#[section(mutable)]
pub static MUT_LINK_SECTION: link_section::TypedMutableSection<ComplexType>;

#[section(typed)]
pub static IMMUTABLE_LINK_SECTION: link_section::TypedSection<ComplexType>;
14 changes: 14 additions & 0 deletions tests/link_section/copied/copied/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
[package]
name = "copied"
version = "0.1.0"
edition = "2021"
publish = false

[dependencies]
copied-types = { path = "../copied-types" }
register-a = { path = "../register-a" }
register-b = { path = "../register-b" }

[[bin]]
name = "copied"
path = "src/main.rs"
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
//! Example usage of the `link-section` crate.
//! Cross-crate link-section smoke test under fat LTO.
//!
//! Sections and shared types live in `copied-types`; item registrations are
//! split across `register-a` and `register-b`.

mod sections;
use copied_types::{IMMUTABLE_LINK_SECTION, MUT_LINK_SECTION, VALUES};

use sections::{IMMUTABLE_LINK_SECTION, MUT_LINK_SECTION, VALUES};
// Pull registrar object code into the link (no direct API use).
use register_a as _;
use register_b as _;

pub fn main() {
// LLVM was optimizing these copies into memsets
Expand Down
9 changes: 9 additions & 0 deletions tests/link_section/copied/register-a/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
[package]
name = "register-a"
version = "0.1.0"
edition = "2021"
publish = false

[dependencies]
copied-types = { path = "../copied-types" }
link-section = { path = "../../../../link-section" }
46 changes: 46 additions & 0 deletions tests/link_section/copied/register-a/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
//! Registrations for the `copied` integration test (crate A).

use copied_types::{ComplexType, IMMUTABLE_LINK_SECTION, MUT_LINK_SECTION, OTHER_TYPE, OTHER_TYPE_2, VALUES};
use link_section::in_section;

#[in_section(VALUES)]
const _: &'static u64 = {
static V: u64 = 50;
&V
};

#[in_section(VALUES)]
const _: &'static u64 = {
static V: u64 = 10;
&V
};

#[in_section(VALUES)]
const _: &'static u64 = {
static V: u64 = 40;
&V
};

#[in_section(MUT_LINK_SECTION)]
const _: ComplexType = ComplexType {
static_string: "1",
static_ptr: &OTHER_TYPE,
};

#[in_section(MUT_LINK_SECTION)]
const _: ComplexType = ComplexType {
static_string: "2",
static_ptr: &OTHER_TYPE,
};

#[in_section(IMMUTABLE_LINK_SECTION)]
const _: ComplexType = ComplexType {
static_string: "1",
static_ptr: &OTHER_TYPE,
};

#[in_section(IMMUTABLE_LINK_SECTION)]
const _: ComplexType = ComplexType {
static_string: "9",
static_ptr: &OTHER_TYPE_2,
};
9 changes: 9 additions & 0 deletions tests/link_section/copied/register-b/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
[package]
name = "register-b"
version = "0.1.0"
edition = "2021"
publish = false

[dependencies]
copied-types = { path = "../copied-types" }
link-section = { path = "../../../../link-section" }
40 changes: 40 additions & 0 deletions tests/link_section/copied/register-b/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
//! Registrations for the `copied` integration test (crate B).

use copied_types::{ComplexType, IMMUTABLE_LINK_SECTION, MUT_LINK_SECTION, OTHER_TYPE, OTHER_TYPE_2, VALUES};
use link_section::in_section;

#[in_section(VALUES)]
const _: &'static u64 = {
static V: u64 = 20;
&V
};

#[in_section(VALUES)]
const _: &'static u64 = {
static V: u64 = 30;
&V
};

#[in_section(MUT_LINK_SECTION)]
const _: ComplexType = ComplexType {
static_string: "4",
static_ptr: &OTHER_TYPE_2,
};

#[in_section(MUT_LINK_SECTION)]
const _: ComplexType = ComplexType {
static_string: "5",
static_ptr: &OTHER_TYPE,
};

#[in_section(MUT_LINK_SECTION)]
const _: ComplexType = ComplexType {
static_string: "3",
static_ptr: &OTHER_TYPE,
};

#[in_section(IMMUTABLE_LINK_SECTION)]
const _: ComplexType = ComplexType {
static_string: "4",
static_ptr: &OTHER_TYPE,
};
Loading
Loading