Skip to content

Commit

Permalink
Merge pull request #110 from byeongkeunahn/linux-aarch64
Browse files Browse the repository at this point in the history
Support cargo run on Linux AArch64
  • Loading branch information
byeongkeunahn authored Sep 8, 2024
2 parents c4eaee5 + 09cdb5b commit 7816db3
Show file tree
Hide file tree
Showing 10 changed files with 113 additions and 8 deletions.
5 changes: 4 additions & 1 deletion .cargo/config.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,12 @@ rustflags = ["-Z", "share-generics=no", "-Z", "export-executable-symbols", "-C",
[target.aarch64-apple-darwin]
rustflags = ["-Z", "share-generics=no", "-C", "relocation-model=pie"]

[target.aarch64-unknown-linux-gnu]
rustflags = ["-Z", "share-generics=no", "-C", "relocation-model=pie"]

[target.x86_64-pc-windows-gnu]
rustflags = ["-Z", "share-generics=no", "-Z", "export-executable-symbols", "-C", "embed-bitcode=yes", "-C", "lto=thin", "-C", "target-feature=+avx,+avx2,+sse,+sse2,+sse3,+ssse3,+sse4.1,+sse4.2,+fma,+f16c,+aes", "-C", "relocation-model=pie", "-C", "target-cpu=haswell"]
linker = "x86_64-w64-mingw32-gcc"

[target.wasm32-unknown-unknown]
rustflags = ["-Z", "share-generics=no", "-C", "link-args=-z stack-size=67108864"]
rustflags = ["-Z", "share-generics=no", "-C", "link-args=-z stack-size=67108864"]
2 changes: 2 additions & 0 deletions basm-std/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ compiler_builtins = { version = "0.1.118", features = ["mem"] }
compiler_builtins = { version = "0.1.118", features = ["mem"] }
[target.i686-unknown-linux-gnu.dependencies]
compiler_builtins = { version = "0.1.118", features = ["mem"] }
[target.aarch64-unknown-linux-gnu.dependencies]
compiler_builtins = { version = "0.1.118", features = ["mem"] }
[target.aarch64-apple-darwin.dependencies]
compiler_builtins = { version = "0.1.118", features = ["mem"] }
[target.wasm32-unknown-unknown.dependencies]
Expand Down
32 changes: 30 additions & 2 deletions basm-std/src/platform/codegen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,10 @@
use core::arch::asm;

use crate::platform;
#[cfg(not(any(target_arch = "wasm32", target_arch = "aarch64")))]
#[cfg(not(any(
target_arch = "wasm32",
all(target_os = "macos", target_arch = "aarch64")
)))]
use crate::platform::loader;

