From 2371272e5cd2de189feda32b3e486f9fd754008a Mon Sep 17 00:00:00 2001 From: Dan Robertson Date: Sun, 4 Mar 2018 23:01:08 +0000 Subject: [PATCH 1/4] Run rustfmt on code --- src/impl-arm-sysv.rs | 81 ++++++++++++++++++++++++++-------------- src/impl-x86-sysv.rs | 81 ++++++++++++++++++++++++++-------------- src/impl-x86_64-elf.rs | 76 ++++++++++++++++++------------------- src/impl-x86_64-win64.rs | 73 ++++++++++++++++++++++++------------ src/lib.rs | 54 ++++++++++++++------------- tests/lib.rs | 46 +++++++++++++---------- 6 files changed, 246 insertions(+), 165 deletions(-) diff --git a/src/impl-arm-sysv.rs b/src/impl-arm-sysv.rs index ae3f269..ef5e99a 100644 --- a/src/impl-arm-sysv.rs +++ b/src/impl-arm-sysv.rs @@ -1,43 +1,68 @@ /* * */ -use std::{mem,ptr}; +use std::{mem, ptr}; use super::VaPrimitive; #[allow(non_camel_case_types)] pub struct VaList(*const u8); -impl VaList -{ - pub unsafe fn get(&mut self) -> T { - T::get(self) - } - - // Read a raw value from the list - unsafe fn get_raw(&mut self) -> T { - assert_eq!(self.0 as usize % mem::align_of::(), 0); - let rv = ptr::read(self.0 as *const T); - self.0 = self.0.offset( mem::size_of::() as isize ); - rv - } +impl VaList { + pub unsafe fn get(&mut self) -> T { + T::get(self) + } + + // Read a raw value from the list + unsafe fn get_raw(&mut self) -> T { + assert_eq!(self.0 as usize % mem::align_of::(), 0); + let rv = ptr::read(self.0 as *const T); + self.0 = self.0.offset(mem::size_of::() as isize); + rv + } } -impl VaPrimitive for *const T -{ - unsafe fn get(list: &mut VaList) -> Self { - ::get(list) as *const T - } -} -impl VaPrimitive for usize { unsafe fn get(l: &mut VaList) -> Self { l.get_raw() } } -impl VaPrimitive for isize { unsafe fn get(l: &mut VaList) -> Self { l.get_raw() } } -impl VaPrimitive for u64 { unsafe fn get(l: &mut VaList) -> Self { l.get_raw() } } -impl VaPrimitive for i64 { unsafe fn get(l: &mut VaList) -> Self { l.get_raw() } } -impl VaPrimitive for u32 { unsafe fn get(l: &mut VaList) -> Self { l.get_raw() } } -impl VaPrimitive for i32 { unsafe fn get(l: &mut VaList) -> Self { l.get_raw() } } +impl VaPrimitive for *const T { + unsafe fn get(list: &mut VaList) -> Self { + ::get(list) as *const T + } +} +impl VaPrimitive for usize { + unsafe fn get(l: &mut VaList) -> Self { + l.get_raw() + } +} +impl VaPrimitive for isize { + unsafe fn get(l: &mut VaList) -> Self { + l.get_raw() + } +} +impl VaPrimitive for u64 { + unsafe fn get(l: &mut VaList) -> Self { + l.get_raw() + } +} +impl VaPrimitive for i64 { + unsafe fn get(l: &mut VaList) -> Self { + l.get_raw() + } +} +impl VaPrimitive for u32 { + unsafe fn get(l: &mut VaList) -> Self { + l.get_raw() + } +} +impl VaPrimitive for i32 { + unsafe fn get(l: &mut VaList) -> Self { + l.get_raw() + } +} //impl VaPrimitive for u16 { unsafe fn get(l: &mut VaList) -> Self { l.get_raw() } } //impl VaPrimitive for i16 { unsafe fn get(l: &mut VaList) -> Self { l.get_raw() } } //impl VaPrimitive for u8 { unsafe fn get(l: &mut VaList) -> Self { l.get_raw() } } //impl VaPrimitive for i8 { unsafe fn get(l: &mut VaList) -> Self { l.get_raw() } } -impl VaPrimitive for f64 { unsafe fn get(l: &mut VaList) -> Self { l.get_raw() } } +impl VaPrimitive for f64 { + unsafe fn get(l: &mut VaList) -> Self { + l.get_raw() + } +} //impl VaPrimitive for f32 { unsafe fn get(l: &mut VaList) -> Self { l.get_raw() } } - diff --git a/src/impl-x86-sysv.rs b/src/impl-x86-sysv.rs index ae3f269..ef5e99a 100644 --- a/src/impl-x86-sysv.rs +++ b/src/impl-x86-sysv.rs @@ -1,43 +1,68 @@ /* * */ -use std::{mem,ptr}; +use std::{mem, ptr}; use super::VaPrimitive; #[allow(non_camel_case_types)] pub struct VaList(*const u8); -impl VaList -{ - pub unsafe fn get(&mut self) -> T { - T::get(self) - } - - // Read a raw value from the list - unsafe fn get_raw(&mut self) -> T { - assert_eq!(self.0 as usize % mem::align_of::(), 0); - let rv = ptr::read(self.0 as *const T); - self.0 = self.0.offset( mem::size_of::() as isize ); - rv - } +impl VaList { + pub unsafe fn get(&mut self) -> T { + T::get(self) + } + + // Read a raw value from the list + unsafe fn get_raw(&mut self) -> T { + assert_eq!(self.0 as usize % mem::align_of::(), 0); + let rv = ptr::read(self.0 as *const T); + self.0 = self.0.offset(mem::size_of::() as isize); + rv + } } -impl VaPrimitive for *const T -{ - unsafe fn get(list: &mut VaList) -> Self { - ::get(list) as *const T - } -} -impl VaPrimitive for usize { unsafe fn get(l: &mut VaList) -> Self { l.get_raw() } } -impl VaPrimitive for isize { unsafe fn get(l: &mut VaList) -> Self { l.get_raw() } } -impl VaPrimitive for u64 { unsafe fn get(l: &mut VaList) -> Self { l.get_raw() } } -impl VaPrimitive for i64 { unsafe fn get(l: &mut VaList) -> Self { l.get_raw() } } -impl VaPrimitive for u32 { unsafe fn get(l: &mut VaList) -> Self { l.get_raw() } } -impl VaPrimitive for i32 { unsafe fn get(l: &mut VaList) -> Self { l.get_raw() } } +impl VaPrimitive for *const T { + unsafe fn get(list: &mut VaList) -> Self { + ::get(list) as *const T + } +} +impl VaPrimitive for usize { + unsafe fn get(l: &mut VaList) -> Self { + l.get_raw() + } +} +impl VaPrimitive for isize { + unsafe fn get(l: &mut VaList) -> Self { + l.get_raw() + } +} +impl VaPrimitive for u64 { + unsafe fn get(l: &mut VaList) -> Self { + l.get_raw() + } +} +impl VaPrimitive for i64 { + unsafe fn get(l: &mut VaList) -> Self { + l.get_raw() + } +} +impl VaPrimitive for u32 { + unsafe fn get(l: &mut VaList) -> Self { + l.get_raw() + } +} +impl VaPrimitive for i32 { + unsafe fn get(l: &mut VaList) -> Self { + l.get_raw() + } +} //impl VaPrimitive for u16 { unsafe fn get(l: &mut VaList) -> Self { l.get_raw() } } //impl VaPrimitive for i16 { unsafe fn get(l: &mut VaList) -> Self { l.get_raw() } } //impl VaPrimitive for u8 { unsafe fn get(l: &mut VaList) -> Self { l.get_raw() } } //impl VaPrimitive for i8 { unsafe fn get(l: &mut VaList) -> Self { l.get_raw() } } -impl VaPrimitive for f64 { unsafe fn get(l: &mut VaList) -> Self { l.get_raw() } } +impl VaPrimitive for f64 { + unsafe fn get(l: &mut VaList) -> Self { + l.get_raw() + } +} //impl VaPrimitive for f32 { unsafe fn get(l: &mut VaList) -> Self { l.get_raw() } } - diff --git a/src/impl-x86_64-elf.rs b/src/impl-x86_64-elf.rs index 3680196..92a2e9c 100644 --- a/src/impl-x86_64-elf.rs +++ b/src/impl-x86_64-elf.rs @@ -1,6 +1,6 @@ // x86_64 ELF - Aka the Itanium ABI // -use std::{mem,ptr}; +use std::{mem, ptr}; use super::VaPrimitive; pub struct VaList(*mut VaListInner); @@ -10,28 +10,26 @@ pub struct VaList(*mut VaListInner); #[repr(C)] #[derive(Debug)] #[doc(hidden)] -pub struct VaListInner -{ - gp_offset: u32, - fp_offset: u32, - overflow_arg_area: *const (), - reg_save_area: *const (), +pub struct VaListInner { + gp_offset: u32, + fp_offset: u32, + overflow_arg_area: *const (), + reg_save_area: *const (), } -impl VaList -{ - fn inner(&mut self) -> &mut VaListInner { - // This pointer should be valid - unsafe { &mut *self.0 } - } +impl VaList { + fn inner(&mut self) -> &mut VaListInner { + // This pointer should be valid + unsafe { &mut *self.0 } + } } #[doc(hidden)] -impl VaListInner -{ +impl VaListInner { fn check_space(&self, num_gp: u32, num_fp: u32) -> bool { !(self.gp_offset > 48 - num_gp * 8 || self.fp_offset > 304 - num_fp * 16) } + unsafe fn get_gp(&mut self) -> T { let n_gp = (mem::size_of::()+7)/8; assert!( self.check_space(n_gp as u32, 0) ); @@ -39,6 +37,7 @@ impl VaListInner self.gp_offset += (8*n_gp) as u32; rv } + unsafe fn get_fp(&mut self) -> T { let n_fp = (mem::size_of::()+15)/16; assert!( self.check_space(0, n_fp as u32) ); @@ -46,6 +45,7 @@ impl VaListInner self.fp_offset += (16*n_fp) as u32; rv } + unsafe fn get_overflow(&mut self) -> T { let align = mem::align_of::(); // 7. Align overflow_reg_area upwards to a 16-byte boundary if alignment @@ -68,33 +68,31 @@ impl VaListInner } } -impl VaPrimitive for *const T -{ - unsafe fn get(list: &mut VaList) -> Self { - ::get(list) as *const T - } +impl VaPrimitive for *const T { + unsafe fn get(list: &mut VaList) -> Self { + ::get(list) as *const T + } } macro_rules! impl_va_prim { - ($u:ty, $s:ty) => { - impl VaPrimitive for $u { - unsafe fn get(list: &mut VaList) -> Self { - let inner = list.inner(); - // See the ELF AMD64 ABI document for a description of how this should act - if ! inner.check_space(1, 0) { - inner.get_overflow() - } - else { - inner.get_gp() - } - } - } - impl VaPrimitive for $s { - unsafe fn get(list: &mut VaList) -> Self { - mem::transmute( <$u>::get(list) ) - } - } - }; + ($u: ty, $s: ty) => { + impl VaPrimitive for $u { + unsafe fn get(list: &mut VaList) -> Self { + let inner = list.inner(); + // See the ELF AMD64 ABI document for a description of how this should act + if !inner.check_space(1, 0) { + inner.get_overflow() + } else { + inner.get_gp() + } + } + } + impl VaPrimitive for $s { + unsafe fn get(list: &mut VaList) -> Self { + mem::transmute(<$u>::get(list)) + } + } + }; } impl_va_prim!{ usize, isize } diff --git a/src/impl-x86_64-win64.rs b/src/impl-x86_64-win64.rs index 40e5758..49a78ff 100644 --- a/src/impl-x86_64-win64.rs +++ b/src/impl-x86_64-win64.rs @@ -1,39 +1,64 @@ /* * */ -use std::{mem,ptr}; +use std::{mem, ptr}; use super::VaPrimitive; #[allow(non_camel_case_types)] pub struct VaList(*const u8); -impl VaList -{ - // Read a raw value from the list - unsafe fn get_raw(&mut self) -> T { - assert_eq!(self.0 as usize % mem::align_of::(), 0); - let rv = ptr::read(self.0 as *const T); - self.0 = self.0.offset( mem::size_of::() as isize ); - rv - } +impl VaList { + // Read a raw value from the list + unsafe fn get_raw(&mut self) -> T { + assert_eq!(self.0 as usize % mem::align_of::(), 0); + let rv = ptr::read(self.0 as *const T); + self.0 = self.0.offset(mem::size_of::() as isize); + rv + } } -impl VaPrimitive for *const T -{ - unsafe fn get(list: &mut VaList) -> Self { - ::get(list) as *const T - } -} -impl VaPrimitive for usize { unsafe fn get(l: &mut VaList) -> Self { l.get_raw() } } -impl VaPrimitive for isize { unsafe fn get(l: &mut VaList) -> Self { l.get_raw() } } -impl VaPrimitive for u64 { unsafe fn get(l: &mut VaList) -> Self { l.get_raw() } } -impl VaPrimitive for i64 { unsafe fn get(l: &mut VaList) -> Self { l.get_raw() } } -impl VaPrimitive for u32 { unsafe fn get(l: &mut VaList) -> Self { l.get_raw::() as u32 } } -impl VaPrimitive for i32 { unsafe fn get(l: &mut VaList) -> Self { l.get_raw::() as i32 } } +impl VaPrimitive for *const T { + unsafe fn get(list: &mut VaList) -> Self { + ::get(list) as *const T + } +} +impl VaPrimitive for usize { + unsafe fn get(l: &mut VaList) -> Self { + l.get_raw() + } +} +impl VaPrimitive for isize { + unsafe fn get(l: &mut VaList) -> Self { + l.get_raw() + } +} +impl VaPrimitive for u64 { + unsafe fn get(l: &mut VaList) -> Self { + l.get_raw() + } +} +impl VaPrimitive for i64 { + unsafe fn get(l: &mut VaList) -> Self { + l.get_raw() + } +} +impl VaPrimitive for u32 { + unsafe fn get(l: &mut VaList) -> Self { + l.get_raw::() as u32 + } +} +impl VaPrimitive for i32 { + unsafe fn get(l: &mut VaList) -> Self { + l.get_raw::() as i32 + } +} //impl VaPrimitive for u16 { unsafe fn get(l: &mut VaList) -> Self { l.get_raw() } } //impl VaPrimitive for i16 { unsafe fn get(l: &mut VaList) -> Self { l.get_raw() } } //impl VaPrimitive for u8 { unsafe fn get(l: &mut VaList) -> Self { l.get_raw() } } //impl VaPrimitive for i8 { unsafe fn get(l: &mut VaList) -> Self { l.get_raw() } } -impl VaPrimitive for f64 { unsafe fn get(l: &mut VaList) -> Self { l.get_raw() } } - +impl VaPrimitive for f64 { + unsafe fn get(l: &mut VaList) -> Self { + l.get_raw() + } +} diff --git a/src/lib.rs b/src/lib.rs index b86cdbf..4ae12bb 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -33,52 +33,54 @@ * } * ``` */ -#![cfg_attr(feature="no_std",no_std)] -#![crate_type="lib"] -#![crate_name="va_list"] +#![cfg_attr(feature = "no_std", no_std)] +#![crate_type = "lib"] +#![crate_name = "va_list"] -#[cfg(feature="no_std")] +#[cfg(feature = "no_std")] #[doc(hidden)] mod std { - pub use core::{mem,ptr}; + pub use core::{mem, ptr}; } // x86_64 on unix platforms is _usually_ ELF. -#[cfg(all( target_arch="x86_64", any(target_family="unix", target_os="redox", target_os="tifflin") ))] -#[path="impl-x86_64-elf.rs"] mod imp; +#[cfg(all(target_arch="x86_64", any(target_family="unix", target_os="redox", target_os="tifflin")))] +#[path = "impl-x86_64-elf.rs"] +mod imp; //// x86_64 on windows is special -#[cfg(all( target_arch="x86_64", target_family="windows" ))] -#[path="impl-x86_64-win64.rs"] mod imp; +#[cfg(all(target_arch = "x86_64", target_family = "windows"))] +#[path = "impl-x86_64-win64.rs"] +mod imp; // x86+unix = cdecl -#[cfg(all( target_arch="x86", target_family="unix" ))] -#[path="impl-x86-sysv.rs"] mod imp; +#[cfg(all(target_arch = "x86", target_family = "unix"))] +#[path = "impl-x86-sysv.rs"] +mod imp; // arm+unix = cdecl -#[cfg(all( target_arch="arm", target_family="unix" ))] -#[path="impl-arm-sysv.rs"] mod imp; +#[cfg(all(target_arch = "arm", target_family = "unix"))] +#[path = "impl-arm-sysv.rs"] +mod imp; /// Rust version of C's `va_list` type from the `stdarg.h` header #[repr(C)] pub struct VaList { - internal: imp::VaList + internal: imp::VaList, } /// Core type as passed though the FFI -impl VaList -{ - /// Read a value from the VaList. - /// - /// Users should take care that they are reading the correct type - pub unsafe fn get(&mut self) -> T { - T::get(&mut self.internal) - } +impl VaList { + /// Read a value from the VaList. + /// + /// Users should take care that they are reading the correct type + pub unsafe fn get(&mut self) -> T { + T::get(&mut self.internal) + } } /// Trait implemented on types that can be read from a va_list -pub trait VaPrimitive: 'static -{ - #[doc(hidden)] - unsafe fn get(&mut imp::VaList) -> Self; +pub trait VaPrimitive: 'static { + #[doc(hidden)] + unsafe fn get(&mut imp::VaList) -> Self; } diff --git a/tests/lib.rs b/tests/lib.rs index 602e364..bf1a73b 100644 --- a/tests/lib.rs +++ b/tests/lib.rs @@ -1,8 +1,8 @@ extern crate va_list; -#[link(name="va_list_test")] +#[link(name = "va_list_test")] extern "C" { - fn dispatch(context: *mut u8, count: u32, ...); + fn dispatch(context: *mut u8, count: u32, ...); } type CbType<'a> = &'a mut FnMut(u32, va_list::VaList); @@ -10,16 +10,16 @@ type CbType<'a> = &'a mut FnMut(u32, va_list::VaList); #[no_mangle] /// Method called by 'dispatch' pub extern "C" fn inbound(context: *mut u8, count: u32, args: va_list::VaList) { - let cb_ptr = unsafe { ::std::ptr::read(context as *mut CbType ) }; - // call passed closure - (cb_ptr)(count, args); + let cb_ptr = unsafe { ::std::ptr::read(context as *mut CbType) }; + // call passed closure + (cb_ptr)(count, args); } macro_rules! test_va_list { ($int:expr, ($($args:expr),*), $code:expr) => ({ let mut cb = $code; let mut cb_ref: CbType = &mut cb; - + unsafe { dispatch(&mut cb_ref as *mut _ as *mut u8, $int, $($args),*); } @@ -28,22 +28,28 @@ macro_rules! test_va_list { #[test] fn trivial_values() { - // Trivial test: Pass four random-ish sized integers - test_va_list!(4, (123456u32, 2u64, 1i32, -23i64), - |_count, mut list: va_list::VaList| { unsafe { - assert_eq!( list.get::(), 123456u32 ); - assert_eq!( list.get::(), 2u64 ); - assert_eq!( list.get::(), 1i32 ); - assert_eq!( list.get::(), -23i64 ); - } }); + // Trivial test: Pass four random-ish sized integers + test_va_list!( + 4, + (123456u32, 2u64, 1i32, -23i64), + |_count, mut list: va_list::VaList| unsafe { + assert_eq!(list.get::(), 123456u32); + assert_eq!(list.get::(), 2u64); + assert_eq!(list.get::(), 1i32); + assert_eq!(list.get::(), -23i64); + } + ); } #[test] -#[cfg(not(all( target_arch="x86_64", target_family="unix" )))] // TODO: Float on AMD64 +#[cfg(not(all(target_arch = "x86_64", target_family = "unix")))] // TODO: Float on AMD64 fn floating_point() { - test_va_list!(4, (123456f64, 0.1f64), - |_count, mut list: va_list::VaList| { unsafe { - assert_eq!( list.get::(), 123456f64 ); - assert_eq!( list.get::(), 0.1f64 ); - } }); + test_va_list!( + 4, + (123456f64, 0.1f64), + |_count, mut list: va_list::VaList| unsafe { + assert_eq!(list.get::(), 123456f64); + assert_eq!(list.get::(), 0.1f64); + } + ); } -- GitLab From b0e8415caaf2f161c6eadeff583fd59d6217d691 Mon Sep 17 00:00:00 2001 From: Dan Robertson Date: Tue, 6 Mar 2018 04:07:29 +0000 Subject: [PATCH 2/4] Updates and support RedoxOS - Support RedoxOS - Use the cc crate instead of the deprecated gcc - Minor newline nits --- deps/helper/Cargo.toml | 2 +- deps/helper/build.rs | 6 ++++-- src/lib.rs | 3 ++- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/deps/helper/Cargo.toml b/deps/helper/Cargo.toml index 61ef414..6df4a9b 100644 --- a/deps/helper/Cargo.toml +++ b/deps/helper/Cargo.toml @@ -7,4 +7,4 @@ description = "Test helper for the `va_list` crate. Not for user consumption." license = "MIT" [build-dependencies] -gcc = "0.3" +cc = "1.0" diff --git a/deps/helper/build.rs b/deps/helper/build.rs index 852f200..2769ac8 100644 --- a/deps/helper/build.rs +++ b/deps/helper/build.rs @@ -1,5 +1,7 @@ -extern crate gcc; +extern crate cc; fn main() { - ::gcc::compile_library("libva_list_test.a", &["src/helper.c"]); + ::cc::Build::new() + .file("src/helper.c") + .compile("libva_list_test.a"); } diff --git a/src/lib.rs b/src/lib.rs index 4ae12bb..bbba81f 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -44,7 +44,8 @@ mod std { } // x86_64 on unix platforms is _usually_ ELF. -#[cfg(all(target_arch="x86_64", any(target_family="unix", target_os="redox", target_os="tifflin")))] +#[cfg(all(target_arch = "x86_64", + any(target_family = "unix", target_os = "redox", target_os = "tifflin")))] #[path = "impl-x86_64-elf.rs"] mod imp; -- GitLab From 952bf100bdf147c4c6045512dc43fea5ae64819e Mon Sep 17 00:00:00 2001 From: Dan Robertson Date: Tue, 6 Mar 2018 04:08:20 +0000 Subject: [PATCH 3/4] Support aarch64 Add support for Aarch64. --- src/impl-aarch64-elf.rs | 76 +++++++++++++++++++++++++++++++++++++++++ src/lib.rs | 5 +++ 2 files changed, 81 insertions(+) create mode 100644 src/impl-aarch64-elf.rs diff --git a/src/impl-aarch64-elf.rs b/src/impl-aarch64-elf.rs new file mode 100644 index 0000000..4764da6 --- /dev/null +++ b/src/impl-aarch64-elf.rs @@ -0,0 +1,76 @@ +use std::{mem, ptr}; +use super::VaPrimitive; + +pub struct VaList(*mut VaListInner); + +#[repr(C)] +#[derive(Debug)] +#[doc(hidden)] +pub struct VaListInner { + stack: *const (), + gr_top: *const (), + vr_top: *const (), + gr_offs: i32, + vr_offs: i32, +} + +impl VaList { + fn inner(&mut self) -> &mut VaListInner { + // This pointer should be valid + unsafe { &mut *self.0 } + } +} + +impl VaListInner { + pub unsafe fn get_gr(&mut self) -> T { + assert!(!self.gr_top.is_null()); + let rv = ptr::read((self.gr_top as usize - self.gr_offs.abs() as usize) as *const _); + self.gr_offs += 8; + rv + } + + pub unsafe fn get_vr(&mut self) -> T { + assert!(!self.vr_top.is_null()); + let rv = ptr::read((self.vr_top as usize - self.vr_offs.abs() as usize) as *const _); + self.vr_offs += 16; + rv + } +} + +impl VaPrimitive for *const T { + unsafe fn get(list: &mut VaList) -> Self { + ::get(list) as *const T + } +} + +macro_rules! impl_va_prim_gr { + ($u: ty, $s: ty) => { + impl VaPrimitive for $u { + unsafe fn get(list: &mut VaList) -> Self { + list.inner().get_gr() + } + } + impl VaPrimitive for $s { + unsafe fn get(list: &mut VaList) -> Self { + mem::transmute(<$u>::get(list)) + } + } + }; +} + +macro_rules! impl_va_prim_vr { + ($($t:ty),+) => { + $( + impl VaPrimitive for $t { + unsafe fn get(list: &mut VaList) -> Self { + list.inner().get_vr() + } + } + )+ + }; +} + +impl_va_prim_gr!{ usize, isize } +impl_va_prim_gr!{ u64, i64 } +impl_va_prim_gr!{ u32, i32 } +impl_va_prim_vr!{ f64, f32 } diff --git a/src/lib.rs b/src/lib.rs index bbba81f..84a709f 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -59,6 +59,11 @@ mod imp; #[path = "impl-x86-sysv.rs"] mod imp; +// aarch64 +#[cfg(all(target_arch = "aarch64", any(target_family = "unix", target_os = "redox")))] +#[path = "impl-aarch64-elf.rs"] +mod imp; + // arm+unix = cdecl #[cfg(all(target_arch = "arm", target_family = "unix"))] #[path = "impl-arm-sysv.rs"] -- GitLab From 1ead8f81a492dadac271437f348f4875ba9191f4 Mon Sep 17 00:00:00 2001 From: Dan Robertson Date: Fri, 9 Mar 2018 04:11:37 +0000 Subject: [PATCH 4/4] Post merge updates - Enable floating point test on AMD64 - Run formatter on code --- src/impl-x86_64-elf.rs | 93 +++++++++++++++++++++--------------------- tests/lib.rs | 1 - 2 files changed, 46 insertions(+), 48 deletions(-) diff --git a/src/impl-x86_64-elf.rs b/src/impl-x86_64-elf.rs index 92a2e9c..e0fffd6 100644 --- a/src/impl-x86_64-elf.rs +++ b/src/impl-x86_64-elf.rs @@ -26,46 +26,46 @@ impl VaList { #[doc(hidden)] impl VaListInner { - fn check_space(&self, num_gp: u32, num_fp: u32) -> bool { - !(self.gp_offset > 48 - num_gp * 8 || self.fp_offset > 304 - num_fp * 16) - } + fn check_space(&self, num_gp: u32, num_fp: u32) -> bool { + !(self.gp_offset > 48 - num_gp * 8 || self.fp_offset > 304 - num_fp * 16) + } - unsafe fn get_gp(&mut self) -> T { - let n_gp = (mem::size_of::()+7)/8; - assert!( self.check_space(n_gp as u32, 0) ); - let rv = ptr::read( (self.reg_save_area as usize + self.gp_offset as usize) as *const _ ); - self.gp_offset += (8*n_gp) as u32; - rv - } + unsafe fn get_gp(&mut self) -> T { + let n_gp = (mem::size_of::() + 7) / 8; + assert!(self.check_space(n_gp as u32, 0)); + let rv = ptr::read((self.reg_save_area as usize + self.gp_offset as usize) as *const _); + self.gp_offset += (8 * n_gp) as u32; + rv + } - unsafe fn get_fp(&mut self) -> T { - let n_fp = (mem::size_of::()+15)/16; - assert!( self.check_space(0, n_fp as u32) ); - let rv = ptr::read( (self.reg_save_area as usize + self.fp_offset as usize) as *const _ ); - self.fp_offset += (16*n_fp) as u32; - rv - } + unsafe fn get_fp(&mut self) -> T { + let n_fp = (mem::size_of::() + 15) / 16; + assert!(self.check_space(0, n_fp as u32)); + let rv = ptr::read((self.reg_save_area as usize + self.fp_offset as usize) as *const _); + self.fp_offset += (16 * n_fp) as u32; + rv + } - unsafe fn get_overflow(&mut self) -> T { - let align = mem::align_of::(); - // 7. Align overflow_reg_area upwards to a 16-byte boundary if alignment - // needed by T exceeds 8 bytes - let addr = self.overflow_arg_area as usize; - if align > 8 { - if addr % 16 != 0 { - self.overflow_arg_area = ((addr + 15) & !(16-1)) as *const _; - } - } - else { - if addr % 8 != 0 { - self.overflow_arg_area = ((addr + 7) & !(8-1)) as *const _; - } - } - // 8. Fetch from overflow areay - let rv = ptr::read( self.overflow_arg_area as *const _ ); - self.overflow_arg_area = ((self.overflow_arg_area as usize) + mem::size_of::()) as *const _; - rv - } + unsafe fn get_overflow(&mut self) -> T { + let align = mem::align_of::(); + // 7. Align overflow_reg_area upwards to a 16-byte boundary if alignment + // needed by T exceeds 8 bytes + let addr = self.overflow_arg_area as usize; + if align > 8 { + if addr % 16 != 0 { + self.overflow_arg_area = ((addr + 15) & !(16 - 1)) as *const _; + } + } else { + if addr % 8 != 0 { + self.overflow_arg_area = ((addr + 7) & !(8 - 1)) as *const _; + } + } + // 8. Fetch from overflow areay + let rv = ptr::read(self.overflow_arg_area as *const _); + self.overflow_arg_area = + ((self.overflow_arg_area as usize) + mem::size_of::()) as *const _; + rv + } } impl VaPrimitive for *const T { @@ -102,14 +102,13 @@ impl_va_prim!{ u32, i32 } //impl_va_prim!{ u8, i8 } impl VaPrimitive for f64 { - unsafe fn get(list: &mut VaList) -> Self { - let inner = list.inner(); - // See the ELF AMD64 ABI document for a description of how this should act - if ! inner.check_space(0, 1) { - inner.get_overflow() - } - else { - inner.get_fp() - } - } + unsafe fn get(list: &mut VaList) -> Self { + let inner = list.inner(); + // See the ELF AMD64 ABI document for a description of how this should act + if !inner.check_space(0, 1) { + inner.get_overflow() + } else { + inner.get_fp() + } + } } diff --git a/tests/lib.rs b/tests/lib.rs index bf1a73b..667207c 100644 --- a/tests/lib.rs +++ b/tests/lib.rs @@ -42,7 +42,6 @@ fn trivial_values() { } #[test] -#[cfg(not(all(target_arch = "x86_64", target_family = "unix")))] // TODO: Float on AMD64 fn floating_point() { test_va_list!( 4, -- GitLab