1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
use std::{env, fs::File, io::Write, path::PathBuf};

pub fn simink_gen_linker(offset: usize) {
    let target = env::var("TARGET").unwrap();
    let out = &PathBuf::from(env::var_os("OUT_DIR").unwrap());
    if target.starts_with("aarch64") {
        let mut f = File::create(out.join("linker.ld")).unwrap();
        writeln!(f, "OUTPUT_ARCH(aarch64)\nENTRY(_text)\nSECTIONS\n{{").unwrap();
        writeln!(
            f,
            "    /DISCARD/ : {{
        *(.discard)
        *(.discard.*)
        *(.interp .dynamic)
        *(.dynsym, .dynstr .hash .gnu.hash)
        *(.eh_frame)
    }}"
        )
        .unwrap();
        let off = 0xffff000000000000 + offset;
        writeln!(f, "    . = {:#x};", off).unwrap();
        writeln!(
            f,
            "    .head.text : {{
        _text = .;
        KEEP(*(.head.text))
    }}
    .text : {{
        _stext = .;
        . = ALIGN(8);
        *(.text.hot .text.* .text.fixup .text.unlikely)
        *(.fixup)
        *(.gnu.warning)
        . = ALIGN(16);
        *(.got)
    }}
    .idmap.text : {{
        . = ALIGN(0x00001000); __idmap_text_start = .; *(.idmap.text) __idmap_text_end = .;
    }}

    .got.plt : {{ *(.got.plt) }}
    . = ALIGN(0x10000);
    _etext = .;

    . = ALIGN(4096);
    .rodata : AT(ADDR(.rodata)) {{
        __start_rodata = .;
        *(.rodata) *(.rodata.*)
    }}
    .rodata1 : AT(ADDR(.rodata1)) {{
        *(.rodata1)
        __end_rodata = .;
    }}
    .notes : AT(ADDR(.notes)) {{
        __start_notes = .;
        KEEP(*(.note.*))
        __stop_notes = .;
    }}

    . = ALIGN(4096);
    idmap_pg_dir = .;
    . += 8192;
    idmap_pg_end = .;

    swapper_pg_dir = .;
    . += 8192;
    swapper_pg_end = .;

    . = ALIGN(4096);
    .data : AT(ADDR(.data)) {{
        _sdata = .;
        . = ALIGN(1 << 14);
        __start_stack = .;
        . = __start_stack + (1 << 14);
        __top_stack = .;
        . = ALIGN(4096);
        *(.data*)
        CONSTRUCTORS
        _edata = .;
    }}

    __bss_start = .;
    .sbss : AT(ADDR(.sbss)) {{
        *(.dynsbss) *(.sbss) *(.scommon)
    }}
    .bss : AT(ADDR(.bss)) {{
        *(.dynbss) *(.bss*) *(COMMON)
    }}
    . = ALIGN(8);
    __bss_stop = .;
    _end = .;
    .stab 0 : {{ *(.stab) }} .stabstr 0 : {{ *(.stabstr) }} .stab.excl 0 : {{ *(.stab.excl) }} .stab.exclstr 0 : {{ *(.stab.exclstr) }} .stab.index 0 : {{ *(.stab.index) }} .stab.indexstr 0 : {{ *(.stab.indexstr) }}
    .debug 0 : {{ *(.debug) }} .line 0 : {{ *(.line) }} .debug_srcinfo 0 : {{ *(.debug_srcinfo) }} .debug_sfnames 0 : {{ *(.debug_sfnames) }} .debug_aranges 0 : {{ *(.debug_aranges) }} .debug_pubnames 0 : {{ *(.debug_pubnames) }} .debug_info 0 : {{ *(.debug_info .gnu.linkonce.wi.*) }} .debug_abbrev 0 : {{ *(.debug_abbrev) }} .debug_line 0 : {{ *(.debug_line) }} .debug_frame 0 : {{ *(.debug_frame) }} .debug_str 0 : {{ *(.debug_str) }} .debug_loc 0 : {{ *(.debug_loc) }} .debug_macinfo 0 : {{ *(.debug_macinfo) }} .debug_pubtypes 0 : {{ *(.debug_pubtypes) }} .debug_ranges 0 : {{ *(.debug_ranges) }} .debug_weaknames 0 : {{ *(.debug_weaknames) }} .debug_funcnames 0 : {{ *(.debug_funcnames) }} .debug_typenames 0 : {{ *(.debug_typenames) }} .debug_varnames 0 : {{ *(.debug_varnames) }} .debug_gnu_pubnames 0 : {{ *(.debug_gnu_pubnames) }} .debug_gnu_pubtypes 0 : {{ *(.debug_gnu_pubtypes) }} .debug_types 0 : {{ *(.debug_types) }} .debug_addr 0 : {{ *(.debug_addr) }} .debug_line_str 0 : {{ *(.debug_line_str) }} .debug_loclists 0 : {{ *(.debug_loclists) }} .debug_macro 0 : {{ *(.debug_macro) }} .debug_names 0 : {{ *(.debug_names) }} .debug_rnglists 0 : {{ *(.debug_rnglists) }} .debug_str_offsets 0 : {{ *(.debug_str_offsets) }}
    .comment 0 : {{ *(.comment) }} .symtab 0 : {{ *(.symtab) }} .strtab 0 : {{ *(.strtab) }} .shstrtab 0 : {{ *(.shstrtab) }}
    .plt : {{
        *(.plt) *(.plt.*) *(.iplt) *(.igot .igot.plt)
    }}
    ASSERT(SIZEOF(.plt) == 0, \"Unexpected run-time procedure linkages detected!\")
    .data.rel.ro : {{ *(.data.rel.ro) }}
    ASSERT(SIZEOF(.data.rel.ro) == 0, \"Unexpected RELRO detected!\")
}}"
        )
        .unwrap();
    }

    println!("cargo:rustc-link-search={}", out.display());

    println!("cargo:rerun-if-changed=build.rs");
    println!("cargo:rustc-link-arg=-Tlinker.ld");
}