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");
}