Skip to main content

link_section_example/
example.rs

1//! Example usage of the `link-section` crate.
2#![cfg_attr(linktime_used_linker, feature(used_with_arg))]
3
4use link_section::{in_section, section};
5
6/// An untyped link section with `code` linkage.
7#[section]
8pub static LINK_SECTION: link_section::Section;
9
10/// A function in the `LINK_SECTION` section.
11#[in_section(LINK_SECTION)]
12pub fn link_section_function() {
13    println!("link_section_function");
14}
15
16/// A typed link section with `data` linkage.
17#[section]
18pub static TYPED_LINK_SECTION: link_section::TypedSection<u32>;
19
20/// A `u32` in the `TYPED_LINK_SECTION` section.
21#[in_section(TYPED_LINK_SECTION)]
22pub static LINKED_U32: u32 = 1;
23
24/// Another `u32` in the `TYPED_LINK_SECTION` section.
25#[in_section(TYPED_LINK_SECTION)]
26pub static LINKED_U32_2: u32 = 2;
27
28/// Create an aux link section for `TYPED_LINK_SECTION`.
29#[section(aux = TYPED_LINK_SECTION)]
30pub static AUX_LINK_SECTION: link_section::TypedSection<u32>;
31
32/// An auxiliary section item.
33#[in_section(AUX_LINK_SECTION)]
34pub static AUX_LINKED_U32: u32 = 3;
35
36/// A function pointerarray in the `data` section.
37#[section]
38pub static FN_ARRAY: link_section::TypedSection<fn()>;
39
40/// A function in the `FN_ARRAY` section.
41#[in_section(FN_ARRAY)]
42pub fn linked_function() {
43    eprintln!("linked_function");
44}
45
46/// Another function in the `FN_ARRAY` section.
47#[in_section(FN_ARRAY)]
48pub fn linked_function_2() {
49    eprintln!("linked_function_2");
50}
51
52/// Yet another function in the `FN_ARRAY` section.
53#[in_section(FN_ARRAY)]
54pub static OTHER_FN: fn() = link_section_function;
55
56/// A debuggable section in the `data` section.
57#[section]
58pub static DEBUGGABLES: link_section::TypedSection<&'static (dyn ::core::fmt::Debug + Sync)>;
59
60/// A debuggable in the `DEBUGGABLES` section.
61#[in_section(DEBUGGABLES)]
62pub static DEBUGGABLE: &'static (dyn ::core::fmt::Debug + Sync) = &1;
63
64/// Another debuggable in the `DEBUGGABLES` section.
65#[in_section(DEBUGGABLES)]
66pub static DEBUGGABLE_2: &'static (dyn ::core::fmt::Debug + Sync) = &2;
67
68/// A function pointer in the `DEBUGGABLES` section.
69#[in_section(DEBUGGABLES)]
70pub const DEBUGGABLE_FUNCTION: &'static (dyn ::core::fmt::Debug + Sync) = {
71    struct Debuggable;
72    impl ::core::fmt::Debug for Debuggable {
73        fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
74            f.write_str("debuggable_function")
75        }
76    }
77    &Debuggable
78};
79
80/// Dumps the various sections.
81pub fn main() {
82    eprintln!("LINK_SECTION: {:?}", LINK_SECTION);
83    link_section_function();
84    eprintln!("TYPED_LINK_SECTION: {:?}", TYPED_LINK_SECTION);
85    assert!(TYPED_LINK_SECTION.offset_of(&LINKED_U32).is_some());
86    assert!(TYPED_LINK_SECTION.offset_of(&LINKED_U32_2).is_some());
87    eprintln!("AUX_LINK_SECTION: {:?}", AUX_LINK_SECTION);
88    assert!(AUX_LINK_SECTION.len() == 1);
89    let random_u32 = 1234567890;
90    assert!(TYPED_LINK_SECTION.offset_of(&random_u32).is_none());
91    eprintln!("CODE_SECTION: {:?}", FN_ARRAY);
92    eprintln!("{:?}", FN_ARRAY.as_slice());
93    for f in FN_ARRAY {
94        eprintln!("f: {:?}", f);
95        f();
96        assert!(FN_ARRAY.offset_of(f).is_some());
97    }
98    eprintln!("DEBUGGABLES: {:?}", DEBUGGABLES.as_slice());
99}