commit 02347abf7a0a54eeecaf6c4561d92b99a19f1819 Author: jam1garner Date: Wed Apr 8 00:21:52 2020 -0400 Initial commit, no_std_test diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..d7e9a64 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +**/target +**/*.py +**/*.pyc diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 0000000..66f45ed --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,140 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "cfg-if" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" + +[[package]] +name = "extern_alloc" +version = "0.1.0" + +[[package]] +name = "getrandom" +version = "0.1.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7abc8dd8451921606d809ba32e95b6111925cd2906060d2dcc29c070220503eb" +dependencies = [ + "cfg-if", + "libc", + "wasi", +] + +[[package]] +name = "libc" +version = "0.2.68" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dea0c0405123bba743ee3f91f49b1c7cfb684eef0da0a50110f758ccf24cdff0" + +[[package]] +name = "no_std_test" +version = "0.1.0" +dependencies = [ + "extern_alloc", + "tempfile", +] + +[[package]] +name = "ppv-lite86" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74490b50b9fbe561ac330df47c08f3f33073d2d00c150f719147d7c54522fa1b" + +[[package]] +name = "rand" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" +dependencies = [ + "getrandom", + "libc", + "rand_chacha", + "rand_core", + "rand_hc", +] + +[[package]] +name = "rand_chacha" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402" +dependencies = [ + "ppv-lite86", + "rand_core", +] + +[[package]] +name = "rand_core" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" +dependencies = [ + "getrandom", +] + +[[package]] +name = "rand_hc" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" +dependencies = [ + "rand_core", +] + +[[package]] +name = "redox_syscall" +version = "0.1.56" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2439c63f3f6139d1b57529d16bc3b8bb855230c8efcc5d3a896c8bea7c3b1e84" + +[[package]] +name = "remove_dir_all" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a83fa3702a688b9359eccba92d153ac33fd2e8462f9e0e3fdf155239ea7792e" +dependencies = [ + "winapi", +] + +[[package]] +name = "tempfile" +version = "3.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a6e24d9338a0a5be79593e2fa15a648add6138caa803e2d5bc782c371732ca9" +dependencies = [ + "cfg-if", + "libc", + "rand", + "redox_syscall", + "remove_dir_all", + "winapi", +] + +[[package]] +name = "wasi" +version = "0.9.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" + +[[package]] +name = "winapi" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8093091eeb260906a183e6ae1abdba2ef5ef2257a21801128899c3fc699229c6" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..b0a3ed6 --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "no_std_test" +version = "0.1.0" +authors = ["jam1garner "] +edition = "2018" + +[lib] +crate-type = ["cdylib"] + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +extern_alloc = { path = "./extern_alloc" } + +[build-dependencies] +tempfile = "3" + diff --git a/Xargo.toml b/Xargo.toml new file mode 100644 index 0000000..e5806e0 --- /dev/null +++ b/Xargo.toml @@ -0,0 +1,2 @@ +[target.aarch64-roblabla-switch.dependencies] +alloc = {} # implies alloc diff --git a/aarch64-roblabla-switch.json b/aarch64-roblabla-switch.json new file mode 100644 index 0000000..1f328e1 --- /dev/null +++ b/aarch64-roblabla-switch.json @@ -0,0 +1,44 @@ +{ + "abi-blacklist": [ + "stdcall", + "fastcall", + "vectorcall", + "thiscall", + "win64", + "sysv64" + ], + "arch": "aarch64", + "crt-static-default": false, + "crt-static-respected": false, + "data-layout": "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128", + "dynamic-linking": true, + "dynamic-linking-available": true, + "executables": true, + "has-elf-tls": false, + "has-rpath": false, + "linker-flavor": "ld.lld", + "llvm-target": "aarch64-unknown-none", + "max-atomic-width": 128, + "os": "switch", + "panic-strategy": "unwind", + "position-independent-executables": true, + "pre-link-args": { + "ld.lld": [ + "-Tlink.T", + "-init=__custom_init", + "-fini=__custom_fini", + "--export-dynamic" + ] + }, + "post-link-args": { + "ld.lld": [ + "--no-gc-sections", + "--eh-frame-hdr" + ] + }, + "relro-level": "off", + "target-c-int-width": "32", + "target-endian": "little", + "target-pointer-width": "64", + "vendor": "roblabla" +} diff --git a/extern_alloc/Cargo.lock b/extern_alloc/Cargo.lock new file mode 100644 index 0000000..99f6afe --- /dev/null +++ b/extern_alloc/Cargo.lock @@ -0,0 +1,5 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "extern_alloc" +version = "0.1.0" diff --git a/extern_alloc/Cargo.toml b/extern_alloc/Cargo.toml new file mode 100644 index 0000000..231b201 --- /dev/null +++ b/extern_alloc/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "extern_alloc" +version = "0.1.0" +authors = ["jam1garner "] +edition = "2018" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] diff --git a/extern_alloc/src/lib.rs b/extern_alloc/src/lib.rs new file mode 100644 index 0000000..2eac7eb --- /dev/null +++ b/extern_alloc/src/lib.rs @@ -0,0 +1,41 @@ +#![no_std] +#![feature(alloc_error_handler)] +use core::alloc::{GlobalAlloc, Layout}; +use core::ffi::c_void; + +extern "C" { + fn malloc(size: usize) -> *const c_void; + fn free(ptr: *const c_void); + fn calloc(num: usize, size: usize) -> *const c_void; + fn realloc(ptr: *const c_void, size: usize) -> *const c_void; + // fn aligned_alloc(align: usize, size: usize) -> *const c_void; +} + +pub struct Allocator; + +unsafe impl GlobalAlloc for Allocator { + #[inline] + unsafe fn alloc(&self, layout: Layout) -> *mut u8 { + malloc(layout.size()) as *mut u8 + } + + #[inline] + unsafe fn alloc_zeroed(&self, layout: Layout) -> *mut u8 { + calloc(layout.size(), 1) as *mut u8 + } + + #[inline] + unsafe fn dealloc(&self, ptr: *mut u8, _layout: Layout) { + free(ptr as *mut c_void) + } + + #[inline] + unsafe fn realloc(&self, ptr: *mut u8, _layout: Layout, new_size: usize) -> *mut u8 { + realloc(ptr as *mut c_void, new_size) as *mut u8 + } +} + +#[alloc_error_handler] +fn _alloc_error(_layout: Layout) -> ! { + panic!("Allocation error"); +} diff --git a/link.T b/link.T new file mode 100644 index 0000000..b67b4ea --- /dev/null +++ b/link.T @@ -0,0 +1,96 @@ +OUTPUT_FORMAT(elf64-littleaarch64) +OUTPUT_ARCH(aarch64) +ENTRY(_start) + +PHDRS +{ + text PT_LOAD FLAGS(5); + rodata PT_LOAD FLAGS(4); + data PT_LOAD FLAGS(6); + bss PT_LOAD FLAGS(6); + dynamic PT_DYNAMIC; +} + +SECTIONS +{ + . = 0; + + .text : ALIGN(0x1000) { + HIDDEN(__text_start = .); + KEEP(*(.nro_header)) + KEEP(*(.text.jmp)) + + . = 0x80; + + *(.text .text.*) + *(.plt .plt.*) + HIDDEN(__text_end = .); + } :text + + /* Read-only sections */ + + + . = ALIGN(0x1000); + .module_name : { KEEP (*(.rodata.module_name)) } :rodata + .rodata : { *(.rodata .rodata.*) } :rodata + .mod0 : { + KEEP(crt0.nso.o(.data.mod0)) + KEEP(crt0.nro.o(.data.mod0)) + KEEP(crt0.lib.nro.o(.data.mod0)) + } + .hash : { *(.hash) } + .dynsym : { *(.dynsym .dynsym.*) } + .dynstr : { *(.dynstr .dynstr.*) } + .rela.dyn : { *(.rela.dyn) } + + .eh_frame : ONLY_IF_RO { + HIDDEN(__eh_frame_start = .); + KEEP (*(.eh_frame)) *(.eh_frame.*) + HIDDEN(__eh_frame_end = .); + } + + .eh_frame_hdr : { + HIDDEN(__eh_frame_hdr_start = .); + *(.eh_frame_hdr) *(.eh_frame_entry .eh_frame_entry.*) + HIDDEN(__eh_frame_hdr_end = .); + } + .gcc_except_table : ONLY_IF_RO { *(.gcc_except_table .gcc_except_table.*) } + .gnu_extab : ONLY_IF_RO { *(.gnu_extab*) } + + /* Read-write sections */ + + . = ALIGN(0x1000); + + .data : { + *(.data .data.*) + *(.got .got.*) + *(.got.plt .got.plt.*) + } :data + + .eh_frame : ONLY_IF_RW { + HIDDEN(__eh_frame_start = .); + KEEP (*(.eh_frame)) *(.eh_frame.*) + HIDDEN(__eh_frame_end = .); + } + .gnu_extab : ONLY_IF_RW { *(.gnu_extab*) } + .gcc_except_table : ONLY_IF_RW { *(.gcc_except_table .gcc_except_table.*) } + + .dynamic : { + HIDDEN(__dynamic_start = .); + *(.dynamic) + } + + /* BSS section */ + + . = ALIGN(0x1000); + + .bss : { + HIDDEN(__bss_start = .); + *(.bss .bss.*) + *(COMMON) + HIDDEN(__nx_module_runtime = .); + *(.bss.module_runtime) + . = ALIGN(8); + HIDDEN(__bss_end = .); + } :bss +} diff --git a/src/lib.rs b/src/lib.rs new file mode 100644 index 0000000..7a03ab9 --- /dev/null +++ b/src/lib.rs @@ -0,0 +1,70 @@ +#![no_std] +#![allow(incomplete_features)] +#![feature(lang_items, start, global_asm, const_generics, impl_trait_in_bindings)] + +use core::any::Any; +use extern_alloc::Allocator; + +#[global_allocator] +pub static ALLOCATOR: Allocator = Allocator; + +extern crate alloc; +use alloc::vec; + +#[panic_handler] +fn panic(_info: &core::panic::PanicInfo) -> ! { + + log("Panic at the Rust lib!\n"); + + loop {} +} + +#[lang = "eh_personality"] extern fn eh_personality() {} + +extern "C" { + fn skyline_tcp_send_raw(bytes: *const u8, usize: u64); +} + +fn log(message: &str) { + unsafe { + skyline_tcp_send_raw(message.as_bytes().as_ptr(), message.as_bytes().len() as _); + } +} + +#[no_mangle] +pub fn main() { + let x = vec![1, 2, 3]; + log("Hello from Skyline Rust Plugin!\n"); + + if x[1] == 2 { + log("x[1] == 2\n"); + } else { + log("x[1] != 2\n"); + } +} + +global_asm!(include_str!("mod0.s")); + +#[repr(packed)] +#[allow(unused_variables)] +pub struct ModuleName { + pub unk: u32, + pub name_length: u32, + pub name: [u8; LEN], +} + +impl ModuleName { + pub const fn new(bytes: &[u8; LEN]) -> Self { + Self { + unk: 0, + name_length: LEN as u32, + name: *bytes, + } + } +} + +#[link_section = ".rodata.module_name"] +pub static MODULE_NAME: impl Any = ModuleName::new(b"no_std_test\0"); + +#[no_mangle] pub extern "C" fn __custom_init() {} +#[no_mangle] pub extern "C" fn __custom_fini() {} diff --git a/src/mod0.s b/src/mod0.s new file mode 100644 index 0000000..bd14ce2 --- /dev/null +++ b/src/mod0.s @@ -0,0 +1,24 @@ +.section .nro_header +.global __nro_header_start +.word 0 +.word _mod_header +.word 0 +.word 0 + +.section .rodata.mod0 +.global _mod_header +_mod_header: + .ascii "MOD0" + .word __dynamic_start - _mod_header + .word __bss_start - _mod_header + .word __bss_end - _mod_header + .word __eh_frame_hdr_start - _mod_header + .word __eh_frame_hdr_end - _mod_header + .word __nx_module_runtime - _mod_header // runtime-generated module object offset +.global IS_NRO +IS_NRO: + .word 1 + +.section .bss.module_runtime +.space 0xD0 +