/* We need to support multiple scenarios.
Expand Down Expand Up @@ -259,7 +262,7 @@ pub extern "C" fn _basm_start() {
_start_rust(&mut pd as *mut platform::services::PlatformData as usize);
}

#[cfg(target_arch = "aarch64")]
#[cfg(all(target_os = "macos", target_arch = "aarch64"))]
#[unsafe(no_mangle)]
#[naked]
#[repr(align(8))]
Expand All @@ -279,6 +282,31 @@ pub unsafe extern "C" fn _basm_start() -> ! {
}
}

#[cfg(all(target_os = "linux", target_arch = "aarch64"))]
#[unsafe(no_mangle)]
#[naked]
pub unsafe extern "C" fn _basm_start() -> ! {
unsafe {
asm!(
"adrp x0, __ehdr_start",
"add x0, x0, #:lo12:__ehdr_start",
"adrp x1, _DYNAMIC",
"add x1, x1, #:lo12:_DYNAMIC",
"bl {0}",
"sub sp, sp, #96",
"mov x0, #2", // 2 = ENV_ID_LINUX
"str x0, [sp, #(8 * 0)]",
"mov x0, #2", // 2 = ENV_FLAGS_NATIVE
"str x0, [sp, #(8 * 1)]",
"mov x0, sp",
"bl {1}",
sym loader::aarch64_elf::relocate,
sym _start_rust,
options(noreturn)
)
}
}

/* We prevent inlining solution::main, since if the user allocates
* a large amount of stack memory there, it will be zero-initialized (or probed)
* *before* we increase the stack limits if it is inlined into _start_rust.
Expand Down
67 changes: 67 additions & 0 deletions basm-std/src/platform/loader/aarch64_elf.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
const R_AARCH64_RELATIVE: u32 = 1027;

const DT_RELA: u64 = 7;
const DT_RELASZ: u64 = 8;
const DT_RELAENT: u64 = 9;

#[repr(C, packed)]
struct Elf64Dyn {
d_tag: u64,
d_val_or_ptr: u64,
}

#[repr(C, packed)]
struct Elf64Rela {
r_offset: u64,
r_info: u64,
r_addend: u64,
}

unsafe fn locate_dynamic_hdr(addr_dynamic_section: u64, d_tag: u64) -> *const Elf64Dyn {
unsafe {
let mut ptr = addr_dynamic_section as *const Elf64Dyn;
loop {
if (*ptr).d_tag == 0 {
break core::ptr::null();
}
if (*ptr).d_tag == d_tag {
break ptr;
}
ptr = ptr.add(1);
}
}
}

pub unsafe extern "C" fn relocate(addr_image_base: u64, addr_dynamic_section: u64) {
unsafe {
let dyn_ptr_rela = locate_dynamic_hdr(addr_dynamic_section, DT_RELA);
let dyn_ptr_relasz = locate_dynamic_hdr(addr_dynamic_section, DT_RELASZ);
let dyn_ptr_relaent = locate_dynamic_hdr(addr_dynamic_section, DT_RELAENT);

if dyn_ptr_rela == core::ptr::null()
|| dyn_ptr_relasz == core::ptr::null()
|| dyn_ptr_relaent == core::ptr::null()
{
return;
}

let rela_base = (addr_image_base + (*dyn_ptr_rela).d_val_or_ptr) as usize;
let relasz = (*dyn_ptr_relasz).d_val_or_ptr as usize;
let relaent = (*dyn_ptr_relaent).d_val_or_ptr as usize;

let mut rela_addr = rela_base;
while rela_addr < rela_base + relasz {
let rela_ptr = rela_addr as *const Elf64Rela;
let r_info_type = (*rela_ptr).r_info as u32;
if r_info_type == R_AARCH64_RELATIVE {
let addr = (addr_image_base + (*rela_ptr).r_offset) as usize;
let value = addr_image_base.wrapping_add((*rela_ptr).r_addend);
core::ptr::write(addr as *mut u64, value);
} else {
// Unimplemented or unknown relocation type
panic!();
}
rela_addr += relaent;
}
}
}
2 changes: 2 additions & 0 deletions basm-std/src/platform/loader/mod.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
#[cfg(all(target_arch = "aarch64", target_os = "linux"))]
pub mod aarch64_elf;
#[cfg(all(target_arch = "x86_64", not(target_os = "windows")))]
pub mod amd64_elf;
#[cfg(all(target_arch = "x86_64", target_os = "windows"))]
Expand Down
2 changes: 1 addition & 1 deletion basm-std/src/platform/malloc/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ pub mod dlmalloc;
pub mod dlmalloc_interface;
#[cfg(not(target_arch = "wasm32"))]
pub mod dlmalloc_linux;
#[cfg(target_arch = "aarch64")]
#[cfg(all(target_os = "macos", target_arch = "aarch64"))]
pub mod dlmalloc_macos;
#[cfg(target_arch = "wasm32")]
pub mod dlmalloc_wasm32;
Expand Down
2 changes: 1 addition & 1 deletion basm-std/src/platform/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ pub fn try_exit() {
os::linux::syscall::exit_group(services::get_exit_status() as usize);
}
}
#[cfg(target_arch = "aarch64")]
#[cfg(all(target_os = "macos", target_arch = "aarch64"))]
if pd.env_id == services::ENV_ID_MACOS {
unsafe {
os::macos::syscall::exit_group(services::get_exit_status() as usize);
Expand Down
4 changes: 2 additions & 2 deletions basm-std/src/platform/os/mod.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#[cfg(not(any(target_arch = "wasm32")))]
#[cfg(not(target_arch = "wasm32"))]
pub mod linux;
#[cfg(target_arch = "aarch64")]
#[cfg(all(target_os = "macos", target_arch = "aarch64"))]
pub mod macos;
pub mod unknown;
#[cfg(target_arch = "wasm32")]
Expand Down
2 changes: 2 additions & 0 deletions basm/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ compiler_builtins = { version = "0.1.118", features = ["mem"] }
compiler_builtins = { version = "0.1.118", features = ["mem"] }
[target.i686-unknown-linux-gnu.dependencies]
compiler_builtins = { version = "0.1.118", features = ["mem"] }
[target.aarch64-unknown-linux-gnu.dependencies]
compiler_builtins = { version = "0.1.118", features = ["mem"] }
[target.aarch64-apple-darwin.dependencies]
compiler_builtins = { version = "0.1.118", features = ["mem"] }
[target.wasm32-unknown-unknown.dependencies]
Expand Down
3 changes: 2 additions & 1 deletion basm/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,8 @@ fn main() {
}
"x86_64-unknown-linux-gnu"
| "x86_64-unknown-linux-gnu-short"
| "i686-unknown-linux-gnu" => {
| "i686-unknown-linux-gnu"
| "aarch64-unknown-linux-gnu" => {
link_args_basm.push("-nostartfiles");
link_args_basm.push("-nostdlib");
link_args_basm.push("-static-pie");
Expand Down

0 comments on commit 7816db3

Please sign in to comment.