Skip to content

Commit 9e97050

Browse files
committed
[namespace] support link section for macos
1 parent 15d84c9 commit 9e97050

File tree

2 files changed

+109
-15
lines changed

2 files changed

+109
-15
lines changed

modules/axns/src/lib.rs

Lines changed: 6 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -23,13 +23,9 @@ extern crate alloc;
2323

2424
use alloc::sync::Arc;
2525
use core::{alloc::Layout, fmt, ops::Deref};
26-
2726
use lazyinit::LazyInit;
2827

29-
unsafe extern "C" {
30-
fn __start_axns_resource();
31-
fn __stop_axns_resource();
32-
}
28+
pub mod link;
3329

3430
/// A namespace that contains all user-defined resources.
3531
///
@@ -66,13 +62,13 @@ impl AxNamespace {
6662

6763
/// Returns the size of the `axns_resource` section.
6864
fn section_size() -> usize {
69-
__stop_axns_resource as usize - __start_axns_resource as usize
65+
link::section_end() as usize - link::section_start() as usize
7066
}
7167

7268
/// Returns the global namespace.
7369
pub fn global() -> Self {
7470
Self {
75-
base: __start_axns_resource as *mut u8,
71+
base: link::section_start() as *mut u8,
7672
alloc: false,
7773
}
7874
}
@@ -92,7 +88,7 @@ impl AxNamespace {
9288
} else {
9389
let layout = Layout::from_size_align(size, 64).unwrap();
9490
let dst = unsafe { alloc::alloc::alloc(layout) };
95-
let src = __start_axns_resource as *const u8;
91+
let src = link::section_start();
9692
unsafe { core::ptr::copy_nonoverlapping(src, dst, size) };
9793
dst
9894
};
@@ -233,14 +229,9 @@ macro_rules! def_resource {
233229

234230
impl $name {
235231
unsafe fn deref_from_base(&self, ns_base: *mut u8) -> &$ty {
236-
unsafe extern {
237-
fn __start_axns_resource();
238-
}
239-
240-
#[unsafe(link_section = "axns_resource")]
241-
static RES: $ty = $default;
232+
$crate::def_static_resource!(RES, $ty, $default);
242233

243-
let offset = &RES as *const _ as usize - __start_axns_resource as usize;
234+
let offset = &RES as *const _ as *const u8 as usize - $crate::link::section_start() as usize;
244235
let ptr = unsafe{ ns_base.add(offset) } as *const _;
245236
unsafe{ &*ptr }
246237
}

modules/axns/src/link.rs

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
//! Module for defining static resources in the `axns_resource` section under
2+
//! different operating systems.
3+
//!
4+
//! The implementation is based on `link_section` attributes and platform-specific
5+
//! linker support.
6+
7+
#[cfg(any(target_os = "linux", target_os = "none"))]
8+
#[macro_use]
9+
pub mod linux {
10+
//! Module for defining static resources in the `axns_resource` section under Linux and
11+
//! other similar ELF environments.
12+
13+
unsafe extern "C" {
14+
fn __start_axns_resource();
15+
fn __stop_axns_resource();
16+
}
17+
18+
/// Defines a static resource of the specified type and default value,
19+
/// placing it in the custom linker section `axns_resource`.
20+
///
21+
/// # Parameters
22+
/// - `$ty`: The type of the static resource.
23+
/// - `$default`: The default value to initialize the resource with.
24+
///
25+
/// # Generated Items
26+
/// - A static variable `RES` of type `$ty`, initialized with `$default`.
27+
/// - A function `res_ptr()` that returns a raw pointer to the resource as `*const u8`.
28+
///
29+
/// # Example
30+
/// ```rust,ignore
31+
/// def_static_resource!(u32, 0);
32+
/// ```
33+
#[macro_export]
34+
macro_rules! def_static_resource {
35+
(RES, $ty: ty, $default: expr) => {
36+
#[unsafe(link_section = "axns_resource")]
37+
static RES: $ty = $default;
38+
};
39+
}
40+
41+
/// Returns a raw pointer to the static resource defined in the `axns_resource` section.
42+
pub fn section_start() -> *const u8 {
43+
__start_axns_resource as *const u8
44+
}
45+
46+
/// Returns a raw pointer to the end of the `axns_resource` section.
47+
pub fn section_end() -> *const u8 {
48+
__stop_axns_resource as *const u8
49+
}
50+
}
51+
52+
#[cfg(target_os = "macos")]
53+
#[macro_use]
54+
pub mod macho {
55+
//! Module for defining static resources in the `axns_resource` section under macOS
56+
//! and other similar mach-O environments.
57+
58+
unsafe extern "Rust" {
59+
#[link_name = "\u{1}section$start$__AXNS$__axns_resource"]
60+
static AXNS_RESOURCE_START: *const u8;
61+
#[link_name = "\u{1}section$end$__AXNS$__axns_resource"]
62+
static AXNS_RESOURCE_END: *const u8;
63+
}
64+
65+
#[macro_export]
66+
/// Defines a static resource of the specified type and default value,
67+
/// placing it in the custom linker section `axns_resource`.
68+
///
69+
/// # Parameters
70+
/// - `$ty`: The type of the static resource.
71+
/// - `$default`: The default value to initialize the resource with.
72+
///
73+
/// # Generated Items
74+
/// - A static variable `RES` of type `$ty`, initialized with `$default`.
75+
/// - A function `res_ptr()` that returns a raw pointer to the resource as `*const u8`.
76+
///
77+
/// # Example
78+
/// ```rust,ignore
79+
/// def_static_resource!(u32, 0);
80+
/// ```
81+
macro_rules! def_static_resource {
82+
(RES, $ty: ty, $default: expr) => {
83+
#[unsafe(link_section = "__AXNS,axns_resource")]
84+
static RES: $ty = $default;
85+
};
86+
}
87+
88+
/// Returns a pointer to the start of `axns_resource` section.
89+
pub fn section_start() -> *const u8 {
90+
unsafe { AXNS_RESOURCE_START }
91+
}
92+
93+
/// Returns a pointer to the end of `axns_resource` section.
94+
pub fn section_end() -> *const u8 {
95+
unsafe { AXNS_RESOURCE_END }
96+
}
97+
}
98+
99+
#[cfg(any(target_os = "linux", target_os = "none"))]
100+
pub use linux::*;
101+
102+
#[cfg(target_os = "macos")]
103+
pub use macho::*;

0 commit comments

Comments
 (0)