From c80ca6b919f3b3031cdfdc3b8b9d1716f0f640a0 Mon Sep 17 00:00:00 2001 From: Oliver Steffen Date: Wed, 16 Sep 2026 12:44:08 +0200 Subject: [PATCH 01/13] kernel: utils: add static array backed object pool Add a simple object pool implementation usable for static pools. Signed-off-by: Oliver Steffen --- kernel/src/utils/mod.rs | 2 + kernel/src/utils/pool.rs | 154 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 156 insertions(+) create mode 100644 kernel/src/utils/pool.rs diff --git a/kernel/src/utils/mod.rs b/kernel/src/utils/mod.rs index f75221a44a..a9bc9cbb5a 100644 --- a/kernel/src/utils/mod.rs +++ b/kernel/src/utils/mod.rs @@ -7,12 +7,14 @@ pub mod bitmap_allocator; pub mod immut_after_init; pub mod memory_region; +pub mod pool; pub mod scoped; pub mod tcb_ptr; pub mod util; pub mod vec; pub use memory_region::MemoryRegion; +pub use pool::{Pool, PoolGuard}; pub use scoped::{ScopedMut, ScopedRef}; pub use util::{ align_down, align_up, is_aligned, overlap, page_align_up, page_offset, round_to_pages, diff --git a/kernel/src/utils/pool.rs b/kernel/src/utils/pool.rs new file mode 100644 index 0000000000..f3762f946f --- /dev/null +++ b/kernel/src/utils/pool.rs @@ -0,0 +1,154 @@ +// SPDX-License-Identifier: MIT OR Apache-2.0 +// +// Copyright (c) 2026 Red Hat +// +// Author: Oliver Steffen + +use core::fmt; +use core::mem::ManuallyDrop; +use core::ops::{Deref, DerefMut}; + +use crate::locking::SpinLock; + +/// A fixed-size object pool with internal locking. +/// +/// Objects are checked out via [`Pool::get`] and automatically returned when +/// the [`PoolGuard`] is dropped. If the pool is empty on checkout, a +/// caller-provided factory creates a new object. If the pool is full on +/// return, the object is dropped. +pub struct Pool { + objects: SpinLock<[Option; N]>, +} + +impl Pool { + /// Creates an empty pool suitable for use in `static` declarations. + pub const fn empty() -> Self { + Self { + objects: SpinLock::new([const { None }; N]), + } + } + + /// Checks out an object from the pool, or creates one via `factory` if + /// the pool is empty. The factory runs outside the lock. + pub fn get(&self, factory: impl FnOnce() -> Result) -> Result, E> { + { + let mut pool = self.objects.lock(); + for slot in pool.iter_mut() { + if let Some(obj) = slot.take() { + return Ok(PoolGuard { + pool: self, + data: ManuallyDrop::new(obj), + }); + } + } + } + let obj = factory()?; + Ok(PoolGuard { + pool: self, + data: ManuallyDrop::new(obj), + }) + } + + fn put(&self, obj: T) { + let mut pool = self.objects.lock(); + for slot in pool.iter_mut() { + if slot.is_none() { + *slot = Some(obj); + return; + } + } + } +} + +impl fmt::Debug for Pool { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct("Pool").field("capacity", &N).finish() + } +} + +/// RAII guard that returns its object to the originating [`Pool`] on drop. +/// +/// Dereferences to the contained `T`, allowing direct use of the pooled +/// object. +pub struct PoolGuard<'a, T: Send, const N: usize> { + pool: &'a Pool, + data: ManuallyDrop, +} + +impl Deref for PoolGuard<'_, T, N> { + type Target = T; + + fn deref(&self) -> &Self::Target { + self.data.deref() + } +} + +impl DerefMut for PoolGuard<'_, T, N> { + fn deref_mut(&mut self) -> &mut Self::Target { + self.data.deref_mut() + } +} + +impl Drop for PoolGuard<'_, T, N> { + fn drop(&mut self) { + // SAFETY: `self.data` cannot be used again, since this is + // the drop() implementation. + let obj = unsafe { ManuallyDrop::take(&mut self.data) }; + self.pool.put(obj); + } +} + +impl fmt::Debug for PoolGuard<'_, T, N> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct("PoolGuard").finish_non_exhaustive() + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn get_from_empty_pool_calls_factory() { + let pool: Pool = Pool::empty(); + let guard = pool.get(|| Ok::<_, ()>(42)).unwrap(); + assert_eq!(*guard, 42); + } + + #[test] + fn object_returned_to_pool_on_drop() { + let pool: Pool = Pool::empty(); + { + let guard = pool.get(|| Ok::<_, ()>(42)).unwrap(); + assert_eq!(*guard, 42); + } + let guard = pool.get(|| Ok::<_, ()>(99)).unwrap(); + assert_eq!(*guard, 42); + } + + #[test] + fn factory_error_propagated() { + let pool: Pool = Pool::empty(); + let result = pool.get(|| Err::("failed")); + assert!(result.is_err()); + } + + #[test] + fn deref_mut_allows_modification() { + let pool: Pool = Pool::empty(); + let mut guard = pool.get(|| Ok::<_, ()>(10)).unwrap(); + *guard = 20; + assert_eq!(*guard, 20); + } + + #[test] + fn overflow_drops_excess_objects() { + let pool: Pool = Pool::empty(); + { + let _g1 = pool.get(|| Ok::<_, ()>(1)).unwrap(); + let _g2 = pool.get(|| Ok::<_, ()>(2)).unwrap(); + } + let g = pool.get(|| Ok::<_, ()>(99)).unwrap(); + assert!(*g == 1 || *g == 2); + } +} From ddbb60a62c036ea095c0c59a7f1464d919993509 Mon Sep 17 00:00:00 2001 From: Oliver Steffen Date: Mon, 14 Sep 2026 18:34:00 +0200 Subject: [PATCH 02/13] kernel: crypto: refactor RNG pool Refactor the random number generator pool using the new object pool implementation from "utils". Move the DRBG generator implementation to its own submodule to further abstract it. We will gain another RNG implementation in a following commit. Signed-off-by: Oliver Steffen --- kernel/src/crypto/rng.rs | 158 ---------------------------------- kernel/src/crypto/rng/drbg.rs | 94 ++++++++++++++++++++ kernel/src/crypto/rng/mod.rs | 60 +++++++++++++ 3 files changed, 154 insertions(+), 158 deletions(-) delete mode 100644 kernel/src/crypto/rng.rs create mode 100644 kernel/src/crypto/rng/drbg.rs create mode 100644 kernel/src/crypto/rng/mod.rs diff --git a/kernel/src/crypto/rng.rs b/kernel/src/crypto/rng.rs deleted file mode 100644 index e0587553f2..0000000000 --- a/kernel/src/crypto/rng.rs +++ /dev/null @@ -1,158 +0,0 @@ -// SPDX-License-Identifier: MIT OR Apache-2.0 -// Copyright 2025 SUSE LLC -// Author: Nicolai Stange - -//! SVSM Random Number Generator (RNG) management. -//! -//! Whenever users need an cryptographically secure RNG, they should invoke [`get_svsm_rng()`] to -//! obtain an exclusively owned [`SvsmRng`] instance. - -extern crate alloc; -use alloc::boxed::Box; - -use crate::locking::SpinLock; - -use core::sync::atomic; - -use cocoon_tpm_crypto::{ - CryptoError, EmptyCryptoIoSlices, - hash::hash_alg_digest_len, - rng::{self, HashDrbg, RngCore, X86RdSeedRng}, -}; -use cocoon_tpm_tpm2_interface::TpmiAlgHash; -use cocoon_tpm_utils_common::{ - alloc::box_try_new, - fixed_vec::{FixedVec, FixedVecMemoryAllocationFailure}, - io_slices::{self, IoSlicesIterCommon as _}, - zeroize, -}; - -/// Hash algorithm to be used for all NIST HashDrbg instantiations. -// C.f. NIST SP 800-90A Rev. 1: the HashDrbg's security strength is equal to the underlying hash -// algorithm's pre-image resistance. That is, SHA256 gives a security strength of 256 bits. -const SVSM_RNG_DRBG_HASH_ALG: TpmiAlgHash = TpmiAlgHash::Sha256; - -/// Number of [`SVSM_RNG_POOL`] slots. -const SVSM_RNG_POOL_SIZE: usize = 4; - -/// RNG instance pool -/// -/// [`SvsmRng::drop()`] returns instances back into some free slot, if any. [`get_svsm_rng()`] tries -/// to take a currently unused instance from the pool before attempting to instantiate one. -#[allow(clippy::type_complexity)] -static SVSM_RNG_POOL: SpinLock< - [Option>>; SVSM_RNG_POOL_SIZE], -> = SpinLock::new([None, None, None, None]); - -/// Counter used for the RNG instance's personalization. -static SVSM_RNG_INSTANTIATION_ID: atomic::AtomicU64 = atomic::AtomicU64::new(0); - -/// Opaque type implementing [`RngCore`] as suitable for the SVSM environment and build -/// configuration. -/// -/// Instances of `SvsmRng` are to be obtained through [`get_svsm_rng()`]. -/// -/// No assumptions must be made about `SvsmRng`, other than instances thereof are small, typically -/// of pointer size, and that it implements [`RngCore`]. -#[allow(missing_debug_implementations)] -pub struct SvsmRng { - // Is never None while self is alive, the rng needs to get stored in an Option<> so that it can - // get returned back to the pool when dropped. - rng: Option>>, -} - -impl SvsmRng { - fn instantiate() -> Result { - // The FixedVec internal representation is optimized for the case of power-of-two lengths, - // relative to a specified compile-time "base" value. In practice, the HashDrbg seed length - // is equal to the digest length for all known hashes, so use that for the FixedVec base. If - // not a power of two (e.g. SHA-1), the optimization wouldn't be possible anyway, so the - // value is irrelevant then. - const DRBG_HASH_ALG_DIGEST_LEN_LOG2: u32 = - hash_alg_digest_len(SVSM_RNG_DRBG_HASH_ALG).ilog2(); - let mut hash_drbg_entropy = zeroize::Zeroizing::new( - FixedVec::::new_with_default( - HashDrbg::min_seed_entropy_len(SVSM_RNG_DRBG_HASH_ALG), - ) - .map_err(|e| match e { - FixedVecMemoryAllocationFailure => CryptoError::MemoryAllocationFailure, - })?, - ); - - let mut rdseed_rng = X86RdSeedRng::instantiate().map_err(|_| CryptoError::RngFailure)?; - rdseed_rng.generate::<_, EmptyCryptoIoSlices>( - io_slices::SingletonIoSliceMut::new(hash_drbg_entropy.as_mut_slice()) - .map_infallible_err(), - None, - )?; - - let mut personalization = [0u8; 16]; - personalization[..8].copy_from_slice(b"SVSM-RNG"); - personalization[8..].copy_from_slice( - &SVSM_RNG_INSTANTIATION_ID - .fetch_add(1, atomic::Ordering::Relaxed) - .to_ne_bytes(), - ); - - let hash_drbg_rng = rng::HashDrbg::instantiate( - SVSM_RNG_DRBG_HASH_ALG, - &hash_drbg_entropy, - None, - Some(&personalization), - )?; - - let chained_rng = rng::ChainedRng::chain(rdseed_rng, hash_drbg_rng); - - Ok(Self { - rng: Some(box_try_new(chained_rng).map_err(|_| CryptoError::MemoryAllocationFailure)?), - }) - } -} - -impl rng::RngCore for SvsmRng { - fn generate< - 'a, - 'b, - OI: cocoon_tpm_crypto::CryptoWalkableIoSlicesMutIter<'a>, - AII: cocoon_tpm_crypto::CryptoPeekableIoSlicesIter<'b>, - >( - &mut self, - output: OI, - additional_input: Option, - ) -> Result<(), rng::RngGenerateError> { - let rng = match self.rng.as_mut() { - Some(rng) => rng, - None => { - return Err(rng::RngGenerateError::CryptoError(CryptoError::Internal)); - } - }; - rng.generate(output, additional_input) - } -} - -impl Drop for SvsmRng { - fn drop(&mut self) { - if let Some(rng) = self.rng.take() { - // Return the rng instance in some free pool slot, if any. - let mut pool = SVSM_RNG_POOL.lock(); - for pool_slot in pool.iter_mut() { - if pool_slot.is_none() { - *pool_slot = Some(rng); - break; - } - } - } - } -} - -/// Obtain an exclusively owned [`SvsmRng`] instance. -pub fn get_svsm_rng() -> Result { - let mut pool = SVSM_RNG_POOL.lock(); - for pool_slot in pool.iter_mut() { - if let Some(rng) = pool_slot.take() { - return Ok(SvsmRng { rng: Some(rng) }); - } - } - - SvsmRng::instantiate() -} diff --git a/kernel/src/crypto/rng/drbg.rs b/kernel/src/crypto/rng/drbg.rs new file mode 100644 index 0000000000..269b0c84cb --- /dev/null +++ b/kernel/src/crypto/rng/drbg.rs @@ -0,0 +1,94 @@ +// SPDX-License-Identifier: MIT OR Apache-2.0 +// Copyright 2025 SUSE LLC +// Author: Nicolai Stange + +extern crate alloc; +use alloc::boxed::Box; + +use core::sync::atomic; + +use cocoon_tpm_crypto::{ + CryptoError, CryptoPeekableIoSlicesIter, CryptoWalkableIoSlicesMutIter, EmptyCryptoIoSlices, + hash::hash_alg_digest_len, + rng::{self, HashDrbg, RngCore as _, RngGenerateError, X86RdSeedRng}, +}; +use cocoon_tpm_tpm2_interface::TpmiAlgHash; +use cocoon_tpm_utils_common::{ + alloc::box_try_new, + fixed_vec::{FixedVec, FixedVecMemoryAllocationFailure}, + io_slices::{self, IoSlicesIterCommon as _}, + zeroize, +}; + +/// Hash algorithm to be used for all NIST HashDrbg instantiations. +// C.f. NIST SP 800-90A Rev. 1: the HashDrbg's security strength is equal to the underlying hash +// algorithm's pre-image resistance. That is, SHA256 gives a security strength of 256 bits. +const SVSM_RNG_DRBG_HASH_ALG: TpmiAlgHash = TpmiAlgHash::Sha256; + +/// Counter used for the RNG instance's personalization. +static SVSM_RNG_INSTANTIATION_ID: atomic::AtomicU64 = atomic::AtomicU64::new(0); + +/// DRBG-based RNG seeded from hardware entropy (RDSEED). +pub(super) struct SvsmRngImpl { + inner: rng::ChainedRng, +} + +impl SvsmRngImpl { + pub(super) fn new() -> Result, CryptoError> { + // The FixedVec internal representation is optimized for the case of power-of-two lengths, + // relative to a specified compile-time "base" value. In practice, the HashDrbg seed length + // is equal to the digest length for all known hashes, so use that for the FixedVec base. If + // not a power of two (e.g. SHA-1), the optimization wouldn't be possible anyway, so the + // value is irrelevant then. + const DRBG_HASH_ALG_DIGEST_LEN_LOG2: u32 = + hash_alg_digest_len(SVSM_RNG_DRBG_HASH_ALG).ilog2(); + let mut hash_drbg_entropy = zeroize::Zeroizing::new( + FixedVec::::new_with_default( + HashDrbg::min_seed_entropy_len(SVSM_RNG_DRBG_HASH_ALG), + ) + .map_err(|e| match e { + FixedVecMemoryAllocationFailure => CryptoError::MemoryAllocationFailure, + })?, + ); + + let mut rdseed_rng = X86RdSeedRng::instantiate().map_err(|_| CryptoError::RngFailure)?; + rdseed_rng.generate::<_, EmptyCryptoIoSlices>( + io_slices::SingletonIoSliceMut::new(hash_drbg_entropy.as_mut_slice()) + .map_infallible_err(), + None, + )?; + + let mut personalization = [0u8; 16]; + personalization[..8].copy_from_slice(b"SVSM-RNG"); + personalization[8..].copy_from_slice( + &SVSM_RNG_INSTANTIATION_ID + .fetch_add(1, atomic::Ordering::Relaxed) + .to_ne_bytes(), + ); + + let hash_drbg_rng = rng::HashDrbg::instantiate( + SVSM_RNG_DRBG_HASH_ALG, + &hash_drbg_entropy, + None, + Some(&personalization), + )?; + + let inner = rng::ChainedRng::chain(rdseed_rng, hash_drbg_rng); + box_try_new(SvsmRngImpl { inner }).map_err(|_| CryptoError::MemoryAllocationFailure) + } +} + +impl rng::RngCore for SvsmRngImpl { + fn generate< + 'a, + 'b, + OI: CryptoWalkableIoSlicesMutIter<'a>, + AII: CryptoPeekableIoSlicesIter<'b>, + >( + &mut self, + output: OI, + additional_input: Option, + ) -> Result<(), RngGenerateError> { + self.inner.generate(output, additional_input) + } +} diff --git a/kernel/src/crypto/rng/mod.rs b/kernel/src/crypto/rng/mod.rs new file mode 100644 index 0000000000..11012dde3b --- /dev/null +++ b/kernel/src/crypto/rng/mod.rs @@ -0,0 +1,60 @@ +// SPDX-License-Identifier: MIT OR Apache-2.0 +// Copyright 2025 SUSE LLC +// Author: Nicolai Stange + +//! SVSM Random Number Generator (RNG) management. +//! +//! Whenever users need an cryptographically secure RNG, they should invoke [`get_svsm_rng()`] to +//! obtain an exclusively owned [`SvsmRng`] instance. + +extern crate alloc; +use alloc::boxed::Box; + +use crate::utils::pool::{Pool, PoolGuard}; + +use cocoon_tpm_crypto::{CryptoError, rng}; + +mod drbg; +use drbg::SvsmRngImpl; + +/// Number of [`SVSM_RNG_POOL`] slots. +const SVSM_RNG_POOL_SIZE: usize = 4; + +/// RNG instance pool +/// +/// Dropped [`SvsmRng`] instances return to the pool for reuse. [`get_svsm_rng()`] takes from +/// the pool when possible, falling back to instantiation. +static SVSM_RNG_POOL: Pool, SVSM_RNG_POOL_SIZE> = Pool::empty(); + +/// Opaque type implementing [`rng::RngCore`] as suitable for the SVSM environment and build +/// configuration. +/// +/// Instances of `SvsmRng` are to be obtained through [`get_svsm_rng()`]. +/// +/// No assumptions must be made about `SvsmRng`, other than instances thereof are small, typically +/// of pointer size, and that it implements [`rng::RngCore`]. +#[allow(missing_debug_implementations)] +pub struct SvsmRng { + guard: PoolGuard<'static, Box, SVSM_RNG_POOL_SIZE>, +} + +impl rng::RngCore for SvsmRng { + fn generate< + 'a, + 'b, + OI: cocoon_tpm_crypto::CryptoWalkableIoSlicesMutIter<'a>, + AII: cocoon_tpm_crypto::CryptoPeekableIoSlicesIter<'b>, + >( + &mut self, + output: OI, + additional_input: Option, + ) -> Result<(), rng::RngGenerateError> { + self.guard.generate(output, additional_input) + } +} + +/// Obtain an exclusively owned [`SvsmRng`] instance. +pub fn get_svsm_rng() -> Result { + let guard = SVSM_RNG_POOL.get(SvsmRngImpl::new)?; + Ok(SvsmRng { guard }) +} From 0112fa5b14d44d02db8648421ca7e22db5891212 Mon Sep 17 00:00:00 2001 From: Oliver Steffen Date: Thu, 1 Oct 2026 12:48:58 +0200 Subject: [PATCH 03/13] workspace: Bump bindgen to 0.73.2 Use the same version of bindgen as we do in cocoon-tpm (where 0.73.2 is needed). Pin prettyplease to 0.2.29 in Cargo.lock. bindgen 0.73.2 accepts prettyplease >=0.2.7, <0.4 but uses syn 2.x internally. If Cargo resolves prettyplease to 0.3.0 (which depends on syn 3.x), the build fails due to conflicting syn versions. Signed-off-by: Oliver Steffen --- Cargo.lock | 41 +++++++++++++++++++++-------------------- Cargo.toml | 2 +- libtcgtpm/Cargo.toml | 3 +++ 3 files changed, 25 insertions(+), 21 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 3041d30a37..7bc72d9c1a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -209,19 +209,18 @@ checksum = "55248b47b0caf0546f7988906588779981c43bb1bc9d0c44087278f80cdb44ba" [[package]] name = "bindgen" -version = "0.72.1" +version = "0.73.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "993776b509cfb49c750f11b8f07a46fa23e0a1386ffc01fb1e7d343efc387895" +checksum = "787ef8ef523575546b106a58213d6e6b06198a05c2f757258c68a74273670cfa" dependencies = [ "bitflags 2.13.0", "cexpr", "clang-sys", - "itertools", "proc-macro2", "quote", "regex", "rustc-hash", - "shlex", + "shlex 2.0.1", "syn", ] @@ -364,7 +363,7 @@ dependencies = [ "find-msvc-tools", "jobserver", "libc", - "shlex", + "shlex 1.3.0", ] [[package]] @@ -830,12 +829,6 @@ dependencies = [ "spki", ] -[[package]] -name = "either" -version = "1.15.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719" - [[package]] name = "elf" version = "0.1.0" @@ -1428,15 +1421,6 @@ version = "1.70.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a6cb138bb79a146c1bd460005623e142ef0181e3d0219cb493e02f7d08a35695" -[[package]] -name = "itertools" -version = "0.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "413ee7dfc52ee1a4949ceeb7dbc8a33f2d6c088194d9f922fb8318faf1f01186" -dependencies = [ - "either", -] - [[package]] name = "itoa" version = "1.0.15" @@ -1571,6 +1555,7 @@ name = "libtcgtpm" version = "0.1.0" dependencies = [ "bindgen", + "prettyplease", ] [[package]] @@ -1829,6 +1814,16 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" +[[package]] +name = "prettyplease" +version = "0.2.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "479ca8adacdd7ce8f1fb39ce9ecccbfe93a3f1344b3d0d97f20bc0196208f62b" +dependencies = [ + "proc-macro2", + "syn", +] + [[package]] name = "primeorder" version = "0.13.6" @@ -2117,6 +2112,12 @@ version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" +[[package]] +name = "shlex" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8fadd59c855ef2080decdef8ff161eb6661b86933c9d82e5ba29dc602a55aba" + [[package]] name = "signature" version = "2.2.0" diff --git a/Cargo.toml b/Cargo.toml index a47efdc7ff..f4cc0e0d74 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -74,7 +74,7 @@ aes-gcm = { version = "0.10.3", default-features = false } aes-kw = { version = "0.3.1", default-features = false } arbitrary = "1.3.0" base64 = { version = "0.22.1", default-features = false } -bindgen = { version = "0.72.0", default-features = false } +bindgen = { version = "0.73.2", default-features = false } bitfield-struct = "0.13.0" bitflags = "2.6" clap = { version = "4.4.14", default-features = false } diff --git a/libtcgtpm/Cargo.toml b/libtcgtpm/Cargo.toml index 6f58967aac..64d3cb8a68 100644 --- a/libtcgtpm/Cargo.toml +++ b/libtcgtpm/Cargo.toml @@ -7,6 +7,9 @@ edition.workspace = true [build-dependencies] bindgen = { workspace = true, features = ["runtime"] } +# Pin prettyplease <0.3 — prettyplease 0.3 uses syn v3 but bindgen 0.73 +# uses syn v2 internally, causing a type mismatch at compile time. +prettyplease = ">=0.2.29, <0.3" [lints] workspace = true From 0fe11bfb1eb04f186c655b2ae80bb9e315b10b66 Mon Sep 17 00:00:00 2001 From: Oliver Steffen Date: Wed, 16 Sep 2026 12:49:33 +0200 Subject: [PATCH 04/13] workspace: Bump cocoon-tpm crates to latest version Use the latest releases of the cocoon-tpm crates from crates.io. This includes the new OpenSSL backend for cocoon-tpm-crypto, which we will use in a following commit. Signed-off-by: Oliver Steffen --- Cargo.lock | 24 ++++++++++++------------ Cargo.toml | 10 +++++----- 2 files changed, 17 insertions(+), 17 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 7bc72d9c1a..ed45d2cf9a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -470,18 +470,18 @@ checksum = "a1d728cc89cf3aee9ff92b05e62b19ee65a02b5702cff7d5a377e32c6ae29d8d" [[package]] name = "cmpa" -version = "0.1.2" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "360388c699cb87bbff6ad171727548056ccf43cc8fa442a745ad0676ab23b888" +checksum = "ce707bf177f81ed1bb853582be1911ed701c13599e0ab81594a2dd24c7f11355" dependencies = [ "zeroize", ] [[package]] name = "cocoon-tpm-crypto" -version = "0.1.4" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3df5637dcf02eb5defb21bb108c0f3796bda0db2c7c7e3804759447b10e781c" +checksum = "a65c8f2d0eb99ce3c53a9ad906e707a3e61a26569f8035ee07772e83d4ab4009" dependencies = [ "aes 0.8.4", "camellia", @@ -505,9 +505,9 @@ dependencies = [ [[package]] name = "cocoon-tpm-storage" -version = "0.1.4" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4557cee7aa93353f56d63bcacb0673c6b0ef296668b436d8d2e7b9f690ef9b0" +checksum = "3be9a24b772eb4e094f2c76f3bd9f20ce1046d5dcea4adc255e51a81c921bfe8" dependencies = [ "cocoon-tpm-crypto", "cocoon-tpm-tpm2-interface", @@ -518,24 +518,24 @@ dependencies = [ [[package]] name = "cocoon-tpm-tpm2-interface" -version = "0.1.1" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f524208dcc8aa8c63f8d0a1a64f458beeb6eff7d7d64deec515be639a57811ea" +checksum = "d44a2e63098a1cfdb24b1ba94dc1057d4c491ff3212337078052fecd9dddaa2b" [[package]] name = "cocoon-tpm-utils-async" -version = "0.1.3" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff56a8746df3ead93d408761fed1e39974e4395fcab63084272fd7b8b33d8391" +checksum = "ca101df93c1937ee110cf2dcebdd71af86a9826f6d95bd0ff17d064599cd0d2e" dependencies = [ "cocoon-tpm-utils-common", ] [[package]] name = "cocoon-tpm-utils-common" -version = "0.1.3" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ba97316b8f3f4ab72ee646c222285a8c2480130e30ba3a7e38596ef36812598" +checksum = "cbcc7da8ec0dbafead26b361b060e5f2ff83220cde219277b3f996a637b8131d" dependencies = [ "cmpa", "zeroize", diff --git a/Cargo.toml b/Cargo.toml index f4cc0e0d74..418c1a6f1e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -78,11 +78,11 @@ bindgen = { version = "0.73.2", default-features = false } bitfield-struct = "0.13.0" bitflags = "2.6" clap = { version = "4.4.14", default-features = false } -cocoon-tpm-crypto = { version = "0.1.4", default-features = false } -cocoon-tpm-storage = { version = "0.1.4", default-features = false } -cocoon-tpm-tpm2-interface = { version = "0.1.1", default-features = false } -cocoon-tpm-utils-async = { version = "0.1.3", default-features = false } -cocoon-tpm-utils-common = { version = "0.1.3", default-features = false } +cocoon-tpm-crypto = { version = "0.1.5", default-features = false } +cocoon-tpm-storage = { version = "0.1.5", default-features = false } +cocoon-tpm-tpm2-interface = { version = "0.1.2", default-features = false } +cocoon-tpm-utils-async = { version = "0.1.4", default-features = false } +cocoon-tpm-utils-common = { version = "0.1.4", default-features = false } concat-kdf = "0.1.0" gdbstub = { version = "0.7.10", default-features = false } gdbstub_arch = { version = "0.3.3" } From d270492b38da19a3949aa7a5c17e4720c15e7b99 Mon Sep 17 00:00:00 2001 From: Oliver Steffen Date: Fri, 4 Sep 2026 10:22:25 +0200 Subject: [PATCH 05/13] kernel: print cocoon-tpm crypto backend name Print the name of the compile-time selected backend of cocoon-tpm-crypto to the log. Signed-off-by: Oliver Steffen --- kernel/src/svsm.rs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/kernel/src/svsm.rs b/kernel/src/svsm.rs index e6a33f4039..c9fbbd3fd9 100755 --- a/kernel/src/svsm.rs +++ b/kernel/src/svsm.rs @@ -558,6 +558,11 @@ fn svsm_init(launch_info: &KernelLaunchInfo) { panic!("Failed to prepare guest FW: {e:#?}"); } + log::info!( + "Cocoon-tpm crypto backend: {}", + cocoon_tpm_crypto::backend_name() + ); + #[cfg(feature = "virtio-drivers")] initialize_virtio_mmio(&boot_params).expect("Failed to initialize virtio-mmio drivers"); From 1757f599d33f088d640f36345530a96f3a082fef Mon Sep 17 00:00:00 2001 From: Oliver Steffen Date: Wed, 16 Sep 2026 13:02:28 +0200 Subject: [PATCH 06/13] workspace: add libcrt from libtcgtpm as its own crate Copy the libcrt C library used to integrate OpenSSL from the libtcgtpm crate to its own. It will gain an additional consumer in the future and thus should live in a common place. The new libcrt crate has no Rust code. It just builds libcrt and provides it at link time. libtcgtpm will depend on the new crate and drop its copy of the C code in a following commit. The C code is only compiled for bare-metal targets, to allow regular host-side tests to compile against system libc. Signed-off-by: Oliver Steffen --- Cargo.lock | 4 + Cargo.toml | 3 + libcrt/Cargo.toml | 9 + libcrt/build.rs | 66 ++++ libcrt/c/Makefile | 113 +++++++ libcrt/c/include/assert.h | 3 + libcrt/c/include/atomic.h | 335 ++++++++++++++++++++ libcrt/c/include/bits/alltypes.h | 417 +++++++++++++++++++++++++ libcrt/c/include/bits/atomic_arch.h | 125 ++++++++ libcrt/c/include/ctype.h | 3 + libcrt/c/include/dirent.h | 3 + libcrt/c/include/endian.h | 3 + libcrt/c/include/errno.h | 3 + libcrt/c/include/fcntl.h | 3 + libcrt/c/include/inttypes.h | 3 + libcrt/c/include/libcrt.h | 408 ++++++++++++++++++++++++ libcrt/c/include/limits.h | 3 + libcrt/c/include/memory.h | 3 + libcrt/c/include/setjmp.h | 3 + libcrt/c/include/stdarg.h | 3 + libcrt/c/include/stdatomic.h | 3 + libcrt/c/include/stdbool.h | 3 + libcrt/c/include/stddef.h | 3 + libcrt/c/include/stdint.h | 3 + libcrt/c/include/stdio.h | 3 + libcrt/c/include/stdlib.h | 3 + libcrt/c/include/string.h | 3 + libcrt/c/include/strings.h | 3 + libcrt/c/include/sys/shm.h | 3 + libcrt/c/include/sys/stat.h | 3 + libcrt/c/include/sys/syscall.h | 3 + libcrt/c/include/sys/time.h | 3 + libcrt/c/include/sys/types.h | 3 + libcrt/c/include/sys/utsname.h | 3 + libcrt/c/include/time.h | 3 + libcrt/c/include/unistd.h | 3 + libcrt/c/src/ctype/isascii.c | 8 + libcrt/c/src/ctype/isdigit.c | 6 + libcrt/c/src/ctype/islower.c | 8 + libcrt/c/src/ctype/isspace.c | 8 + libcrt/c/src/ctype/isupper.c | 8 + libcrt/c/src/ctype/tolower.c | 9 + libcrt/c/src/ctype/toupper.c | 9 + libcrt/c/src/exit/assert.c | 10 + libcrt/c/src/prng/rand.c | 151 +++++++++ libcrt/c/src/setjmp/x86_64/longjmp.s | 20 ++ libcrt/c/src/setjmp/x86_64/setjmp.s | 24 ++ libcrt/c/src/stdio/asprintf.c | 14 + libcrt/c/src/stdio/fprintf.c | 14 + libcrt/c/src/stdio/printf.c | 34 ++ libcrt/c/src/stdio/printf_wrapper.c | 269 ++++++++++++++++ libcrt/c/src/stdio/snprintf.c | 15 + libcrt/c/src/stdio/sprintf.c | 14 + libcrt/c/src/stdio/vasprintf.c | 16 + libcrt/c/src/stdio/vsnprintf.c | 9 + libcrt/c/src/stdio/vsprintf.c | 9 + libcrt/c/src/stdlib/atoi.c | 18 ++ libcrt/c/src/stdlib/qsort.c | 222 +++++++++++++ libcrt/c/src/stdlib/qsort_nr.c | 16 + libcrt/c/src/string/memchr.c | 29 ++ libcrt/c/src/string/memcmp.c | 10 + libcrt/c/src/string/memcpy.c | 126 ++++++++ libcrt/c/src/string/memmove.c | 44 +++ libcrt/c/src/string/memrchr.c | 13 + libcrt/c/src/string/memset.c | 92 ++++++ libcrt/c/src/string/stpcpy.c | 31 ++ libcrt/c/src/string/stpncpy.c | 34 ++ libcrt/c/src/string/strcasecmp.c | 20 ++ libcrt/c/src/string/strcat.c | 9 + libcrt/c/src/string/strchr.c | 9 + libcrt/c/src/string/strchrnul.c | 30 ++ libcrt/c/src/string/strcmp.c | 9 + libcrt/c/src/string/strcpy.c | 9 + libcrt/c/src/string/strcspn.c | 19 ++ libcrt/c/src/string/strdup.c | 13 + libcrt/c/src/string/strlen.c | 24 ++ libcrt/c/src/string/strncasecmp.c | 12 + libcrt/c/src/string/strncat.c | 12 + libcrt/c/src/string/strncmp.c | 11 + libcrt/c/src/string/strncpy.c | 9 + libcrt/c/src/string/strrchr.c | 8 + libcrt/c/src/string/strspn.c | 22 ++ libcrt/c/src/string/strstr.c | 156 +++++++++ libcrt/c/src/stub.c | 183 +++++++++++ libcrt/c/src/time/__secs_to_tm.c | 84 +++++ libcrt/c/src/time/gmtime_r.c | 25 ++ libcrt/c/src/time/time.c | 37 +++ libcrt/src/lib.rs | 20 ++ libtcgtpm/deps/libcrt/include/libcrt.h | 16 +- libtcgtpm/deps/libcrt/src/stub.c | 5 +- 90 files changed, 3583 insertions(+), 10 deletions(-) create mode 100644 libcrt/Cargo.toml create mode 100644 libcrt/build.rs create mode 100644 libcrt/c/Makefile create mode 100644 libcrt/c/include/assert.h create mode 100644 libcrt/c/include/atomic.h create mode 100644 libcrt/c/include/bits/alltypes.h create mode 100644 libcrt/c/include/bits/atomic_arch.h create mode 100644 libcrt/c/include/ctype.h create mode 100644 libcrt/c/include/dirent.h create mode 100644 libcrt/c/include/endian.h create mode 100644 libcrt/c/include/errno.h create mode 100644 libcrt/c/include/fcntl.h create mode 100644 libcrt/c/include/inttypes.h create mode 100644 libcrt/c/include/libcrt.h create mode 100644 libcrt/c/include/limits.h create mode 100644 libcrt/c/include/memory.h create mode 100644 libcrt/c/include/setjmp.h create mode 100644 libcrt/c/include/stdarg.h create mode 100644 libcrt/c/include/stdatomic.h create mode 100644 libcrt/c/include/stdbool.h create mode 100644 libcrt/c/include/stddef.h create mode 100644 libcrt/c/include/stdint.h create mode 100644 libcrt/c/include/stdio.h create mode 100644 libcrt/c/include/stdlib.h create mode 100644 libcrt/c/include/string.h create mode 100644 libcrt/c/include/strings.h create mode 100644 libcrt/c/include/sys/shm.h create mode 100644 libcrt/c/include/sys/stat.h create mode 100644 libcrt/c/include/sys/syscall.h create mode 100644 libcrt/c/include/sys/time.h create mode 100644 libcrt/c/include/sys/types.h create mode 100644 libcrt/c/include/sys/utsname.h create mode 100644 libcrt/c/include/time.h create mode 100644 libcrt/c/include/unistd.h create mode 100644 libcrt/c/src/ctype/isascii.c create mode 100644 libcrt/c/src/ctype/isdigit.c create mode 100644 libcrt/c/src/ctype/islower.c create mode 100644 libcrt/c/src/ctype/isspace.c create mode 100644 libcrt/c/src/ctype/isupper.c create mode 100644 libcrt/c/src/ctype/tolower.c create mode 100644 libcrt/c/src/ctype/toupper.c create mode 100644 libcrt/c/src/exit/assert.c create mode 100644 libcrt/c/src/prng/rand.c create mode 100644 libcrt/c/src/setjmp/x86_64/longjmp.s create mode 100644 libcrt/c/src/setjmp/x86_64/setjmp.s create mode 100644 libcrt/c/src/stdio/asprintf.c create mode 100644 libcrt/c/src/stdio/fprintf.c create mode 100644 libcrt/c/src/stdio/printf.c create mode 100644 libcrt/c/src/stdio/printf_wrapper.c create mode 100644 libcrt/c/src/stdio/snprintf.c create mode 100644 libcrt/c/src/stdio/sprintf.c create mode 100644 libcrt/c/src/stdio/vasprintf.c create mode 100644 libcrt/c/src/stdio/vsnprintf.c create mode 100644 libcrt/c/src/stdio/vsprintf.c create mode 100644 libcrt/c/src/stdlib/atoi.c create mode 100644 libcrt/c/src/stdlib/qsort.c create mode 100644 libcrt/c/src/stdlib/qsort_nr.c create mode 100644 libcrt/c/src/string/memchr.c create mode 100644 libcrt/c/src/string/memcmp.c create mode 100644 libcrt/c/src/string/memcpy.c create mode 100644 libcrt/c/src/string/memmove.c create mode 100644 libcrt/c/src/string/memrchr.c create mode 100644 libcrt/c/src/string/memset.c create mode 100644 libcrt/c/src/string/stpcpy.c create mode 100644 libcrt/c/src/string/stpncpy.c create mode 100644 libcrt/c/src/string/strcasecmp.c create mode 100644 libcrt/c/src/string/strcat.c create mode 100644 libcrt/c/src/string/strchr.c create mode 100644 libcrt/c/src/string/strchrnul.c create mode 100644 libcrt/c/src/string/strcmp.c create mode 100644 libcrt/c/src/string/strcpy.c create mode 100644 libcrt/c/src/string/strcspn.c create mode 100644 libcrt/c/src/string/strdup.c create mode 100644 libcrt/c/src/string/strlen.c create mode 100644 libcrt/c/src/string/strncasecmp.c create mode 100644 libcrt/c/src/string/strncat.c create mode 100644 libcrt/c/src/string/strncmp.c create mode 100644 libcrt/c/src/string/strncpy.c create mode 100644 libcrt/c/src/string/strrchr.c create mode 100644 libcrt/c/src/string/strspn.c create mode 100644 libcrt/c/src/string/strstr.c create mode 100644 libcrt/c/src/stub.c create mode 100644 libcrt/c/src/time/__secs_to_tm.c create mode 100644 libcrt/c/src/time/gmtime_r.c create mode 100644 libcrt/c/src/time/time.c create mode 100644 libcrt/src/lib.rs diff --git a/Cargo.lock b/Cargo.lock index ed45d2cf9a..375b1cc5f2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1530,6 +1530,10 @@ version = "0.2.186" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "68ab91017fe16c622486840e4c83c9a37afeff978bd239b5293d61ece587de66" +[[package]] +name = "libcrt" +version = "0.1.0" + [[package]] name = "libfuzzer-sys" version = "0.4.10" diff --git a/Cargo.toml b/Cargo.toml index 418c1a6f1e..a0c872a384 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -17,6 +17,8 @@ members = [ "fuzz", # ELF loader "elf", + # Minimal C runtime for freestanding environments + "libcrt", # TPM 2.0 Reference Implementation library "libtcgtpm", # syscall interface definitions @@ -60,6 +62,7 @@ svsm = { path = "kernel" } elf = { path = "elf" } verus_stub = { path = "verification/verus_stub" } verus_macro_stub = { path = "verification/verus_macro_stub" } +libcrt = { path = "libcrt" } libtcgtpm = { path = "libtcgtpm" } libaproxy = { path = "libaproxy" } syscall = { path = "syscall" } diff --git a/libcrt/Cargo.toml b/libcrt/Cargo.toml new file mode 100644 index 0000000000..57ec62c31b --- /dev/null +++ b/libcrt/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "libcrt" +version = "0.1.0" +edition.workspace = true + +links = "crt" + +[lints] +workspace = true diff --git a/libcrt/build.rs b/libcrt/build.rs new file mode 100644 index 0000000000..5588eef69f --- /dev/null +++ b/libcrt/build.rs @@ -0,0 +1,66 @@ +// SPDX-License-Identifier: MIT OR Apache-2.0 +// +// Copyright (c) 2026 Red Hat +// +// Author: Oliver Steffen + +use std::env; +use std::path::PathBuf; +use std::process::{Command, Stdio}; + +fn main() { + let src_dir = PathBuf::from(env::var("CARGO_MANIFEST_DIR").unwrap()); + let out_dir = env::var("OUT_DIR").unwrap(); + let out_path = PathBuf::from(&out_dir); + + let libcrt_src_dir = src_dir.join("c"); + println!( + "cargo::rerun-if-changed={}", + libcrt_src_dir.to_str().unwrap() + ); + + let target = env::var("TARGET").unwrap(); + let libcrt_build_dir = out_path.join("libcrt"); + + // Only compile and link the C runtime for bare-metal targets. + // For host builds (tests), the system libc provides these symbols. + // Linking the bare-metal C objects on the host causes hidden-visibility + // conflicts (-fPIE triggers #pragma GCC visibility push(hidden) in + // libcrt.h, making all symbol references unsatisfiable by shared libs). + // + // TODO: The target-integration crate should be made target-conditional so + // the entire SVSM-specific build pipeline (libcrt, SVSM OpenSSL config, + // custom CFLAGS/CPPFLAGS) is skipped for host builds. Currently, host + // test builds still pull in the integration crate and configure OpenSSL + // with SVSM flags — only the C library link is skipped here as a + // workaround. + if target.ends_with("-none") { + std::fs::create_dir_all(&libcrt_build_dir).unwrap(); + + let status = Command::new("make") + .arg("-C") + .arg(&libcrt_src_dir) + .arg(format!("OUT_DIR={}", libcrt_build_dir.to_str().unwrap())) + .stdout(Stdio::inherit()) + .stderr(Stdio::inherit()) + .status() + .unwrap(); + assert!(status.success()); + + println!( + "cargo::rustc-link-search={}", + libcrt_build_dir.to_str().unwrap() + ); + println!("cargo::rustc-link-lib=static=crt"); + } + + let libcrt_include = libcrt_src_dir.join("include"); + println!( + "cargo::metadata=INCLUDE_DIR={}", + libcrt_include.to_str().unwrap() + ); + println!( + "cargo::metadata=LIB_DIR={}", + libcrt_build_dir.to_str().unwrap() + ); +} diff --git a/libcrt/c/Makefile b/libcrt/c/Makefile new file mode 100644 index 0000000000..7826d273dd --- /dev/null +++ b/libcrt/c/Makefile @@ -0,0 +1,113 @@ +# SPDX-License-Identifier: MIT + +ifdef RELEASE +CFLAGS = -O3 +else +CFLAGS = -g -O0 +endif + +SRC_DIR := $(dir $(realpath $(lastword $(MAKEFILE_LIST)))) +OUT_DIR ?= $(SRC_DIR) + +CFLAGS += -I$(SRC_DIR)/include -nostdinc -nostdlib -mno-red-zone +CFLAGS += -m64 -march=x86-64 -mno-sse2 -fPIE +CFLAGS += -fno-stack-protector +CFLAGS += -ffreestanding +CFLAGS += -Wall -Werror + +CC = gcc + +vpath %.c $(SRC_DIR) +vpath %.s $(SRC_DIR) + +# Functions we stub out +OBJS = $(OUT_DIR)/src/stub.o + +# ctype +OBJS += $(addprefix $(OUT_DIR)/src/ctype/, \ + isdigit.o \ + islower.o \ + isspace.o \ + isupper.o \ + tolower.o \ + toupper.o \ + ) +# exit +OBJS += $(OUT_DIR)/src/exit/assert.o + +# prng +OBJS += $(OUT_DIR)/src/prng/rand.o + +# setjmp +OBJS += $(addprefix $(OUT_DIR)/src/setjmp/x86_64/, \ + longjmp.o \ + setjmp.o \ + ) +# stdio +OBJS += $(addprefix $(OUT_DIR)/src/stdio/, \ + asprintf.o \ + fprintf.o \ + printf.o \ + printf_wrapper.o \ + snprintf.o \ + sprintf.o \ + vasprintf.o \ + vsnprintf.o \ + vsprintf.o \ + ) +# stdlib +OBJS += $(addprefix $(OUT_DIR)/src/stdlib/, \ + atoi.o \ + qsort.o \ + qsort_nr.o \ + ) +# string +OBJS += $(addprefix $(OUT_DIR)/src/string/, \ + memchr.o \ + memcmp.o \ + memcpy.o \ + memmove.o \ + memrchr.o \ + memset.o \ + stpcpy.o \ + stpncpy.o \ + strcasecmp.o \ + strcat.o \ + strchr.o \ + strchrnul.o \ + strcmp.o \ + strcspn.o \ + strcpy.o \ + strdup.o \ + strlen.o \ + strncasecmp.o \ + strncat.o \ + strncmp.o \ + strncpy.o \ + strrchr.o \ + strspn.o \ + strstr.o \ + ) +# time +OBJS += $(addprefix $(OUT_DIR)/src/time/, \ + __secs_to_tm.o \ + gmtime_r.o \ + time.o \ + ) + +all: $(OUT_DIR)/libcrt.a + +$(OUT_DIR)/libcrt.a: $(OBJS) + ar rcs $@ $(OBJS) + +$(OUT_DIR)/%.o : %.c + @mkdir -p $(dir $@) + $(CC) $(CFLAGS) -c -o $@ $< + +$(OUT_DIR)/%.o : %.s + @mkdir -p $(dir $@) + $(CC) $(CFLAGS) -c -o $@ $< + +clean: + rm -f $(OUT_DIR)/libcrt.a + rm -f $(OBJS) diff --git a/libcrt/c/include/assert.h b/libcrt/c/include/assert.h new file mode 100644 index 0000000000..bbfe5d4940 --- /dev/null +++ b/libcrt/c/include/assert.h @@ -0,0 +1,3 @@ +/* SPDX-License-Identifier: MIT */ + +#include diff --git a/libcrt/c/include/atomic.h b/libcrt/c/include/atomic.h new file mode 100644 index 0000000000..5198189049 --- /dev/null +++ b/libcrt/c/include/atomic.h @@ -0,0 +1,335 @@ +/* SPDX-License-Identifier: MIT */ + +#ifndef _ATOMIC_H +#define _ATOMIC_H + +#include + +#include + +#ifdef a_ll + +#ifndef a_pre_llsc +#define a_pre_llsc() +#endif + +#ifndef a_post_llsc +#define a_post_llsc() +#endif + +#ifndef a_cas +#define a_cas a_cas +static inline int a_cas(volatile int *p, int t, int s) +{ + int old; + a_pre_llsc(); + do old = a_ll(p); + while (old==t && !a_sc(p, s)); + a_post_llsc(); + return old; +} +#endif + +#ifndef a_swap +#define a_swap a_swap +static inline int a_swap(volatile int *p, int v) +{ + int old; + a_pre_llsc(); + do old = a_ll(p); + while (!a_sc(p, v)); + a_post_llsc(); + return old; +} +#endif + +#ifndef a_fetch_add +#define a_fetch_add a_fetch_add +static inline int a_fetch_add(volatile int *p, int v) +{ + int old; + a_pre_llsc(); + do old = a_ll(p); + while (!a_sc(p, (unsigned)old + v)); + a_post_llsc(); + return old; +} +#endif + +#ifndef a_fetch_and +#define a_fetch_and a_fetch_and +static inline int a_fetch_and(volatile int *p, int v) +{ + int old; + a_pre_llsc(); + do old = a_ll(p); + while (!a_sc(p, old & v)); + a_post_llsc(); + return old; +} +#endif + +#ifndef a_fetch_or +#define a_fetch_or a_fetch_or +static inline int a_fetch_or(volatile int *p, int v) +{ + int old; + a_pre_llsc(); + do old = a_ll(p); + while (!a_sc(p, old | v)); + a_post_llsc(); + return old; +} +#endif + +#endif + +#ifdef a_ll_p + +#ifndef a_cas_p +#define a_cas_p a_cas_p +static inline void *a_cas_p(volatile void *p, void *t, void *s) +{ + void *old; + a_pre_llsc(); + do old = a_ll_p(p); + while (old==t && !a_sc_p(p, s)); + a_post_llsc(); + return old; +} +#endif + +#endif + +#ifndef a_cas +#error missing definition of a_cas +#endif + +#ifndef a_swap +#define a_swap a_swap +static inline int a_swap(volatile int *p, int v) +{ + int old; + do old = *p; + while (a_cas(p, old, v) != old); + return old; +} +#endif + +#ifndef a_fetch_add +#define a_fetch_add a_fetch_add +static inline int a_fetch_add(volatile int *p, int v) +{ + int old; + do old = *p; + while (a_cas(p, old, (unsigned)old+v) != old); + return old; +} +#endif + +#ifndef a_fetch_and +#define a_fetch_and a_fetch_and +static inline int a_fetch_and(volatile int *p, int v) +{ + int old; + do old = *p; + while (a_cas(p, old, old&v) != old); + return old; +} +#endif +#ifndef a_fetch_or +#define a_fetch_or a_fetch_or +static inline int a_fetch_or(volatile int *p, int v) +{ + int old; + do old = *p; + while (a_cas(p, old, old|v) != old); + return old; +} +#endif + +#ifndef a_and +#define a_and a_and +static inline void a_and(volatile int *p, int v) +{ + a_fetch_and(p, v); +} +#endif + +#ifndef a_or +#define a_or a_or +static inline void a_or(volatile int *p, int v) +{ + a_fetch_or(p, v); +} +#endif + +#ifndef a_inc +#define a_inc a_inc +static inline void a_inc(volatile int *p) +{ + a_fetch_add(p, 1); +} +#endif + +#ifndef a_dec +#define a_dec a_dec +static inline void a_dec(volatile int *p) +{ + a_fetch_add(p, -1); +} +#endif + +#ifndef a_store +#define a_store a_store +static inline void a_store(volatile int *p, int v) +{ +#ifdef a_barrier + a_barrier(); + *p = v; + a_barrier(); +#else + a_swap(p, v); +#endif +} +#endif + +#ifndef a_barrier +#define a_barrier a_barrier +static void a_barrier() +{ + volatile int tmp = 0; + a_cas(&tmp, 0, 0); +} +#endif + +#ifndef a_spin +#define a_spin a_barrier +#endif + +#ifndef a_and_64 +#define a_and_64 a_and_64 +static inline void a_and_64(volatile uint64_t *p, uint64_t v) +{ + union { uint64_t v; uint32_t r[2]; } u = { v }; + if (u.r[0]+1) a_and((int *)p, u.r[0]); + if (u.r[1]+1) a_and((int *)p+1, u.r[1]); +} +#endif + +#ifndef a_or_64 +#define a_or_64 a_or_64 +static inline void a_or_64(volatile uint64_t *p, uint64_t v) +{ + union { uint64_t v; uint32_t r[2]; } u = { v }; + if (u.r[0]) a_or((int *)p, u.r[0]); + if (u.r[1]) a_or((int *)p+1, u.r[1]); +} +#endif + +#ifndef a_cas_p +typedef char a_cas_p_undefined_but_pointer_not_32bit[-sizeof(char) == 0xffffffff ? 1 : -1]; +#define a_cas_p a_cas_p +static inline void *a_cas_p(volatile void *p, void *t, void *s) +{ + return (void *)a_cas((volatile int *)p, (int)t, (int)s); +} +#endif + +#ifndef a_or_l +#define a_or_l a_or_l +static inline void a_or_l(volatile void *p, long v) +{ + if (sizeof(long) == sizeof(int)) a_or(p, v); + else a_or_64(p, v); +} +#endif + +#ifndef a_crash +#define a_crash a_crash +static inline void a_crash() +{ + *(volatile char *)0=0; +} +#endif + +#ifndef a_ctz_32 +#define a_ctz_32 a_ctz_32 +static inline int a_ctz_32(uint32_t x) +{ +#ifdef a_clz_32 + return 31-a_clz_32(x&-x); +#else + static const char debruijn32[32] = { + 0, 1, 23, 2, 29, 24, 19, 3, 30, 27, 25, 11, 20, 8, 4, 13, + 31, 22, 28, 18, 26, 10, 7, 12, 21, 17, 9, 6, 16, 5, 15, 14 + }; + return debruijn32[(x&-x)*0x076be629 >> 27]; +#endif +} +#endif + +#ifndef a_ctz_64 +#define a_ctz_64 a_ctz_64 +static inline int a_ctz_64(uint64_t x) +{ + static const char debruijn64[64] = { + 0, 1, 2, 53, 3, 7, 54, 27, 4, 38, 41, 8, 34, 55, 48, 28, + 62, 5, 39, 46, 44, 42, 22, 9, 24, 35, 59, 56, 49, 18, 29, 11, + 63, 52, 6, 26, 37, 40, 33, 47, 61, 45, 43, 21, 23, 58, 17, 10, + 51, 25, 36, 32, 60, 20, 57, 16, 50, 31, 19, 15, 30, 14, 13, 12 + }; + if (sizeof(long) < 8) { + uint32_t y = x; + if (!y) { + y = x>>32; + return 32 + a_ctz_32(y); + } + return a_ctz_32(y); + } + return debruijn64[(x&-x)*0x022fdd63cc95386dull >> 58]; +} +#endif + +static inline int a_ctz_l(unsigned long x) +{ + return (sizeof(long) < 8) ? a_ctz_32(x) : a_ctz_64(x); +} + +#ifndef a_clz_64 +#define a_clz_64 a_clz_64 +static inline int a_clz_64(uint64_t x) +{ +#ifdef a_clz_32 + if (x>>32) + return a_clz_32(x>>32); + return a_clz_32(x) + 32; +#else + uint32_t y; + int r; + if (x>>32) y=x>>32, r=0; else y=x, r=32; + if (y>>16) y>>=16; else r |= 16; + if (y>>8) y>>=8; else r |= 8; + if (y>>4) y>>=4; else r |= 4; + if (y>>2) y>>=2; else r |= 2; + return r | !(y>>1); +#endif +} +#endif + +#ifndef a_clz_32 +#define a_clz_32 a_clz_32 +static inline int a_clz_32(uint32_t x) +{ + x >>= 1; + x |= x >> 1; + x |= x >> 2; + x |= x >> 4; + x |= x >> 8; + x |= x >> 16; + x++; + return 31-a_ctz_32(x); +} +#endif + +#endif diff --git a/libcrt/c/include/bits/alltypes.h b/libcrt/c/include/bits/alltypes.h new file mode 100644 index 0000000000..56d4713382 --- /dev/null +++ b/libcrt/c/include/bits/alltypes.h @@ -0,0 +1,417 @@ +/* SPDX-License-Identifier: MIT */ + +#define _Addr long +#define _Int64 long +#define _Reg long + +#define __BYTE_ORDER 1234 +#define __LONG_MAX 0x7fffffffffffffffL + +#ifndef __cplusplus +#if defined(__NEED_wchar_t) && !defined(__DEFINED_wchar_t) +typedef int wchar_t; +#define __DEFINED_wchar_t +#endif + +#endif + +#if defined(__FLT_EVAL_METHOD__) && __FLT_EVAL_METHOD__ == 2 +#if defined(__NEED_float_t) && !defined(__DEFINED_float_t) +typedef long double float_t; +#define __DEFINED_float_t +#endif + +#if defined(__NEED_double_t) && !defined(__DEFINED_double_t) +typedef long double double_t; +#define __DEFINED_double_t +#endif + +#else +#if defined(__NEED_float_t) && !defined(__DEFINED_float_t) +typedef float float_t; +#define __DEFINED_float_t +#endif + +#if defined(__NEED_double_t) && !defined(__DEFINED_double_t) +typedef double double_t; +#define __DEFINED_double_t +#endif + +#endif + +#if defined(__NEED_max_align_t) && !defined(__DEFINED_max_align_t) +typedef struct { long long __ll; long double __ld; } max_align_t; +#define __DEFINED_max_align_t +#endif + +#define __LITTLE_ENDIAN 1234 +#define __BIG_ENDIAN 4321 +#define __USE_TIME_BITS64 1 + +#if defined(__NEED_size_t) && !defined(__DEFINED_size_t) +typedef unsigned _Addr size_t; +#define __DEFINED_size_t +#endif + +#if defined(__NEED_uintptr_t) && !defined(__DEFINED_uintptr_t) +typedef unsigned _Addr uintptr_t; +#define __DEFINED_uintptr_t +#endif + +#if defined(__NEED_ptrdiff_t) && !defined(__DEFINED_ptrdiff_t) +typedef _Addr ptrdiff_t; +#define __DEFINED_ptrdiff_t +#endif + +#if defined(__NEED_ssize_t) && !defined(__DEFINED_ssize_t) +typedef _Addr ssize_t; +#define __DEFINED_ssize_t +#endif + +#if defined(__NEED_intptr_t) && !defined(__DEFINED_intptr_t) +typedef _Addr intptr_t; +#define __DEFINED_intptr_t +#endif + +#if defined(__NEED_regoff_t) && !defined(__DEFINED_regoff_t) +typedef _Addr regoff_t; +#define __DEFINED_regoff_t +#endif + +#if defined(__NEED_register_t) && !defined(__DEFINED_register_t) +typedef _Reg register_t; +#define __DEFINED_register_t +#endif + +#if defined(__NEED_time_t) && !defined(__DEFINED_time_t) +typedef _Int64 time_t; +#define __DEFINED_time_t +#endif + +#if defined(__NEED_suseconds_t) && !defined(__DEFINED_suseconds_t) +typedef _Int64 suseconds_t; +#define __DEFINED_suseconds_t +#endif + + +#if defined(__NEED_int8_t) && !defined(__DEFINED_int8_t) +typedef signed char int8_t; +#define __DEFINED_int8_t +#endif + +#if defined(__NEED_int16_t) && !defined(__DEFINED_int16_t) +typedef signed short int16_t; +#define __DEFINED_int16_t +#endif + +#if defined(__NEED_int32_t) && !defined(__DEFINED_int32_t) +typedef signed int int32_t; +#define __DEFINED_int32_t +#endif + +#if defined(__NEED_int64_t) && !defined(__DEFINED_int64_t) +typedef signed _Int64 int64_t; +#define __DEFINED_int64_t +#endif + +#if defined(__NEED_intmax_t) && !defined(__DEFINED_intmax_t) +typedef signed _Int64 intmax_t; +#define __DEFINED_intmax_t +#endif + +#if defined(__NEED_uint8_t) && !defined(__DEFINED_uint8_t) +typedef unsigned char uint8_t; +#define __DEFINED_uint8_t +#endif + +#if defined(__NEED_uint16_t) && !defined(__DEFINED_uint16_t) +typedef unsigned short uint16_t; +#define __DEFINED_uint16_t +#endif + +#if defined(__NEED_uint32_t) && !defined(__DEFINED_uint32_t) +typedef unsigned int uint32_t; +#define __DEFINED_uint32_t +#endif + +#if defined(__NEED_uint64_t) && !defined(__DEFINED_uint64_t) +typedef unsigned _Int64 uint64_t; +#define __DEFINED_uint64_t +#endif + +#if defined(__NEED_u_int64_t) && !defined(__DEFINED_u_int64_t) +typedef unsigned _Int64 u_int64_t; +#define __DEFINED_u_int64_t +#endif + +#if defined(__NEED_uintmax_t) && !defined(__DEFINED_uintmax_t) +typedef unsigned _Int64 uintmax_t; +#define __DEFINED_uintmax_t +#endif + + +#if defined(__NEED_mode_t) && !defined(__DEFINED_mode_t) +typedef unsigned mode_t; +#define __DEFINED_mode_t +#endif + +#if defined(__NEED_nlink_t) && !defined(__DEFINED_nlink_t) +typedef unsigned _Reg nlink_t; +#define __DEFINED_nlink_t +#endif + +#if defined(__NEED_off_t) && !defined(__DEFINED_off_t) +typedef _Int64 off_t; +#define __DEFINED_off_t +#endif + +#if defined(__NEED_ino_t) && !defined(__DEFINED_ino_t) +typedef unsigned _Int64 ino_t; +#define __DEFINED_ino_t +#endif + +#if defined(__NEED_dev_t) && !defined(__DEFINED_dev_t) +typedef unsigned _Int64 dev_t; +#define __DEFINED_dev_t +#endif + +#if defined(__NEED_blksize_t) && !defined(__DEFINED_blksize_t) +typedef long blksize_t; +#define __DEFINED_blksize_t +#endif + +#if defined(__NEED_blkcnt_t) && !defined(__DEFINED_blkcnt_t) +typedef _Int64 blkcnt_t; +#define __DEFINED_blkcnt_t +#endif + +#if defined(__NEED_fsblkcnt_t) && !defined(__DEFINED_fsblkcnt_t) +typedef unsigned _Int64 fsblkcnt_t; +#define __DEFINED_fsblkcnt_t +#endif + +#if defined(__NEED_fsfilcnt_t) && !defined(__DEFINED_fsfilcnt_t) +typedef unsigned _Int64 fsfilcnt_t; +#define __DEFINED_fsfilcnt_t +#endif + + +#if defined(__NEED_wint_t) && !defined(__DEFINED_wint_t) +typedef unsigned wint_t; +#define __DEFINED_wint_t +#endif + +#if defined(__NEED_wctype_t) && !defined(__DEFINED_wctype_t) +typedef unsigned long wctype_t; +#define __DEFINED_wctype_t +#endif + + +#if defined(__NEED_timer_t) && !defined(__DEFINED_timer_t) +typedef void * timer_t; +#define __DEFINED_timer_t +#endif + +#if defined(__NEED_clockid_t) && !defined(__DEFINED_clockid_t) +typedef int clockid_t; +#define __DEFINED_clockid_t +#endif + +#if defined(__NEED_clock_t) && !defined(__DEFINED_clock_t) +typedef long clock_t; +#define __DEFINED_clock_t +#endif + +#if defined(__NEED_struct_timeval) && !defined(__DEFINED_struct_timeval) +struct timeval { time_t tv_sec; suseconds_t tv_usec; }; +#define __DEFINED_struct_timeval +#endif + +#if defined(__NEED_struct_timespec) && !defined(__DEFINED_struct_timespec) +struct timespec { time_t tv_sec; int :8*(sizeof(time_t)-sizeof(long))*(__BYTE_ORDER==4321); long tv_nsec; int :8*(sizeof(time_t)-sizeof(long))*(__BYTE_ORDER!=4321); }; +#define __DEFINED_struct_timespec +#endif + + +#if defined(__NEED_pid_t) && !defined(__DEFINED_pid_t) +typedef int pid_t; +#define __DEFINED_pid_t +#endif + +#if defined(__NEED_id_t) && !defined(__DEFINED_id_t) +typedef unsigned id_t; +#define __DEFINED_id_t +#endif + +#if defined(__NEED_uid_t) && !defined(__DEFINED_uid_t) +typedef unsigned uid_t; +#define __DEFINED_uid_t +#endif + +#if defined(__NEED_gid_t) && !defined(__DEFINED_gid_t) +typedef unsigned gid_t; +#define __DEFINED_gid_t +#endif + +#if defined(__NEED_key_t) && !defined(__DEFINED_key_t) +typedef int key_t; +#define __DEFINED_key_t +#endif + +#if defined(__NEED_useconds_t) && !defined(__DEFINED_useconds_t) +typedef unsigned useconds_t; +#define __DEFINED_useconds_t +#endif + + +#ifdef __cplusplus +#if defined(__NEED_pthread_t) && !defined(__DEFINED_pthread_t) +typedef unsigned long pthread_t; +#define __DEFINED_pthread_t +#endif + +#else +#if defined(__NEED_pthread_t) && !defined(__DEFINED_pthread_t) +typedef struct __pthread * pthread_t; +#define __DEFINED_pthread_t +#endif + +#endif +#if defined(__NEED_pthread_once_t) && !defined(__DEFINED_pthread_once_t) +typedef int pthread_once_t; +#define __DEFINED_pthread_once_t +#endif + +#if defined(__NEED_pthread_key_t) && !defined(__DEFINED_pthread_key_t) +typedef unsigned pthread_key_t; +#define __DEFINED_pthread_key_t +#endif + +#if defined(__NEED_pthread_spinlock_t) && !defined(__DEFINED_pthread_spinlock_t) +typedef int pthread_spinlock_t; +#define __DEFINED_pthread_spinlock_t +#endif + +#if defined(__NEED_pthread_mutexattr_t) && !defined(__DEFINED_pthread_mutexattr_t) +typedef struct { unsigned __attr; } pthread_mutexattr_t; +#define __DEFINED_pthread_mutexattr_t +#endif + +#if defined(__NEED_pthread_condattr_t) && !defined(__DEFINED_pthread_condattr_t) +typedef struct { unsigned __attr; } pthread_condattr_t; +#define __DEFINED_pthread_condattr_t +#endif + +#if defined(__NEED_pthread_barrierattr_t) && !defined(__DEFINED_pthread_barrierattr_t) +typedef struct { unsigned __attr; } pthread_barrierattr_t; +#define __DEFINED_pthread_barrierattr_t +#endif + +#if defined(__NEED_pthread_rwlockattr_t) && !defined(__DEFINED_pthread_rwlockattr_t) +typedef struct { unsigned __attr[2]; } pthread_rwlockattr_t; +#define __DEFINED_pthread_rwlockattr_t +#endif + + +#if defined(__NEED_struct__IO_FILE) && !defined(__DEFINED_struct__IO_FILE) +struct _IO_FILE { char __x; }; +#define __DEFINED_struct__IO_FILE +#endif + +#if defined(__NEED_FILE) && !defined(__DEFINED_FILE) +typedef struct _IO_FILE FILE; +#define __DEFINED_FILE +#endif + + +#if defined(__NEED_va_list) && !defined(__DEFINED_va_list) +typedef __builtin_va_list va_list; +#define __DEFINED_va_list +#endif + +#if defined(__NEED___isoc_va_list) && !defined(__DEFINED___isoc_va_list) +typedef __builtin_va_list __isoc_va_list; +#define __DEFINED___isoc_va_list +#endif + + +#if defined(__NEED_mbstate_t) && !defined(__DEFINED_mbstate_t) +typedef struct __mbstate_t { unsigned __opaque1, __opaque2; } mbstate_t; +#define __DEFINED_mbstate_t +#endif + + +#if defined(__NEED_locale_t) && !defined(__DEFINED_locale_t) +typedef struct __locale_struct * locale_t; +#define __DEFINED_locale_t +#endif + + +#if defined(__NEED_sigset_t) && !defined(__DEFINED_sigset_t) +typedef struct __sigset_t { unsigned long __bits[128/sizeof(long)]; } sigset_t; +#define __DEFINED_sigset_t +#endif + + +#if defined(__NEED_struct_iovec) && !defined(__DEFINED_struct_iovec) +struct iovec { void *iov_base; size_t iov_len; }; +#define __DEFINED_struct_iovec +#endif + + +#if defined(__NEED_struct_winsize) && !defined(__DEFINED_struct_winsize) +struct winsize { unsigned short ws_row, ws_col, ws_xpixel, ws_ypixel; }; +#define __DEFINED_struct_winsize +#endif + + +#if defined(__NEED_socklen_t) && !defined(__DEFINED_socklen_t) +typedef unsigned socklen_t; +#define __DEFINED_socklen_t +#endif + +#if defined(__NEED_sa_family_t) && !defined(__DEFINED_sa_family_t) +typedef unsigned short sa_family_t; +#define __DEFINED_sa_family_t +#endif + + +#if defined(__NEED_pthread_attr_t) && !defined(__DEFINED_pthread_attr_t) +typedef struct { union { int __i[sizeof(long)==8?14:9]; volatile int __vi[sizeof(long)==8?14:9]; unsigned long __s[sizeof(long)==8?7:9]; } __u; } pthread_attr_t; +#define __DEFINED_pthread_attr_t +#endif + +#if defined(__NEED_pthread_mutex_t) && !defined(__DEFINED_pthread_mutex_t) +typedef struct { union { int __i[sizeof(long)==8?10:6]; volatile int __vi[sizeof(long)==8?10:6]; volatile void *volatile __p[sizeof(long)==8?5:6]; } __u; } pthread_mutex_t; +#define __DEFINED_pthread_mutex_t +#endif + +#if defined(__NEED_mtx_t) && !defined(__DEFINED_mtx_t) +typedef struct { union { int __i[sizeof(long)==8?10:6]; volatile int __vi[sizeof(long)==8?10:6]; volatile void *volatile __p[sizeof(long)==8?5:6]; } __u; } mtx_t; +#define __DEFINED_mtx_t +#endif + +#if defined(__NEED_pthread_cond_t) && !defined(__DEFINED_pthread_cond_t) +typedef struct { union { int __i[12]; volatile int __vi[12]; void *__p[12*sizeof(int)/sizeof(void*)]; } __u; } pthread_cond_t; +#define __DEFINED_pthread_cond_t +#endif + +#if defined(__NEED_cnd_t) && !defined(__DEFINED_cnd_t) +typedef struct { union { int __i[12]; volatile int __vi[12]; void *__p[12*sizeof(int)/sizeof(void*)]; } __u; } cnd_t; +#define __DEFINED_cnd_t +#endif + +#if defined(__NEED_pthread_rwlock_t) && !defined(__DEFINED_pthread_rwlock_t) +typedef struct { union { int __i[sizeof(long)==8?14:8]; volatile int __vi[sizeof(long)==8?14:8]; void *__p[sizeof(long)==8?7:8]; } __u; } pthread_rwlock_t; +#define __DEFINED_pthread_rwlock_t +#endif + +#if defined(__NEED_pthread_barrier_t) && !defined(__DEFINED_pthread_barrier_t) +typedef struct { union { int __i[sizeof(long)==8?8:5]; volatile int __vi[sizeof(long)==8?8:5]; void *__p[sizeof(long)==8?4:5]; } __u; } pthread_barrier_t; +#define __DEFINED_pthread_barrier_t +#endif + + +#undef _Addr +#undef _Int64 +#undef _Reg diff --git a/libcrt/c/include/bits/atomic_arch.h b/libcrt/c/include/bits/atomic_arch.h new file mode 100644 index 0000000000..5809f8e52f --- /dev/null +++ b/libcrt/c/include/bits/atomic_arch.h @@ -0,0 +1,125 @@ +/* SPDX-License-Identifier: MIT */ + +#define a_cas a_cas +static inline int a_cas(volatile int *p, int t, int s) +{ + __asm__ __volatile__ ( + "lock ; cmpxchg %3, %1" + : "=a"(t), "=m"(*p) : "a"(t), "r"(s) : "memory" ); + return t; +} + +#define a_cas_p a_cas_p +static inline void *a_cas_p(volatile void *p, void *t, void *s) +{ + __asm__( "lock ; cmpxchg %3, %1" + : "=a"(t), "=m"(*(void *volatile *)p) + : "a"(t), "r"(s) : "memory" ); + return t; +} + +#define a_swap a_swap +static inline int a_swap(volatile int *p, int v) +{ + __asm__ __volatile__( + "xchg %0, %1" + : "=r"(v), "=m"(*p) : "0"(v) : "memory" ); + return v; +} + +#define a_fetch_add a_fetch_add +static inline int a_fetch_add(volatile int *p, int v) +{ + __asm__ __volatile__( + "lock ; xadd %0, %1" + : "=r"(v), "=m"(*p) : "0"(v) : "memory" ); + return v; +} + +#define a_and a_and +static inline void a_and(volatile int *p, int v) +{ + __asm__ __volatile__( + "lock ; and %1, %0" + : "=m"(*p) : "r"(v) : "memory" ); +} + +#define a_or a_or +static inline void a_or(volatile int *p, int v) +{ + __asm__ __volatile__( + "lock ; or %1, %0" + : "=m"(*p) : "r"(v) : "memory" ); +} + +#define a_and_64 a_and_64 +static inline void a_and_64(volatile uint64_t *p, uint64_t v) +{ + __asm__ __volatile( + "lock ; and %1, %0" + : "=m"(*p) : "r"(v) : "memory" ); +} + +#define a_or_64 a_or_64 +static inline void a_or_64(volatile uint64_t *p, uint64_t v) +{ + __asm__ __volatile__( + "lock ; or %1, %0" + : "=m"(*p) : "r"(v) : "memory" ); +} + +#define a_inc a_inc +static inline void a_inc(volatile int *p) +{ + __asm__ __volatile__( + "lock ; incl %0" + : "=m"(*p) : "m"(*p) : "memory" ); +} + +#define a_dec a_dec +static inline void a_dec(volatile int *p) +{ + __asm__ __volatile__( + "lock ; decl %0" + : "=m"(*p) : "m"(*p) : "memory" ); +} + +#define a_store a_store +static inline void a_store(volatile int *p, int x) +{ + __asm__ __volatile__( + "mov %1, %0 ; lock ; orl $0,(%%rsp)" + : "=m"(*p) : "r"(x) : "memory" ); +} + +#define a_barrier a_barrier +static inline void a_barrier() +{ + __asm__ __volatile__( "" : : : "memory" ); +} + +#define a_spin a_spin +static inline void a_spin() +{ + __asm__ __volatile__( "pause" : : : "memory" ); +} + +#define a_crash a_crash +static inline void a_crash() +{ + __asm__ __volatile__( "hlt" : : : "memory" ); +} + +#define a_ctz_64 a_ctz_64 +static inline int a_ctz_64(uint64_t x) +{ + __asm__( "bsf %1,%0" : "=r"(x) : "r"(x) ); + return x; +} + +#define a_clz_64 a_clz_64 +static inline int a_clz_64(uint64_t x) +{ + __asm__( "bsr %1,%0 ; xor $63,%0" : "=r"(x) : "r"(x) ); + return x; +} diff --git a/libcrt/c/include/ctype.h b/libcrt/c/include/ctype.h new file mode 100644 index 0000000000..bbfe5d4940 --- /dev/null +++ b/libcrt/c/include/ctype.h @@ -0,0 +1,3 @@ +/* SPDX-License-Identifier: MIT */ + +#include diff --git a/libcrt/c/include/dirent.h b/libcrt/c/include/dirent.h new file mode 100644 index 0000000000..bbfe5d4940 --- /dev/null +++ b/libcrt/c/include/dirent.h @@ -0,0 +1,3 @@ +/* SPDX-License-Identifier: MIT */ + +#include diff --git a/libcrt/c/include/endian.h b/libcrt/c/include/endian.h new file mode 100644 index 0000000000..bbfe5d4940 --- /dev/null +++ b/libcrt/c/include/endian.h @@ -0,0 +1,3 @@ +/* SPDX-License-Identifier: MIT */ + +#include diff --git a/libcrt/c/include/errno.h b/libcrt/c/include/errno.h new file mode 100644 index 0000000000..bbfe5d4940 --- /dev/null +++ b/libcrt/c/include/errno.h @@ -0,0 +1,3 @@ +/* SPDX-License-Identifier: MIT */ + +#include diff --git a/libcrt/c/include/fcntl.h b/libcrt/c/include/fcntl.h new file mode 100644 index 0000000000..bbfe5d4940 --- /dev/null +++ b/libcrt/c/include/fcntl.h @@ -0,0 +1,3 @@ +/* SPDX-License-Identifier: MIT */ + +#include diff --git a/libcrt/c/include/inttypes.h b/libcrt/c/include/inttypes.h new file mode 100644 index 0000000000..bbfe5d4940 --- /dev/null +++ b/libcrt/c/include/inttypes.h @@ -0,0 +1,3 @@ +/* SPDX-License-Identifier: MIT */ + +#include diff --git a/libcrt/c/include/libcrt.h b/libcrt/c/include/libcrt.h new file mode 100644 index 0000000000..9d7447628f --- /dev/null +++ b/libcrt/c/include/libcrt.h @@ -0,0 +1,408 @@ +/* SPDX-License-Identifier: MIT */ + +#ifndef __LIBCRT_H__ +#define __LIBCRT_H__ + +// The SVSM guids are expected to be the last bytes of the svsm.bin file. When +// we set the external dependencies symbols to be hidden, we prevent them from +// being preempted. Otherwise, the SVSM guids will not be the last bytes of the +// svsm.bin. +#if defined(__pie__) +#pragma GCC visibility push (hidden) +#endif + +// features.h + +#define _Noreturn __attribute__((__noreturn__)) + +#define hidden __attribute__((__visibility__("hidden"))) +#define weak_alias(old, new) \ + extern __typeof(old) new __attribute__((__weak__, __alias__(#old))) + +// All types required + +#define __NEED_va_list + +#define __NEED_int8_t +#define __NEED_int16_t +#define __NEED_int32_t +#define __NEED_int64_t + +#define __NEED_uint8_t +#define __NEED_uint16_t +#define __NEED_uint32_t +#define __NEED_uint64_t + +#define __NEED_intptr_t +#define __NEED_uintptr_t +#define __NEED_size_t +#define __NEED_ssize_t +#define __NEED_ptrdiff_t +#define __NEED_wchar_t + +#define __NEED_intmax_t +#define __NEED_uintmax_t + +#define __NEED_time_t +#define __NEED_clock_t +#define __NEED_clockid_t +#define __NEED_struct_timespec + +#define __NEED_pid_t +#define __NEED_FILE +#define __NEED_struct__IO_FILE + +#define __NEED_dev_t +#define __NEED_ino_t +#define __NEED_mode_t +#define __NEED_nlink_t +#define __NEED_uid_t +#define __NEED_gid_t +#define __NEED_off_t +#define __NEED_blksize_t +#define __NEED_blkcnt_t + +#define __NEED_useconds_t + +#include + +// errno.h + +extern int errno; +#define EINTR 4 +#define ENOMEM 12 +#define EINVAL 22 +#define ENOSYS 38 +#define EAFNOSUPPORT 47 +#define EOVERFLOW 75 + +// stddef.h + +#ifndef NULL +#define NULL ((void *) 0) +#endif + +#define offsetof(type, member) __builtin_offsetof(type, member) + +// stdbool.h + +#define true 1 +#define false 0 +#define bool _Bool + +// stdint.h + +#define INT8_MIN (-1-0x7f) +#define INT16_MIN (-1-0x7fff) +#define INT32_MIN (-1-0x7fffffff) +#define INT64_MIN (-1-0x7fffffffffffffff) + +#define INT8_MAX (0x7f) +#define INT16_MAX (0x7fff) +#define INT32_MAX (0x7fffffff) +#define INT64_MAX (0x7fffffffffffffff) + +#define UINT8_MAX (0xff) +#define UINT16_MAX (0xffff) +#define UINT32_MAX (0xffffffffu) +#define UINT64_MAX (0xffffffffffffffffu) + +// limits.h + +#define UCHAR_MAX 255 +#define SSIZE_MAX 0xFFFFFFFFFFFFFFFFU +#define INT_MIN (-1-0x7fffffff) +#define INT_MAX 0x7fffffff +#define LONG_MIN (-LONG_MAX-1) +#define LONG_MAX __LONG_MAX +#define UINT_MAX 0xffffffffU +#define ULONG_MAX (2UL*LONG_MAX+1) +#define CHAR_BIT 8 + +// atomic.h + +// Check the atomic.h file for the atomic definitions. It is a busy file with +// lots of inline functions and it also includes architecture dependent code. + +// stdarg.h + +#define va_start(v,l) __builtin_va_start(v,l) +#define va_end(v) __builtin_va_end(v) +#define va_arg(v,l) __builtin_va_arg(v,l) +#define va_copy(d,s) __builtin_va_copy(d,s) + +// unistd.h + +#define STDERR_FILENO 2 +#define SEEK_SET 0 +#define SEEK_CUR 1 +#define SEEK_END 2 + +pid_t getpid(void); +uid_t getuid(void); +uid_t geteuid(void); +gid_t getgid(void); +gid_t getegid(void); +int issetugid(void); + +int getentropy(void *buffer, size_t length); +long syscall(long number, ...); +int usleep(useconds_t usec); +unsigned int sleep(unsigned int seconds); + +// stdio.h + +#define EOF (-1) +#define BUFSIZ 8192 +void setbuf(FILE *stream, char *buf); +int printf(const char *restrict fmt, ...); +int dprintf(int fd, const char *__restrict fmt, ...); +int vdprintf(int fd, const char *restrict fmt, va_list ap); +int puts(const char *s); +int fprintf(FILE *restrict f, const char *restrict fmt, ...); +int asprintf(char **s, const char *fmt, ...); +int snprintf(char *restrict s, size_t n, const char *restrict fmt, ...); +int sprintf(char *restrict s, const char *restrict fmt, ...); +int vasprintf(char **s, const char *fmt, va_list ap); +int vsnprintf(char *restrict s, size_t n, const char *restrict fmt, va_list ap); +int vsprintf(char *restrict s, const char *restrict fmt, va_list ap); + +int vprints(const char *format, va_list ap); +int vsnprints(char *str, size_t size, const char *format, va_list ap); + +// Functions exported by the SVSM +extern void serial_out(const char *s, int len); + +// stdlib.h + +// Functions exported by the SVSM +extern void *malloc(size_t size); +extern void *realloc(void *ptr, size_t size); +extern void *calloc(size_t nmemb, size_t size); +extern void free(void *ptr); +extern _Noreturn void abort(void); + +int atoi(const char *s); +int atexit(void (*func)(void)); + +void qsort(void *, size_t, size_t, int (*)(const void *, const void *)); +void qsort_r(void *, size_t, size_t, int (*)(const void *, const void *, void *), void *); +void __qsort_r(void *, size_t, size_t, int (*)(const void *, const void *, void *), void *); + +char *getenv(const char *); + +int rand(void); +void srand(unsigned s); + +// time.h + +#define CLOCK_MONOTONIC 1 + +struct tm { + int tm_sec; /* seconds after the minute [0-60] */ + int tm_min; /* minutes after the hour [0-59] */ + int tm_hour; /* hours since midnight [0-23] */ + int tm_mday; /* day of the month [1-31] */ + int tm_mon; /* months since January [0-11] */ + int tm_year; /* years since 1900 */ + int tm_wday; /* days since Sunday [0-6] */ + int tm_yday; /* days since January 1 [0-365] */ + int tm_isdst; /* Daylight Savings Time flag */ + long tm_gmtoff; /* offset from CUT in seconds */ + char *tm_zone; /* timezone abbreviation */ +}; + +struct timeval { + long tv_sec; /* time value, in seconds */ + long tv_usec; /* time value, in microseconds */ +}; + +char *ctime(const time_t *t); +time_t time(time_t *); +struct tm *gmtime(const time_t *); +struct tm *gmtime_r(const time_t *restrict t, struct tm *restrict tm); +clock_t clock(void); +int clock_gettime(clockid_t clk_id, struct timespec *tp); +int gettimeofday(struct timeval *restrict tv, void *restrict tz); +int __secs_to_tm(long long t, struct tm *tm); +time_t mktime(struct tm *tm); + +extern int timezone; + +#define DECLARE_ARGS(val, low, high) unsigned long low, high +#define EAX_EDX_VAL(val, low, high) ((low) | (high) << 32) +#define EAX_EDX_RET(val, low, high) "=a" (low), "=d" (high) + +static inline unsigned long long rdtsc(void) +{ + DECLARE_ARGS(val, low, high); + asm volatile("rdtsc" : EAX_EDX_RET(val, low, high)); + return EAX_EDX_VAL(val, low, high); +} + +// inttypes.h + +#if UINTPTR_MAX == UINT64_MAX +#define __PRI64 "l" +#define __PRIPTR "l" +#else +#define __PRI64 "ll" +#define __PRIPTR "" +#endif + +#define PRIu8 "u" +#define PRIu16 "u" +#define PRIu32 "u" +#define PRIu64 __PRI64 "u" + +// dirent.h + +typedef struct __dirstream DIR; + +struct dirent { + ino_t d_ino; + off_t d_off; + unsigned short d_reclen; + unsigned char d_type; + char d_name[256]; +}; + +DIR *opendir(const char *name); +int closedir(DIR *name); +struct dirent *readdir(DIR *name); + +typedef unsigned long __jmp_buf[8]; + +typedef struct __jmp_buf_tag { + __jmp_buf __jb; + unsigned long __fl; + unsigned long __ss[128/sizeof(long)]; +} jmp_buf[1]; + +#define __setjmp_attr __attribute__((__returns_twice__)) + +// sys/stat.h + +#define S_IFDIR 0040000 +#define S_IFMT 0170000 + +#define S_ISDIR(mode) (((mode) & S_IFMT) == S_IFDIR) + +/* copied from kernel definition, but with padding replaced + * by the corresponding correctly-sized userspace types. */ +struct stat { + dev_t st_dev; + ino_t st_ino; + nlink_t st_nlink; + + mode_t st_mode; + uid_t st_uid; + gid_t st_gid; + unsigned int __pad0; + dev_t st_rdev; + off_t st_size; + blksize_t st_blksize; + blkcnt_t st_blocks; + + struct timespec st_atim; + struct timespec st_mtim; + struct timespec st_ctim; + long __unused[3]; +}; + +int stat(const char *__restrict path, struct stat *restrict buf); + +// string.h + +void *memset(void *, int, size_t); +int memcmp(const void *, const void *, size_t); +void *memcpy(void *restrict dest, const void *restrict src, size_t n); +void *memchr(const void *src, int c, size_t n); +void *memmove(void *dest, const void *src, size_t n); +void *memrchr(const void *m, int c, size_t n); +void *__memrchr(const void *m, int c, size_t n); + +int strcmp(const char *, const char *); +int strncasecmp(const char *, const char *, size_t); +char *strchr(const char *, int); +char *strrchr(const char *, int); +unsigned long strtoul(const char *, char **, int); +long strtol(const char *, char **, int); +char *strerror(int); +size_t strspn(const char *, const char *); +size_t strcspn(const char *, const char *); + +char *strcpy(char *strDest, const char *strSource); +size_t strlen(const char *s); +char *__strchrnul(const char *s, int c); +char *__stpcpy(char *restrict d, const char *restrict s); +char *__stpncpy(char *restrict d, const char *restrict s, size_t n); +char *strstr(const char *h, const char *n); +char *strdup(const char *s); +char *strncpy(char *restrict d, const char *restrict s, size_t n); +int strncmp(const char *_l, const char *_r, size_t n); +int strcasecmp(const char *_l, const char *_r); +char *strcat(char *restrict dest, const char *restrict src); +char *strncat (char *__restrict, const char *__restrict, size_t); +char *strpbrk(const char *s, const char *accept); + +// ctype.h + +int isdigit(int c); +int isspace(int c); +int isupper(int c); +int isascii(int c); +int islower(int c); + +int tolower(int c); +int toupper(int c); + +// stdio.h + +int printf(const char *, ...); +int sscanf(const char *, const char *, ...); + +FILE *fopen(const char *, const char *); +int fclose(FILE *); +size_t fread(void *, size_t, size_t, FILE *); +size_t fwrite(const void *buffer, size_t size, size_t count, FILE *stream); +int fprintf(FILE *, const char *, ...); +int fputc(int c, FILE *f); +int fseek(FILE *stream, long offset, int whence); +long ftell(FILE *stream); +int fflush(FILE *stream); + +int ferror(FILE *stream); +int clearerr(FILE *stream); + +int vasprintf(char **s, const char *fmt, va_list ap); +int asprintf(char **s, const char *fmt, ...); +int vsnprintf(char *restrict s, size_t n, const char *restrict fmt, va_list ap); +int vsprintf(char *restrict s, const char *restrict fmt, va_list ap); +int snprintf(char *restrict s, size_t n, const char *restrict fmt, ...); +int sprintf(char *restrict s, const char *restrict fmt, ...); +int dprintf(int fd, const char *__restrict fmt, ...); +int vdprintf(int fd, const char *restrict fmt, va_list ap); + +// inet.h + +int inet_pton(int, const char *, void *); + +// setjmp.h + +int setjmp (jmp_buf) __setjmp_attr; +_Noreturn void longjmp (jmp_buf, int); + +// assert.h + +#define assert(x) ((void)((x) || (__assert_fail(#x, __FILE__, __LINE__, __func__),0))) +_Noreturn void __assert_fail (const char *, const char *, int, const char *); + +// select.h +#define FD_SETSIZE 1024 +typedef unsigned long fd_mask; +typedef struct { + unsigned long fds_bits[FD_SETSIZE / 8 / sizeof(long)]; +} fd_set; + +#endif diff --git a/libcrt/c/include/limits.h b/libcrt/c/include/limits.h new file mode 100644 index 0000000000..bbfe5d4940 --- /dev/null +++ b/libcrt/c/include/limits.h @@ -0,0 +1,3 @@ +/* SPDX-License-Identifier: MIT */ + +#include diff --git a/libcrt/c/include/memory.h b/libcrt/c/include/memory.h new file mode 100644 index 0000000000..bbfe5d4940 --- /dev/null +++ b/libcrt/c/include/memory.h @@ -0,0 +1,3 @@ +/* SPDX-License-Identifier: MIT */ + +#include diff --git a/libcrt/c/include/setjmp.h b/libcrt/c/include/setjmp.h new file mode 100644 index 0000000000..bbfe5d4940 --- /dev/null +++ b/libcrt/c/include/setjmp.h @@ -0,0 +1,3 @@ +/* SPDX-License-Identifier: MIT */ + +#include diff --git a/libcrt/c/include/stdarg.h b/libcrt/c/include/stdarg.h new file mode 100644 index 0000000000..bbfe5d4940 --- /dev/null +++ b/libcrt/c/include/stdarg.h @@ -0,0 +1,3 @@ +/* SPDX-License-Identifier: MIT */ + +#include diff --git a/libcrt/c/include/stdatomic.h b/libcrt/c/include/stdatomic.h new file mode 100644 index 0000000000..bbfe5d4940 --- /dev/null +++ b/libcrt/c/include/stdatomic.h @@ -0,0 +1,3 @@ +/* SPDX-License-Identifier: MIT */ + +#include diff --git a/libcrt/c/include/stdbool.h b/libcrt/c/include/stdbool.h new file mode 100644 index 0000000000..bbfe5d4940 --- /dev/null +++ b/libcrt/c/include/stdbool.h @@ -0,0 +1,3 @@ +/* SPDX-License-Identifier: MIT */ + +#include diff --git a/libcrt/c/include/stddef.h b/libcrt/c/include/stddef.h new file mode 100644 index 0000000000..bbfe5d4940 --- /dev/null +++ b/libcrt/c/include/stddef.h @@ -0,0 +1,3 @@ +/* SPDX-License-Identifier: MIT */ + +#include diff --git a/libcrt/c/include/stdint.h b/libcrt/c/include/stdint.h new file mode 100644 index 0000000000..bbfe5d4940 --- /dev/null +++ b/libcrt/c/include/stdint.h @@ -0,0 +1,3 @@ +/* SPDX-License-Identifier: MIT */ + +#include diff --git a/libcrt/c/include/stdio.h b/libcrt/c/include/stdio.h new file mode 100644 index 0000000000..bbfe5d4940 --- /dev/null +++ b/libcrt/c/include/stdio.h @@ -0,0 +1,3 @@ +/* SPDX-License-Identifier: MIT */ + +#include diff --git a/libcrt/c/include/stdlib.h b/libcrt/c/include/stdlib.h new file mode 100644 index 0000000000..bbfe5d4940 --- /dev/null +++ b/libcrt/c/include/stdlib.h @@ -0,0 +1,3 @@ +/* SPDX-License-Identifier: MIT */ + +#include diff --git a/libcrt/c/include/string.h b/libcrt/c/include/string.h new file mode 100644 index 0000000000..bbfe5d4940 --- /dev/null +++ b/libcrt/c/include/string.h @@ -0,0 +1,3 @@ +/* SPDX-License-Identifier: MIT */ + +#include diff --git a/libcrt/c/include/strings.h b/libcrt/c/include/strings.h new file mode 100644 index 0000000000..bbfe5d4940 --- /dev/null +++ b/libcrt/c/include/strings.h @@ -0,0 +1,3 @@ +/* SPDX-License-Identifier: MIT */ + +#include diff --git a/libcrt/c/include/sys/shm.h b/libcrt/c/include/sys/shm.h new file mode 100644 index 0000000000..bbfe5d4940 --- /dev/null +++ b/libcrt/c/include/sys/shm.h @@ -0,0 +1,3 @@ +/* SPDX-License-Identifier: MIT */ + +#include diff --git a/libcrt/c/include/sys/stat.h b/libcrt/c/include/sys/stat.h new file mode 100644 index 0000000000..bbfe5d4940 --- /dev/null +++ b/libcrt/c/include/sys/stat.h @@ -0,0 +1,3 @@ +/* SPDX-License-Identifier: MIT */ + +#include diff --git a/libcrt/c/include/sys/syscall.h b/libcrt/c/include/sys/syscall.h new file mode 100644 index 0000000000..bbfe5d4940 --- /dev/null +++ b/libcrt/c/include/sys/syscall.h @@ -0,0 +1,3 @@ +/* SPDX-License-Identifier: MIT */ + +#include diff --git a/libcrt/c/include/sys/time.h b/libcrt/c/include/sys/time.h new file mode 100644 index 0000000000..bbfe5d4940 --- /dev/null +++ b/libcrt/c/include/sys/time.h @@ -0,0 +1,3 @@ +/* SPDX-License-Identifier: MIT */ + +#include diff --git a/libcrt/c/include/sys/types.h b/libcrt/c/include/sys/types.h new file mode 100644 index 0000000000..bbfe5d4940 --- /dev/null +++ b/libcrt/c/include/sys/types.h @@ -0,0 +1,3 @@ +/* SPDX-License-Identifier: MIT */ + +#include diff --git a/libcrt/c/include/sys/utsname.h b/libcrt/c/include/sys/utsname.h new file mode 100644 index 0000000000..bbfe5d4940 --- /dev/null +++ b/libcrt/c/include/sys/utsname.h @@ -0,0 +1,3 @@ +/* SPDX-License-Identifier: MIT */ + +#include diff --git a/libcrt/c/include/time.h b/libcrt/c/include/time.h new file mode 100644 index 0000000000..bbfe5d4940 --- /dev/null +++ b/libcrt/c/include/time.h @@ -0,0 +1,3 @@ +/* SPDX-License-Identifier: MIT */ + +#include diff --git a/libcrt/c/include/unistd.h b/libcrt/c/include/unistd.h new file mode 100644 index 0000000000..bbfe5d4940 --- /dev/null +++ b/libcrt/c/include/unistd.h @@ -0,0 +1,3 @@ +/* SPDX-License-Identifier: MIT */ + +#include diff --git a/libcrt/c/src/ctype/isascii.c b/libcrt/c/src/ctype/isascii.c new file mode 100644 index 0000000000..14da4dcc23 --- /dev/null +++ b/libcrt/c/src/ctype/isascii.c @@ -0,0 +1,8 @@ +/* SPDX-License-Identifier: MIT */ + +#include + +int isascii(int c) +{ + return !(c&~0x7f); +} diff --git a/libcrt/c/src/ctype/isdigit.c b/libcrt/c/src/ctype/isdigit.c new file mode 100644 index 0000000000..2860cc9d3f --- /dev/null +++ b/libcrt/c/src/ctype/isdigit.c @@ -0,0 +1,6 @@ +#include + +int isdigit(int c) +{ + return (unsigned)c-'0' < 10; +} diff --git a/libcrt/c/src/ctype/islower.c b/libcrt/c/src/ctype/islower.c new file mode 100644 index 0000000000..228823be92 --- /dev/null +++ b/libcrt/c/src/ctype/islower.c @@ -0,0 +1,8 @@ +/* SPDX-License-Identifier: MIT */ + +#include + +int islower(int c) +{ + return (unsigned)c-'a' < 26; +} diff --git a/libcrt/c/src/ctype/isspace.c b/libcrt/c/src/ctype/isspace.c new file mode 100644 index 0000000000..7d2a8ebcfc --- /dev/null +++ b/libcrt/c/src/ctype/isspace.c @@ -0,0 +1,8 @@ +/* SPDX-License-Identifier: MIT */ + +#include + +int isspace(int c) +{ + return c == ' ' || (unsigned)c-'\t' < 5; +} diff --git a/libcrt/c/src/ctype/isupper.c b/libcrt/c/src/ctype/isupper.c new file mode 100644 index 0000000000..6b507ef931 --- /dev/null +++ b/libcrt/c/src/ctype/isupper.c @@ -0,0 +1,8 @@ +/* SPDX-License-Identifier: MIT */ + +#include + +int isupper(int c) +{ + return (unsigned)c-'A' < 26; +} diff --git a/libcrt/c/src/ctype/tolower.c b/libcrt/c/src/ctype/tolower.c new file mode 100644 index 0000000000..fb4b7635b9 --- /dev/null +++ b/libcrt/c/src/ctype/tolower.c @@ -0,0 +1,9 @@ +/* SPDX-License-Identifier: MIT */ + +#include + +int tolower(int c) +{ + if (isupper(c)) return c | 32; + return c; +} diff --git a/libcrt/c/src/ctype/toupper.c b/libcrt/c/src/ctype/toupper.c new file mode 100644 index 0000000000..aa55481963 --- /dev/null +++ b/libcrt/c/src/ctype/toupper.c @@ -0,0 +1,9 @@ +/* SPDX-License-Identifier: MIT */ + +#include + +int toupper(int c) +{ + if (islower(c)) return c & 0x5f; + return c; +} diff --git a/libcrt/c/src/exit/assert.c b/libcrt/c/src/exit/assert.c new file mode 100644 index 0000000000..f243c8e0f9 --- /dev/null +++ b/libcrt/c/src/exit/assert.c @@ -0,0 +1,10 @@ +/* SPDX-License-Identifier: MIT */ + +#include +#include + +void __assert_fail(const char *expr, const char *file, int line, const char *func) +{ + printf("Assertion failed: %s (%s: %s: %d)\n", expr, file, func, line); + abort(); +} diff --git a/libcrt/c/src/prng/rand.c b/libcrt/c/src/prng/rand.c new file mode 100644 index 0000000000..0fc09358b1 --- /dev/null +++ b/libcrt/c/src/prng/rand.c @@ -0,0 +1,151 @@ +/* SPDX-License-Identifier: MIT */ + +#include +#include +#include +#include +#include + +/* + * In the AMD64 Programmer's Manual Volume 3, the RDRAND and RDRAND + * instructions suggests that software should implement a retry limit + * to ensure forward progress of code. + */ +const uint32_t RDSEED_RETRIES = 1024; +const uint32_t RDRAND_RETRIES = 1024; + +static uint64_t seed; + +void srand(unsigned s) +{ + seed = s - 1; +} + +static inline int rdrand32(uint32_t *rnd) +{ + unsigned char ok; + + __asm__ volatile("rdrand %0; setc %1":"=r"(*rnd), "=qm"(ok)); + if (!ok) { + uint32_t retry = 0; + while (retry < RDRAND_RETRIES) { + __asm__ volatile("rdrand %0; setc %1":"=r"(*rnd), "=qm"(ok)); + if (ok) + goto rc_success; + retry++; + } + printf("%s: failed %d times\n", __func__, retry); + return -1; + } + +rc_success: + return 0; +} + +static inline int rdrand64(uint64_t *rnd) +{ + unsigned char ok; + + __asm__ volatile("rdrand %0; setc %1":"=r"(*rnd), "=qm"(ok)); + if (!ok) { + uint32_t retry = 0; + while (retry < RDRAND_RETRIES) { + __asm__ volatile("rdrand %0; setc %1":"=r"(*rnd), "=qm"(ok)); + if (ok) + goto rc_success; + retry++; + } + printf("%s: failed %d times\n", __func__, retry); + return -1; + } + +rc_success: + return 0; +} + +static inline int rdseed32(uint32_t *rnd) +{ + unsigned char ok; + + __asm__ volatile("rdseed %0; setc %1":"=r"(*rnd), "=qm"(ok)); + if (!ok) { + uint32_t retry = 0; + while (retry < RDSEED_RETRIES) { + __asm__ volatile("rdseed %0; setc %1":"=r"(*rnd), "=qm"(ok)); + if (ok) + goto rc_success; + retry++; + } + printf("%s: failed %d times\n", __func__, retry); + return -1; + } + +rc_success: + return 0; +} + +static inline int rdseed64(uint64_t *rnd) +{ + unsigned char ok; + + __asm__ volatile("rdseed %0; setc %1":"=r"(*rnd), "=qm"(ok)); + if (!ok) { + uint32_t retry = 0; + while (retry < RDSEED_RETRIES) { + __asm__ volatile("rdseed %0; setc %1":"=r"(*rnd), "=qm"(ok)); + if (ok) + goto rc_success; + retry++; + } + printf("%s: failed %d times\n", __func__, retry); + return -1; + } + +rc_success: + return 0; +} + +int rand(void) +{ + uint32_t r = 0; + if (rdrand32(&r)) { + if (rdseed32(&r)) { + printf("ERROR: %s: RDRAND and RDSEED failed reaching the retry count\n", __func__); + abort(); + } + } + return r; +} + +int getentropy(void *buffer, size_t length) +{ + char *b; + uint64_t r; + uint64_t *a; + size_t i, bytes_remaining; + + i = 0; + b = buffer; + + while (i < length) { + r = 0; + if (rdseed64(&r)) { + if (rdrand64(&r)) { + printf("ERROR: %s: RDRAND and RDSEED failed reaching the retry count\n", __func__); + return -1; + } + } + + bytes_remaining = length - i; + + if (bytes_remaining < sizeof(uint64_t)) { + memcpy(&b[i], &r, bytes_remaining); + i += bytes_remaining; + } else { + a = (uint64_t *)&b[i]; + *a = r; + i += sizeof(uint64_t); + } + } + return 0; +} diff --git a/libcrt/c/src/setjmp/x86_64/longjmp.s b/libcrt/c/src/setjmp/x86_64/longjmp.s new file mode 100644 index 0000000000..845a4e933c --- /dev/null +++ b/libcrt/c/src/setjmp/x86_64/longjmp.s @@ -0,0 +1,20 @@ +/* SPDX-License-Identifier: MIT */ +/* Copyright 2011-2012 Nicholas J. Kain, licensed under standard MIT license */ + +.global _longjmp +.global longjmp +.type _longjmp,@function +.type longjmp,@function +_longjmp: +longjmp: + xor %eax,%eax + cmp $1,%esi /* CF = val ? 0 : 1 */ + adc %esi,%eax /* eax = val + !val */ + mov (%rdi),%rbx /* rdi is the jmp_buf, restore regs from it */ + mov 8(%rdi),%rbp + mov 16(%rdi),%r12 + mov 24(%rdi),%r13 + mov 32(%rdi),%r14 + mov 40(%rdi),%r15 + mov 48(%rdi),%rsp + jmp *56(%rdi) /* goto saved address without altering rsp */ diff --git a/libcrt/c/src/setjmp/x86_64/setjmp.s b/libcrt/c/src/setjmp/x86_64/setjmp.s new file mode 100644 index 0000000000..64d6e9df4e --- /dev/null +++ b/libcrt/c/src/setjmp/x86_64/setjmp.s @@ -0,0 +1,24 @@ +/* SPDX-License-Identifier: MIT */ +/* Copyright 2011-2012 Nicholas J. Kain, licensed under standard MIT license */ + +.global __setjmp +.global _setjmp +.global setjmp +.type __setjmp,@function +.type _setjmp,@function +.type setjmp,@function +__setjmp: +_setjmp: +setjmp: + mov %rbx,(%rdi) /* rdi is jmp_buf, move registers onto it */ + mov %rbp,8(%rdi) + mov %r12,16(%rdi) + mov %r13,24(%rdi) + mov %r14,32(%rdi) + mov %r15,40(%rdi) + lea 8(%rsp),%rdx /* this is our rsp WITHOUT current ret addr */ + mov %rdx,48(%rdi) + mov (%rsp),%rdx /* save return addr ptr for new rip */ + mov %rdx,56(%rdi) + xor %eax,%eax /* always return 0 */ + ret diff --git a/libcrt/c/src/stdio/asprintf.c b/libcrt/c/src/stdio/asprintf.c new file mode 100644 index 0000000000..71a150d9e2 --- /dev/null +++ b/libcrt/c/src/stdio/asprintf.c @@ -0,0 +1,14 @@ +/* SPDX-License-Identifier: MIT */ + +#include +#include + +int asprintf(char **s, const char *fmt, ...) +{ + int ret; + va_list ap; + va_start(ap, fmt); + ret = vasprintf(s, fmt, ap); + va_end(ap); + return ret; +} diff --git a/libcrt/c/src/stdio/fprintf.c b/libcrt/c/src/stdio/fprintf.c new file mode 100644 index 0000000000..549bcc3f49 --- /dev/null +++ b/libcrt/c/src/stdio/fprintf.c @@ -0,0 +1,14 @@ +/* SPDX-License-Identifier: MIT */ + +#include +#include + +int fprintf(FILE *restrict f, const char *restrict fmt, ...) +{ + int ret; + va_list ap; + va_start(ap, fmt); + ret = vprints(fmt, ap); + va_end(ap); + return ret; +} diff --git a/libcrt/c/src/stdio/printf.c b/libcrt/c/src/stdio/printf.c new file mode 100644 index 0000000000..998148b087 --- /dev/null +++ b/libcrt/c/src/stdio/printf.c @@ -0,0 +1,34 @@ +/* SPDX-License-Identifier: MIT */ + +#include +#include + +int printf(const char *restrict fmt, ...) +{ + int ret; + va_list ap; + va_start(ap, fmt); + ret = vprints(fmt, ap); + va_end(ap); + return ret; +} + +int dprintf(int fd, const char *__restrict fmt, ...) +{ + int ret; + va_list ap; + va_start(ap, fmt); + ret = vprints(fmt, ap); + va_end(ap); + return ret; +} + +int vdprintf(int fd, const char *restrict fmt, va_list ap) +{ + return vprints(fmt, ap); +} + +int puts(const char *s) +{ + return printf("%s\n", s); +} diff --git a/libcrt/c/src/stdio/printf_wrapper.c b/libcrt/c/src/stdio/printf_wrapper.c new file mode 100644 index 0000000000..6e3eab6a4b --- /dev/null +++ b/libcrt/c/src/stdio/printf_wrapper.c @@ -0,0 +1,269 @@ +/* SPDX-License-Identifier: MIT */ + +#include +#include +#include + +enum { + LEN_MOD_INVALID = 0, + LEN_MOD_HALF_HALF, + LEN_MOD_HALF, + LEN_MOD_INT, + LEN_MOD_LONG, + LEN_MOD_LONG_LONG, + LEN_MOD_MAX +}; + +static char *format_string(char *cur, char *end, va_list ap) +{ + char *tmp = va_arg(ap, char *); + + while (*tmp) { + if (cur < end) + *cur = *tmp; + cur++; + tmp++; + } + + return cur; +} + +static char *format_base16(char *cur, char *end, int width, va_list ap) +{ + unsigned long long num; + char *tmp, buffer[32]; + unsigned int size; + char *map; + + map = "0123456789abcdef"; + + if (cur < end) + *cur++ = '0'; + if (cur < end) + *cur++ = 'x'; + + if (width == LEN_MOD_HALF_HALF) { + unsigned char n = (unsigned char) va_arg(ap, int); + num = (unsigned long long)n; + size = 1; + } else if (width == LEN_MOD_HALF) { + unsigned short n = (unsigned short) va_arg(ap, int); + num = (unsigned long long)n; + size = 2; + } else if (width == LEN_MOD_INT) { + unsigned int n = (unsigned int) va_arg(ap, int); + num = (unsigned long long)n; + size = 4; + } else if (width == LEN_MOD_LONG) { + unsigned long n = (unsigned long) va_arg(ap, long); + num = (unsigned long long)n; + size = 8; + } else { + unsigned long long n = (unsigned long long) va_arg(ap, long long); + num = (unsigned long long)n; + size = 8; + } + + tmp = buffer + sizeof(buffer); + + tmp--; + *tmp = '\0'; + while (size--) { + tmp--; + *tmp = map[num & 0xf]; + num >>= 4; + + tmp--; + *tmp = map[num & 0xf]; + num >>= 4; + } + + while (*tmp) { + if (cur < end) + *cur = *tmp; + cur++; + tmp++; + } + + return cur; +} + +static char *format_base10(char *cur, char *end, int width, bool signed_format, va_list ap) +{ + unsigned long long num; + char *tmp, buffer[32]; + + if (width == LEN_MOD_HALF_HALF) { + unsigned char n = (unsigned char) va_arg(ap, int); + if (signed_format && (char)n < 0) { + if (cur < end) + *cur++ = '-'; + n = -(char)n; + } + num = (unsigned long long)n; + } else if (width == LEN_MOD_HALF) { + unsigned short n = (unsigned short) va_arg(ap, int); + if (signed_format && (short)n < 0) { + if (cur < end) + *cur++ = '-'; + n = -(short)n; + } + num = (unsigned long long)n; + } else if (width == LEN_MOD_INT) { + unsigned int n = (unsigned int) va_arg(ap, int); + if (signed_format && (int)n < 0) { + if (cur < end) + *cur++ = '-'; + n = -(int)n; + } + num = (unsigned long long)n; + } else if (width == LEN_MOD_LONG) { + unsigned long n = (unsigned long) va_arg(ap, long); + if (signed_format && (long)n < 0) { + if (cur < end) + *cur++ = '-'; + n = -(long)n; + } + num = (unsigned long long)n; + } else { + unsigned long long n = (unsigned long long) va_arg(ap, long long); + if (signed_format && (long long)n < 0) { + if (cur < end) + *cur++ = '-'; + n = -(long long)n; + } + num = (unsigned long long)n; + } + + tmp = buffer + sizeof(buffer); + + tmp--; + *tmp = '\0'; + do { + tmp--; + *tmp = (char)('0' + num % 10); + + num /= 10; + } while (num); + + while (*tmp) { + if (cur < end) + *cur = *tmp; + + cur++; + tmp++; + } + + return cur; +} + +int vsnprints(char *str, size_t size, const char *format, va_list ap) +{ + unsigned int width = LEN_MOD_INVALID; + char *cur, *end; + bool convert; + + cur = str; + end = cur + size; + if (end < cur) { + end = (void *)-1; + size = end - cur; + } + + convert = false; + while (*format) { + if (!convert) { + if (*format != '%') { + if (cur < end) + *cur = *format; + + cur++; + format++; + continue; + } + + format++; + if (*format == '%') { + if (cur < end) + *cur = '%'; + + cur++; + format++; + continue; + } + + convert = true; + width = LEN_MOD_INT; + } else { + bool signed_format = false; + + switch (*format) { + case 'h': + width--; + if (width == LEN_MOD_INVALID) + convert = false; + break; + case 'l': + width++; + if (width == LEN_MOD_MAX) + convert = false; + break; + case 'd': + signed_format = true; + case 'z': + // handle %zu + if (*(format+1) && *(format+1) == 'u' ) + format++; + case 'u': + cur = format_base10(cur, end, width, signed_format, ap); + convert = false; + break; + case 'p': + width = LEN_MOD_LONG; + case 'x': + cur = format_base16(cur, end, width, ap); + convert = false; + break; + case 's': { + cur = format_string(cur, end, ap); + convert = false; + break; + } + default: + convert = false; + } + + format++; + } + } + + if (size) { + if (cur < end) + *cur = '\0'; + else + *(end - 1) = '\0'; + } + + return cur - str; +} + +// A format string is converted to the actual string, which is then +// truncated to PRINT_STR_MAX before printing. +#define PRINT_STR_MAX 256 + +int vprints(const char *format, va_list ap) +{ + char buffer[PRINT_STR_MAX]; + int ret; + + ret = vsnprints(buffer, sizeof(buffer), format, ap); + + if (ret >= sizeof(buffer)) { + ret = PRINT_STR_MAX; + buffer[PRINT_STR_MAX - 1] = '\0'; + } + + serial_out(buffer, ret); + + return ret; +} diff --git a/libcrt/c/src/stdio/snprintf.c b/libcrt/c/src/stdio/snprintf.c new file mode 100644 index 0000000000..8a3f51aa69 --- /dev/null +++ b/libcrt/c/src/stdio/snprintf.c @@ -0,0 +1,15 @@ +/* SPDX-License-Identifier: MIT */ + +#include +#include + +int snprintf(char *restrict s, size_t n, const char *restrict fmt, ...) +{ + int ret; + va_list ap; + va_start(ap, fmt); + ret = vsnprintf(s, n, fmt, ap); + va_end(ap); + return ret; +} + diff --git a/libcrt/c/src/stdio/sprintf.c b/libcrt/c/src/stdio/sprintf.c new file mode 100644 index 0000000000..8960560ac1 --- /dev/null +++ b/libcrt/c/src/stdio/sprintf.c @@ -0,0 +1,14 @@ +/* SPDX-License-Identifier: MIT */ + +#include +#include + +int sprintf(char *restrict s, const char *restrict fmt, ...) +{ + int ret; + va_list ap; + va_start(ap, fmt); + ret = vsprintf(s, fmt, ap); + va_end(ap); + return ret; +} diff --git a/libcrt/c/src/stdio/vasprintf.c b/libcrt/c/src/stdio/vasprintf.c new file mode 100644 index 0000000000..a0c43a30c9 --- /dev/null +++ b/libcrt/c/src/stdio/vasprintf.c @@ -0,0 +1,16 @@ +/* SPDX-License-Identifier: MIT */ + +#include +#include +#include + +int vasprintf(char **s, const char *fmt, va_list ap) +{ + va_list ap2; + va_copy(ap2, ap); + int l = vsnprintf(0, 0, fmt, ap2); + va_end(ap2); + + if (l<0 || !(*s=malloc(l+1U))) return -1; + return vsnprintf(*s, l+1U, fmt, ap); +} diff --git a/libcrt/c/src/stdio/vsnprintf.c b/libcrt/c/src/stdio/vsnprintf.c new file mode 100644 index 0000000000..3b572f7f79 --- /dev/null +++ b/libcrt/c/src/stdio/vsnprintf.c @@ -0,0 +1,9 @@ +/* SPDX-License-Identifier: MIT */ + +#include +#include + +int vsnprintf(char *restrict s, size_t n, const char *restrict fmt, va_list ap) +{ + return vsnprints(s, n, fmt, ap); +} diff --git a/libcrt/c/src/stdio/vsprintf.c b/libcrt/c/src/stdio/vsprintf.c new file mode 100644 index 0000000000..f0691a32e2 --- /dev/null +++ b/libcrt/c/src/stdio/vsprintf.c @@ -0,0 +1,9 @@ +/* SPDX-License-Identifier: MIT */ + +#include +#include + +int vsprintf(char *restrict s, const char *restrict fmt, va_list ap) +{ + return vsnprintf(s, INT_MAX, fmt, ap); +} diff --git a/libcrt/c/src/stdlib/atoi.c b/libcrt/c/src/stdlib/atoi.c new file mode 100644 index 0000000000..02bed169db --- /dev/null +++ b/libcrt/c/src/stdlib/atoi.c @@ -0,0 +1,18 @@ +/* SPDX-License-Identifier: MIT */ + +#include +#include + +int atoi(const char *s) +{ + int n=0, neg=0; + while (isspace(*s)) s++; + switch (*s) { + case '-': neg=1; + case '+': s++; + } + /* Compute n as a negative number to avoid overflow on INT_MIN */ + while (isdigit(*s)) + n = 10*n - (*s++ - '0'); + return neg ? n : -n; +} diff --git a/libcrt/c/src/stdlib/qsort.c b/libcrt/c/src/stdlib/qsort.c new file mode 100644 index 0000000000..fa4ca0a3f3 --- /dev/null +++ b/libcrt/c/src/stdlib/qsort.c @@ -0,0 +1,222 @@ +/* Copyright (C) 2011 by Valentin Ochs + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +/* Minor changes by Rich Felker for integration in musl, 2011-04-27. */ + +/* Smoothsort, an adaptive variant of Heapsort. Memory usage: O(1). + Run time: Worst case O(n log n), close to O(n) in the mostly-sorted case. */ + +#define _BSD_SOURCE +#include +#include +#include + +#include "atomic.h" +#define ntz(x) a_ctz_l((x)) + +typedef int (*cmpfun)(const void *, const void *, void *); + +static inline int pntz(size_t p[2]) { + int r = ntz(p[0] - 1); + if(r != 0 || (r = 8*sizeof(size_t) + ntz(p[1])) != 8*sizeof(size_t)) { + return r; + } + return 0; +} + +static void cycle(size_t width, unsigned char* ar[], int n) +{ + unsigned char tmp[256]; + size_t l; + int i; + + if(n < 2) { + return; + } + + ar[n] = tmp; + while(width) { + l = sizeof(tmp) < width ? sizeof(tmp) : width; + memcpy(ar[n], ar[0], l); + for(i = 0; i < n; i++) { + memcpy(ar[i], ar[i + 1], l); + ar[i] += l; + } + width -= l; + } + ar[n] = NULL; +} + +/* shl() and shr() need n > 0 */ +static inline void shl(size_t p[2], int n) +{ + if(n >= 8 * sizeof(size_t)) { + n -= 8 * sizeof(size_t); + p[1] = p[0]; + p[0] = 0; + } + p[1] <<= n; + p[1] |= p[0] >> (sizeof(size_t) * 8 - n); + p[0] <<= n; +} + +static inline void shr(size_t p[2], int n) +{ + if(n >= 8 * sizeof(size_t)) { + n -= 8 * sizeof(size_t); + p[0] = p[1]; + p[1] = 0; + } + p[0] >>= n; + p[0] |= p[1] << (sizeof(size_t) * 8 - n); + p[1] >>= n; +} + +static void sift(unsigned char *head, size_t width, cmpfun cmp, void *arg, int pshift, size_t lp[]) +{ + unsigned char *rt, *lf; + unsigned char *ar[14 * sizeof(size_t) + 1]; + int i = 1; + + ar[0] = head; + while(pshift > 1) { + rt = head - width; + lf = head - width - lp[pshift - 2]; + + if(cmp(ar[0], lf, arg) >= 0 && cmp(ar[0], rt, arg) >= 0) { + break; + } + if(cmp(lf, rt, arg) >= 0) { + ar[i++] = lf; + head = lf; + pshift -= 1; + } else { + ar[i++] = rt; + head = rt; + pshift -= 2; + } + } + cycle(width, ar, i); +} + +static void trinkle(unsigned char *head, size_t width, cmpfun cmp, void *arg, size_t pp[2], int pshift, int trusty, size_t lp[]) +{ + unsigned char *stepson, + *rt, *lf; + size_t p[2]; + unsigned char *ar[14 * sizeof(size_t) + 1]; + int i = 1; + int trail; + + p[0] = pp[0]; + p[1] = pp[1]; + + ar[0] = head; + while(p[0] != 1 || p[1] != 0) { + stepson = head - lp[pshift]; + if(cmp(stepson, ar[0], arg) <= 0) { + break; + } + if(!trusty && pshift > 1) { + rt = head - width; + lf = head - width - lp[pshift - 2]; + if(cmp(rt, stepson, arg) >= 0 || cmp(lf, stepson, arg) >= 0) { + break; + } + } + + ar[i++] = stepson; + head = stepson; + trail = pntz(p); + shr(p, trail); + pshift += trail; + trusty = 0; + } + if(!trusty) { + cycle(width, ar, i); + sift(head, width, cmp, arg, pshift, lp); + } +} + +void __qsort_r(void *base, size_t nel, size_t width, cmpfun cmp, void *arg) +{ + size_t lp[12*sizeof(size_t)]; + size_t i, size = width * nel; + unsigned char *head, *high; + size_t p[2] = {1, 0}; + int pshift = 1; + int trail; + + if (!size) return; + + head = base; + high = head + size - width; + + /* Precompute Leonardo numbers, scaled by element width */ + for(lp[0]=lp[1]=width, i=2; (lp[i]=lp[i-2]+lp[i-1]+width) < size; i++); + + while(head < high) { + if((p[0] & 3) == 3) { + sift(head, width, cmp, arg, pshift, lp); + shr(p, 2); + pshift += 2; + } else { + if(lp[pshift - 1] >= high - head) { + trinkle(head, width, cmp, arg, p, pshift, 0, lp); + } else { + sift(head, width, cmp, arg, pshift, lp); + } + + if(pshift == 1) { + shl(p, 1); + pshift = 0; + } else { + shl(p, pshift - 1); + pshift = 1; + } + } + + p[0] |= 1; + head += width; + } + + trinkle(head, width, cmp, arg, p, pshift, 0, lp); + + while(pshift != 1 || p[0] != 1 || p[1] != 0) { + if(pshift <= 1) { + trail = pntz(p); + shr(p, trail); + pshift += trail; + } else { + shl(p, 2); + pshift -= 2; + p[0] ^= 7; + shr(p, 1); + trinkle(head - lp[pshift] - width, width, cmp, arg, p, pshift + 1, 1, lp); + shl(p, 1); + p[0] |= 1; + trinkle(head - width, width, cmp, arg, p, pshift, 1, lp); + } + head -= width; + } +} + +weak_alias(__qsort_r, qsort_r); diff --git a/libcrt/c/src/stdlib/qsort_nr.c b/libcrt/c/src/stdlib/qsort_nr.c new file mode 100644 index 0000000000..46132065c1 --- /dev/null +++ b/libcrt/c/src/stdlib/qsort_nr.c @@ -0,0 +1,16 @@ +/* SPDX-License-Identifier: MIT */ + +#define _BSD_SOURCE +#include + +typedef int (*cmpfun)(const void *, const void *); + +static int wrapper_cmp(const void *v1, const void *v2, void *cmp) +{ + return ((cmpfun)cmp)(v1, v2); +} + +void qsort(void *base, size_t nel, size_t width, cmpfun cmp) +{ + __qsort_r(base, nel, width, wrapper_cmp, (void *)cmp); +} diff --git a/libcrt/c/src/string/memchr.c b/libcrt/c/src/string/memchr.c new file mode 100644 index 0000000000..046529f009 --- /dev/null +++ b/libcrt/c/src/string/memchr.c @@ -0,0 +1,29 @@ +/* SPDX-License-Identifier: MIT */ + +#include +#include +#include + +#define SS (sizeof(size_t)) +#define ALIGN (sizeof(size_t)-1) +#define ONES ((size_t)-1/UCHAR_MAX) +#define HIGHS (ONES * (UCHAR_MAX/2+1)) +#define HASZERO(x) (((x)-ONES) & ~(x) & HIGHS) + +void *memchr(const void *src, int c, size_t n) +{ + const unsigned char *s = src; + c = (unsigned char)c; +#ifdef __GNUC__ + for (; ((uintptr_t)s & ALIGN) && n && *s != c; s++, n--); + if (n && *s != c) { + typedef size_t __attribute__((__may_alias__)) word; + const word *w; + size_t k = ONES * c; + for (w = (const void *)s; n>=SS && !HASZERO(*w^k); w++, n-=SS); + s = (const void *)w; + } +#endif + for (; n && *s != c; s++, n--); + return n ? (void *)s : 0; +} diff --git a/libcrt/c/src/string/memcmp.c b/libcrt/c/src/string/memcmp.c new file mode 100644 index 0000000000..502ca098c0 --- /dev/null +++ b/libcrt/c/src/string/memcmp.c @@ -0,0 +1,10 @@ +/* SPDX-License-Identifier: MIT */ + +#include + +int memcmp(const void *vl, const void *vr, size_t n) +{ + const unsigned char *l=vl, *r=vr; + for (; n && *l == *r; n--, l++, r++); + return n ? *l-*r : 0; +} diff --git a/libcrt/c/src/string/memcpy.c b/libcrt/c/src/string/memcpy.c new file mode 100644 index 0000000000..cb7127ca08 --- /dev/null +++ b/libcrt/c/src/string/memcpy.c @@ -0,0 +1,126 @@ +/* SPDX-License-Identifier: MIT */ + +#include +#include +#include + +void *memcpy(void *restrict dest, const void *restrict src, size_t n) +{ + unsigned char *d = dest; + const unsigned char *s = src; + +#ifdef __GNUC__ + +#if __BYTE_ORDER == __LITTLE_ENDIAN +#define LS >> +#define RS << +#else +#define LS << +#define RS >> +#endif + + typedef uint32_t __attribute__((__may_alias__)) u32; + uint32_t w, x; + + for (; (uintptr_t)s % 4 && n; n--) *d++ = *s++; + + if ((uintptr_t)d % 4 == 0) { + for (; n>=16; s+=16, d+=16, n-=16) { + *(u32 *)(d+0) = *(u32 *)(s+0); + *(u32 *)(d+4) = *(u32 *)(s+4); + *(u32 *)(d+8) = *(u32 *)(s+8); + *(u32 *)(d+12) = *(u32 *)(s+12); + } + if (n&8) { + *(u32 *)(d+0) = *(u32 *)(s+0); + *(u32 *)(d+4) = *(u32 *)(s+4); + d += 8; s += 8; + } + if (n&4) { + *(u32 *)(d+0) = *(u32 *)(s+0); + d += 4; s += 4; + } + if (n&2) { + *d++ = *s++; *d++ = *s++; + } + if (n&1) { + *d = *s; + } + return dest; + } + + if (n >= 32) switch ((uintptr_t)d % 4) { + case 1: + w = *(u32 *)s; + *d++ = *s++; + *d++ = *s++; + *d++ = *s++; + n -= 3; + for (; n>=17; s+=16, d+=16, n-=16) { + x = *(u32 *)(s+1); + *(u32 *)(d+0) = (w LS 24) | (x RS 8); + w = *(u32 *)(s+5); + *(u32 *)(d+4) = (x LS 24) | (w RS 8); + x = *(u32 *)(s+9); + *(u32 *)(d+8) = (w LS 24) | (x RS 8); + w = *(u32 *)(s+13); + *(u32 *)(d+12) = (x LS 24) | (w RS 8); + } + break; + case 2: + w = *(u32 *)s; + *d++ = *s++; + *d++ = *s++; + n -= 2; + for (; n>=18; s+=16, d+=16, n-=16) { + x = *(u32 *)(s+2); + *(u32 *)(d+0) = (w LS 16) | (x RS 16); + w = *(u32 *)(s+6); + *(u32 *)(d+4) = (x LS 16) | (w RS 16); + x = *(u32 *)(s+10); + *(u32 *)(d+8) = (w LS 16) | (x RS 16); + w = *(u32 *)(s+14); + *(u32 *)(d+12) = (x LS 16) | (w RS 16); + } + break; + case 3: + w = *(u32 *)s; + *d++ = *s++; + n -= 1; + for (; n>=19; s+=16, d+=16, n-=16) { + x = *(u32 *)(s+3); + *(u32 *)(d+0) = (w LS 8) | (x RS 24); + w = *(u32 *)(s+7); + *(u32 *)(d+4) = (x LS 8) | (w RS 24); + x = *(u32 *)(s+11); + *(u32 *)(d+8) = (w LS 8) | (x RS 24); + w = *(u32 *)(s+15); + *(u32 *)(d+12) = (x LS 8) | (w RS 24); + } + break; + } + if (n&16) { + *d++ = *s++; *d++ = *s++; *d++ = *s++; *d++ = *s++; + *d++ = *s++; *d++ = *s++; *d++ = *s++; *d++ = *s++; + *d++ = *s++; *d++ = *s++; *d++ = *s++; *d++ = *s++; + *d++ = *s++; *d++ = *s++; *d++ = *s++; *d++ = *s++; + } + if (n&8) { + *d++ = *s++; *d++ = *s++; *d++ = *s++; *d++ = *s++; + *d++ = *s++; *d++ = *s++; *d++ = *s++; *d++ = *s++; + } + if (n&4) { + *d++ = *s++; *d++ = *s++; *d++ = *s++; *d++ = *s++; + } + if (n&2) { + *d++ = *s++; *d++ = *s++; + } + if (n&1) { + *d = *s; + } + return dest; +#endif + + for (; n; n--) *d++ = *s++; + return dest; +} diff --git a/libcrt/c/src/string/memmove.c b/libcrt/c/src/string/memmove.c new file mode 100644 index 0000000000..ab2778bcad --- /dev/null +++ b/libcrt/c/src/string/memmove.c @@ -0,0 +1,44 @@ +/* SPDX-License-Identifier: MIT */ + +#include +#include + +#ifdef __GNUC__ +typedef __attribute__((__may_alias__)) size_t WT; +#define WS (sizeof(WT)) +#endif + +void *memmove(void *dest, const void *src, size_t n) +{ + char *d = dest; + const char *s = src; + + if (d==s) return d; + if ((uintptr_t)s-(uintptr_t)d-n <= -2*n) return memcpy(d, s, n); + + if (d=WS; n-=WS, d+=WS, s+=WS) *(WT *)d = *(WT *)s; + } +#endif + for (; n; n--) *d++ = *s++; + } else { +#ifdef __GNUC__ + if ((uintptr_t)s % WS == (uintptr_t)d % WS) { + while ((uintptr_t)(d+n) % WS) { + if (!n--) return dest; + d[n] = s[n]; + } + while (n>=WS) n-=WS, *(WT *)(d+n) = *(WT *)(s+n); + } +#endif + while (n) n--, d[n] = s[n]; + } + + return dest; +} diff --git a/libcrt/c/src/string/memrchr.c b/libcrt/c/src/string/memrchr.c new file mode 100644 index 0000000000..61eb745cf6 --- /dev/null +++ b/libcrt/c/src/string/memrchr.c @@ -0,0 +1,13 @@ +/* SPDX-License-Identifier: MIT */ + +#include + +void *__memrchr(const void *m, int c, size_t n) +{ + const unsigned char *s = m; + c = (unsigned char)c; + while (n--) if (s[n]==c) return (void *)(s+n); + return 0; +} + +weak_alias(__memrchr, memrchr); diff --git a/libcrt/c/src/string/memset.c b/libcrt/c/src/string/memset.c new file mode 100644 index 0000000000..36a07447e9 --- /dev/null +++ b/libcrt/c/src/string/memset.c @@ -0,0 +1,92 @@ +/* SPDX-License-Identifier: MIT */ + +#include +#include + +void *memset(void *dest, int c, size_t n) +{ + unsigned char *s = dest; + size_t k; + + /* Fill head and tail with minimal branching. Each + * conditional ensures that all the subsequently used + * offsets are well-defined and in the dest region. */ + + if (!n) return dest; + s[0] = c; + s[n-1] = c; + if (n <= 2) return dest; + s[1] = c; + s[2] = c; + s[n-2] = c; + s[n-3] = c; + if (n <= 6) return dest; + s[3] = c; + s[n-4] = c; + if (n <= 8) return dest; + + /* Advance pointer to align it at a 4-byte boundary, + * and truncate n to a multiple of 4. The previous code + * already took care of any head/tail that get cut off + * by the alignment. */ + + k = -(uintptr_t)s & 3; + s += k; + n -= k; + n &= -4; + +#ifdef __GNUC__ + typedef uint32_t __attribute__((__may_alias__)) u32; + typedef uint64_t __attribute__((__may_alias__)) u64; + + u32 c32 = ((u32)-1)/255 * (unsigned char)c; + + /* In preparation to copy 32 bytes at a time, aligned on + * an 8-byte bounary, fill head/tail up to 28 bytes each. + * As in the initial byte-based head/tail fill, each + * conditional below ensures that the subsequent offsets + * are valid (e.g. !(n<=24) implies n>=28). */ + + *(u32 *)(s+0) = c32; + *(u32 *)(s+n-4) = c32; + if (n <= 8) return dest; + *(u32 *)(s+4) = c32; + *(u32 *)(s+8) = c32; + *(u32 *)(s+n-12) = c32; + *(u32 *)(s+n-8) = c32; + if (n <= 24) return dest; + *(u32 *)(s+12) = c32; + *(u32 *)(s+16) = c32; + *(u32 *)(s+20) = c32; + *(u32 *)(s+24) = c32; + *(u32 *)(s+n-28) = c32; + *(u32 *)(s+n-24) = c32; + *(u32 *)(s+n-20) = c32; + *(u32 *)(s+n-16) = c32; + + /* Align to a multiple of 8 so we can fill 64 bits at a time, + * and avoid writing the same bytes twice as much as is + * practical without introducing additional branching. */ + + k = 24 + ((uintptr_t)s & 4); + s += k; + n -= k; + + /* If this loop is reached, 28 tail bytes have already been + * filled, so any remainder when n drops below 32 can be + * safely ignored. */ + + u64 c64 = c32 | ((u64)c32 << 32); + for (; n >= 32; n-=32, s+=32) { + *(u64 *)(s+0) = c64; + *(u64 *)(s+8) = c64; + *(u64 *)(s+16) = c64; + *(u64 *)(s+24) = c64; + } +#else + /* Pure C fallback with no aliasing violations. */ + for (; n; n--, s++) *s = c; +#endif + + return dest; +} diff --git a/libcrt/c/src/string/stpcpy.c b/libcrt/c/src/string/stpcpy.c new file mode 100644 index 0000000000..ca0191934f --- /dev/null +++ b/libcrt/c/src/string/stpcpy.c @@ -0,0 +1,31 @@ +/* SPDX-License-Identifier: MIT */ + +#include +#include +#include + +#define ALIGN (sizeof(size_t)) +#define ONES ((size_t)-1/UCHAR_MAX) +#define HIGHS (ONES * (UCHAR_MAX/2+1)) +#define HASZERO(x) (((x)-ONES) & ~(x) & HIGHS) + +char *__stpcpy(char *restrict d, const char *restrict s) +{ +#ifdef __GNUC__ + typedef size_t __attribute__((__may_alias__)) word; + word *wd; + const word *ws; + if ((uintptr_t)s % ALIGN == (uintptr_t)d % ALIGN) { + for (; (uintptr_t)s % ALIGN; s++, d++) + if (!(*d=*s)) return d; + wd=(void *)d; ws=(const void *)s; + for (; !HASZERO(*ws); *wd++ = *ws++); + d=(void *)wd; s=(const void *)ws; + } +#endif + for (; (*d=*s); s++, d++); + + return d; +} + +weak_alias(__stpcpy, stpcpy); diff --git a/libcrt/c/src/string/stpncpy.c b/libcrt/c/src/string/stpncpy.c new file mode 100644 index 0000000000..3ef51f84ea --- /dev/null +++ b/libcrt/c/src/string/stpncpy.c @@ -0,0 +1,34 @@ +/* SPDX-License-Identifier: MIT */ + +#include +#include +#include + +#define ALIGN (sizeof(size_t)-1) +#define ONES ((size_t)-1/UCHAR_MAX) +#define HIGHS (ONES * (UCHAR_MAX/2+1)) +#define HASZERO(x) (((x)-ONES) & ~(x) & HIGHS) + +char *__stpncpy(char *restrict d, const char *restrict s, size_t n) +{ +#ifdef __GNUC__ + typedef size_t __attribute__((__may_alias__)) word; + word *wd; + const word *ws; + if (((uintptr_t)s & ALIGN) == ((uintptr_t)d & ALIGN)) { + for (; ((uintptr_t)s & ALIGN) && n && (*d=*s); n--, s++, d++); + if (!n || !*s) goto tail; + wd=(void *)d; ws=(const void *)s; + for (; n>=sizeof(size_t) && !HASZERO(*ws); + n-=sizeof(size_t), ws++, wd++) *wd = *ws; + d=(void *)wd; s=(const void *)ws; + } +#endif + for (; n && (*d=*s); n--, s++, d++); +tail: + memset(d, 0, n); + return d; +} + +weak_alias(__stpncpy, stpncpy); + diff --git a/libcrt/c/src/string/strcasecmp.c b/libcrt/c/src/string/strcasecmp.c new file mode 100644 index 0000000000..5c69f1e2f6 --- /dev/null +++ b/libcrt/c/src/string/strcasecmp.c @@ -0,0 +1,20 @@ +/* SPDX-License-Identifier: MIT */ + +#include +#include + +int strcasecmp(const char *_l, const char *_r) +{ + const unsigned char *l=(void *)_l, *r=(void *)_r; + for (; *l && *r && (*l == *r || tolower(*l) == tolower(*r)); l++, r++); + return tolower(*l) - tolower(*r); +} + +#if 0 +int __strcasecmp_l(const char *l, const char *r, locale_t loc) +{ + return strcasecmp(l, r); +} + +weak_alias(__strcasecmp_l, strcasecmp_l); +#endif diff --git a/libcrt/c/src/string/strcat.c b/libcrt/c/src/string/strcat.c new file mode 100644 index 0000000000..aa27b390b9 --- /dev/null +++ b/libcrt/c/src/string/strcat.c @@ -0,0 +1,9 @@ +/* SPDX-License-Identifier: MIT */ + +#include + +char *strcat(char *restrict dest, const char *restrict src) +{ + strcpy(dest + strlen(dest), src); + return dest; +} diff --git a/libcrt/c/src/string/strchr.c b/libcrt/c/src/string/strchr.c new file mode 100644 index 0000000000..27ff430f3b --- /dev/null +++ b/libcrt/c/src/string/strchr.c @@ -0,0 +1,9 @@ +/* SPDX-License-Identifier: MIT */ + +#include + +char *strchr(const char *s, int c) +{ + char *r = __strchrnul(s, c); + return *(unsigned char *)r == (unsigned char)c ? r : 0; +} diff --git a/libcrt/c/src/string/strchrnul.c b/libcrt/c/src/string/strchrnul.c new file mode 100644 index 0000000000..7d9fa43201 --- /dev/null +++ b/libcrt/c/src/string/strchrnul.c @@ -0,0 +1,30 @@ +/* SPDX-License-Identifier: MIT */ + +#include +#include +#include + +#define ALIGN (sizeof(size_t)) +#define ONES ((size_t)-1/UCHAR_MAX) +#define HIGHS (ONES * (UCHAR_MAX/2+1)) +#define HASZERO(x) (((x)-ONES) & ~(x) & HIGHS) + +char *__strchrnul(const char *s, int c) +{ + c = (unsigned char)c; + if (!c) return (char *)s + strlen(s); + +#ifdef __GNUC__ + typedef size_t __attribute__((__may_alias__)) word; + const word *w; + for (; (uintptr_t)s % ALIGN; s++) + if (!*s || *(unsigned char *)s == c) return (char *)s; + size_t k = ONES * c; + for (w = (void *)s; !HASZERO(*w) && !HASZERO(*w^k); w++); + s = (void *)w; +#endif + for (; *s && *(unsigned char *)s != c; s++); + return (char *)s; +} + +weak_alias(__strchrnul, strchrnul); diff --git a/libcrt/c/src/string/strcmp.c b/libcrt/c/src/string/strcmp.c new file mode 100644 index 0000000000..617315139e --- /dev/null +++ b/libcrt/c/src/string/strcmp.c @@ -0,0 +1,9 @@ +/* SPDX-License-Identifier: MIT */ + +#include + +int strcmp(const char *l, const char *r) +{ + for (; *l==*r && *l; l++, r++); + return *(unsigned char *)l - *(unsigned char *)r; +} diff --git a/libcrt/c/src/string/strcpy.c b/libcrt/c/src/string/strcpy.c new file mode 100644 index 0000000000..8a247c6585 --- /dev/null +++ b/libcrt/c/src/string/strcpy.c @@ -0,0 +1,9 @@ +/* SPDX-License-Identifier: MIT */ + +#include + +char *strcpy(char *restrict dest, const char *restrict src) +{ + __stpcpy(dest, src); + return dest; +} diff --git a/libcrt/c/src/string/strcspn.c b/libcrt/c/src/string/strcspn.c new file mode 100644 index 0000000000..e9294f6a72 --- /dev/null +++ b/libcrt/c/src/string/strcspn.c @@ -0,0 +1,19 @@ +/* SPDX-License-Identifier: MIT */ + +#include + +#define BITOP(a,b,op) \ + ((a)[(size_t)(b)/(8*sizeof *(a))] op (size_t)1<<((size_t)(b)%(8*sizeof *(a)))) + +size_t strcspn(const char *s, const char *c) +{ + const char *a = s; + size_t byteset[32/sizeof(size_t)]; + + if (!c[0] || !c[1]) return __strchrnul(s, *c)-a; + + memset(byteset, 0, sizeof byteset); + for (; *c && BITOP(byteset, *(unsigned char *)c, |=); c++); + for (; *s && !BITOP(byteset, *(unsigned char *)s, &); s++); + return s-a; +} diff --git a/libcrt/c/src/string/strdup.c b/libcrt/c/src/string/strdup.c new file mode 100644 index 0000000000..09c603e033 --- /dev/null +++ b/libcrt/c/src/string/strdup.c @@ -0,0 +1,13 @@ +/* SPDX-License-Identifier: MIT */ + +#include +#include +#include + +char *strdup(const char *s) +{ + size_t l = strlen(s); + char *d = malloc(l+1); + if (!d) return NULL; + return memcpy(d, s, l+1); +} diff --git a/libcrt/c/src/string/strlen.c b/libcrt/c/src/string/strlen.c new file mode 100644 index 0000000000..f1500c25aa --- /dev/null +++ b/libcrt/c/src/string/strlen.c @@ -0,0 +1,24 @@ +/* SPDX-License-Identifier: MIT */ + +#include +#include +#include + +#define ALIGN (sizeof(size_t)) +#define ONES ((size_t)-1/UCHAR_MAX) +#define HIGHS (ONES * (UCHAR_MAX/2+1)) +#define HASZERO(x) (((x)-ONES) & ~(x) & HIGHS) + +size_t strlen(const char *s) +{ + const char *a = s; +#ifdef __GNUC__ + typedef size_t __attribute__((__may_alias__)) word; + const word *w; + for (; (uintptr_t)s % ALIGN; s++) if (!*s) return s-a; + for (w = (const void *)s; !HASZERO(*w); w++); + s = (const void *)w; +#endif + for (; *s; s++); + return s-a; +} diff --git a/libcrt/c/src/string/strncasecmp.c b/libcrt/c/src/string/strncasecmp.c new file mode 100644 index 0000000000..8e990d11e1 --- /dev/null +++ b/libcrt/c/src/string/strncasecmp.c @@ -0,0 +1,12 @@ +/* SPDX-License-Identifier: MIT */ + +#include +#include + +int strncasecmp(const char *_l, const char *_r, size_t n) +{ + const unsigned char *l=(void *)_l, *r=(void *)_r; + if (!n--) return 0; + for (; *l && *r && n && (*l == *r || tolower(*l) == tolower(*r)); l++, r++, n--); + return tolower(*l) - tolower(*r); +} diff --git a/libcrt/c/src/string/strncat.c b/libcrt/c/src/string/strncat.c new file mode 100644 index 0000000000..5fe48e1686 --- /dev/null +++ b/libcrt/c/src/string/strncat.c @@ -0,0 +1,12 @@ +/* SPDX-License-Identifier: MIT */ + +#include + +char *strncat(char *restrict d, const char *restrict s, size_t n) +{ + char *a = d; + d += strlen(d); + while (n && *s) n--, *d++ = *s++; + *d++ = 0; + return a; +} diff --git a/libcrt/c/src/string/strncmp.c b/libcrt/c/src/string/strncmp.c new file mode 100644 index 0000000000..b39777c54c --- /dev/null +++ b/libcrt/c/src/string/strncmp.c @@ -0,0 +1,11 @@ +/* SPDX-License-Identifier: MIT */ + +#include + +int strncmp(const char *_l, const char *_r, size_t n) +{ + const unsigned char *l=(void *)_l, *r=(void *)_r; + if (!n--) return 0; + for (; *l && *r && n && *l == *r ; l++, r++, n--); + return *l - *r; +} diff --git a/libcrt/c/src/string/strncpy.c b/libcrt/c/src/string/strncpy.c new file mode 100644 index 0000000000..5528d062e7 --- /dev/null +++ b/libcrt/c/src/string/strncpy.c @@ -0,0 +1,9 @@ +/* SPDX-License-Identifier: MIT */ + +#include + +char *strncpy(char *restrict d, const char *restrict s, size_t n) +{ + __stpncpy(d, s, n); + return d; +} diff --git a/libcrt/c/src/string/strrchr.c b/libcrt/c/src/string/strrchr.c new file mode 100644 index 0000000000..614c2c9f7a --- /dev/null +++ b/libcrt/c/src/string/strrchr.c @@ -0,0 +1,8 @@ +/* SPDX-License-Identifier: MIT */ + +#include + +char *strrchr(const char *s, int c) +{ + return __memrchr(s, c, strlen(s) + 1); +} diff --git a/libcrt/c/src/string/strspn.c b/libcrt/c/src/string/strspn.c new file mode 100644 index 0000000000..c4aaa8e3d8 --- /dev/null +++ b/libcrt/c/src/string/strspn.c @@ -0,0 +1,22 @@ +/* SPDX-License-Identifier: MIT */ + +#include + +#define BITOP(a,b,op) \ + ((a)[(size_t)(b)/(8*sizeof *(a))] op (size_t)1<<((size_t)(b)%(8*sizeof *(a)))) + +size_t strspn(const char *s, const char *c) +{ + const char *a = s; + size_t byteset[32/sizeof(size_t)] = { 0 }; + + if (!c[0]) return 0; + if (!c[1]) { + for (; *s == *c; s++); + return s-a; + } + + for (; *c && BITOP(byteset, *(unsigned char *)c, |=); c++); + for (; *s && BITOP(byteset, *(unsigned char *)s, &); s++); + return s-a; +} diff --git a/libcrt/c/src/string/strstr.c b/libcrt/c/src/string/strstr.c new file mode 100644 index 0000000000..dc9bb73e55 --- /dev/null +++ b/libcrt/c/src/string/strstr.c @@ -0,0 +1,156 @@ +/* SPDX-License-Identifier: MIT */ + +#include +#include + +static char *twobyte_strstr(const unsigned char *h, const unsigned char *n) +{ + uint16_t nw = n[0]<<8 | n[1], hw = h[0]<<8 | h[1]; + for (h++; *h && hw != nw; hw = hw<<8 | *++h); + return *h ? (char *)h-1 : 0; +} + +static char *threebyte_strstr(const unsigned char *h, const unsigned char *n) +{ + uint32_t nw = (uint32_t)n[0]<<24 | n[1]<<16 | n[2]<<8; + uint32_t hw = (uint32_t)h[0]<<24 | h[1]<<16 | h[2]<<8; + for (h+=2; *h && hw != nw; hw = (hw|*++h)<<8); + return *h ? (char *)h-2 : 0; +} + +static char *fourbyte_strstr(const unsigned char *h, const unsigned char *n) +{ + uint32_t nw = (uint32_t)n[0]<<24 | n[1]<<16 | n[2]<<8 | n[3]; + uint32_t hw = (uint32_t)h[0]<<24 | h[1]<<16 | h[2]<<8 | h[3]; + for (h+=3; *h && hw != nw; hw = hw<<8 | *++h); + return *h ? (char *)h-3 : 0; +} + +#define MAX(a,b) ((a)>(b)?(a):(b)) +#define MIN(a,b) ((a)<(b)?(a):(b)) + +#define BITOP(a,b,op) \ + ((a)[(size_t)(b)/(8*sizeof *(a))] op (size_t)1<<((size_t)(b)%(8*sizeof *(a)))) + +static char *twoway_strstr(const unsigned char *h, const unsigned char *n) +{ + const unsigned char *z; + size_t l, ip, jp, k, p, ms, p0, mem, mem0; + size_t byteset[32 / sizeof(size_t)] = { 0 }; + size_t shift[256]; + + /* Computing length of needle and fill shift table */ + for (l=0; n[l] && h[l]; l++) + BITOP(byteset, n[l], |=), shift[n[l]] = l+1; + if (n[l]) return 0; /* hit the end of h */ + + /* Compute maximal suffix */ + ip = -1; jp = 0; k = p = 1; + while (jp+k n[jp+k]) { + jp += k; + k = 1; + p = jp - ip; + } else { + ip = jp++; + k = p = 1; + } + } + ms = ip; + p0 = p; + + /* And with the opposite comparison */ + ip = -1; jp = 0; k = p = 1; + while (jp+k ms+1) ms = ip; + else p = p0; + + /* Periodic needle? */ + if (memcmp(n, n+p, ms+1)) { + mem0 = 0; + p = MAX(ms, l-ms-1) + 1; + } else mem0 = l-p; + mem = 0; + + /* Initialize incremental end-of-haystack pointer */ + z = h; + + /* Search loop */ + for (;;) { + /* Update incremental end-of-haystack pointer */ + if (z-h < l) { + /* Fast estimate for MAX(l,63) */ + size_t grow = l | 63; + const unsigned char *z2 = memchr(z, 0, grow); + if (z2) { + z = z2; + if (z-h < l) return 0; + } else z += grow; + } + + /* Check last byte first; advance by shift on mismatch */ + if (BITOP(byteset, h[l-1], &)) { + k = l-shift[h[l-1]]; + if (k) { + if (k < mem) k = mem; + h += k; + mem = 0; + continue; + } + } else { + h += l; + mem = 0; + continue; + } + + /* Compare right half */ + for (k=MAX(ms+1,mem); n[k] && n[k] == h[k]; k++); + if (n[k]) { + h += k-ms; + mem = 0; + continue; + } + /* Compare left half */ + for (k=ms+1; k>mem && n[k-1] == h[k-1]; k--); + if (k <= mem) return (char *)h; + h += p; + mem = mem0; + } +} + +char *strstr(const char *h, const char *n) +{ + /* Return immediately on empty needle */ + if (!n[0]) return (char *)h; + + /* Use faster algorithms for short needles */ + h = strchr(h, *n); + if (!h || !n[1]) return (char *)h; + if (!h[1]) return 0; + if (!n[2]) return twobyte_strstr((void *)h, (void *)n); + if (!h[2]) return 0; + if (!n[3]) return threebyte_strstr((void *)h, (void *)n); + if (!h[3]) return 0; + if (!n[4]) return fourbyte_strstr((void *)h, (void *)n); + + return twoway_strstr((void *)h, (void *)n); +} diff --git a/libcrt/c/src/stub.c b/libcrt/c/src/stub.c new file mode 100644 index 0000000000..16a21ca029 --- /dev/null +++ b/libcrt/c/src/stub.c @@ -0,0 +1,183 @@ +/* SPDX-License-Identifier: MIT */ + +#include + +#define NOT_IMPLEMENTED \ + do { \ + printf("ERROR: libcrt: %s not implemented\n", __func__); \ + abort(); \ + } while (0) + + +// errno.h + +int errno = 0; +FILE *stderr = NULL; +FILE *stdin = NULL; +FILE *stdout = NULL; + +char *strerror(int errnum) +{ + NOT_IMPLEMENTED; + return NULL; +} + +// stdio.h + +int sscanf(const char *buffer, const char *format, ...) +{ + NOT_IMPLEMENTED; + return 0; +} + +// fwrite, fread, fclose, fopen, fseek, ftell, fflush are provided by +// SVSM Rust code (kernel/src/vtpm/tcgtpm/wrapper.rs). + +int fputc(int c, FILE *f) +{ + NOT_IMPLEMENTED; + return 0; +} + + +void setbuf(FILE *stream, char *buf) +{ + NOT_IMPLEMENTED; +} + +int ferror(FILE *stream) { + NOT_IMPLEMENTED; + return -1; +} + +int clearerr(FILE *stream) { + NOT_IMPLEMENTED; + return -1; +} + +// stdlib.h + +long strtol(const char *nptr, char **endptr, int base) +{ + NOT_IMPLEMENTED; + return LONG_MIN; +} + +unsigned long strtoul(const char *nptr, char **endptr, int base) +{ + NOT_IMPLEMENTED; + return ULONG_MAX; +} + +char *getenv(const char *varname) +{ + NOT_IMPLEMENTED; + return NULL; +} + +int atexit(void (*func)(void)) +{ + NOT_IMPLEMENTED; + return 0; +} + +// unistd.h + +pid_t getpid(void) +{ + // TODO: return the actual PID when CPL3 is supported + return 0; +} + +uid_t getuid(void) +{ + NOT_IMPLEMENTED; + return 0; +} + +uid_t geteuid(void) +{ + NOT_IMPLEMENTED; + return 0; +} + +gid_t getgid(void) +{ + NOT_IMPLEMENTED; + return 0; +} + +gid_t getegid(void) +{ + NOT_IMPLEMENTED; + return 0; +} + +long syscall(long number, ...) +{ + NOT_IMPLEMENTED; + errno = ENOSYS; + return -1; +} + +int usleep(useconds_t usec) +{ + NOT_IMPLEMENTED; + return -1; +} + +unsigned int sleep(unsigned int seconds) +{ + NOT_IMPLEMENTED; + return seconds; +} + +int timezone = 0; + +// dirent.h + +DIR *opendir(const char *name) +{ + NOT_IMPLEMENTED; + return NULL; +} + +int closedir(DIR *name) +{ + NOT_IMPLEMENTED; + return -1; +} + +struct dirent *readdir(DIR *name) +{ + NOT_IMPLEMENTED; + return NULL; +} + +// sys/stat.h + +int stat(const char *__restrict path, struct stat *restrict buf) +{ + NOT_IMPLEMENTED; + return -1; +} + +// time.h + +char *ctime(const time_t *t) { + NOT_IMPLEMENTED; + return NULL; +} + +time_t mktime(struct tm *tm) { + NOT_IMPLEMENTED; + return 0; +} + +// string.h + +char *strpbrk(const char *s, const char *accept) +{ + NOT_IMPLEMENTED; + return NULL; +} diff --git a/libcrt/c/src/time/__secs_to_tm.c b/libcrt/c/src/time/__secs_to_tm.c new file mode 100644 index 0000000000..a32c39ee63 --- /dev/null +++ b/libcrt/c/src/time/__secs_to_tm.c @@ -0,0 +1,84 @@ +/* SPDX-License-Identifier: MIT */ + +#include +#include + +/* 2000-03-01 (mod 400 year, immediately after feb29 */ +#define LEAPOCH (946684800LL + 86400*(31+29)) + +#define DAYS_PER_400Y (365*400 + 97) +#define DAYS_PER_100Y (365*100 + 24) +#define DAYS_PER_4Y (365*4 + 1) + +int __secs_to_tm(long long t, struct tm *tm) +{ + long long days, secs, years; + int remdays, remsecs, remyears; + int qc_cycles, c_cycles, q_cycles; + int months; + int wday, yday, leap; + static const char days_in_month[] = {31,30,31,30,31,31,30,31,30,31,31,29}; + + /* Reject time_t values whose year would overflow int */ + if (t < INT_MIN * 31622400LL || t > INT_MAX * 31622400LL) + return -1; + + secs = t - LEAPOCH; + days = secs / 86400; + remsecs = secs % 86400; + if (remsecs < 0) { + remsecs += 86400; + days--; + } + + wday = (3+days)%7; + if (wday < 0) wday += 7; + + qc_cycles = days / DAYS_PER_400Y; + remdays = days % DAYS_PER_400Y; + if (remdays < 0) { + remdays += DAYS_PER_400Y; + qc_cycles--; + } + + c_cycles = remdays / DAYS_PER_100Y; + if (c_cycles == 4) c_cycles--; + remdays -= c_cycles * DAYS_PER_100Y; + + q_cycles = remdays / DAYS_PER_4Y; + if (q_cycles == 25) q_cycles--; + remdays -= q_cycles * DAYS_PER_4Y; + + remyears = remdays / 365; + if (remyears == 4) remyears--; + remdays -= remyears * 365; + + leap = !remyears && (q_cycles || !c_cycles); + yday = remdays + 31 + 28 + leap; + if (yday >= 365+leap) yday -= 365+leap; + + years = remyears + 4*q_cycles + 100*c_cycles + 400LL*qc_cycles; + + for (months=0; days_in_month[months] <= remdays; months++) + remdays -= days_in_month[months]; + + if (months >= 10) { + months -= 12; + years++; + } + + if (years+100 > INT_MAX || years+100 < INT_MIN) + return -1; + + tm->tm_year = years + 100; + tm->tm_mon = months + 2; + tm->tm_mday = remdays + 1; + tm->tm_wday = wday; + tm->tm_yday = yday; + + tm->tm_hour = remsecs / 3600; + tm->tm_min = remsecs / 60 % 60; + tm->tm_sec = remsecs % 60; + + return 0; +} diff --git a/libcrt/c/src/time/gmtime_r.c b/libcrt/c/src/time/gmtime_r.c new file mode 100644 index 0000000000..2aefad83a0 --- /dev/null +++ b/libcrt/c/src/time/gmtime_r.c @@ -0,0 +1,25 @@ +/* SPDX-License-Identifier: MIT */ + +#include +#include + +char *__utc = "UTC"; + +struct tm *gmtime_r(const time_t *restrict t, struct tm *restrict tm) +{ + if (__secs_to_tm(*t, tm) < 0) { + errno = EOVERFLOW; + return 0; + } + tm->tm_isdst = 0; + tm->tm_gmtoff = 0; + tm->tm_zone = __utc; + return tm; +} + + +struct tm *gmtime(const time_t *t) +{ + static struct tm tm; + return gmtime_r(t, &tm); +} diff --git a/libcrt/c/src/time/time.c b/libcrt/c/src/time/time.c new file mode 100644 index 0000000000..60016eefc6 --- /dev/null +++ b/libcrt/c/src/time/time.c @@ -0,0 +1,37 @@ +/* SPDX-License-Identifier: MIT */ + +#include +#include +#include + +// Calls the rdtsc instruction to read the current value of the processor's +// time-stamp counter (a 64-bit MSR) +clock_t clock(void) { + return rdtsc(); +} + +uint64_t secs; + +int clock_gettime(clockid_t clk_id, struct timespec *tp) { + (void) clk_id; + if (tp) { + tp->tv_nsec = rdtsc(); + tp->tv_sec = secs++; + } + return 0; +} + +// time() returns the time as the number of seconds since the Epoch +time_t time(time_t *tloc) { + (void)tloc; + time_t t = rdtsc(); + return t; +} + +int gettimeofday(struct timeval *restrict tv, void *restrict tz) +{ + if (!tv) return 0; + tv->tv_sec = clock(); + tv->tv_usec = 0; + return 0; +} diff --git a/libcrt/src/lib.rs b/libcrt/src/lib.rs new file mode 100644 index 0000000000..8ba9f63e9c --- /dev/null +++ b/libcrt/src/lib.rs @@ -0,0 +1,20 @@ +// SPDX-License-Identifier: MIT OR Apache-2.0 +// +// Copyright (c) 2026 Red Hat +// +// Author: Oliver Steffen + +//! C runtime library for the SVSM target. +//! +//! Builds a minimal C runtime (libc headers and static library) from the +//! bundled C sources. The build script exposes the result to dependent +//! crates via Cargo `links` metadata (`links = "crt"`). +//! +//! # Build metadata provided +//! +//! | Key | Env var consumed as | Description | +//! |---------------|-------------------------|-------------------------------------| +//! | `INCLUDE_DIR` | `DEP_CRT_INCLUDE_DIR` | Path to the C runtime header files | +//! | `LIB_DIR` | `DEP_CRT_LIB_DIR` | Path to the compiled static library | + +#![no_std] diff --git a/libtcgtpm/deps/libcrt/include/libcrt.h b/libtcgtpm/deps/libcrt/include/libcrt.h index f796f2ddc8..9d7447628f 100644 --- a/libtcgtpm/deps/libcrt/include/libcrt.h +++ b/libtcgtpm/deps/libcrt/include/libcrt.h @@ -362,17 +362,15 @@ int toupper(int c); int printf(const char *, ...); int sscanf(const char *, const char *, ...); -// Functions exported by the SVSM -extern FILE *fopen(const char *, const char *); -extern int fclose(FILE *); -extern size_t fread(void *, size_t, size_t, FILE *); -extern size_t fwrite(const void *buffer, size_t size, size_t count, FILE *stream); -extern int fseek(FILE *stream, long offset, int whence); -extern long ftell(FILE *stream); -extern int fflush(FILE *stream); - +FILE *fopen(const char *, const char *); +int fclose(FILE *); +size_t fread(void *, size_t, size_t, FILE *); +size_t fwrite(const void *buffer, size_t size, size_t count, FILE *stream); int fprintf(FILE *, const char *, ...); int fputc(int c, FILE *f); +int fseek(FILE *stream, long offset, int whence); +long ftell(FILE *stream); +int fflush(FILE *stream); int ferror(FILE *stream); int clearerr(FILE *stream); diff --git a/libtcgtpm/deps/libcrt/src/stub.c b/libtcgtpm/deps/libcrt/src/stub.c index 66aa196930..16a21ca029 100644 --- a/libtcgtpm/deps/libcrt/src/stub.c +++ b/libtcgtpm/deps/libcrt/src/stub.c @@ -30,7 +30,10 @@ int sscanf(const char *buffer, const char *format, ...) return 0; } -int fputc(int c, FILE *f) +// fwrite, fread, fclose, fopen, fseek, ftell, fflush are provided by +// SVSM Rust code (kernel/src/vtpm/tcgtpm/wrapper.rs). + +int fputc(int c, FILE *f) { NOT_IMPLEMENTED; return 0; From e505031dde5e6365e483ec95322be85a6be9b504 Mon Sep 17 00:00:00 2001 From: Oliver Steffen Date: Fri, 18 Sep 2026 11:42:36 +0200 Subject: [PATCH 07/13] libcrt: add missing visibility pop to match push in libcrt.h MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit libcrt.h opens with `#pragma GCC visibility push(hidden)` when __pie__ is defined, but never pops it. This leaks hidden visibility into every translation unit that transitively includes any libcrt header (stddef.h, stdio.h, stdlib.h, etc. all include libcrt.h). For the SVSM kernel built with gcc -nostdinc this is harmless because gcc does not default to PIE and the SVSM link step uses explicit symbol visibility anyway. However, when a host-side tool such as bindgen uses libclang to parse OpenSSL headers that pull in libcrt's stdio.h, the missing pop causes all subsequent function declarations (BN_*, EC_*, EVP_*, ...) to inherit hidden visibility. On hosts where clang defaults to PIE (Ubuntu, Debian), __pie__ is defined and the pragma fires — bindgen's enable_function_attribute_detection() then silently drops the hidden functions, producing only 15 out of ~1873 expected bindings. Hosts without PIE defaults (Fedora, RHEL) are unaffected, hiding the bug. Add the matching `#pragma GCC visibility pop` before the include guard close. Signed-off-by: Oliver Steffen --- libcrt/c/include/libcrt.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/libcrt/c/include/libcrt.h b/libcrt/c/include/libcrt.h index 9d7447628f..a58de2589b 100644 --- a/libcrt/c/include/libcrt.h +++ b/libcrt/c/include/libcrt.h @@ -405,4 +405,8 @@ typedef struct { unsigned long fds_bits[FD_SETSIZE / 8 / sizeof(long)]; } fd_set; +#if defined(__pie__) +#pragma GCC visibility pop +#endif + #endif From fd51576922ce5f8d3f0f60e91657ec68901434b8 Mon Sep 17 00:00:00 2001 From: Oliver Steffen Date: Mon, 19 Oct 2026 17:23:54 +0200 Subject: [PATCH 08/13] kernel/crt: Move C runtime glue out of vtpm module MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The #[no_mangle] functions that satisfy libcrt's extern declarations (malloc, free, serial_out, abort, fopen, …) and the CFile/StorageBackend infrastructure live under kernel/src/vtpm/tcgtpm/. This means enabling the "openssl" feature without "vtpm" causes linker errors because the entire vtpm module — and with it the C runtime symbols — is gated on feature = "vtpm". Create a new kernel/src/crt/ module gated on any(feature = "openssl", feature = "vtpm") and move: - wrapper.rs (all #[no_mangle] extern "C" functions) - cfile.rs (CFileBuffer, StorageBackend trait, backends) - TpmInode (persistence inode mapping, stays behind feature = "persistence") The TPM-specific ManufacturedMarker and Marker trait remain under vtpm/tcgtpm/persistence/ and import TpmInode from the new location. Signed-off-by: Oliver Steffen --- .../{vtpm/tcgtpm/persistence => crt}/cfile.rs | 13 +++++- kernel/src/crt/mod.rs | 41 +++++++++++++++++++ kernel/src/{vtpm/tcgtpm => crt}/wrapper.rs | 8 ++-- kernel/src/lib.rs | 2 + kernel/src/vtpm/tcgtpm/mod.rs | 4 -- kernel/src/vtpm/tcgtpm/persistence/mod.rs | 34 +-------------- 6 files changed, 59 insertions(+), 43 deletions(-) rename kernel/src/{vtpm/tcgtpm/persistence => crt}/cfile.rs (95%) create mode 100644 kernel/src/crt/mod.rs rename kernel/src/{vtpm/tcgtpm => crt}/wrapper.rs (96%) diff --git a/kernel/src/vtpm/tcgtpm/persistence/cfile.rs b/kernel/src/crt/cfile.rs similarity index 95% rename from kernel/src/vtpm/tcgtpm/persistence/cfile.rs rename to kernel/src/crt/cfile.rs index 2eaae6b559..1f6204eec7 100644 --- a/kernel/src/vtpm/tcgtpm/persistence/cfile.rs +++ b/kernel/src/crt/cfile.rs @@ -32,12 +32,12 @@ pub trait StorageBackend: Sized { #[cfg(feature = "persistence")] mod backend { use super::*; + use crate::crt::TpmInode; use crate::persistence::{ Inode, persistence_available, persistence_read_inode_sync, persistence_write_inode_sync, }; - use super::super::TpmInode; - + #[derive(Debug)] pub struct CocoonFsBackend { inode: u64, } @@ -88,6 +88,7 @@ mod backend { mod backend { use super::*; + #[derive(Debug)] pub struct VolatileBackend; impl StorageBackend for VolatileBackend { @@ -113,6 +114,14 @@ pub struct CFileBuffer { backend: B, } +impl core::fmt::Debug for CFileBuffer { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + f.debug_struct("CFileBuffer") + .field("pos", &self.pos) + .finish_non_exhaustive() + } +} + impl CFileBuffer { fn buf(&self) -> Result<&Zeroizing>, SvsmError> { self.buf.as_ref().ok_or(FsError::BadHandle.into()) diff --git a/kernel/src/crt/mod.rs b/kernel/src/crt/mod.rs new file mode 100644 index 0000000000..a38a8a33fe --- /dev/null +++ b/kernel/src/crt/mod.rs @@ -0,0 +1,41 @@ +// SPDX-License-Identifier: MIT OR Apache-2.0 +// +// Copyright (c) 2023 IBM +// Copyright (c) 2026 Red Hat, Inc. + +//! C runtime glue: `#[no_mangle]` wrappers that satisfy the `extern` +//! declarations in libcrt (malloc/free, serial_out, abort, file I/O). + +#[cfg(target_os = "none")] +mod wrapper; + +#[cfg(target_os = "none")] +pub mod cfile; + +#[cfg(target_os = "none")] +pub use cfile::CFile; + +#[cfg(feature = "persistence")] +mod inode { + use crate::persistence::{Inode, InodeNamespace}; + + #[derive(Clone, Copy, Debug)] + #[repr(u32)] + pub enum TpmInode { + NvChip = 0, + Manufactured = 1, + } + + impl From for u32 { + fn from(val: TpmInode) -> u32 { + val as u32 + } + } + + impl Inode for TpmInode { + const NAMESPACE: InodeNamespace = InodeNamespace::Tpm; + } +} + +#[cfg(feature = "persistence")] +pub use inode::TpmInode; diff --git a/kernel/src/vtpm/tcgtpm/wrapper.rs b/kernel/src/crt/wrapper.rs similarity index 96% rename from kernel/src/vtpm/tcgtpm/wrapper.rs rename to kernel/src/crt/wrapper.rs index bbfb258afc..0fd5630016 100644 --- a/kernel/src/vtpm/tcgtpm/wrapper.rs +++ b/kernel/src/crt/wrapper.rs @@ -4,10 +4,8 @@ // // Author: Claudio Carvalho -//! Implement functions required to build the TPM 2.0 Reference Implementation -//! libraries. -//! All these functionalities are owned by the SVSM Rust code, -//! so we just need to create wrappers for them. +//! `#[no_mangle]` C-ABI wrappers for functions declared as `extern` in +//! libcrt headers: memory allocation, console output, and file I/O. use crate::{ console::_print, @@ -27,7 +25,7 @@ extern crate alloc; use alloc::alloc::{alloc, alloc_zeroed, dealloc, realloc as _realloc}; use alloc::boxed::Box; -use super::persistence::CFile; +use super::cfile::CFile; #[unsafe(no_mangle)] pub extern "C" fn malloc(size: c_ulong) -> *mut c_void { diff --git a/kernel/src/lib.rs b/kernel/src/lib.rs index 99c651e47e..083756114e 100644 --- a/kernel/src/lib.rs +++ b/kernel/src/lib.rs @@ -29,6 +29,8 @@ pub mod block; pub mod boot_params; pub mod console; pub mod cpu; +#[cfg(feature = "vtpm")] +pub mod crt; pub mod crypto; pub mod debug; pub mod error; diff --git a/kernel/src/vtpm/tcgtpm/mod.rs b/kernel/src/vtpm/tcgtpm/mod.rs index e81da36e90..acaf5fc2de 100644 --- a/kernel/src/vtpm/tcgtpm/mod.rs +++ b/kernel/src/vtpm/tcgtpm/mod.rs @@ -7,10 +7,6 @@ //! This crate implements the virtual TPM interfaces for the TPM 2.0 //! Reference Implementation (by Microsoft) -/// Functions required to build the TPM 2.0 Reference Implementation libraries -#[cfg(target_os = "none")] -mod wrapper; - mod persistence; use persistence::{ManufacturedMarker, Marker as _}; diff --git a/kernel/src/vtpm/tcgtpm/persistence/mod.rs b/kernel/src/vtpm/tcgtpm/persistence/mod.rs index c42142753a..1f69bb8024 100644 --- a/kernel/src/vtpm/tcgtpm/persistence/mod.rs +++ b/kernel/src/vtpm/tcgtpm/persistence/mod.rs @@ -2,41 +2,10 @@ // // Copyright (c) 2026 Red Hat, Inc. -//! TPM persistence: manufacturing marker and C file I/O backend. - -#[cfg(target_os = "none")] -pub mod cfile; - -#[cfg(target_os = "none")] -pub use cfile::CFile; +//! TPM persistence: manufacturing marker. use crate::error::SvsmError; -#[cfg(feature = "persistence")] -mod inode { - use crate::persistence::{Inode, InodeNamespace}; - - #[derive(Clone, Copy, Debug)] - #[repr(u32)] - pub enum TpmInode { - NvChip = 0, - Manufactured = 1, - } - - impl From for u32 { - fn from(val: TpmInode) -> u32 { - val as u32 - } - } - - impl Inode for TpmInode { - const NAMESPACE: InodeNamespace = InodeNamespace::Tpm; - } -} - -#[cfg(feature = "persistence")] -use inode::TpmInode; - pub trait Marker { fn exists() -> Result { Ok(false) @@ -56,6 +25,7 @@ mod marker { use alloc::vec::Vec; use zeroize::Zeroizing; + use crate::crt::TpmInode; use crate::persistence::{ Inode, persistence_available, persistence_read_inode_sync, persistence_write_inode_sync, }; From fc807fdf23ef6ea0fdb1969517b632ad2e3985f9 Mon Sep 17 00:00:00 2001 From: Oliver Steffen Date: Wed, 16 Sep 2026 13:26:25 +0200 Subject: [PATCH 09/13] libtcgtpm: use libcrt from dedicated crate Use the libcrt crate instead of building libcrt locally. The libcrt crate provides include and lib paths via cargo metadata (DEP_CRT_*), and handles linking at build time. Signed-off-by: Oliver Steffen --- Cargo.lock | 1 + libtcgtpm/Cargo.toml | 1 + libtcgtpm/Makefile | 39 +- libtcgtpm/build.rs | 14 +- libtcgtpm/deps/libcrt/Makefile | 113 ----- libtcgtpm/deps/libcrt/include/assert.h | 3 - libtcgtpm/deps/libcrt/include/atomic.h | 335 -------------- libtcgtpm/deps/libcrt/include/bits/alltypes.h | 417 ------------------ .../deps/libcrt/include/bits/atomic_arch.h | 125 ------ libtcgtpm/deps/libcrt/include/ctype.h | 3 - libtcgtpm/deps/libcrt/include/dirent.h | 3 - libtcgtpm/deps/libcrt/include/endian.h | 3 - libtcgtpm/deps/libcrt/include/errno.h | 3 - libtcgtpm/deps/libcrt/include/fcntl.h | 3 - libtcgtpm/deps/libcrt/include/inttypes.h | 3 - libtcgtpm/deps/libcrt/include/libcrt.h | 408 ----------------- libtcgtpm/deps/libcrt/include/limits.h | 3 - libtcgtpm/deps/libcrt/include/memory.h | 3 - libtcgtpm/deps/libcrt/include/setjmp.h | 3 - libtcgtpm/deps/libcrt/include/stdarg.h | 3 - libtcgtpm/deps/libcrt/include/stdatomic.h | 3 - libtcgtpm/deps/libcrt/include/stdbool.h | 3 - libtcgtpm/deps/libcrt/include/stddef.h | 3 - libtcgtpm/deps/libcrt/include/stdint.h | 3 - libtcgtpm/deps/libcrt/include/stdio.h | 3 - libtcgtpm/deps/libcrt/include/stdlib.h | 3 - libtcgtpm/deps/libcrt/include/string.h | 3 - libtcgtpm/deps/libcrt/include/strings.h | 3 - libtcgtpm/deps/libcrt/include/sys/shm.h | 3 - libtcgtpm/deps/libcrt/include/sys/stat.h | 3 - libtcgtpm/deps/libcrt/include/sys/syscall.h | 3 - libtcgtpm/deps/libcrt/include/sys/time.h | 3 - libtcgtpm/deps/libcrt/include/sys/types.h | 3 - libtcgtpm/deps/libcrt/include/sys/utsname.h | 3 - libtcgtpm/deps/libcrt/include/time.h | 3 - libtcgtpm/deps/libcrt/include/unistd.h | 3 - libtcgtpm/deps/libcrt/src/ctype/isascii.c | 8 - libtcgtpm/deps/libcrt/src/ctype/isdigit.c | 6 - libtcgtpm/deps/libcrt/src/ctype/islower.c | 8 - libtcgtpm/deps/libcrt/src/ctype/isspace.c | 8 - libtcgtpm/deps/libcrt/src/ctype/isupper.c | 8 - libtcgtpm/deps/libcrt/src/ctype/tolower.c | 9 - libtcgtpm/deps/libcrt/src/ctype/toupper.c | 9 - libtcgtpm/deps/libcrt/src/exit/assert.c | 10 - libtcgtpm/deps/libcrt/src/prng/rand.c | 151 ------- .../deps/libcrt/src/setjmp/x86_64/longjmp.s | 20 - .../deps/libcrt/src/setjmp/x86_64/setjmp.s | 24 - libtcgtpm/deps/libcrt/src/stdio/asprintf.c | 14 - libtcgtpm/deps/libcrt/src/stdio/fprintf.c | 14 - libtcgtpm/deps/libcrt/src/stdio/printf.c | 34 -- .../deps/libcrt/src/stdio/printf_wrapper.c | 269 ----------- libtcgtpm/deps/libcrt/src/stdio/snprintf.c | 15 - libtcgtpm/deps/libcrt/src/stdio/sprintf.c | 14 - libtcgtpm/deps/libcrt/src/stdio/vasprintf.c | 16 - libtcgtpm/deps/libcrt/src/stdio/vsnprintf.c | 9 - libtcgtpm/deps/libcrt/src/stdio/vsprintf.c | 9 - libtcgtpm/deps/libcrt/src/stdlib/atoi.c | 18 - libtcgtpm/deps/libcrt/src/stdlib/qsort.c | 222 ---------- libtcgtpm/deps/libcrt/src/stdlib/qsort_nr.c | 16 - libtcgtpm/deps/libcrt/src/string/memchr.c | 29 -- libtcgtpm/deps/libcrt/src/string/memcmp.c | 10 - libtcgtpm/deps/libcrt/src/string/memcpy.c | 126 ------ libtcgtpm/deps/libcrt/src/string/memmove.c | 44 -- libtcgtpm/deps/libcrt/src/string/memrchr.c | 13 - libtcgtpm/deps/libcrt/src/string/memset.c | 92 ---- libtcgtpm/deps/libcrt/src/string/stpcpy.c | 31 -- libtcgtpm/deps/libcrt/src/string/stpncpy.c | 34 -- libtcgtpm/deps/libcrt/src/string/strcasecmp.c | 20 - libtcgtpm/deps/libcrt/src/string/strcat.c | 9 - libtcgtpm/deps/libcrt/src/string/strchr.c | 9 - libtcgtpm/deps/libcrt/src/string/strchrnul.c | 30 -- libtcgtpm/deps/libcrt/src/string/strcmp.c | 9 - libtcgtpm/deps/libcrt/src/string/strcpy.c | 9 - libtcgtpm/deps/libcrt/src/string/strcspn.c | 19 - libtcgtpm/deps/libcrt/src/string/strdup.c | 13 - libtcgtpm/deps/libcrt/src/string/strlen.c | 24 - .../deps/libcrt/src/string/strncasecmp.c | 12 - libtcgtpm/deps/libcrt/src/string/strncat.c | 12 - libtcgtpm/deps/libcrt/src/string/strncmp.c | 11 - libtcgtpm/deps/libcrt/src/string/strncpy.c | 9 - libtcgtpm/deps/libcrt/src/string/strrchr.c | 8 - libtcgtpm/deps/libcrt/src/string/strspn.c | 22 - libtcgtpm/deps/libcrt/src/string/strstr.c | 156 ------- libtcgtpm/deps/libcrt/src/stub.c | 183 -------- libtcgtpm/deps/libcrt/src/time/__secs_to_tm.c | 84 ---- libtcgtpm/deps/libcrt/src/time/gmtime_r.c | 25 -- libtcgtpm/deps/libcrt/src/time/time.c | 37 -- libtcgtpm/src/lib.rs | 13 + 88 files changed, 35 insertions(+), 3503 deletions(-) delete mode 100644 libtcgtpm/deps/libcrt/Makefile delete mode 100644 libtcgtpm/deps/libcrt/include/assert.h delete mode 100644 libtcgtpm/deps/libcrt/include/atomic.h delete mode 100644 libtcgtpm/deps/libcrt/include/bits/alltypes.h delete mode 100644 libtcgtpm/deps/libcrt/include/bits/atomic_arch.h delete mode 100644 libtcgtpm/deps/libcrt/include/ctype.h delete mode 100644 libtcgtpm/deps/libcrt/include/dirent.h delete mode 100644 libtcgtpm/deps/libcrt/include/endian.h delete mode 100644 libtcgtpm/deps/libcrt/include/errno.h delete mode 100644 libtcgtpm/deps/libcrt/include/fcntl.h delete mode 100644 libtcgtpm/deps/libcrt/include/inttypes.h delete mode 100644 libtcgtpm/deps/libcrt/include/libcrt.h delete mode 100644 libtcgtpm/deps/libcrt/include/limits.h delete mode 100644 libtcgtpm/deps/libcrt/include/memory.h delete mode 100644 libtcgtpm/deps/libcrt/include/setjmp.h delete mode 100644 libtcgtpm/deps/libcrt/include/stdarg.h delete mode 100644 libtcgtpm/deps/libcrt/include/stdatomic.h delete mode 100644 libtcgtpm/deps/libcrt/include/stdbool.h delete mode 100644 libtcgtpm/deps/libcrt/include/stddef.h delete mode 100644 libtcgtpm/deps/libcrt/include/stdint.h delete mode 100644 libtcgtpm/deps/libcrt/include/stdio.h delete mode 100644 libtcgtpm/deps/libcrt/include/stdlib.h delete mode 100644 libtcgtpm/deps/libcrt/include/string.h delete mode 100644 libtcgtpm/deps/libcrt/include/strings.h delete mode 100644 libtcgtpm/deps/libcrt/include/sys/shm.h delete mode 100644 libtcgtpm/deps/libcrt/include/sys/stat.h delete mode 100644 libtcgtpm/deps/libcrt/include/sys/syscall.h delete mode 100644 libtcgtpm/deps/libcrt/include/sys/time.h delete mode 100644 libtcgtpm/deps/libcrt/include/sys/types.h delete mode 100644 libtcgtpm/deps/libcrt/include/sys/utsname.h delete mode 100644 libtcgtpm/deps/libcrt/include/time.h delete mode 100644 libtcgtpm/deps/libcrt/include/unistd.h delete mode 100644 libtcgtpm/deps/libcrt/src/ctype/isascii.c delete mode 100644 libtcgtpm/deps/libcrt/src/ctype/isdigit.c delete mode 100644 libtcgtpm/deps/libcrt/src/ctype/islower.c delete mode 100644 libtcgtpm/deps/libcrt/src/ctype/isspace.c delete mode 100644 libtcgtpm/deps/libcrt/src/ctype/isupper.c delete mode 100644 libtcgtpm/deps/libcrt/src/ctype/tolower.c delete mode 100644 libtcgtpm/deps/libcrt/src/ctype/toupper.c delete mode 100644 libtcgtpm/deps/libcrt/src/exit/assert.c delete mode 100644 libtcgtpm/deps/libcrt/src/prng/rand.c delete mode 100644 libtcgtpm/deps/libcrt/src/setjmp/x86_64/longjmp.s delete mode 100644 libtcgtpm/deps/libcrt/src/setjmp/x86_64/setjmp.s delete mode 100644 libtcgtpm/deps/libcrt/src/stdio/asprintf.c delete mode 100644 libtcgtpm/deps/libcrt/src/stdio/fprintf.c delete mode 100644 libtcgtpm/deps/libcrt/src/stdio/printf.c delete mode 100644 libtcgtpm/deps/libcrt/src/stdio/printf_wrapper.c delete mode 100644 libtcgtpm/deps/libcrt/src/stdio/snprintf.c delete mode 100644 libtcgtpm/deps/libcrt/src/stdio/sprintf.c delete mode 100644 libtcgtpm/deps/libcrt/src/stdio/vasprintf.c delete mode 100644 libtcgtpm/deps/libcrt/src/stdio/vsnprintf.c delete mode 100644 libtcgtpm/deps/libcrt/src/stdio/vsprintf.c delete mode 100644 libtcgtpm/deps/libcrt/src/stdlib/atoi.c delete mode 100644 libtcgtpm/deps/libcrt/src/stdlib/qsort.c delete mode 100644 libtcgtpm/deps/libcrt/src/stdlib/qsort_nr.c delete mode 100644 libtcgtpm/deps/libcrt/src/string/memchr.c delete mode 100644 libtcgtpm/deps/libcrt/src/string/memcmp.c delete mode 100644 libtcgtpm/deps/libcrt/src/string/memcpy.c delete mode 100644 libtcgtpm/deps/libcrt/src/string/memmove.c delete mode 100644 libtcgtpm/deps/libcrt/src/string/memrchr.c delete mode 100644 libtcgtpm/deps/libcrt/src/string/memset.c delete mode 100644 libtcgtpm/deps/libcrt/src/string/stpcpy.c delete mode 100644 libtcgtpm/deps/libcrt/src/string/stpncpy.c delete mode 100644 libtcgtpm/deps/libcrt/src/string/strcasecmp.c delete mode 100644 libtcgtpm/deps/libcrt/src/string/strcat.c delete mode 100644 libtcgtpm/deps/libcrt/src/string/strchr.c delete mode 100644 libtcgtpm/deps/libcrt/src/string/strchrnul.c delete mode 100644 libtcgtpm/deps/libcrt/src/string/strcmp.c delete mode 100644 libtcgtpm/deps/libcrt/src/string/strcpy.c delete mode 100644 libtcgtpm/deps/libcrt/src/string/strcspn.c delete mode 100644 libtcgtpm/deps/libcrt/src/string/strdup.c delete mode 100644 libtcgtpm/deps/libcrt/src/string/strlen.c delete mode 100644 libtcgtpm/deps/libcrt/src/string/strncasecmp.c delete mode 100644 libtcgtpm/deps/libcrt/src/string/strncat.c delete mode 100644 libtcgtpm/deps/libcrt/src/string/strncmp.c delete mode 100644 libtcgtpm/deps/libcrt/src/string/strncpy.c delete mode 100644 libtcgtpm/deps/libcrt/src/string/strrchr.c delete mode 100644 libtcgtpm/deps/libcrt/src/string/strspn.c delete mode 100644 libtcgtpm/deps/libcrt/src/string/strstr.c delete mode 100644 libtcgtpm/deps/libcrt/src/stub.c delete mode 100644 libtcgtpm/deps/libcrt/src/time/__secs_to_tm.c delete mode 100644 libtcgtpm/deps/libcrt/src/time/gmtime_r.c delete mode 100644 libtcgtpm/deps/libcrt/src/time/time.c diff --git a/Cargo.lock b/Cargo.lock index 375b1cc5f2..a1798a77d6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1559,6 +1559,7 @@ name = "libtcgtpm" version = "0.1.0" dependencies = [ "bindgen", + "libcrt", "prettyplease", ] diff --git a/libtcgtpm/Cargo.toml b/libtcgtpm/Cargo.toml index 64d3cb8a68..0c96a7927e 100644 --- a/libtcgtpm/Cargo.toml +++ b/libtcgtpm/Cargo.toml @@ -4,6 +4,7 @@ version = "0.1.0" edition.workspace = true [dependencies] +libcrt = { workspace = true } [build-dependencies] bindgen = { workspace = true, features = ["runtime"] } diff --git a/libtcgtpm/Makefile b/libtcgtpm/Makefile index f72ca816f1..a2a89b4a72 100644 --- a/libtcgtpm/Makefile +++ b/libtcgtpm/Makefile @@ -16,6 +16,10 @@ endif # Allow user to not link in libcrt USE_LIBCRT ?= 1 +# libcrt is built externally (by the libcrt crate). +# The following must be provided by the caller: +# LIBCRT_INCLUDE_DIR + ROOT_DIR := $(dir $(abspath $(lastword $(MAKEFILE_LIST)))) DEPS_DIR := $(ROOT_DIR)/deps OUT_DIR ?= $(ROOT_DIR) @@ -33,19 +37,12 @@ NUM_JOBS ?= $(shell nproc) MAKEFLAGS += -j$(NUM_JOBS) endif -LIBCRT_SRC_DIR = $(DEPS_DIR)/libcrt OPENSSL_SRC_DIR = $(DEPS_DIR)/openssl TCGTPM_SRC_DIR = $(DEPS_DIR)/tpm-20-ref/TPMCmd -LIBCRT_BUILD_DIR = $(OUT_DIR)/libcrt-build OPENSSL_BUILD_DIR = $(OUT_DIR)/openssl-build TCGTPM_BUILD_DIR = $(OUT_DIR)/tcgtpm-build -ifeq ($(USE_LIBCRT),1) -LIBCRT = $(LIBCRT_BUILD_DIR)/libcrt.a -else -LIBCRT = -endif LIBCRYPTO = $(OPENSSL_BUILD_DIR)/libcrypto.a LIBTPM_TARGET = Tpm_CoreLib @@ -64,14 +61,15 @@ OPENSSL_MAKEFILE = $(OPENSSL_BUILD_DIR)/Makefile TCGTPM_MAKEFILE = $(TCGTPM_BUILD_DIR)/Makefile ifeq ($(USE_LIBCRT),1) -LIBCRT_INCLUDE = -I$(LIBCRT_SRC_DIR)/include -LIBCRT_LINK = -Wl,rpath=$(LIBCRT_BUILD_DIR) -lcrt TCGTPM_CFLAGS += -static -nostdinc -fno-stack-protector -mno-sse -mno-red-zone +TCGTPM_CFLAGS += -I$(LIBCRT_INCLUDE_DIR) OPENSSL_CFLAGS = -static -nostdinc -nostdlib -fno-stack-protector -mno-red-zone +LIBCRT_INCLUDE = -I$(LIBCRT_INCLUDE_DIR) +LIBCRT_LINK = -Wl,rpath=$(LIBCRT_LIB_DIR) -lcrt else +OPENSSL_CFLAGS = LIBCRT_INCLUDE = LIBCRT_LINK = -OPENSSL_CFLAGS = endif # Avoid running jobs of this Makefile in parallel to avoid possible conflicts @@ -79,17 +77,10 @@ endif # Parallel builds are still used inside the sub-targets (-j flag) .NOTPARALLEL: -all: $(LIBCRT) $(LIBCRYPTO) $(LIBBNMATH) $(LIBTPMBIGNUM) $(LIBTPM) $(LIBPLATFORM) - -.PHONY: $(LIBCRT) - -# libcrt -$(LIBCRT): - mkdir -p $(LIBCRT_BUILD_DIR) - $(MAKE) -C $(LIBCRT_SRC_DIR) OUT_DIR=$(LIBCRT_BUILD_DIR) CC=$(CC) +all: $(LIBCRYPTO) $(LIBBNMATH) $(LIBTPMBIGNUM) $(LIBTPM) $(LIBPLATFORM) # openssl -$(LIBCRYPTO): $(OPENSSL_MAKEFILE) $(LIBCRT) +$(LIBCRYPTO): $(OPENSSL_MAKEFILE) $(MAKE) -C $(OPENSSL_BUILD_DIR) $(OPENSSL_MAKEFILE): @@ -215,11 +206,10 @@ $(LIBPLATFORM): $(TCGTPM_MAKEFILE) $(LIBCRYPTO) TCGTPM_CFLAGS += -fPIE TCGTPM_CFLAGS += -DFILE_BACKED_NV=YES -DVTPM=YES -TCGTPM_CFLAGS += $(LIBCRT_INCLUDE) TCGTPM_CFLAGS += -I$(OPENSSL_BUILD_DIR)/include TCGTPM_CFLAGS += -I$(OPENSSL_SRC_DIR)/include -$(TCGTPM_MAKEFILE): $(LIBCRYPTO) $(LIBCRT) +$(TCGTPM_MAKEFILE): $(LIBCRYPTO) mkdir -p $(TCGTPM_BUILD_DIR) (cd $(TCGTPM_BUILD_DIR) && \ cmake \ @@ -233,19 +223,14 @@ $(TCGTPM_MAKEFILE): $(LIBCRYPTO) $(LIBCRT) $(TCGTPM_SRC_DIR)) clean: - $(MAKE) -C $(LIBCRT_SRC_DIR) OUT_DIR=$(LIBCRT_BUILD_DIR) clean [ ! -f $(OPENSSL_MAKEFILE) ] || $(MAKE) -C $(OPENSSL_BUILD_DIR) clean [ ! -f $(TCGTPM_MAKEFILE) ] || $(MAKE) -C $(TCGTPM_BUILD_DIR) clean distclean: clean - rm -rf $(LIBCRT_BUILD_DIR) rm -rf $(OPENSSL_BUILD_DIR) rm -rf $(TCGTPM_BUILD_DIR) -.PHONY: all clean distclean - -.PHONY: libcrt configure_openssl configure_tcgtpm libcrypto -libcrt: $(LIBCRT) +.PHONY: all clean distclean configure_openssl configure_tcgtpm libcrypto configure_openssl: $(OPENSSL_MAKEFILE) libcrypto: $(LIBCRYPTO) configure_tcgtpm: $(TCGTPM_MAKEFILE) diff --git a/libtcgtpm/build.rs b/libtcgtpm/build.rs index afd8d69f09..fef815d50e 100644 --- a/libtcgtpm/build.rs +++ b/libtcgtpm/build.rs @@ -12,8 +12,13 @@ use std::process::Stdio; fn main() { let target_os = std::env::var("CARGO_CFG_TARGET_OS").unwrap_or_default(); - // Build libtcgtpm. + // Read libcrt include path from the libcrt crate (via cargo metadata). + let libcrt_include_dir = + std::env::var("DEP_CRT_INCLUDE_DIR").expect("DEP_CRT_INCLUDE_DIR not set"); + + // Build libtcgtpm. libcrt comes from the libcrt crate. let mut cmd = Command::new("make"); + cmd.arg(format!("LIBCRT_INCLUDE_DIR={libcrt_include_dir}")); if target_os != "none" { cmd.arg("USE_LIBCRT=0"); } @@ -41,7 +46,7 @@ fn main() { .use_core() .clang_arg("-Wno-incompatible-library-redeclaration") .clang_arg("-nostdinc") - .clang_arg("-isystemdeps/libcrt/include/") + .clang_arg(format!("-isystem{libcrt_include_dir}")) .clang_arg("-fno-pie") // libcrt.h hides symbols if pie is enabled .clang_arg("-Ideps/tpm-20-ref/TPMCmd/tpm/include") .clang_arg("-Ideps/TpmConfiguration") @@ -69,10 +74,7 @@ fn main() { println!("cargo:rustc-link-search={out_dir}/openssl-build"); println!("cargo:rustc-link-lib=crypto"); - if target_os == "none" { - println!("cargo:rustc-link-search={out_dir}/libcrt-build"); - println!("cargo:rustc-link-lib=crt"); - } + // libcrt is linked by the libcrt crate at link time. // Tell cargo not to rerun the build-script unless anything in this // directory changes. diff --git a/libtcgtpm/deps/libcrt/Makefile b/libtcgtpm/deps/libcrt/Makefile deleted file mode 100644 index 7826d273dd..0000000000 --- a/libtcgtpm/deps/libcrt/Makefile +++ /dev/null @@ -1,113 +0,0 @@ -# SPDX-License-Identifier: MIT - -ifdef RELEASE -CFLAGS = -O3 -else -CFLAGS = -g -O0 -endif - -SRC_DIR := $(dir $(realpath $(lastword $(MAKEFILE_LIST)))) -OUT_DIR ?= $(SRC_DIR) - -CFLAGS += -I$(SRC_DIR)/include -nostdinc -nostdlib -mno-red-zone -CFLAGS += -m64 -march=x86-64 -mno-sse2 -fPIE -CFLAGS += -fno-stack-protector -CFLAGS += -ffreestanding -CFLAGS += -Wall -Werror - -CC = gcc - -vpath %.c $(SRC_DIR) -vpath %.s $(SRC_DIR) - -# Functions we stub out -OBJS = $(OUT_DIR)/src/stub.o - -# ctype -OBJS += $(addprefix $(OUT_DIR)/src/ctype/, \ - isdigit.o \ - islower.o \ - isspace.o \ - isupper.o \ - tolower.o \ - toupper.o \ - ) -# exit -OBJS += $(OUT_DIR)/src/exit/assert.o - -# prng -OBJS += $(OUT_DIR)/src/prng/rand.o - -# setjmp -OBJS += $(addprefix $(OUT_DIR)/src/setjmp/x86_64/, \ - longjmp.o \ - setjmp.o \ - ) -# stdio -OBJS += $(addprefix $(OUT_DIR)/src/stdio/, \ - asprintf.o \ - fprintf.o \ - printf.o \ - printf_wrapper.o \ - snprintf.o \ - sprintf.o \ - vasprintf.o \ - vsnprintf.o \ - vsprintf.o \ - ) -# stdlib -OBJS += $(addprefix $(OUT_DIR)/src/stdlib/, \ - atoi.o \ - qsort.o \ - qsort_nr.o \ - ) -# string -OBJS += $(addprefix $(OUT_DIR)/src/string/, \ - memchr.o \ - memcmp.o \ - memcpy.o \ - memmove.o \ - memrchr.o \ - memset.o \ - stpcpy.o \ - stpncpy.o \ - strcasecmp.o \ - strcat.o \ - strchr.o \ - strchrnul.o \ - strcmp.o \ - strcspn.o \ - strcpy.o \ - strdup.o \ - strlen.o \ - strncasecmp.o \ - strncat.o \ - strncmp.o \ - strncpy.o \ - strrchr.o \ - strspn.o \ - strstr.o \ - ) -# time -OBJS += $(addprefix $(OUT_DIR)/src/time/, \ - __secs_to_tm.o \ - gmtime_r.o \ - time.o \ - ) - -all: $(OUT_DIR)/libcrt.a - -$(OUT_DIR)/libcrt.a: $(OBJS) - ar rcs $@ $(OBJS) - -$(OUT_DIR)/%.o : %.c - @mkdir -p $(dir $@) - $(CC) $(CFLAGS) -c -o $@ $< - -$(OUT_DIR)/%.o : %.s - @mkdir -p $(dir $@) - $(CC) $(CFLAGS) -c -o $@ $< - -clean: - rm -f $(OUT_DIR)/libcrt.a - rm -f $(OBJS) diff --git a/libtcgtpm/deps/libcrt/include/assert.h b/libtcgtpm/deps/libcrt/include/assert.h deleted file mode 100644 index bbfe5d4940..0000000000 --- a/libtcgtpm/deps/libcrt/include/assert.h +++ /dev/null @@ -1,3 +0,0 @@ -/* SPDX-License-Identifier: MIT */ - -#include diff --git a/libtcgtpm/deps/libcrt/include/atomic.h b/libtcgtpm/deps/libcrt/include/atomic.h deleted file mode 100644 index 5198189049..0000000000 --- a/libtcgtpm/deps/libcrt/include/atomic.h +++ /dev/null @@ -1,335 +0,0 @@ -/* SPDX-License-Identifier: MIT */ - -#ifndef _ATOMIC_H -#define _ATOMIC_H - -#include - -#include - -#ifdef a_ll - -#ifndef a_pre_llsc -#define a_pre_llsc() -#endif - -#ifndef a_post_llsc -#define a_post_llsc() -#endif - -#ifndef a_cas -#define a_cas a_cas -static inline int a_cas(volatile int *p, int t, int s) -{ - int old; - a_pre_llsc(); - do old = a_ll(p); - while (old==t && !a_sc(p, s)); - a_post_llsc(); - return old; -} -#endif - -#ifndef a_swap -#define a_swap a_swap -static inline int a_swap(volatile int *p, int v) -{ - int old; - a_pre_llsc(); - do old = a_ll(p); - while (!a_sc(p, v)); - a_post_llsc(); - return old; -} -#endif - -#ifndef a_fetch_add -#define a_fetch_add a_fetch_add -static inline int a_fetch_add(volatile int *p, int v) -{ - int old; - a_pre_llsc(); - do old = a_ll(p); - while (!a_sc(p, (unsigned)old + v)); - a_post_llsc(); - return old; -} -#endif - -#ifndef a_fetch_and -#define a_fetch_and a_fetch_and -static inline int a_fetch_and(volatile int *p, int v) -{ - int old; - a_pre_llsc(); - do old = a_ll(p); - while (!a_sc(p, old & v)); - a_post_llsc(); - return old; -} -#endif - -#ifndef a_fetch_or -#define a_fetch_or a_fetch_or -static inline int a_fetch_or(volatile int *p, int v) -{ - int old; - a_pre_llsc(); - do old = a_ll(p); - while (!a_sc(p, old | v)); - a_post_llsc(); - return old; -} -#endif - -#endif - -#ifdef a_ll_p - -#ifndef a_cas_p -#define a_cas_p a_cas_p -static inline void *a_cas_p(volatile void *p, void *t, void *s) -{ - void *old; - a_pre_llsc(); - do old = a_ll_p(p); - while (old==t && !a_sc_p(p, s)); - a_post_llsc(); - return old; -} -#endif - -#endif - -#ifndef a_cas -#error missing definition of a_cas -#endif - -#ifndef a_swap -#define a_swap a_swap -static inline int a_swap(volatile int *p, int v) -{ - int old; - do old = *p; - while (a_cas(p, old, v) != old); - return old; -} -#endif - -#ifndef a_fetch_add -#define a_fetch_add a_fetch_add -static inline int a_fetch_add(volatile int *p, int v) -{ - int old; - do old = *p; - while (a_cas(p, old, (unsigned)old+v) != old); - return old; -} -#endif - -#ifndef a_fetch_and -#define a_fetch_and a_fetch_and -static inline int a_fetch_and(volatile int *p, int v) -{ - int old; - do old = *p; - while (a_cas(p, old, old&v) != old); - return old; -} -#endif -#ifndef a_fetch_or -#define a_fetch_or a_fetch_or -static inline int a_fetch_or(volatile int *p, int v) -{ - int old; - do old = *p; - while (a_cas(p, old, old|v) != old); - return old; -} -#endif - -#ifndef a_and -#define a_and a_and -static inline void a_and(volatile int *p, int v) -{ - a_fetch_and(p, v); -} -#endif - -#ifndef a_or -#define a_or a_or -static inline void a_or(volatile int *p, int v) -{ - a_fetch_or(p, v); -} -#endif - -#ifndef a_inc -#define a_inc a_inc -static inline void a_inc(volatile int *p) -{ - a_fetch_add(p, 1); -} -#endif - -#ifndef a_dec -#define a_dec a_dec -static inline void a_dec(volatile int *p) -{ - a_fetch_add(p, -1); -} -#endif - -#ifndef a_store -#define a_store a_store -static inline void a_store(volatile int *p, int v) -{ -#ifdef a_barrier - a_barrier(); - *p = v; - a_barrier(); -#else - a_swap(p, v); -#endif -} -#endif - -#ifndef a_barrier -#define a_barrier a_barrier -static void a_barrier() -{ - volatile int tmp = 0; - a_cas(&tmp, 0, 0); -} -#endif - -#ifndef a_spin -#define a_spin a_barrier -#endif - -#ifndef a_and_64 -#define a_and_64 a_and_64 -static inline void a_and_64(volatile uint64_t *p, uint64_t v) -{ - union { uint64_t v; uint32_t r[2]; } u = { v }; - if (u.r[0]+1) a_and((int *)p, u.r[0]); - if (u.r[1]+1) a_and((int *)p+1, u.r[1]); -} -#endif - -#ifndef a_or_64 -#define a_or_64 a_or_64 -static inline void a_or_64(volatile uint64_t *p, uint64_t v) -{ - union { uint64_t v; uint32_t r[2]; } u = { v }; - if (u.r[0]) a_or((int *)p, u.r[0]); - if (u.r[1]) a_or((int *)p+1, u.r[1]); -} -#endif - -#ifndef a_cas_p -typedef char a_cas_p_undefined_but_pointer_not_32bit[-sizeof(char) == 0xffffffff ? 1 : -1]; -#define a_cas_p a_cas_p -static inline void *a_cas_p(volatile void *p, void *t, void *s) -{ - return (void *)a_cas((volatile int *)p, (int)t, (int)s); -} -#endif - -#ifndef a_or_l -#define a_or_l a_or_l -static inline void a_or_l(volatile void *p, long v) -{ - if (sizeof(long) == sizeof(int)) a_or(p, v); - else a_or_64(p, v); -} -#endif - -#ifndef a_crash -#define a_crash a_crash -static inline void a_crash() -{ - *(volatile char *)0=0; -} -#endif - -#ifndef a_ctz_32 -#define a_ctz_32 a_ctz_32 -static inline int a_ctz_32(uint32_t x) -{ -#ifdef a_clz_32 - return 31-a_clz_32(x&-x); -#else - static const char debruijn32[32] = { - 0, 1, 23, 2, 29, 24, 19, 3, 30, 27, 25, 11, 20, 8, 4, 13, - 31, 22, 28, 18, 26, 10, 7, 12, 21, 17, 9, 6, 16, 5, 15, 14 - }; - return debruijn32[(x&-x)*0x076be629 >> 27]; -#endif -} -#endif - -#ifndef a_ctz_64 -#define a_ctz_64 a_ctz_64 -static inline int a_ctz_64(uint64_t x) -{ - static const char debruijn64[64] = { - 0, 1, 2, 53, 3, 7, 54, 27, 4, 38, 41, 8, 34, 55, 48, 28, - 62, 5, 39, 46, 44, 42, 22, 9, 24, 35, 59, 56, 49, 18, 29, 11, - 63, 52, 6, 26, 37, 40, 33, 47, 61, 45, 43, 21, 23, 58, 17, 10, - 51, 25, 36, 32, 60, 20, 57, 16, 50, 31, 19, 15, 30, 14, 13, 12 - }; - if (sizeof(long) < 8) { - uint32_t y = x; - if (!y) { - y = x>>32; - return 32 + a_ctz_32(y); - } - return a_ctz_32(y); - } - return debruijn64[(x&-x)*0x022fdd63cc95386dull >> 58]; -} -#endif - -static inline int a_ctz_l(unsigned long x) -{ - return (sizeof(long) < 8) ? a_ctz_32(x) : a_ctz_64(x); -} - -#ifndef a_clz_64 -#define a_clz_64 a_clz_64 -static inline int a_clz_64(uint64_t x) -{ -#ifdef a_clz_32 - if (x>>32) - return a_clz_32(x>>32); - return a_clz_32(x) + 32; -#else - uint32_t y; - int r; - if (x>>32) y=x>>32, r=0; else y=x, r=32; - if (y>>16) y>>=16; else r |= 16; - if (y>>8) y>>=8; else r |= 8; - if (y>>4) y>>=4; else r |= 4; - if (y>>2) y>>=2; else r |= 2; - return r | !(y>>1); -#endif -} -#endif - -#ifndef a_clz_32 -#define a_clz_32 a_clz_32 -static inline int a_clz_32(uint32_t x) -{ - x >>= 1; - x |= x >> 1; - x |= x >> 2; - x |= x >> 4; - x |= x >> 8; - x |= x >> 16; - x++; - return 31-a_ctz_32(x); -} -#endif - -#endif diff --git a/libtcgtpm/deps/libcrt/include/bits/alltypes.h b/libtcgtpm/deps/libcrt/include/bits/alltypes.h deleted file mode 100644 index 56d4713382..0000000000 --- a/libtcgtpm/deps/libcrt/include/bits/alltypes.h +++ /dev/null @@ -1,417 +0,0 @@ -/* SPDX-License-Identifier: MIT */ - -#define _Addr long -#define _Int64 long -#define _Reg long - -#define __BYTE_ORDER 1234 -#define __LONG_MAX 0x7fffffffffffffffL - -#ifndef __cplusplus -#if defined(__NEED_wchar_t) && !defined(__DEFINED_wchar_t) -typedef int wchar_t; -#define __DEFINED_wchar_t -#endif - -#endif - -#if defined(__FLT_EVAL_METHOD__) && __FLT_EVAL_METHOD__ == 2 -#if defined(__NEED_float_t) && !defined(__DEFINED_float_t) -typedef long double float_t; -#define __DEFINED_float_t -#endif - -#if defined(__NEED_double_t) && !defined(__DEFINED_double_t) -typedef long double double_t; -#define __DEFINED_double_t -#endif - -#else -#if defined(__NEED_float_t) && !defined(__DEFINED_float_t) -typedef float float_t; -#define __DEFINED_float_t -#endif - -#if defined(__NEED_double_t) && !defined(__DEFINED_double_t) -typedef double double_t; -#define __DEFINED_double_t -#endif - -#endif - -#if defined(__NEED_max_align_t) && !defined(__DEFINED_max_align_t) -typedef struct { long long __ll; long double __ld; } max_align_t; -#define __DEFINED_max_align_t -#endif - -#define __LITTLE_ENDIAN 1234 -#define __BIG_ENDIAN 4321 -#define __USE_TIME_BITS64 1 - -#if defined(__NEED_size_t) && !defined(__DEFINED_size_t) -typedef unsigned _Addr size_t; -#define __DEFINED_size_t -#endif - -#if defined(__NEED_uintptr_t) && !defined(__DEFINED_uintptr_t) -typedef unsigned _Addr uintptr_t; -#define __DEFINED_uintptr_t -#endif - -#if defined(__NEED_ptrdiff_t) && !defined(__DEFINED_ptrdiff_t) -typedef _Addr ptrdiff_t; -#define __DEFINED_ptrdiff_t -#endif - -#if defined(__NEED_ssize_t) && !defined(__DEFINED_ssize_t) -typedef _Addr ssize_t; -#define __DEFINED_ssize_t -#endif - -#if defined(__NEED_intptr_t) && !defined(__DEFINED_intptr_t) -typedef _Addr intptr_t; -#define __DEFINED_intptr_t -#endif - -#if defined(__NEED_regoff_t) && !defined(__DEFINED_regoff_t) -typedef _Addr regoff_t; -#define __DEFINED_regoff_t -#endif - -#if defined(__NEED_register_t) && !defined(__DEFINED_register_t) -typedef _Reg register_t; -#define __DEFINED_register_t -#endif - -#if defined(__NEED_time_t) && !defined(__DEFINED_time_t) -typedef _Int64 time_t; -#define __DEFINED_time_t -#endif - -#if defined(__NEED_suseconds_t) && !defined(__DEFINED_suseconds_t) -typedef _Int64 suseconds_t; -#define __DEFINED_suseconds_t -#endif - - -#if defined(__NEED_int8_t) && !defined(__DEFINED_int8_t) -typedef signed char int8_t; -#define __DEFINED_int8_t -#endif - -#if defined(__NEED_int16_t) && !defined(__DEFINED_int16_t) -typedef signed short int16_t; -#define __DEFINED_int16_t -#endif - -#if defined(__NEED_int32_t) && !defined(__DEFINED_int32_t) -typedef signed int int32_t; -#define __DEFINED_int32_t -#endif - -#if defined(__NEED_int64_t) && !defined(__DEFINED_int64_t) -typedef signed _Int64 int64_t; -#define __DEFINED_int64_t -#endif - -#if defined(__NEED_intmax_t) && !defined(__DEFINED_intmax_t) -typedef signed _Int64 intmax_t; -#define __DEFINED_intmax_t -#endif - -#if defined(__NEED_uint8_t) && !defined(__DEFINED_uint8_t) -typedef unsigned char uint8_t; -#define __DEFINED_uint8_t -#endif - -#if defined(__NEED_uint16_t) && !defined(__DEFINED_uint16_t) -typedef unsigned short uint16_t; -#define __DEFINED_uint16_t -#endif - -#if defined(__NEED_uint32_t) && !defined(__DEFINED_uint32_t) -typedef unsigned int uint32_t; -#define __DEFINED_uint32_t -#endif - -#if defined(__NEED_uint64_t) && !defined(__DEFINED_uint64_t) -typedef unsigned _Int64 uint64_t; -#define __DEFINED_uint64_t -#endif - -#if defined(__NEED_u_int64_t) && !defined(__DEFINED_u_int64_t) -typedef unsigned _Int64 u_int64_t; -#define __DEFINED_u_int64_t -#endif - -#if defined(__NEED_uintmax_t) && !defined(__DEFINED_uintmax_t) -typedef unsigned _Int64 uintmax_t; -#define __DEFINED_uintmax_t -#endif - - -#if defined(__NEED_mode_t) && !defined(__DEFINED_mode_t) -typedef unsigned mode_t; -#define __DEFINED_mode_t -#endif - -#if defined(__NEED_nlink_t) && !defined(__DEFINED_nlink_t) -typedef unsigned _Reg nlink_t; -#define __DEFINED_nlink_t -#endif - -#if defined(__NEED_off_t) && !defined(__DEFINED_off_t) -typedef _Int64 off_t; -#define __DEFINED_off_t -#endif - -#if defined(__NEED_ino_t) && !defined(__DEFINED_ino_t) -typedef unsigned _Int64 ino_t; -#define __DEFINED_ino_t -#endif - -#if defined(__NEED_dev_t) && !defined(__DEFINED_dev_t) -typedef unsigned _Int64 dev_t; -#define __DEFINED_dev_t -#endif - -#if defined(__NEED_blksize_t) && !defined(__DEFINED_blksize_t) -typedef long blksize_t; -#define __DEFINED_blksize_t -#endif - -#if defined(__NEED_blkcnt_t) && !defined(__DEFINED_blkcnt_t) -typedef _Int64 blkcnt_t; -#define __DEFINED_blkcnt_t -#endif - -#if defined(__NEED_fsblkcnt_t) && !defined(__DEFINED_fsblkcnt_t) -typedef unsigned _Int64 fsblkcnt_t; -#define __DEFINED_fsblkcnt_t -#endif - -#if defined(__NEED_fsfilcnt_t) && !defined(__DEFINED_fsfilcnt_t) -typedef unsigned _Int64 fsfilcnt_t; -#define __DEFINED_fsfilcnt_t -#endif - - -#if defined(__NEED_wint_t) && !defined(__DEFINED_wint_t) -typedef unsigned wint_t; -#define __DEFINED_wint_t -#endif - -#if defined(__NEED_wctype_t) && !defined(__DEFINED_wctype_t) -typedef unsigned long wctype_t; -#define __DEFINED_wctype_t -#endif - - -#if defined(__NEED_timer_t) && !defined(__DEFINED_timer_t) -typedef void * timer_t; -#define __DEFINED_timer_t -#endif - -#if defined(__NEED_clockid_t) && !defined(__DEFINED_clockid_t) -typedef int clockid_t; -#define __DEFINED_clockid_t -#endif - -#if defined(__NEED_clock_t) && !defined(__DEFINED_clock_t) -typedef long clock_t; -#define __DEFINED_clock_t -#endif - -#if defined(__NEED_struct_timeval) && !defined(__DEFINED_struct_timeval) -struct timeval { time_t tv_sec; suseconds_t tv_usec; }; -#define __DEFINED_struct_timeval -#endif - -#if defined(__NEED_struct_timespec) && !defined(__DEFINED_struct_timespec) -struct timespec { time_t tv_sec; int :8*(sizeof(time_t)-sizeof(long))*(__BYTE_ORDER==4321); long tv_nsec; int :8*(sizeof(time_t)-sizeof(long))*(__BYTE_ORDER!=4321); }; -#define __DEFINED_struct_timespec -#endif - - -#if defined(__NEED_pid_t) && !defined(__DEFINED_pid_t) -typedef int pid_t; -#define __DEFINED_pid_t -#endif - -#if defined(__NEED_id_t) && !defined(__DEFINED_id_t) -typedef unsigned id_t; -#define __DEFINED_id_t -#endif - -#if defined(__NEED_uid_t) && !defined(__DEFINED_uid_t) -typedef unsigned uid_t; -#define __DEFINED_uid_t -#endif - -#if defined(__NEED_gid_t) && !defined(__DEFINED_gid_t) -typedef unsigned gid_t; -#define __DEFINED_gid_t -#endif - -#if defined(__NEED_key_t) && !defined(__DEFINED_key_t) -typedef int key_t; -#define __DEFINED_key_t -#endif - -#if defined(__NEED_useconds_t) && !defined(__DEFINED_useconds_t) -typedef unsigned useconds_t; -#define __DEFINED_useconds_t -#endif - - -#ifdef __cplusplus -#if defined(__NEED_pthread_t) && !defined(__DEFINED_pthread_t) -typedef unsigned long pthread_t; -#define __DEFINED_pthread_t -#endif - -#else -#if defined(__NEED_pthread_t) && !defined(__DEFINED_pthread_t) -typedef struct __pthread * pthread_t; -#define __DEFINED_pthread_t -#endif - -#endif -#if defined(__NEED_pthread_once_t) && !defined(__DEFINED_pthread_once_t) -typedef int pthread_once_t; -#define __DEFINED_pthread_once_t -#endif - -#if defined(__NEED_pthread_key_t) && !defined(__DEFINED_pthread_key_t) -typedef unsigned pthread_key_t; -#define __DEFINED_pthread_key_t -#endif - -#if defined(__NEED_pthread_spinlock_t) && !defined(__DEFINED_pthread_spinlock_t) -typedef int pthread_spinlock_t; -#define __DEFINED_pthread_spinlock_t -#endif - -#if defined(__NEED_pthread_mutexattr_t) && !defined(__DEFINED_pthread_mutexattr_t) -typedef struct { unsigned __attr; } pthread_mutexattr_t; -#define __DEFINED_pthread_mutexattr_t -#endif - -#if defined(__NEED_pthread_condattr_t) && !defined(__DEFINED_pthread_condattr_t) -typedef struct { unsigned __attr; } pthread_condattr_t; -#define __DEFINED_pthread_condattr_t -#endif - -#if defined(__NEED_pthread_barrierattr_t) && !defined(__DEFINED_pthread_barrierattr_t) -typedef struct { unsigned __attr; } pthread_barrierattr_t; -#define __DEFINED_pthread_barrierattr_t -#endif - -#if defined(__NEED_pthread_rwlockattr_t) && !defined(__DEFINED_pthread_rwlockattr_t) -typedef struct { unsigned __attr[2]; } pthread_rwlockattr_t; -#define __DEFINED_pthread_rwlockattr_t -#endif - - -#if defined(__NEED_struct__IO_FILE) && !defined(__DEFINED_struct__IO_FILE) -struct _IO_FILE { char __x; }; -#define __DEFINED_struct__IO_FILE -#endif - -#if defined(__NEED_FILE) && !defined(__DEFINED_FILE) -typedef struct _IO_FILE FILE; -#define __DEFINED_FILE -#endif - - -#if defined(__NEED_va_list) && !defined(__DEFINED_va_list) -typedef __builtin_va_list va_list; -#define __DEFINED_va_list -#endif - -#if defined(__NEED___isoc_va_list) && !defined(__DEFINED___isoc_va_list) -typedef __builtin_va_list __isoc_va_list; -#define __DEFINED___isoc_va_list -#endif - - -#if defined(__NEED_mbstate_t) && !defined(__DEFINED_mbstate_t) -typedef struct __mbstate_t { unsigned __opaque1, __opaque2; } mbstate_t; -#define __DEFINED_mbstate_t -#endif - - -#if defined(__NEED_locale_t) && !defined(__DEFINED_locale_t) -typedef struct __locale_struct * locale_t; -#define __DEFINED_locale_t -#endif - - -#if defined(__NEED_sigset_t) && !defined(__DEFINED_sigset_t) -typedef struct __sigset_t { unsigned long __bits[128/sizeof(long)]; } sigset_t; -#define __DEFINED_sigset_t -#endif - - -#if defined(__NEED_struct_iovec) && !defined(__DEFINED_struct_iovec) -struct iovec { void *iov_base; size_t iov_len; }; -#define __DEFINED_struct_iovec -#endif - - -#if defined(__NEED_struct_winsize) && !defined(__DEFINED_struct_winsize) -struct winsize { unsigned short ws_row, ws_col, ws_xpixel, ws_ypixel; }; -#define __DEFINED_struct_winsize -#endif - - -#if defined(__NEED_socklen_t) && !defined(__DEFINED_socklen_t) -typedef unsigned socklen_t; -#define __DEFINED_socklen_t -#endif - -#if defined(__NEED_sa_family_t) && !defined(__DEFINED_sa_family_t) -typedef unsigned short sa_family_t; -#define __DEFINED_sa_family_t -#endif - - -#if defined(__NEED_pthread_attr_t) && !defined(__DEFINED_pthread_attr_t) -typedef struct { union { int __i[sizeof(long)==8?14:9]; volatile int __vi[sizeof(long)==8?14:9]; unsigned long __s[sizeof(long)==8?7:9]; } __u; } pthread_attr_t; -#define __DEFINED_pthread_attr_t -#endif - -#if defined(__NEED_pthread_mutex_t) && !defined(__DEFINED_pthread_mutex_t) -typedef struct { union { int __i[sizeof(long)==8?10:6]; volatile int __vi[sizeof(long)==8?10:6]; volatile void *volatile __p[sizeof(long)==8?5:6]; } __u; } pthread_mutex_t; -#define __DEFINED_pthread_mutex_t -#endif - -#if defined(__NEED_mtx_t) && !defined(__DEFINED_mtx_t) -typedef struct { union { int __i[sizeof(long)==8?10:6]; volatile int __vi[sizeof(long)==8?10:6]; volatile void *volatile __p[sizeof(long)==8?5:6]; } __u; } mtx_t; -#define __DEFINED_mtx_t -#endif - -#if defined(__NEED_pthread_cond_t) && !defined(__DEFINED_pthread_cond_t) -typedef struct { union { int __i[12]; volatile int __vi[12]; void *__p[12*sizeof(int)/sizeof(void*)]; } __u; } pthread_cond_t; -#define __DEFINED_pthread_cond_t -#endif - -#if defined(__NEED_cnd_t) && !defined(__DEFINED_cnd_t) -typedef struct { union { int __i[12]; volatile int __vi[12]; void *__p[12*sizeof(int)/sizeof(void*)]; } __u; } cnd_t; -#define __DEFINED_cnd_t -#endif - -#if defined(__NEED_pthread_rwlock_t) && !defined(__DEFINED_pthread_rwlock_t) -typedef struct { union { int __i[sizeof(long)==8?14:8]; volatile int __vi[sizeof(long)==8?14:8]; void *__p[sizeof(long)==8?7:8]; } __u; } pthread_rwlock_t; -#define __DEFINED_pthread_rwlock_t -#endif - -#if defined(__NEED_pthread_barrier_t) && !defined(__DEFINED_pthread_barrier_t) -typedef struct { union { int __i[sizeof(long)==8?8:5]; volatile int __vi[sizeof(long)==8?8:5]; void *__p[sizeof(long)==8?4:5]; } __u; } pthread_barrier_t; -#define __DEFINED_pthread_barrier_t -#endif - - -#undef _Addr -#undef _Int64 -#undef _Reg diff --git a/libtcgtpm/deps/libcrt/include/bits/atomic_arch.h b/libtcgtpm/deps/libcrt/include/bits/atomic_arch.h deleted file mode 100644 index 5809f8e52f..0000000000 --- a/libtcgtpm/deps/libcrt/include/bits/atomic_arch.h +++ /dev/null @@ -1,125 +0,0 @@ -/* SPDX-License-Identifier: MIT */ - -#define a_cas a_cas -static inline int a_cas(volatile int *p, int t, int s) -{ - __asm__ __volatile__ ( - "lock ; cmpxchg %3, %1" - : "=a"(t), "=m"(*p) : "a"(t), "r"(s) : "memory" ); - return t; -} - -#define a_cas_p a_cas_p -static inline void *a_cas_p(volatile void *p, void *t, void *s) -{ - __asm__( "lock ; cmpxchg %3, %1" - : "=a"(t), "=m"(*(void *volatile *)p) - : "a"(t), "r"(s) : "memory" ); - return t; -} - -#define a_swap a_swap -static inline int a_swap(volatile int *p, int v) -{ - __asm__ __volatile__( - "xchg %0, %1" - : "=r"(v), "=m"(*p) : "0"(v) : "memory" ); - return v; -} - -#define a_fetch_add a_fetch_add -static inline int a_fetch_add(volatile int *p, int v) -{ - __asm__ __volatile__( - "lock ; xadd %0, %1" - : "=r"(v), "=m"(*p) : "0"(v) : "memory" ); - return v; -} - -#define a_and a_and -static inline void a_and(volatile int *p, int v) -{ - __asm__ __volatile__( - "lock ; and %1, %0" - : "=m"(*p) : "r"(v) : "memory" ); -} - -#define a_or a_or -static inline void a_or(volatile int *p, int v) -{ - __asm__ __volatile__( - "lock ; or %1, %0" - : "=m"(*p) : "r"(v) : "memory" ); -} - -#define a_and_64 a_and_64 -static inline void a_and_64(volatile uint64_t *p, uint64_t v) -{ - __asm__ __volatile( - "lock ; and %1, %0" - : "=m"(*p) : "r"(v) : "memory" ); -} - -#define a_or_64 a_or_64 -static inline void a_or_64(volatile uint64_t *p, uint64_t v) -{ - __asm__ __volatile__( - "lock ; or %1, %0" - : "=m"(*p) : "r"(v) : "memory" ); -} - -#define a_inc a_inc -static inline void a_inc(volatile int *p) -{ - __asm__ __volatile__( - "lock ; incl %0" - : "=m"(*p) : "m"(*p) : "memory" ); -} - -#define a_dec a_dec -static inline void a_dec(volatile int *p) -{ - __asm__ __volatile__( - "lock ; decl %0" - : "=m"(*p) : "m"(*p) : "memory" ); -} - -#define a_store a_store -static inline void a_store(volatile int *p, int x) -{ - __asm__ __volatile__( - "mov %1, %0 ; lock ; orl $0,(%%rsp)" - : "=m"(*p) : "r"(x) : "memory" ); -} - -#define a_barrier a_barrier -static inline void a_barrier() -{ - __asm__ __volatile__( "" : : : "memory" ); -} - -#define a_spin a_spin -static inline void a_spin() -{ - __asm__ __volatile__( "pause" : : : "memory" ); -} - -#define a_crash a_crash -static inline void a_crash() -{ - __asm__ __volatile__( "hlt" : : : "memory" ); -} - -#define a_ctz_64 a_ctz_64 -static inline int a_ctz_64(uint64_t x) -{ - __asm__( "bsf %1,%0" : "=r"(x) : "r"(x) ); - return x; -} - -#define a_clz_64 a_clz_64 -static inline int a_clz_64(uint64_t x) -{ - __asm__( "bsr %1,%0 ; xor $63,%0" : "=r"(x) : "r"(x) ); - return x; -} diff --git a/libtcgtpm/deps/libcrt/include/ctype.h b/libtcgtpm/deps/libcrt/include/ctype.h deleted file mode 100644 index bbfe5d4940..0000000000 --- a/libtcgtpm/deps/libcrt/include/ctype.h +++ /dev/null @@ -1,3 +0,0 @@ -/* SPDX-License-Identifier: MIT */ - -#include diff --git a/libtcgtpm/deps/libcrt/include/dirent.h b/libtcgtpm/deps/libcrt/include/dirent.h deleted file mode 100644 index bbfe5d4940..0000000000 --- a/libtcgtpm/deps/libcrt/include/dirent.h +++ /dev/null @@ -1,3 +0,0 @@ -/* SPDX-License-Identifier: MIT */ - -#include diff --git a/libtcgtpm/deps/libcrt/include/endian.h b/libtcgtpm/deps/libcrt/include/endian.h deleted file mode 100644 index bbfe5d4940..0000000000 --- a/libtcgtpm/deps/libcrt/include/endian.h +++ /dev/null @@ -1,3 +0,0 @@ -/* SPDX-License-Identifier: MIT */ - -#include diff --git a/libtcgtpm/deps/libcrt/include/errno.h b/libtcgtpm/deps/libcrt/include/errno.h deleted file mode 100644 index bbfe5d4940..0000000000 --- a/libtcgtpm/deps/libcrt/include/errno.h +++ /dev/null @@ -1,3 +0,0 @@ -/* SPDX-License-Identifier: MIT */ - -#include diff --git a/libtcgtpm/deps/libcrt/include/fcntl.h b/libtcgtpm/deps/libcrt/include/fcntl.h deleted file mode 100644 index bbfe5d4940..0000000000 --- a/libtcgtpm/deps/libcrt/include/fcntl.h +++ /dev/null @@ -1,3 +0,0 @@ -/* SPDX-License-Identifier: MIT */ - -#include diff --git a/libtcgtpm/deps/libcrt/include/inttypes.h b/libtcgtpm/deps/libcrt/include/inttypes.h deleted file mode 100644 index bbfe5d4940..0000000000 --- a/libtcgtpm/deps/libcrt/include/inttypes.h +++ /dev/null @@ -1,3 +0,0 @@ -/* SPDX-License-Identifier: MIT */ - -#include diff --git a/libtcgtpm/deps/libcrt/include/libcrt.h b/libtcgtpm/deps/libcrt/include/libcrt.h deleted file mode 100644 index 9d7447628f..0000000000 --- a/libtcgtpm/deps/libcrt/include/libcrt.h +++ /dev/null @@ -1,408 +0,0 @@ -/* SPDX-License-Identifier: MIT */ - -#ifndef __LIBCRT_H__ -#define __LIBCRT_H__ - -// The SVSM guids are expected to be the last bytes of the svsm.bin file. When -// we set the external dependencies symbols to be hidden, we prevent them from -// being preempted. Otherwise, the SVSM guids will not be the last bytes of the -// svsm.bin. -#if defined(__pie__) -#pragma GCC visibility push (hidden) -#endif - -// features.h - -#define _Noreturn __attribute__((__noreturn__)) - -#define hidden __attribute__((__visibility__("hidden"))) -#define weak_alias(old, new) \ - extern __typeof(old) new __attribute__((__weak__, __alias__(#old))) - -// All types required - -#define __NEED_va_list - -#define __NEED_int8_t -#define __NEED_int16_t -#define __NEED_int32_t -#define __NEED_int64_t - -#define __NEED_uint8_t -#define __NEED_uint16_t -#define __NEED_uint32_t -#define __NEED_uint64_t - -#define __NEED_intptr_t -#define __NEED_uintptr_t -#define __NEED_size_t -#define __NEED_ssize_t -#define __NEED_ptrdiff_t -#define __NEED_wchar_t - -#define __NEED_intmax_t -#define __NEED_uintmax_t - -#define __NEED_time_t -#define __NEED_clock_t -#define __NEED_clockid_t -#define __NEED_struct_timespec - -#define __NEED_pid_t -#define __NEED_FILE -#define __NEED_struct__IO_FILE - -#define __NEED_dev_t -#define __NEED_ino_t -#define __NEED_mode_t -#define __NEED_nlink_t -#define __NEED_uid_t -#define __NEED_gid_t -#define __NEED_off_t -#define __NEED_blksize_t -#define __NEED_blkcnt_t - -#define __NEED_useconds_t - -#include - -// errno.h - -extern int errno; -#define EINTR 4 -#define ENOMEM 12 -#define EINVAL 22 -#define ENOSYS 38 -#define EAFNOSUPPORT 47 -#define EOVERFLOW 75 - -// stddef.h - -#ifndef NULL -#define NULL ((void *) 0) -#endif - -#define offsetof(type, member) __builtin_offsetof(type, member) - -// stdbool.h - -#define true 1 -#define false 0 -#define bool _Bool - -// stdint.h - -#define INT8_MIN (-1-0x7f) -#define INT16_MIN (-1-0x7fff) -#define INT32_MIN (-1-0x7fffffff) -#define INT64_MIN (-1-0x7fffffffffffffff) - -#define INT8_MAX (0x7f) -#define INT16_MAX (0x7fff) -#define INT32_MAX (0x7fffffff) -#define INT64_MAX (0x7fffffffffffffff) - -#define UINT8_MAX (0xff) -#define UINT16_MAX (0xffff) -#define UINT32_MAX (0xffffffffu) -#define UINT64_MAX (0xffffffffffffffffu) - -// limits.h - -#define UCHAR_MAX 255 -#define SSIZE_MAX 0xFFFFFFFFFFFFFFFFU -#define INT_MIN (-1-0x7fffffff) -#define INT_MAX 0x7fffffff -#define LONG_MIN (-LONG_MAX-1) -#define LONG_MAX __LONG_MAX -#define UINT_MAX 0xffffffffU -#define ULONG_MAX (2UL*LONG_MAX+1) -#define CHAR_BIT 8 - -// atomic.h - -// Check the atomic.h file for the atomic definitions. It is a busy file with -// lots of inline functions and it also includes architecture dependent code. - -// stdarg.h - -#define va_start(v,l) __builtin_va_start(v,l) -#define va_end(v) __builtin_va_end(v) -#define va_arg(v,l) __builtin_va_arg(v,l) -#define va_copy(d,s) __builtin_va_copy(d,s) - -// unistd.h - -#define STDERR_FILENO 2 -#define SEEK_SET 0 -#define SEEK_CUR 1 -#define SEEK_END 2 - -pid_t getpid(void); -uid_t getuid(void); -uid_t geteuid(void); -gid_t getgid(void); -gid_t getegid(void); -int issetugid(void); - -int getentropy(void *buffer, size_t length); -long syscall(long number, ...); -int usleep(useconds_t usec); -unsigned int sleep(unsigned int seconds); - -// stdio.h - -#define EOF (-1) -#define BUFSIZ 8192 -void setbuf(FILE *stream, char *buf); -int printf(const char *restrict fmt, ...); -int dprintf(int fd, const char *__restrict fmt, ...); -int vdprintf(int fd, const char *restrict fmt, va_list ap); -int puts(const char *s); -int fprintf(FILE *restrict f, const char *restrict fmt, ...); -int asprintf(char **s, const char *fmt, ...); -int snprintf(char *restrict s, size_t n, const char *restrict fmt, ...); -int sprintf(char *restrict s, const char *restrict fmt, ...); -int vasprintf(char **s, const char *fmt, va_list ap); -int vsnprintf(char *restrict s, size_t n, const char *restrict fmt, va_list ap); -int vsprintf(char *restrict s, const char *restrict fmt, va_list ap); - -int vprints(const char *format, va_list ap); -int vsnprints(char *str, size_t size, const char *format, va_list ap); - -// Functions exported by the SVSM -extern void serial_out(const char *s, int len); - -// stdlib.h - -// Functions exported by the SVSM -extern void *malloc(size_t size); -extern void *realloc(void *ptr, size_t size); -extern void *calloc(size_t nmemb, size_t size); -extern void free(void *ptr); -extern _Noreturn void abort(void); - -int atoi(const char *s); -int atexit(void (*func)(void)); - -void qsort(void *, size_t, size_t, int (*)(const void *, const void *)); -void qsort_r(void *, size_t, size_t, int (*)(const void *, const void *, void *), void *); -void __qsort_r(void *, size_t, size_t, int (*)(const void *, const void *, void *), void *); - -char *getenv(const char *); - -int rand(void); -void srand(unsigned s); - -// time.h - -#define CLOCK_MONOTONIC 1 - -struct tm { - int tm_sec; /* seconds after the minute [0-60] */ - int tm_min; /* minutes after the hour [0-59] */ - int tm_hour; /* hours since midnight [0-23] */ - int tm_mday; /* day of the month [1-31] */ - int tm_mon; /* months since January [0-11] */ - int tm_year; /* years since 1900 */ - int tm_wday; /* days since Sunday [0-6] */ - int tm_yday; /* days since January 1 [0-365] */ - int tm_isdst; /* Daylight Savings Time flag */ - long tm_gmtoff; /* offset from CUT in seconds */ - char *tm_zone; /* timezone abbreviation */ -}; - -struct timeval { - long tv_sec; /* time value, in seconds */ - long tv_usec; /* time value, in microseconds */ -}; - -char *ctime(const time_t *t); -time_t time(time_t *); -struct tm *gmtime(const time_t *); -struct tm *gmtime_r(const time_t *restrict t, struct tm *restrict tm); -clock_t clock(void); -int clock_gettime(clockid_t clk_id, struct timespec *tp); -int gettimeofday(struct timeval *restrict tv, void *restrict tz); -int __secs_to_tm(long long t, struct tm *tm); -time_t mktime(struct tm *tm); - -extern int timezone; - -#define DECLARE_ARGS(val, low, high) unsigned long low, high -#define EAX_EDX_VAL(val, low, high) ((low) | (high) << 32) -#define EAX_EDX_RET(val, low, high) "=a" (low), "=d" (high) - -static inline unsigned long long rdtsc(void) -{ - DECLARE_ARGS(val, low, high); - asm volatile("rdtsc" : EAX_EDX_RET(val, low, high)); - return EAX_EDX_VAL(val, low, high); -} - -// inttypes.h - -#if UINTPTR_MAX == UINT64_MAX -#define __PRI64 "l" -#define __PRIPTR "l" -#else -#define __PRI64 "ll" -#define __PRIPTR "" -#endif - -#define PRIu8 "u" -#define PRIu16 "u" -#define PRIu32 "u" -#define PRIu64 __PRI64 "u" - -// dirent.h - -typedef struct __dirstream DIR; - -struct dirent { - ino_t d_ino; - off_t d_off; - unsigned short d_reclen; - unsigned char d_type; - char d_name[256]; -}; - -DIR *opendir(const char *name); -int closedir(DIR *name); -struct dirent *readdir(DIR *name); - -typedef unsigned long __jmp_buf[8]; - -typedef struct __jmp_buf_tag { - __jmp_buf __jb; - unsigned long __fl; - unsigned long __ss[128/sizeof(long)]; -} jmp_buf[1]; - -#define __setjmp_attr __attribute__((__returns_twice__)) - -// sys/stat.h - -#define S_IFDIR 0040000 -#define S_IFMT 0170000 - -#define S_ISDIR(mode) (((mode) & S_IFMT) == S_IFDIR) - -/* copied from kernel definition, but with padding replaced - * by the corresponding correctly-sized userspace types. */ -struct stat { - dev_t st_dev; - ino_t st_ino; - nlink_t st_nlink; - - mode_t st_mode; - uid_t st_uid; - gid_t st_gid; - unsigned int __pad0; - dev_t st_rdev; - off_t st_size; - blksize_t st_blksize; - blkcnt_t st_blocks; - - struct timespec st_atim; - struct timespec st_mtim; - struct timespec st_ctim; - long __unused[3]; -}; - -int stat(const char *__restrict path, struct stat *restrict buf); - -// string.h - -void *memset(void *, int, size_t); -int memcmp(const void *, const void *, size_t); -void *memcpy(void *restrict dest, const void *restrict src, size_t n); -void *memchr(const void *src, int c, size_t n); -void *memmove(void *dest, const void *src, size_t n); -void *memrchr(const void *m, int c, size_t n); -void *__memrchr(const void *m, int c, size_t n); - -int strcmp(const char *, const char *); -int strncasecmp(const char *, const char *, size_t); -char *strchr(const char *, int); -char *strrchr(const char *, int); -unsigned long strtoul(const char *, char **, int); -long strtol(const char *, char **, int); -char *strerror(int); -size_t strspn(const char *, const char *); -size_t strcspn(const char *, const char *); - -char *strcpy(char *strDest, const char *strSource); -size_t strlen(const char *s); -char *__strchrnul(const char *s, int c); -char *__stpcpy(char *restrict d, const char *restrict s); -char *__stpncpy(char *restrict d, const char *restrict s, size_t n); -char *strstr(const char *h, const char *n); -char *strdup(const char *s); -char *strncpy(char *restrict d, const char *restrict s, size_t n); -int strncmp(const char *_l, const char *_r, size_t n); -int strcasecmp(const char *_l, const char *_r); -char *strcat(char *restrict dest, const char *restrict src); -char *strncat (char *__restrict, const char *__restrict, size_t); -char *strpbrk(const char *s, const char *accept); - -// ctype.h - -int isdigit(int c); -int isspace(int c); -int isupper(int c); -int isascii(int c); -int islower(int c); - -int tolower(int c); -int toupper(int c); - -// stdio.h - -int printf(const char *, ...); -int sscanf(const char *, const char *, ...); - -FILE *fopen(const char *, const char *); -int fclose(FILE *); -size_t fread(void *, size_t, size_t, FILE *); -size_t fwrite(const void *buffer, size_t size, size_t count, FILE *stream); -int fprintf(FILE *, const char *, ...); -int fputc(int c, FILE *f); -int fseek(FILE *stream, long offset, int whence); -long ftell(FILE *stream); -int fflush(FILE *stream); - -int ferror(FILE *stream); -int clearerr(FILE *stream); - -int vasprintf(char **s, const char *fmt, va_list ap); -int asprintf(char **s, const char *fmt, ...); -int vsnprintf(char *restrict s, size_t n, const char *restrict fmt, va_list ap); -int vsprintf(char *restrict s, const char *restrict fmt, va_list ap); -int snprintf(char *restrict s, size_t n, const char *restrict fmt, ...); -int sprintf(char *restrict s, const char *restrict fmt, ...); -int dprintf(int fd, const char *__restrict fmt, ...); -int vdprintf(int fd, const char *restrict fmt, va_list ap); - -// inet.h - -int inet_pton(int, const char *, void *); - -// setjmp.h - -int setjmp (jmp_buf) __setjmp_attr; -_Noreturn void longjmp (jmp_buf, int); - -// assert.h - -#define assert(x) ((void)((x) || (__assert_fail(#x, __FILE__, __LINE__, __func__),0))) -_Noreturn void __assert_fail (const char *, const char *, int, const char *); - -// select.h -#define FD_SETSIZE 1024 -typedef unsigned long fd_mask; -typedef struct { - unsigned long fds_bits[FD_SETSIZE / 8 / sizeof(long)]; -} fd_set; - -#endif diff --git a/libtcgtpm/deps/libcrt/include/limits.h b/libtcgtpm/deps/libcrt/include/limits.h deleted file mode 100644 index bbfe5d4940..0000000000 --- a/libtcgtpm/deps/libcrt/include/limits.h +++ /dev/null @@ -1,3 +0,0 @@ -/* SPDX-License-Identifier: MIT */ - -#include diff --git a/libtcgtpm/deps/libcrt/include/memory.h b/libtcgtpm/deps/libcrt/include/memory.h deleted file mode 100644 index bbfe5d4940..0000000000 --- a/libtcgtpm/deps/libcrt/include/memory.h +++ /dev/null @@ -1,3 +0,0 @@ -/* SPDX-License-Identifier: MIT */ - -#include diff --git a/libtcgtpm/deps/libcrt/include/setjmp.h b/libtcgtpm/deps/libcrt/include/setjmp.h deleted file mode 100644 index bbfe5d4940..0000000000 --- a/libtcgtpm/deps/libcrt/include/setjmp.h +++ /dev/null @@ -1,3 +0,0 @@ -/* SPDX-License-Identifier: MIT */ - -#include diff --git a/libtcgtpm/deps/libcrt/include/stdarg.h b/libtcgtpm/deps/libcrt/include/stdarg.h deleted file mode 100644 index bbfe5d4940..0000000000 --- a/libtcgtpm/deps/libcrt/include/stdarg.h +++ /dev/null @@ -1,3 +0,0 @@ -/* SPDX-License-Identifier: MIT */ - -#include diff --git a/libtcgtpm/deps/libcrt/include/stdatomic.h b/libtcgtpm/deps/libcrt/include/stdatomic.h deleted file mode 100644 index bbfe5d4940..0000000000 --- a/libtcgtpm/deps/libcrt/include/stdatomic.h +++ /dev/null @@ -1,3 +0,0 @@ -/* SPDX-License-Identifier: MIT */ - -#include diff --git a/libtcgtpm/deps/libcrt/include/stdbool.h b/libtcgtpm/deps/libcrt/include/stdbool.h deleted file mode 100644 index bbfe5d4940..0000000000 --- a/libtcgtpm/deps/libcrt/include/stdbool.h +++ /dev/null @@ -1,3 +0,0 @@ -/* SPDX-License-Identifier: MIT */ - -#include diff --git a/libtcgtpm/deps/libcrt/include/stddef.h b/libtcgtpm/deps/libcrt/include/stddef.h deleted file mode 100644 index bbfe5d4940..0000000000 --- a/libtcgtpm/deps/libcrt/include/stddef.h +++ /dev/null @@ -1,3 +0,0 @@ -/* SPDX-License-Identifier: MIT */ - -#include diff --git a/libtcgtpm/deps/libcrt/include/stdint.h b/libtcgtpm/deps/libcrt/include/stdint.h deleted file mode 100644 index bbfe5d4940..0000000000 --- a/libtcgtpm/deps/libcrt/include/stdint.h +++ /dev/null @@ -1,3 +0,0 @@ -/* SPDX-License-Identifier: MIT */ - -#include diff --git a/libtcgtpm/deps/libcrt/include/stdio.h b/libtcgtpm/deps/libcrt/include/stdio.h deleted file mode 100644 index bbfe5d4940..0000000000 --- a/libtcgtpm/deps/libcrt/include/stdio.h +++ /dev/null @@ -1,3 +0,0 @@ -/* SPDX-License-Identifier: MIT */ - -#include diff --git a/libtcgtpm/deps/libcrt/include/stdlib.h b/libtcgtpm/deps/libcrt/include/stdlib.h deleted file mode 100644 index bbfe5d4940..0000000000 --- a/libtcgtpm/deps/libcrt/include/stdlib.h +++ /dev/null @@ -1,3 +0,0 @@ -/* SPDX-License-Identifier: MIT */ - -#include diff --git a/libtcgtpm/deps/libcrt/include/string.h b/libtcgtpm/deps/libcrt/include/string.h deleted file mode 100644 index bbfe5d4940..0000000000 --- a/libtcgtpm/deps/libcrt/include/string.h +++ /dev/null @@ -1,3 +0,0 @@ -/* SPDX-License-Identifier: MIT */ - -#include diff --git a/libtcgtpm/deps/libcrt/include/strings.h b/libtcgtpm/deps/libcrt/include/strings.h deleted file mode 100644 index bbfe5d4940..0000000000 --- a/libtcgtpm/deps/libcrt/include/strings.h +++ /dev/null @@ -1,3 +0,0 @@ -/* SPDX-License-Identifier: MIT */ - -#include diff --git a/libtcgtpm/deps/libcrt/include/sys/shm.h b/libtcgtpm/deps/libcrt/include/sys/shm.h deleted file mode 100644 index bbfe5d4940..0000000000 --- a/libtcgtpm/deps/libcrt/include/sys/shm.h +++ /dev/null @@ -1,3 +0,0 @@ -/* SPDX-License-Identifier: MIT */ - -#include diff --git a/libtcgtpm/deps/libcrt/include/sys/stat.h b/libtcgtpm/deps/libcrt/include/sys/stat.h deleted file mode 100644 index bbfe5d4940..0000000000 --- a/libtcgtpm/deps/libcrt/include/sys/stat.h +++ /dev/null @@ -1,3 +0,0 @@ -/* SPDX-License-Identifier: MIT */ - -#include diff --git a/libtcgtpm/deps/libcrt/include/sys/syscall.h b/libtcgtpm/deps/libcrt/include/sys/syscall.h deleted file mode 100644 index bbfe5d4940..0000000000 --- a/libtcgtpm/deps/libcrt/include/sys/syscall.h +++ /dev/null @@ -1,3 +0,0 @@ -/* SPDX-License-Identifier: MIT */ - -#include diff --git a/libtcgtpm/deps/libcrt/include/sys/time.h b/libtcgtpm/deps/libcrt/include/sys/time.h deleted file mode 100644 index bbfe5d4940..0000000000 --- a/libtcgtpm/deps/libcrt/include/sys/time.h +++ /dev/null @@ -1,3 +0,0 @@ -/* SPDX-License-Identifier: MIT */ - -#include diff --git a/libtcgtpm/deps/libcrt/include/sys/types.h b/libtcgtpm/deps/libcrt/include/sys/types.h deleted file mode 100644 index bbfe5d4940..0000000000 --- a/libtcgtpm/deps/libcrt/include/sys/types.h +++ /dev/null @@ -1,3 +0,0 @@ -/* SPDX-License-Identifier: MIT */ - -#include diff --git a/libtcgtpm/deps/libcrt/include/sys/utsname.h b/libtcgtpm/deps/libcrt/include/sys/utsname.h deleted file mode 100644 index bbfe5d4940..0000000000 --- a/libtcgtpm/deps/libcrt/include/sys/utsname.h +++ /dev/null @@ -1,3 +0,0 @@ -/* SPDX-License-Identifier: MIT */ - -#include diff --git a/libtcgtpm/deps/libcrt/include/time.h b/libtcgtpm/deps/libcrt/include/time.h deleted file mode 100644 index bbfe5d4940..0000000000 --- a/libtcgtpm/deps/libcrt/include/time.h +++ /dev/null @@ -1,3 +0,0 @@ -/* SPDX-License-Identifier: MIT */ - -#include diff --git a/libtcgtpm/deps/libcrt/include/unistd.h b/libtcgtpm/deps/libcrt/include/unistd.h deleted file mode 100644 index bbfe5d4940..0000000000 --- a/libtcgtpm/deps/libcrt/include/unistd.h +++ /dev/null @@ -1,3 +0,0 @@ -/* SPDX-License-Identifier: MIT */ - -#include diff --git a/libtcgtpm/deps/libcrt/src/ctype/isascii.c b/libtcgtpm/deps/libcrt/src/ctype/isascii.c deleted file mode 100644 index 14da4dcc23..0000000000 --- a/libtcgtpm/deps/libcrt/src/ctype/isascii.c +++ /dev/null @@ -1,8 +0,0 @@ -/* SPDX-License-Identifier: MIT */ - -#include - -int isascii(int c) -{ - return !(c&~0x7f); -} diff --git a/libtcgtpm/deps/libcrt/src/ctype/isdigit.c b/libtcgtpm/deps/libcrt/src/ctype/isdigit.c deleted file mode 100644 index 2860cc9d3f..0000000000 --- a/libtcgtpm/deps/libcrt/src/ctype/isdigit.c +++ /dev/null @@ -1,6 +0,0 @@ -#include - -int isdigit(int c) -{ - return (unsigned)c-'0' < 10; -} diff --git a/libtcgtpm/deps/libcrt/src/ctype/islower.c b/libtcgtpm/deps/libcrt/src/ctype/islower.c deleted file mode 100644 index 228823be92..0000000000 --- a/libtcgtpm/deps/libcrt/src/ctype/islower.c +++ /dev/null @@ -1,8 +0,0 @@ -/* SPDX-License-Identifier: MIT */ - -#include - -int islower(int c) -{ - return (unsigned)c-'a' < 26; -} diff --git a/libtcgtpm/deps/libcrt/src/ctype/isspace.c b/libtcgtpm/deps/libcrt/src/ctype/isspace.c deleted file mode 100644 index 7d2a8ebcfc..0000000000 --- a/libtcgtpm/deps/libcrt/src/ctype/isspace.c +++ /dev/null @@ -1,8 +0,0 @@ -/* SPDX-License-Identifier: MIT */ - -#include - -int isspace(int c) -{ - return c == ' ' || (unsigned)c-'\t' < 5; -} diff --git a/libtcgtpm/deps/libcrt/src/ctype/isupper.c b/libtcgtpm/deps/libcrt/src/ctype/isupper.c deleted file mode 100644 index 6b507ef931..0000000000 --- a/libtcgtpm/deps/libcrt/src/ctype/isupper.c +++ /dev/null @@ -1,8 +0,0 @@ -/* SPDX-License-Identifier: MIT */ - -#include - -int isupper(int c) -{ - return (unsigned)c-'A' < 26; -} diff --git a/libtcgtpm/deps/libcrt/src/ctype/tolower.c b/libtcgtpm/deps/libcrt/src/ctype/tolower.c deleted file mode 100644 index fb4b7635b9..0000000000 --- a/libtcgtpm/deps/libcrt/src/ctype/tolower.c +++ /dev/null @@ -1,9 +0,0 @@ -/* SPDX-License-Identifier: MIT */ - -#include - -int tolower(int c) -{ - if (isupper(c)) return c | 32; - return c; -} diff --git a/libtcgtpm/deps/libcrt/src/ctype/toupper.c b/libtcgtpm/deps/libcrt/src/ctype/toupper.c deleted file mode 100644 index aa55481963..0000000000 --- a/libtcgtpm/deps/libcrt/src/ctype/toupper.c +++ /dev/null @@ -1,9 +0,0 @@ -/* SPDX-License-Identifier: MIT */ - -#include - -int toupper(int c) -{ - if (islower(c)) return c & 0x5f; - return c; -} diff --git a/libtcgtpm/deps/libcrt/src/exit/assert.c b/libtcgtpm/deps/libcrt/src/exit/assert.c deleted file mode 100644 index f243c8e0f9..0000000000 --- a/libtcgtpm/deps/libcrt/src/exit/assert.c +++ /dev/null @@ -1,10 +0,0 @@ -/* SPDX-License-Identifier: MIT */ - -#include -#include - -void __assert_fail(const char *expr, const char *file, int line, const char *func) -{ - printf("Assertion failed: %s (%s: %s: %d)\n", expr, file, func, line); - abort(); -} diff --git a/libtcgtpm/deps/libcrt/src/prng/rand.c b/libtcgtpm/deps/libcrt/src/prng/rand.c deleted file mode 100644 index 0fc09358b1..0000000000 --- a/libtcgtpm/deps/libcrt/src/prng/rand.c +++ /dev/null @@ -1,151 +0,0 @@ -/* SPDX-License-Identifier: MIT */ - -#include -#include -#include -#include -#include - -/* - * In the AMD64 Programmer's Manual Volume 3, the RDRAND and RDRAND - * instructions suggests that software should implement a retry limit - * to ensure forward progress of code. - */ -const uint32_t RDSEED_RETRIES = 1024; -const uint32_t RDRAND_RETRIES = 1024; - -static uint64_t seed; - -void srand(unsigned s) -{ - seed = s - 1; -} - -static inline int rdrand32(uint32_t *rnd) -{ - unsigned char ok; - - __asm__ volatile("rdrand %0; setc %1":"=r"(*rnd), "=qm"(ok)); - if (!ok) { - uint32_t retry = 0; - while (retry < RDRAND_RETRIES) { - __asm__ volatile("rdrand %0; setc %1":"=r"(*rnd), "=qm"(ok)); - if (ok) - goto rc_success; - retry++; - } - printf("%s: failed %d times\n", __func__, retry); - return -1; - } - -rc_success: - return 0; -} - -static inline int rdrand64(uint64_t *rnd) -{ - unsigned char ok; - - __asm__ volatile("rdrand %0; setc %1":"=r"(*rnd), "=qm"(ok)); - if (!ok) { - uint32_t retry = 0; - while (retry < RDRAND_RETRIES) { - __asm__ volatile("rdrand %0; setc %1":"=r"(*rnd), "=qm"(ok)); - if (ok) - goto rc_success; - retry++; - } - printf("%s: failed %d times\n", __func__, retry); - return -1; - } - -rc_success: - return 0; -} - -static inline int rdseed32(uint32_t *rnd) -{ - unsigned char ok; - - __asm__ volatile("rdseed %0; setc %1":"=r"(*rnd), "=qm"(ok)); - if (!ok) { - uint32_t retry = 0; - while (retry < RDSEED_RETRIES) { - __asm__ volatile("rdseed %0; setc %1":"=r"(*rnd), "=qm"(ok)); - if (ok) - goto rc_success; - retry++; - } - printf("%s: failed %d times\n", __func__, retry); - return -1; - } - -rc_success: - return 0; -} - -static inline int rdseed64(uint64_t *rnd) -{ - unsigned char ok; - - __asm__ volatile("rdseed %0; setc %1":"=r"(*rnd), "=qm"(ok)); - if (!ok) { - uint32_t retry = 0; - while (retry < RDSEED_RETRIES) { - __asm__ volatile("rdseed %0; setc %1":"=r"(*rnd), "=qm"(ok)); - if (ok) - goto rc_success; - retry++; - } - printf("%s: failed %d times\n", __func__, retry); - return -1; - } - -rc_success: - return 0; -} - -int rand(void) -{ - uint32_t r = 0; - if (rdrand32(&r)) { - if (rdseed32(&r)) { - printf("ERROR: %s: RDRAND and RDSEED failed reaching the retry count\n", __func__); - abort(); - } - } - return r; -} - -int getentropy(void *buffer, size_t length) -{ - char *b; - uint64_t r; - uint64_t *a; - size_t i, bytes_remaining; - - i = 0; - b = buffer; - - while (i < length) { - r = 0; - if (rdseed64(&r)) { - if (rdrand64(&r)) { - printf("ERROR: %s: RDRAND and RDSEED failed reaching the retry count\n", __func__); - return -1; - } - } - - bytes_remaining = length - i; - - if (bytes_remaining < sizeof(uint64_t)) { - memcpy(&b[i], &r, bytes_remaining); - i += bytes_remaining; - } else { - a = (uint64_t *)&b[i]; - *a = r; - i += sizeof(uint64_t); - } - } - return 0; -} diff --git a/libtcgtpm/deps/libcrt/src/setjmp/x86_64/longjmp.s b/libtcgtpm/deps/libcrt/src/setjmp/x86_64/longjmp.s deleted file mode 100644 index 845a4e933c..0000000000 --- a/libtcgtpm/deps/libcrt/src/setjmp/x86_64/longjmp.s +++ /dev/null @@ -1,20 +0,0 @@ -/* SPDX-License-Identifier: MIT */ -/* Copyright 2011-2012 Nicholas J. Kain, licensed under standard MIT license */ - -.global _longjmp -.global longjmp -.type _longjmp,@function -.type longjmp,@function -_longjmp: -longjmp: - xor %eax,%eax - cmp $1,%esi /* CF = val ? 0 : 1 */ - adc %esi,%eax /* eax = val + !val */ - mov (%rdi),%rbx /* rdi is the jmp_buf, restore regs from it */ - mov 8(%rdi),%rbp - mov 16(%rdi),%r12 - mov 24(%rdi),%r13 - mov 32(%rdi),%r14 - mov 40(%rdi),%r15 - mov 48(%rdi),%rsp - jmp *56(%rdi) /* goto saved address without altering rsp */ diff --git a/libtcgtpm/deps/libcrt/src/setjmp/x86_64/setjmp.s b/libtcgtpm/deps/libcrt/src/setjmp/x86_64/setjmp.s deleted file mode 100644 index 64d6e9df4e..0000000000 --- a/libtcgtpm/deps/libcrt/src/setjmp/x86_64/setjmp.s +++ /dev/null @@ -1,24 +0,0 @@ -/* SPDX-License-Identifier: MIT */ -/* Copyright 2011-2012 Nicholas J. Kain, licensed under standard MIT license */ - -.global __setjmp -.global _setjmp -.global setjmp -.type __setjmp,@function -.type _setjmp,@function -.type setjmp,@function -__setjmp: -_setjmp: -setjmp: - mov %rbx,(%rdi) /* rdi is jmp_buf, move registers onto it */ - mov %rbp,8(%rdi) - mov %r12,16(%rdi) - mov %r13,24(%rdi) - mov %r14,32(%rdi) - mov %r15,40(%rdi) - lea 8(%rsp),%rdx /* this is our rsp WITHOUT current ret addr */ - mov %rdx,48(%rdi) - mov (%rsp),%rdx /* save return addr ptr for new rip */ - mov %rdx,56(%rdi) - xor %eax,%eax /* always return 0 */ - ret diff --git a/libtcgtpm/deps/libcrt/src/stdio/asprintf.c b/libtcgtpm/deps/libcrt/src/stdio/asprintf.c deleted file mode 100644 index 71a150d9e2..0000000000 --- a/libtcgtpm/deps/libcrt/src/stdio/asprintf.c +++ /dev/null @@ -1,14 +0,0 @@ -/* SPDX-License-Identifier: MIT */ - -#include -#include - -int asprintf(char **s, const char *fmt, ...) -{ - int ret; - va_list ap; - va_start(ap, fmt); - ret = vasprintf(s, fmt, ap); - va_end(ap); - return ret; -} diff --git a/libtcgtpm/deps/libcrt/src/stdio/fprintf.c b/libtcgtpm/deps/libcrt/src/stdio/fprintf.c deleted file mode 100644 index 549bcc3f49..0000000000 --- a/libtcgtpm/deps/libcrt/src/stdio/fprintf.c +++ /dev/null @@ -1,14 +0,0 @@ -/* SPDX-License-Identifier: MIT */ - -#include -#include - -int fprintf(FILE *restrict f, const char *restrict fmt, ...) -{ - int ret; - va_list ap; - va_start(ap, fmt); - ret = vprints(fmt, ap); - va_end(ap); - return ret; -} diff --git a/libtcgtpm/deps/libcrt/src/stdio/printf.c b/libtcgtpm/deps/libcrt/src/stdio/printf.c deleted file mode 100644 index 998148b087..0000000000 --- a/libtcgtpm/deps/libcrt/src/stdio/printf.c +++ /dev/null @@ -1,34 +0,0 @@ -/* SPDX-License-Identifier: MIT */ - -#include -#include - -int printf(const char *restrict fmt, ...) -{ - int ret; - va_list ap; - va_start(ap, fmt); - ret = vprints(fmt, ap); - va_end(ap); - return ret; -} - -int dprintf(int fd, const char *__restrict fmt, ...) -{ - int ret; - va_list ap; - va_start(ap, fmt); - ret = vprints(fmt, ap); - va_end(ap); - return ret; -} - -int vdprintf(int fd, const char *restrict fmt, va_list ap) -{ - return vprints(fmt, ap); -} - -int puts(const char *s) -{ - return printf("%s\n", s); -} diff --git a/libtcgtpm/deps/libcrt/src/stdio/printf_wrapper.c b/libtcgtpm/deps/libcrt/src/stdio/printf_wrapper.c deleted file mode 100644 index 6e3eab6a4b..0000000000 --- a/libtcgtpm/deps/libcrt/src/stdio/printf_wrapper.c +++ /dev/null @@ -1,269 +0,0 @@ -/* SPDX-License-Identifier: MIT */ - -#include -#include -#include - -enum { - LEN_MOD_INVALID = 0, - LEN_MOD_HALF_HALF, - LEN_MOD_HALF, - LEN_MOD_INT, - LEN_MOD_LONG, - LEN_MOD_LONG_LONG, - LEN_MOD_MAX -}; - -static char *format_string(char *cur, char *end, va_list ap) -{ - char *tmp = va_arg(ap, char *); - - while (*tmp) { - if (cur < end) - *cur = *tmp; - cur++; - tmp++; - } - - return cur; -} - -static char *format_base16(char *cur, char *end, int width, va_list ap) -{ - unsigned long long num; - char *tmp, buffer[32]; - unsigned int size; - char *map; - - map = "0123456789abcdef"; - - if (cur < end) - *cur++ = '0'; - if (cur < end) - *cur++ = 'x'; - - if (width == LEN_MOD_HALF_HALF) { - unsigned char n = (unsigned char) va_arg(ap, int); - num = (unsigned long long)n; - size = 1; - } else if (width == LEN_MOD_HALF) { - unsigned short n = (unsigned short) va_arg(ap, int); - num = (unsigned long long)n; - size = 2; - } else if (width == LEN_MOD_INT) { - unsigned int n = (unsigned int) va_arg(ap, int); - num = (unsigned long long)n; - size = 4; - } else if (width == LEN_MOD_LONG) { - unsigned long n = (unsigned long) va_arg(ap, long); - num = (unsigned long long)n; - size = 8; - } else { - unsigned long long n = (unsigned long long) va_arg(ap, long long); - num = (unsigned long long)n; - size = 8; - } - - tmp = buffer + sizeof(buffer); - - tmp--; - *tmp = '\0'; - while (size--) { - tmp--; - *tmp = map[num & 0xf]; - num >>= 4; - - tmp--; - *tmp = map[num & 0xf]; - num >>= 4; - } - - while (*tmp) { - if (cur < end) - *cur = *tmp; - cur++; - tmp++; - } - - return cur; -} - -static char *format_base10(char *cur, char *end, int width, bool signed_format, va_list ap) -{ - unsigned long long num; - char *tmp, buffer[32]; - - if (width == LEN_MOD_HALF_HALF) { - unsigned char n = (unsigned char) va_arg(ap, int); - if (signed_format && (char)n < 0) { - if (cur < end) - *cur++ = '-'; - n = -(char)n; - } - num = (unsigned long long)n; - } else if (width == LEN_MOD_HALF) { - unsigned short n = (unsigned short) va_arg(ap, int); - if (signed_format && (short)n < 0) { - if (cur < end) - *cur++ = '-'; - n = -(short)n; - } - num = (unsigned long long)n; - } else if (width == LEN_MOD_INT) { - unsigned int n = (unsigned int) va_arg(ap, int); - if (signed_format && (int)n < 0) { - if (cur < end) - *cur++ = '-'; - n = -(int)n; - } - num = (unsigned long long)n; - } else if (width == LEN_MOD_LONG) { - unsigned long n = (unsigned long) va_arg(ap, long); - if (signed_format && (long)n < 0) { - if (cur < end) - *cur++ = '-'; - n = -(long)n; - } - num = (unsigned long long)n; - } else { - unsigned long long n = (unsigned long long) va_arg(ap, long long); - if (signed_format && (long long)n < 0) { - if (cur < end) - *cur++ = '-'; - n = -(long long)n; - } - num = (unsigned long long)n; - } - - tmp = buffer + sizeof(buffer); - - tmp--; - *tmp = '\0'; - do { - tmp--; - *tmp = (char)('0' + num % 10); - - num /= 10; - } while (num); - - while (*tmp) { - if (cur < end) - *cur = *tmp; - - cur++; - tmp++; - } - - return cur; -} - -int vsnprints(char *str, size_t size, const char *format, va_list ap) -{ - unsigned int width = LEN_MOD_INVALID; - char *cur, *end; - bool convert; - - cur = str; - end = cur + size; - if (end < cur) { - end = (void *)-1; - size = end - cur; - } - - convert = false; - while (*format) { - if (!convert) { - if (*format != '%') { - if (cur < end) - *cur = *format; - - cur++; - format++; - continue; - } - - format++; - if (*format == '%') { - if (cur < end) - *cur = '%'; - - cur++; - format++; - continue; - } - - convert = true; - width = LEN_MOD_INT; - } else { - bool signed_format = false; - - switch (*format) { - case 'h': - width--; - if (width == LEN_MOD_INVALID) - convert = false; - break; - case 'l': - width++; - if (width == LEN_MOD_MAX) - convert = false; - break; - case 'd': - signed_format = true; - case 'z': - // handle %zu - if (*(format+1) && *(format+1) == 'u' ) - format++; - case 'u': - cur = format_base10(cur, end, width, signed_format, ap); - convert = false; - break; - case 'p': - width = LEN_MOD_LONG; - case 'x': - cur = format_base16(cur, end, width, ap); - convert = false; - break; - case 's': { - cur = format_string(cur, end, ap); - convert = false; - break; - } - default: - convert = false; - } - - format++; - } - } - - if (size) { - if (cur < end) - *cur = '\0'; - else - *(end - 1) = '\0'; - } - - return cur - str; -} - -// A format string is converted to the actual string, which is then -// truncated to PRINT_STR_MAX before printing. -#define PRINT_STR_MAX 256 - -int vprints(const char *format, va_list ap) -{ - char buffer[PRINT_STR_MAX]; - int ret; - - ret = vsnprints(buffer, sizeof(buffer), format, ap); - - if (ret >= sizeof(buffer)) { - ret = PRINT_STR_MAX; - buffer[PRINT_STR_MAX - 1] = '\0'; - } - - serial_out(buffer, ret); - - return ret; -} diff --git a/libtcgtpm/deps/libcrt/src/stdio/snprintf.c b/libtcgtpm/deps/libcrt/src/stdio/snprintf.c deleted file mode 100644 index 8a3f51aa69..0000000000 --- a/libtcgtpm/deps/libcrt/src/stdio/snprintf.c +++ /dev/null @@ -1,15 +0,0 @@ -/* SPDX-License-Identifier: MIT */ - -#include -#include - -int snprintf(char *restrict s, size_t n, const char *restrict fmt, ...) -{ - int ret; - va_list ap; - va_start(ap, fmt); - ret = vsnprintf(s, n, fmt, ap); - va_end(ap); - return ret; -} - diff --git a/libtcgtpm/deps/libcrt/src/stdio/sprintf.c b/libtcgtpm/deps/libcrt/src/stdio/sprintf.c deleted file mode 100644 index 8960560ac1..0000000000 --- a/libtcgtpm/deps/libcrt/src/stdio/sprintf.c +++ /dev/null @@ -1,14 +0,0 @@ -/* SPDX-License-Identifier: MIT */ - -#include -#include - -int sprintf(char *restrict s, const char *restrict fmt, ...) -{ - int ret; - va_list ap; - va_start(ap, fmt); - ret = vsprintf(s, fmt, ap); - va_end(ap); - return ret; -} diff --git a/libtcgtpm/deps/libcrt/src/stdio/vasprintf.c b/libtcgtpm/deps/libcrt/src/stdio/vasprintf.c deleted file mode 100644 index a0c43a30c9..0000000000 --- a/libtcgtpm/deps/libcrt/src/stdio/vasprintf.c +++ /dev/null @@ -1,16 +0,0 @@ -/* SPDX-License-Identifier: MIT */ - -#include -#include -#include - -int vasprintf(char **s, const char *fmt, va_list ap) -{ - va_list ap2; - va_copy(ap2, ap); - int l = vsnprintf(0, 0, fmt, ap2); - va_end(ap2); - - if (l<0 || !(*s=malloc(l+1U))) return -1; - return vsnprintf(*s, l+1U, fmt, ap); -} diff --git a/libtcgtpm/deps/libcrt/src/stdio/vsnprintf.c b/libtcgtpm/deps/libcrt/src/stdio/vsnprintf.c deleted file mode 100644 index 3b572f7f79..0000000000 --- a/libtcgtpm/deps/libcrt/src/stdio/vsnprintf.c +++ /dev/null @@ -1,9 +0,0 @@ -/* SPDX-License-Identifier: MIT */ - -#include -#include - -int vsnprintf(char *restrict s, size_t n, const char *restrict fmt, va_list ap) -{ - return vsnprints(s, n, fmt, ap); -} diff --git a/libtcgtpm/deps/libcrt/src/stdio/vsprintf.c b/libtcgtpm/deps/libcrt/src/stdio/vsprintf.c deleted file mode 100644 index f0691a32e2..0000000000 --- a/libtcgtpm/deps/libcrt/src/stdio/vsprintf.c +++ /dev/null @@ -1,9 +0,0 @@ -/* SPDX-License-Identifier: MIT */ - -#include -#include - -int vsprintf(char *restrict s, const char *restrict fmt, va_list ap) -{ - return vsnprintf(s, INT_MAX, fmt, ap); -} diff --git a/libtcgtpm/deps/libcrt/src/stdlib/atoi.c b/libtcgtpm/deps/libcrt/src/stdlib/atoi.c deleted file mode 100644 index 02bed169db..0000000000 --- a/libtcgtpm/deps/libcrt/src/stdlib/atoi.c +++ /dev/null @@ -1,18 +0,0 @@ -/* SPDX-License-Identifier: MIT */ - -#include -#include - -int atoi(const char *s) -{ - int n=0, neg=0; - while (isspace(*s)) s++; - switch (*s) { - case '-': neg=1; - case '+': s++; - } - /* Compute n as a negative number to avoid overflow on INT_MIN */ - while (isdigit(*s)) - n = 10*n - (*s++ - '0'); - return neg ? n : -n; -} diff --git a/libtcgtpm/deps/libcrt/src/stdlib/qsort.c b/libtcgtpm/deps/libcrt/src/stdlib/qsort.c deleted file mode 100644 index fa4ca0a3f3..0000000000 --- a/libtcgtpm/deps/libcrt/src/stdlib/qsort.c +++ /dev/null @@ -1,222 +0,0 @@ -/* Copyright (C) 2011 by Valentin Ochs - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -/* Minor changes by Rich Felker for integration in musl, 2011-04-27. */ - -/* Smoothsort, an adaptive variant of Heapsort. Memory usage: O(1). - Run time: Worst case O(n log n), close to O(n) in the mostly-sorted case. */ - -#define _BSD_SOURCE -#include -#include -#include - -#include "atomic.h" -#define ntz(x) a_ctz_l((x)) - -typedef int (*cmpfun)(const void *, const void *, void *); - -static inline int pntz(size_t p[2]) { - int r = ntz(p[0] - 1); - if(r != 0 || (r = 8*sizeof(size_t) + ntz(p[1])) != 8*sizeof(size_t)) { - return r; - } - return 0; -} - -static void cycle(size_t width, unsigned char* ar[], int n) -{ - unsigned char tmp[256]; - size_t l; - int i; - - if(n < 2) { - return; - } - - ar[n] = tmp; - while(width) { - l = sizeof(tmp) < width ? sizeof(tmp) : width; - memcpy(ar[n], ar[0], l); - for(i = 0; i < n; i++) { - memcpy(ar[i], ar[i + 1], l); - ar[i] += l; - } - width -= l; - } - ar[n] = NULL; -} - -/* shl() and shr() need n > 0 */ -static inline void shl(size_t p[2], int n) -{ - if(n >= 8 * sizeof(size_t)) { - n -= 8 * sizeof(size_t); - p[1] = p[0]; - p[0] = 0; - } - p[1] <<= n; - p[1] |= p[0] >> (sizeof(size_t) * 8 - n); - p[0] <<= n; -} - -static inline void shr(size_t p[2], int n) -{ - if(n >= 8 * sizeof(size_t)) { - n -= 8 * sizeof(size_t); - p[0] = p[1]; - p[1] = 0; - } - p[0] >>= n; - p[0] |= p[1] << (sizeof(size_t) * 8 - n); - p[1] >>= n; -} - -static void sift(unsigned char *head, size_t width, cmpfun cmp, void *arg, int pshift, size_t lp[]) -{ - unsigned char *rt, *lf; - unsigned char *ar[14 * sizeof(size_t) + 1]; - int i = 1; - - ar[0] = head; - while(pshift > 1) { - rt = head - width; - lf = head - width - lp[pshift - 2]; - - if(cmp(ar[0], lf, arg) >= 0 && cmp(ar[0], rt, arg) >= 0) { - break; - } - if(cmp(lf, rt, arg) >= 0) { - ar[i++] = lf; - head = lf; - pshift -= 1; - } else { - ar[i++] = rt; - head = rt; - pshift -= 2; - } - } - cycle(width, ar, i); -} - -static void trinkle(unsigned char *head, size_t width, cmpfun cmp, void *arg, size_t pp[2], int pshift, int trusty, size_t lp[]) -{ - unsigned char *stepson, - *rt, *lf; - size_t p[2]; - unsigned char *ar[14 * sizeof(size_t) + 1]; - int i = 1; - int trail; - - p[0] = pp[0]; - p[1] = pp[1]; - - ar[0] = head; - while(p[0] != 1 || p[1] != 0) { - stepson = head - lp[pshift]; - if(cmp(stepson, ar[0], arg) <= 0) { - break; - } - if(!trusty && pshift > 1) { - rt = head - width; - lf = head - width - lp[pshift - 2]; - if(cmp(rt, stepson, arg) >= 0 || cmp(lf, stepson, arg) >= 0) { - break; - } - } - - ar[i++] = stepson; - head = stepson; - trail = pntz(p); - shr(p, trail); - pshift += trail; - trusty = 0; - } - if(!trusty) { - cycle(width, ar, i); - sift(head, width, cmp, arg, pshift, lp); - } -} - -void __qsort_r(void *base, size_t nel, size_t width, cmpfun cmp, void *arg) -{ - size_t lp[12*sizeof(size_t)]; - size_t i, size = width * nel; - unsigned char *head, *high; - size_t p[2] = {1, 0}; - int pshift = 1; - int trail; - - if (!size) return; - - head = base; - high = head + size - width; - - /* Precompute Leonardo numbers, scaled by element width */ - for(lp[0]=lp[1]=width, i=2; (lp[i]=lp[i-2]+lp[i-1]+width) < size; i++); - - while(head < high) { - if((p[0] & 3) == 3) { - sift(head, width, cmp, arg, pshift, lp); - shr(p, 2); - pshift += 2; - } else { - if(lp[pshift - 1] >= high - head) { - trinkle(head, width, cmp, arg, p, pshift, 0, lp); - } else { - sift(head, width, cmp, arg, pshift, lp); - } - - if(pshift == 1) { - shl(p, 1); - pshift = 0; - } else { - shl(p, pshift - 1); - pshift = 1; - } - } - - p[0] |= 1; - head += width; - } - - trinkle(head, width, cmp, arg, p, pshift, 0, lp); - - while(pshift != 1 || p[0] != 1 || p[1] != 0) { - if(pshift <= 1) { - trail = pntz(p); - shr(p, trail); - pshift += trail; - } else { - shl(p, 2); - pshift -= 2; - p[0] ^= 7; - shr(p, 1); - trinkle(head - lp[pshift] - width, width, cmp, arg, p, pshift + 1, 1, lp); - shl(p, 1); - p[0] |= 1; - trinkle(head - width, width, cmp, arg, p, pshift, 1, lp); - } - head -= width; - } -} - -weak_alias(__qsort_r, qsort_r); diff --git a/libtcgtpm/deps/libcrt/src/stdlib/qsort_nr.c b/libtcgtpm/deps/libcrt/src/stdlib/qsort_nr.c deleted file mode 100644 index 46132065c1..0000000000 --- a/libtcgtpm/deps/libcrt/src/stdlib/qsort_nr.c +++ /dev/null @@ -1,16 +0,0 @@ -/* SPDX-License-Identifier: MIT */ - -#define _BSD_SOURCE -#include - -typedef int (*cmpfun)(const void *, const void *); - -static int wrapper_cmp(const void *v1, const void *v2, void *cmp) -{ - return ((cmpfun)cmp)(v1, v2); -} - -void qsort(void *base, size_t nel, size_t width, cmpfun cmp) -{ - __qsort_r(base, nel, width, wrapper_cmp, (void *)cmp); -} diff --git a/libtcgtpm/deps/libcrt/src/string/memchr.c b/libtcgtpm/deps/libcrt/src/string/memchr.c deleted file mode 100644 index 046529f009..0000000000 --- a/libtcgtpm/deps/libcrt/src/string/memchr.c +++ /dev/null @@ -1,29 +0,0 @@ -/* SPDX-License-Identifier: MIT */ - -#include -#include -#include - -#define SS (sizeof(size_t)) -#define ALIGN (sizeof(size_t)-1) -#define ONES ((size_t)-1/UCHAR_MAX) -#define HIGHS (ONES * (UCHAR_MAX/2+1)) -#define HASZERO(x) (((x)-ONES) & ~(x) & HIGHS) - -void *memchr(const void *src, int c, size_t n) -{ - const unsigned char *s = src; - c = (unsigned char)c; -#ifdef __GNUC__ - for (; ((uintptr_t)s & ALIGN) && n && *s != c; s++, n--); - if (n && *s != c) { - typedef size_t __attribute__((__may_alias__)) word; - const word *w; - size_t k = ONES * c; - for (w = (const void *)s; n>=SS && !HASZERO(*w^k); w++, n-=SS); - s = (const void *)w; - } -#endif - for (; n && *s != c; s++, n--); - return n ? (void *)s : 0; -} diff --git a/libtcgtpm/deps/libcrt/src/string/memcmp.c b/libtcgtpm/deps/libcrt/src/string/memcmp.c deleted file mode 100644 index 502ca098c0..0000000000 --- a/libtcgtpm/deps/libcrt/src/string/memcmp.c +++ /dev/null @@ -1,10 +0,0 @@ -/* SPDX-License-Identifier: MIT */ - -#include - -int memcmp(const void *vl, const void *vr, size_t n) -{ - const unsigned char *l=vl, *r=vr; - for (; n && *l == *r; n--, l++, r++); - return n ? *l-*r : 0; -} diff --git a/libtcgtpm/deps/libcrt/src/string/memcpy.c b/libtcgtpm/deps/libcrt/src/string/memcpy.c deleted file mode 100644 index cb7127ca08..0000000000 --- a/libtcgtpm/deps/libcrt/src/string/memcpy.c +++ /dev/null @@ -1,126 +0,0 @@ -/* SPDX-License-Identifier: MIT */ - -#include -#include -#include - -void *memcpy(void *restrict dest, const void *restrict src, size_t n) -{ - unsigned char *d = dest; - const unsigned char *s = src; - -#ifdef __GNUC__ - -#if __BYTE_ORDER == __LITTLE_ENDIAN -#define LS >> -#define RS << -#else -#define LS << -#define RS >> -#endif - - typedef uint32_t __attribute__((__may_alias__)) u32; - uint32_t w, x; - - for (; (uintptr_t)s % 4 && n; n--) *d++ = *s++; - - if ((uintptr_t)d % 4 == 0) { - for (; n>=16; s+=16, d+=16, n-=16) { - *(u32 *)(d+0) = *(u32 *)(s+0); - *(u32 *)(d+4) = *(u32 *)(s+4); - *(u32 *)(d+8) = *(u32 *)(s+8); - *(u32 *)(d+12) = *(u32 *)(s+12); - } - if (n&8) { - *(u32 *)(d+0) = *(u32 *)(s+0); - *(u32 *)(d+4) = *(u32 *)(s+4); - d += 8; s += 8; - } - if (n&4) { - *(u32 *)(d+0) = *(u32 *)(s+0); - d += 4; s += 4; - } - if (n&2) { - *d++ = *s++; *d++ = *s++; - } - if (n&1) { - *d = *s; - } - return dest; - } - - if (n >= 32) switch ((uintptr_t)d % 4) { - case 1: - w = *(u32 *)s; - *d++ = *s++; - *d++ = *s++; - *d++ = *s++; - n -= 3; - for (; n>=17; s+=16, d+=16, n-=16) { - x = *(u32 *)(s+1); - *(u32 *)(d+0) = (w LS 24) | (x RS 8); - w = *(u32 *)(s+5); - *(u32 *)(d+4) = (x LS 24) | (w RS 8); - x = *(u32 *)(s+9); - *(u32 *)(d+8) = (w LS 24) | (x RS 8); - w = *(u32 *)(s+13); - *(u32 *)(d+12) = (x LS 24) | (w RS 8); - } - break; - case 2: - w = *(u32 *)s; - *d++ = *s++; - *d++ = *s++; - n -= 2; - for (; n>=18; s+=16, d+=16, n-=16) { - x = *(u32 *)(s+2); - *(u32 *)(d+0) = (w LS 16) | (x RS 16); - w = *(u32 *)(s+6); - *(u32 *)(d+4) = (x LS 16) | (w RS 16); - x = *(u32 *)(s+10); - *(u32 *)(d+8) = (w LS 16) | (x RS 16); - w = *(u32 *)(s+14); - *(u32 *)(d+12) = (x LS 16) | (w RS 16); - } - break; - case 3: - w = *(u32 *)s; - *d++ = *s++; - n -= 1; - for (; n>=19; s+=16, d+=16, n-=16) { - x = *(u32 *)(s+3); - *(u32 *)(d+0) = (w LS 8) | (x RS 24); - w = *(u32 *)(s+7); - *(u32 *)(d+4) = (x LS 8) | (w RS 24); - x = *(u32 *)(s+11); - *(u32 *)(d+8) = (w LS 8) | (x RS 24); - w = *(u32 *)(s+15); - *(u32 *)(d+12) = (x LS 8) | (w RS 24); - } - break; - } - if (n&16) { - *d++ = *s++; *d++ = *s++; *d++ = *s++; *d++ = *s++; - *d++ = *s++; *d++ = *s++; *d++ = *s++; *d++ = *s++; - *d++ = *s++; *d++ = *s++; *d++ = *s++; *d++ = *s++; - *d++ = *s++; *d++ = *s++; *d++ = *s++; *d++ = *s++; - } - if (n&8) { - *d++ = *s++; *d++ = *s++; *d++ = *s++; *d++ = *s++; - *d++ = *s++; *d++ = *s++; *d++ = *s++; *d++ = *s++; - } - if (n&4) { - *d++ = *s++; *d++ = *s++; *d++ = *s++; *d++ = *s++; - } - if (n&2) { - *d++ = *s++; *d++ = *s++; - } - if (n&1) { - *d = *s; - } - return dest; -#endif - - for (; n; n--) *d++ = *s++; - return dest; -} diff --git a/libtcgtpm/deps/libcrt/src/string/memmove.c b/libtcgtpm/deps/libcrt/src/string/memmove.c deleted file mode 100644 index ab2778bcad..0000000000 --- a/libtcgtpm/deps/libcrt/src/string/memmove.c +++ /dev/null @@ -1,44 +0,0 @@ -/* SPDX-License-Identifier: MIT */ - -#include -#include - -#ifdef __GNUC__ -typedef __attribute__((__may_alias__)) size_t WT; -#define WS (sizeof(WT)) -#endif - -void *memmove(void *dest, const void *src, size_t n) -{ - char *d = dest; - const char *s = src; - - if (d==s) return d; - if ((uintptr_t)s-(uintptr_t)d-n <= -2*n) return memcpy(d, s, n); - - if (d=WS; n-=WS, d+=WS, s+=WS) *(WT *)d = *(WT *)s; - } -#endif - for (; n; n--) *d++ = *s++; - } else { -#ifdef __GNUC__ - if ((uintptr_t)s % WS == (uintptr_t)d % WS) { - while ((uintptr_t)(d+n) % WS) { - if (!n--) return dest; - d[n] = s[n]; - } - while (n>=WS) n-=WS, *(WT *)(d+n) = *(WT *)(s+n); - } -#endif - while (n) n--, d[n] = s[n]; - } - - return dest; -} diff --git a/libtcgtpm/deps/libcrt/src/string/memrchr.c b/libtcgtpm/deps/libcrt/src/string/memrchr.c deleted file mode 100644 index 61eb745cf6..0000000000 --- a/libtcgtpm/deps/libcrt/src/string/memrchr.c +++ /dev/null @@ -1,13 +0,0 @@ -/* SPDX-License-Identifier: MIT */ - -#include - -void *__memrchr(const void *m, int c, size_t n) -{ - const unsigned char *s = m; - c = (unsigned char)c; - while (n--) if (s[n]==c) return (void *)(s+n); - return 0; -} - -weak_alias(__memrchr, memrchr); diff --git a/libtcgtpm/deps/libcrt/src/string/memset.c b/libtcgtpm/deps/libcrt/src/string/memset.c deleted file mode 100644 index 36a07447e9..0000000000 --- a/libtcgtpm/deps/libcrt/src/string/memset.c +++ /dev/null @@ -1,92 +0,0 @@ -/* SPDX-License-Identifier: MIT */ - -#include -#include - -void *memset(void *dest, int c, size_t n) -{ - unsigned char *s = dest; - size_t k; - - /* Fill head and tail with minimal branching. Each - * conditional ensures that all the subsequently used - * offsets are well-defined and in the dest region. */ - - if (!n) return dest; - s[0] = c; - s[n-1] = c; - if (n <= 2) return dest; - s[1] = c; - s[2] = c; - s[n-2] = c; - s[n-3] = c; - if (n <= 6) return dest; - s[3] = c; - s[n-4] = c; - if (n <= 8) return dest; - - /* Advance pointer to align it at a 4-byte boundary, - * and truncate n to a multiple of 4. The previous code - * already took care of any head/tail that get cut off - * by the alignment. */ - - k = -(uintptr_t)s & 3; - s += k; - n -= k; - n &= -4; - -#ifdef __GNUC__ - typedef uint32_t __attribute__((__may_alias__)) u32; - typedef uint64_t __attribute__((__may_alias__)) u64; - - u32 c32 = ((u32)-1)/255 * (unsigned char)c; - - /* In preparation to copy 32 bytes at a time, aligned on - * an 8-byte bounary, fill head/tail up to 28 bytes each. - * As in the initial byte-based head/tail fill, each - * conditional below ensures that the subsequent offsets - * are valid (e.g. !(n<=24) implies n>=28). */ - - *(u32 *)(s+0) = c32; - *(u32 *)(s+n-4) = c32; - if (n <= 8) return dest; - *(u32 *)(s+4) = c32; - *(u32 *)(s+8) = c32; - *(u32 *)(s+n-12) = c32; - *(u32 *)(s+n-8) = c32; - if (n <= 24) return dest; - *(u32 *)(s+12) = c32; - *(u32 *)(s+16) = c32; - *(u32 *)(s+20) = c32; - *(u32 *)(s+24) = c32; - *(u32 *)(s+n-28) = c32; - *(u32 *)(s+n-24) = c32; - *(u32 *)(s+n-20) = c32; - *(u32 *)(s+n-16) = c32; - - /* Align to a multiple of 8 so we can fill 64 bits at a time, - * and avoid writing the same bytes twice as much as is - * practical without introducing additional branching. */ - - k = 24 + ((uintptr_t)s & 4); - s += k; - n -= k; - - /* If this loop is reached, 28 tail bytes have already been - * filled, so any remainder when n drops below 32 can be - * safely ignored. */ - - u64 c64 = c32 | ((u64)c32 << 32); - for (; n >= 32; n-=32, s+=32) { - *(u64 *)(s+0) = c64; - *(u64 *)(s+8) = c64; - *(u64 *)(s+16) = c64; - *(u64 *)(s+24) = c64; - } -#else - /* Pure C fallback with no aliasing violations. */ - for (; n; n--, s++) *s = c; -#endif - - return dest; -} diff --git a/libtcgtpm/deps/libcrt/src/string/stpcpy.c b/libtcgtpm/deps/libcrt/src/string/stpcpy.c deleted file mode 100644 index ca0191934f..0000000000 --- a/libtcgtpm/deps/libcrt/src/string/stpcpy.c +++ /dev/null @@ -1,31 +0,0 @@ -/* SPDX-License-Identifier: MIT */ - -#include -#include -#include - -#define ALIGN (sizeof(size_t)) -#define ONES ((size_t)-1/UCHAR_MAX) -#define HIGHS (ONES * (UCHAR_MAX/2+1)) -#define HASZERO(x) (((x)-ONES) & ~(x) & HIGHS) - -char *__stpcpy(char *restrict d, const char *restrict s) -{ -#ifdef __GNUC__ - typedef size_t __attribute__((__may_alias__)) word; - word *wd; - const word *ws; - if ((uintptr_t)s % ALIGN == (uintptr_t)d % ALIGN) { - for (; (uintptr_t)s % ALIGN; s++, d++) - if (!(*d=*s)) return d; - wd=(void *)d; ws=(const void *)s; - for (; !HASZERO(*ws); *wd++ = *ws++); - d=(void *)wd; s=(const void *)ws; - } -#endif - for (; (*d=*s); s++, d++); - - return d; -} - -weak_alias(__stpcpy, stpcpy); diff --git a/libtcgtpm/deps/libcrt/src/string/stpncpy.c b/libtcgtpm/deps/libcrt/src/string/stpncpy.c deleted file mode 100644 index 3ef51f84ea..0000000000 --- a/libtcgtpm/deps/libcrt/src/string/stpncpy.c +++ /dev/null @@ -1,34 +0,0 @@ -/* SPDX-License-Identifier: MIT */ - -#include -#include -#include - -#define ALIGN (sizeof(size_t)-1) -#define ONES ((size_t)-1/UCHAR_MAX) -#define HIGHS (ONES * (UCHAR_MAX/2+1)) -#define HASZERO(x) (((x)-ONES) & ~(x) & HIGHS) - -char *__stpncpy(char *restrict d, const char *restrict s, size_t n) -{ -#ifdef __GNUC__ - typedef size_t __attribute__((__may_alias__)) word; - word *wd; - const word *ws; - if (((uintptr_t)s & ALIGN) == ((uintptr_t)d & ALIGN)) { - for (; ((uintptr_t)s & ALIGN) && n && (*d=*s); n--, s++, d++); - if (!n || !*s) goto tail; - wd=(void *)d; ws=(const void *)s; - for (; n>=sizeof(size_t) && !HASZERO(*ws); - n-=sizeof(size_t), ws++, wd++) *wd = *ws; - d=(void *)wd; s=(const void *)ws; - } -#endif - for (; n && (*d=*s); n--, s++, d++); -tail: - memset(d, 0, n); - return d; -} - -weak_alias(__stpncpy, stpncpy); - diff --git a/libtcgtpm/deps/libcrt/src/string/strcasecmp.c b/libtcgtpm/deps/libcrt/src/string/strcasecmp.c deleted file mode 100644 index 5c69f1e2f6..0000000000 --- a/libtcgtpm/deps/libcrt/src/string/strcasecmp.c +++ /dev/null @@ -1,20 +0,0 @@ -/* SPDX-License-Identifier: MIT */ - -#include -#include - -int strcasecmp(const char *_l, const char *_r) -{ - const unsigned char *l=(void *)_l, *r=(void *)_r; - for (; *l && *r && (*l == *r || tolower(*l) == tolower(*r)); l++, r++); - return tolower(*l) - tolower(*r); -} - -#if 0 -int __strcasecmp_l(const char *l, const char *r, locale_t loc) -{ - return strcasecmp(l, r); -} - -weak_alias(__strcasecmp_l, strcasecmp_l); -#endif diff --git a/libtcgtpm/deps/libcrt/src/string/strcat.c b/libtcgtpm/deps/libcrt/src/string/strcat.c deleted file mode 100644 index aa27b390b9..0000000000 --- a/libtcgtpm/deps/libcrt/src/string/strcat.c +++ /dev/null @@ -1,9 +0,0 @@ -/* SPDX-License-Identifier: MIT */ - -#include - -char *strcat(char *restrict dest, const char *restrict src) -{ - strcpy(dest + strlen(dest), src); - return dest; -} diff --git a/libtcgtpm/deps/libcrt/src/string/strchr.c b/libtcgtpm/deps/libcrt/src/string/strchr.c deleted file mode 100644 index 27ff430f3b..0000000000 --- a/libtcgtpm/deps/libcrt/src/string/strchr.c +++ /dev/null @@ -1,9 +0,0 @@ -/* SPDX-License-Identifier: MIT */ - -#include - -char *strchr(const char *s, int c) -{ - char *r = __strchrnul(s, c); - return *(unsigned char *)r == (unsigned char)c ? r : 0; -} diff --git a/libtcgtpm/deps/libcrt/src/string/strchrnul.c b/libtcgtpm/deps/libcrt/src/string/strchrnul.c deleted file mode 100644 index 7d9fa43201..0000000000 --- a/libtcgtpm/deps/libcrt/src/string/strchrnul.c +++ /dev/null @@ -1,30 +0,0 @@ -/* SPDX-License-Identifier: MIT */ - -#include -#include -#include - -#define ALIGN (sizeof(size_t)) -#define ONES ((size_t)-1/UCHAR_MAX) -#define HIGHS (ONES * (UCHAR_MAX/2+1)) -#define HASZERO(x) (((x)-ONES) & ~(x) & HIGHS) - -char *__strchrnul(const char *s, int c) -{ - c = (unsigned char)c; - if (!c) return (char *)s + strlen(s); - -#ifdef __GNUC__ - typedef size_t __attribute__((__may_alias__)) word; - const word *w; - for (; (uintptr_t)s % ALIGN; s++) - if (!*s || *(unsigned char *)s == c) return (char *)s; - size_t k = ONES * c; - for (w = (void *)s; !HASZERO(*w) && !HASZERO(*w^k); w++); - s = (void *)w; -#endif - for (; *s && *(unsigned char *)s != c; s++); - return (char *)s; -} - -weak_alias(__strchrnul, strchrnul); diff --git a/libtcgtpm/deps/libcrt/src/string/strcmp.c b/libtcgtpm/deps/libcrt/src/string/strcmp.c deleted file mode 100644 index 617315139e..0000000000 --- a/libtcgtpm/deps/libcrt/src/string/strcmp.c +++ /dev/null @@ -1,9 +0,0 @@ -/* SPDX-License-Identifier: MIT */ - -#include - -int strcmp(const char *l, const char *r) -{ - for (; *l==*r && *l; l++, r++); - return *(unsigned char *)l - *(unsigned char *)r; -} diff --git a/libtcgtpm/deps/libcrt/src/string/strcpy.c b/libtcgtpm/deps/libcrt/src/string/strcpy.c deleted file mode 100644 index 8a247c6585..0000000000 --- a/libtcgtpm/deps/libcrt/src/string/strcpy.c +++ /dev/null @@ -1,9 +0,0 @@ -/* SPDX-License-Identifier: MIT */ - -#include - -char *strcpy(char *restrict dest, const char *restrict src) -{ - __stpcpy(dest, src); - return dest; -} diff --git a/libtcgtpm/deps/libcrt/src/string/strcspn.c b/libtcgtpm/deps/libcrt/src/string/strcspn.c deleted file mode 100644 index e9294f6a72..0000000000 --- a/libtcgtpm/deps/libcrt/src/string/strcspn.c +++ /dev/null @@ -1,19 +0,0 @@ -/* SPDX-License-Identifier: MIT */ - -#include - -#define BITOP(a,b,op) \ - ((a)[(size_t)(b)/(8*sizeof *(a))] op (size_t)1<<((size_t)(b)%(8*sizeof *(a)))) - -size_t strcspn(const char *s, const char *c) -{ - const char *a = s; - size_t byteset[32/sizeof(size_t)]; - - if (!c[0] || !c[1]) return __strchrnul(s, *c)-a; - - memset(byteset, 0, sizeof byteset); - for (; *c && BITOP(byteset, *(unsigned char *)c, |=); c++); - for (; *s && !BITOP(byteset, *(unsigned char *)s, &); s++); - return s-a; -} diff --git a/libtcgtpm/deps/libcrt/src/string/strdup.c b/libtcgtpm/deps/libcrt/src/string/strdup.c deleted file mode 100644 index 09c603e033..0000000000 --- a/libtcgtpm/deps/libcrt/src/string/strdup.c +++ /dev/null @@ -1,13 +0,0 @@ -/* SPDX-License-Identifier: MIT */ - -#include -#include -#include - -char *strdup(const char *s) -{ - size_t l = strlen(s); - char *d = malloc(l+1); - if (!d) return NULL; - return memcpy(d, s, l+1); -} diff --git a/libtcgtpm/deps/libcrt/src/string/strlen.c b/libtcgtpm/deps/libcrt/src/string/strlen.c deleted file mode 100644 index f1500c25aa..0000000000 --- a/libtcgtpm/deps/libcrt/src/string/strlen.c +++ /dev/null @@ -1,24 +0,0 @@ -/* SPDX-License-Identifier: MIT */ - -#include -#include -#include - -#define ALIGN (sizeof(size_t)) -#define ONES ((size_t)-1/UCHAR_MAX) -#define HIGHS (ONES * (UCHAR_MAX/2+1)) -#define HASZERO(x) (((x)-ONES) & ~(x) & HIGHS) - -size_t strlen(const char *s) -{ - const char *a = s; -#ifdef __GNUC__ - typedef size_t __attribute__((__may_alias__)) word; - const word *w; - for (; (uintptr_t)s % ALIGN; s++) if (!*s) return s-a; - for (w = (const void *)s; !HASZERO(*w); w++); - s = (const void *)w; -#endif - for (; *s; s++); - return s-a; -} diff --git a/libtcgtpm/deps/libcrt/src/string/strncasecmp.c b/libtcgtpm/deps/libcrt/src/string/strncasecmp.c deleted file mode 100644 index 8e990d11e1..0000000000 --- a/libtcgtpm/deps/libcrt/src/string/strncasecmp.c +++ /dev/null @@ -1,12 +0,0 @@ -/* SPDX-License-Identifier: MIT */ - -#include -#include - -int strncasecmp(const char *_l, const char *_r, size_t n) -{ - const unsigned char *l=(void *)_l, *r=(void *)_r; - if (!n--) return 0; - for (; *l && *r && n && (*l == *r || tolower(*l) == tolower(*r)); l++, r++, n--); - return tolower(*l) - tolower(*r); -} diff --git a/libtcgtpm/deps/libcrt/src/string/strncat.c b/libtcgtpm/deps/libcrt/src/string/strncat.c deleted file mode 100644 index 5fe48e1686..0000000000 --- a/libtcgtpm/deps/libcrt/src/string/strncat.c +++ /dev/null @@ -1,12 +0,0 @@ -/* SPDX-License-Identifier: MIT */ - -#include - -char *strncat(char *restrict d, const char *restrict s, size_t n) -{ - char *a = d; - d += strlen(d); - while (n && *s) n--, *d++ = *s++; - *d++ = 0; - return a; -} diff --git a/libtcgtpm/deps/libcrt/src/string/strncmp.c b/libtcgtpm/deps/libcrt/src/string/strncmp.c deleted file mode 100644 index b39777c54c..0000000000 --- a/libtcgtpm/deps/libcrt/src/string/strncmp.c +++ /dev/null @@ -1,11 +0,0 @@ -/* SPDX-License-Identifier: MIT */ - -#include - -int strncmp(const char *_l, const char *_r, size_t n) -{ - const unsigned char *l=(void *)_l, *r=(void *)_r; - if (!n--) return 0; - for (; *l && *r && n && *l == *r ; l++, r++, n--); - return *l - *r; -} diff --git a/libtcgtpm/deps/libcrt/src/string/strncpy.c b/libtcgtpm/deps/libcrt/src/string/strncpy.c deleted file mode 100644 index 5528d062e7..0000000000 --- a/libtcgtpm/deps/libcrt/src/string/strncpy.c +++ /dev/null @@ -1,9 +0,0 @@ -/* SPDX-License-Identifier: MIT */ - -#include - -char *strncpy(char *restrict d, const char *restrict s, size_t n) -{ - __stpncpy(d, s, n); - return d; -} diff --git a/libtcgtpm/deps/libcrt/src/string/strrchr.c b/libtcgtpm/deps/libcrt/src/string/strrchr.c deleted file mode 100644 index 614c2c9f7a..0000000000 --- a/libtcgtpm/deps/libcrt/src/string/strrchr.c +++ /dev/null @@ -1,8 +0,0 @@ -/* SPDX-License-Identifier: MIT */ - -#include - -char *strrchr(const char *s, int c) -{ - return __memrchr(s, c, strlen(s) + 1); -} diff --git a/libtcgtpm/deps/libcrt/src/string/strspn.c b/libtcgtpm/deps/libcrt/src/string/strspn.c deleted file mode 100644 index c4aaa8e3d8..0000000000 --- a/libtcgtpm/deps/libcrt/src/string/strspn.c +++ /dev/null @@ -1,22 +0,0 @@ -/* SPDX-License-Identifier: MIT */ - -#include - -#define BITOP(a,b,op) \ - ((a)[(size_t)(b)/(8*sizeof *(a))] op (size_t)1<<((size_t)(b)%(8*sizeof *(a)))) - -size_t strspn(const char *s, const char *c) -{ - const char *a = s; - size_t byteset[32/sizeof(size_t)] = { 0 }; - - if (!c[0]) return 0; - if (!c[1]) { - for (; *s == *c; s++); - return s-a; - } - - for (; *c && BITOP(byteset, *(unsigned char *)c, |=); c++); - for (; *s && BITOP(byteset, *(unsigned char *)s, &); s++); - return s-a; -} diff --git a/libtcgtpm/deps/libcrt/src/string/strstr.c b/libtcgtpm/deps/libcrt/src/string/strstr.c deleted file mode 100644 index dc9bb73e55..0000000000 --- a/libtcgtpm/deps/libcrt/src/string/strstr.c +++ /dev/null @@ -1,156 +0,0 @@ -/* SPDX-License-Identifier: MIT */ - -#include -#include - -static char *twobyte_strstr(const unsigned char *h, const unsigned char *n) -{ - uint16_t nw = n[0]<<8 | n[1], hw = h[0]<<8 | h[1]; - for (h++; *h && hw != nw; hw = hw<<8 | *++h); - return *h ? (char *)h-1 : 0; -} - -static char *threebyte_strstr(const unsigned char *h, const unsigned char *n) -{ - uint32_t nw = (uint32_t)n[0]<<24 | n[1]<<16 | n[2]<<8; - uint32_t hw = (uint32_t)h[0]<<24 | h[1]<<16 | h[2]<<8; - for (h+=2; *h && hw != nw; hw = (hw|*++h)<<8); - return *h ? (char *)h-2 : 0; -} - -static char *fourbyte_strstr(const unsigned char *h, const unsigned char *n) -{ - uint32_t nw = (uint32_t)n[0]<<24 | n[1]<<16 | n[2]<<8 | n[3]; - uint32_t hw = (uint32_t)h[0]<<24 | h[1]<<16 | h[2]<<8 | h[3]; - for (h+=3; *h && hw != nw; hw = hw<<8 | *++h); - return *h ? (char *)h-3 : 0; -} - -#define MAX(a,b) ((a)>(b)?(a):(b)) -#define MIN(a,b) ((a)<(b)?(a):(b)) - -#define BITOP(a,b,op) \ - ((a)[(size_t)(b)/(8*sizeof *(a))] op (size_t)1<<((size_t)(b)%(8*sizeof *(a)))) - -static char *twoway_strstr(const unsigned char *h, const unsigned char *n) -{ - const unsigned char *z; - size_t l, ip, jp, k, p, ms, p0, mem, mem0; - size_t byteset[32 / sizeof(size_t)] = { 0 }; - size_t shift[256]; - - /* Computing length of needle and fill shift table */ - for (l=0; n[l] && h[l]; l++) - BITOP(byteset, n[l], |=), shift[n[l]] = l+1; - if (n[l]) return 0; /* hit the end of h */ - - /* Compute maximal suffix */ - ip = -1; jp = 0; k = p = 1; - while (jp+k n[jp+k]) { - jp += k; - k = 1; - p = jp - ip; - } else { - ip = jp++; - k = p = 1; - } - } - ms = ip; - p0 = p; - - /* And with the opposite comparison */ - ip = -1; jp = 0; k = p = 1; - while (jp+k ms+1) ms = ip; - else p = p0; - - /* Periodic needle? */ - if (memcmp(n, n+p, ms+1)) { - mem0 = 0; - p = MAX(ms, l-ms-1) + 1; - } else mem0 = l-p; - mem = 0; - - /* Initialize incremental end-of-haystack pointer */ - z = h; - - /* Search loop */ - for (;;) { - /* Update incremental end-of-haystack pointer */ - if (z-h < l) { - /* Fast estimate for MAX(l,63) */ - size_t grow = l | 63; - const unsigned char *z2 = memchr(z, 0, grow); - if (z2) { - z = z2; - if (z-h < l) return 0; - } else z += grow; - } - - /* Check last byte first; advance by shift on mismatch */ - if (BITOP(byteset, h[l-1], &)) { - k = l-shift[h[l-1]]; - if (k) { - if (k < mem) k = mem; - h += k; - mem = 0; - continue; - } - } else { - h += l; - mem = 0; - continue; - } - - /* Compare right half */ - for (k=MAX(ms+1,mem); n[k] && n[k] == h[k]; k++); - if (n[k]) { - h += k-ms; - mem = 0; - continue; - } - /* Compare left half */ - for (k=ms+1; k>mem && n[k-1] == h[k-1]; k--); - if (k <= mem) return (char *)h; - h += p; - mem = mem0; - } -} - -char *strstr(const char *h, const char *n) -{ - /* Return immediately on empty needle */ - if (!n[0]) return (char *)h; - - /* Use faster algorithms for short needles */ - h = strchr(h, *n); - if (!h || !n[1]) return (char *)h; - if (!h[1]) return 0; - if (!n[2]) return twobyte_strstr((void *)h, (void *)n); - if (!h[2]) return 0; - if (!n[3]) return threebyte_strstr((void *)h, (void *)n); - if (!h[3]) return 0; - if (!n[4]) return fourbyte_strstr((void *)h, (void *)n); - - return twoway_strstr((void *)h, (void *)n); -} diff --git a/libtcgtpm/deps/libcrt/src/stub.c b/libtcgtpm/deps/libcrt/src/stub.c deleted file mode 100644 index 16a21ca029..0000000000 --- a/libtcgtpm/deps/libcrt/src/stub.c +++ /dev/null @@ -1,183 +0,0 @@ -/* SPDX-License-Identifier: MIT */ - -#include - -#define NOT_IMPLEMENTED \ - do { \ - printf("ERROR: libcrt: %s not implemented\n", __func__); \ - abort(); \ - } while (0) - - -// errno.h - -int errno = 0; -FILE *stderr = NULL; -FILE *stdin = NULL; -FILE *stdout = NULL; - -char *strerror(int errnum) -{ - NOT_IMPLEMENTED; - return NULL; -} - -// stdio.h - -int sscanf(const char *buffer, const char *format, ...) -{ - NOT_IMPLEMENTED; - return 0; -} - -// fwrite, fread, fclose, fopen, fseek, ftell, fflush are provided by -// SVSM Rust code (kernel/src/vtpm/tcgtpm/wrapper.rs). - -int fputc(int c, FILE *f) -{ - NOT_IMPLEMENTED; - return 0; -} - - -void setbuf(FILE *stream, char *buf) -{ - NOT_IMPLEMENTED; -} - -int ferror(FILE *stream) { - NOT_IMPLEMENTED; - return -1; -} - -int clearerr(FILE *stream) { - NOT_IMPLEMENTED; - return -1; -} - -// stdlib.h - -long strtol(const char *nptr, char **endptr, int base) -{ - NOT_IMPLEMENTED; - return LONG_MIN; -} - -unsigned long strtoul(const char *nptr, char **endptr, int base) -{ - NOT_IMPLEMENTED; - return ULONG_MAX; -} - -char *getenv(const char *varname) -{ - NOT_IMPLEMENTED; - return NULL; -} - -int atexit(void (*func)(void)) -{ - NOT_IMPLEMENTED; - return 0; -} - -// unistd.h - -pid_t getpid(void) -{ - // TODO: return the actual PID when CPL3 is supported - return 0; -} - -uid_t getuid(void) -{ - NOT_IMPLEMENTED; - return 0; -} - -uid_t geteuid(void) -{ - NOT_IMPLEMENTED; - return 0; -} - -gid_t getgid(void) -{ - NOT_IMPLEMENTED; - return 0; -} - -gid_t getegid(void) -{ - NOT_IMPLEMENTED; - return 0; -} - -long syscall(long number, ...) -{ - NOT_IMPLEMENTED; - errno = ENOSYS; - return -1; -} - -int usleep(useconds_t usec) -{ - NOT_IMPLEMENTED; - return -1; -} - -unsigned int sleep(unsigned int seconds) -{ - NOT_IMPLEMENTED; - return seconds; -} - -int timezone = 0; - -// dirent.h - -DIR *opendir(const char *name) -{ - NOT_IMPLEMENTED; - return NULL; -} - -int closedir(DIR *name) -{ - NOT_IMPLEMENTED; - return -1; -} - -struct dirent *readdir(DIR *name) -{ - NOT_IMPLEMENTED; - return NULL; -} - -// sys/stat.h - -int stat(const char *__restrict path, struct stat *restrict buf) -{ - NOT_IMPLEMENTED; - return -1; -} - -// time.h - -char *ctime(const time_t *t) { - NOT_IMPLEMENTED; - return NULL; -} - -time_t mktime(struct tm *tm) { - NOT_IMPLEMENTED; - return 0; -} - -// string.h - -char *strpbrk(const char *s, const char *accept) -{ - NOT_IMPLEMENTED; - return NULL; -} diff --git a/libtcgtpm/deps/libcrt/src/time/__secs_to_tm.c b/libtcgtpm/deps/libcrt/src/time/__secs_to_tm.c deleted file mode 100644 index a32c39ee63..0000000000 --- a/libtcgtpm/deps/libcrt/src/time/__secs_to_tm.c +++ /dev/null @@ -1,84 +0,0 @@ -/* SPDX-License-Identifier: MIT */ - -#include -#include - -/* 2000-03-01 (mod 400 year, immediately after feb29 */ -#define LEAPOCH (946684800LL + 86400*(31+29)) - -#define DAYS_PER_400Y (365*400 + 97) -#define DAYS_PER_100Y (365*100 + 24) -#define DAYS_PER_4Y (365*4 + 1) - -int __secs_to_tm(long long t, struct tm *tm) -{ - long long days, secs, years; - int remdays, remsecs, remyears; - int qc_cycles, c_cycles, q_cycles; - int months; - int wday, yday, leap; - static const char days_in_month[] = {31,30,31,30,31,31,30,31,30,31,31,29}; - - /* Reject time_t values whose year would overflow int */ - if (t < INT_MIN * 31622400LL || t > INT_MAX * 31622400LL) - return -1; - - secs = t - LEAPOCH; - days = secs / 86400; - remsecs = secs % 86400; - if (remsecs < 0) { - remsecs += 86400; - days--; - } - - wday = (3+days)%7; - if (wday < 0) wday += 7; - - qc_cycles = days / DAYS_PER_400Y; - remdays = days % DAYS_PER_400Y; - if (remdays < 0) { - remdays += DAYS_PER_400Y; - qc_cycles--; - } - - c_cycles = remdays / DAYS_PER_100Y; - if (c_cycles == 4) c_cycles--; - remdays -= c_cycles * DAYS_PER_100Y; - - q_cycles = remdays / DAYS_PER_4Y; - if (q_cycles == 25) q_cycles--; - remdays -= q_cycles * DAYS_PER_4Y; - - remyears = remdays / 365; - if (remyears == 4) remyears--; - remdays -= remyears * 365; - - leap = !remyears && (q_cycles || !c_cycles); - yday = remdays + 31 + 28 + leap; - if (yday >= 365+leap) yday -= 365+leap; - - years = remyears + 4*q_cycles + 100*c_cycles + 400LL*qc_cycles; - - for (months=0; days_in_month[months] <= remdays; months++) - remdays -= days_in_month[months]; - - if (months >= 10) { - months -= 12; - years++; - } - - if (years+100 > INT_MAX || years+100 < INT_MIN) - return -1; - - tm->tm_year = years + 100; - tm->tm_mon = months + 2; - tm->tm_mday = remdays + 1; - tm->tm_wday = wday; - tm->tm_yday = yday; - - tm->tm_hour = remsecs / 3600; - tm->tm_min = remsecs / 60 % 60; - tm->tm_sec = remsecs % 60; - - return 0; -} diff --git a/libtcgtpm/deps/libcrt/src/time/gmtime_r.c b/libtcgtpm/deps/libcrt/src/time/gmtime_r.c deleted file mode 100644 index 2aefad83a0..0000000000 --- a/libtcgtpm/deps/libcrt/src/time/gmtime_r.c +++ /dev/null @@ -1,25 +0,0 @@ -/* SPDX-License-Identifier: MIT */ - -#include -#include - -char *__utc = "UTC"; - -struct tm *gmtime_r(const time_t *restrict t, struct tm *restrict tm) -{ - if (__secs_to_tm(*t, tm) < 0) { - errno = EOVERFLOW; - return 0; - } - tm->tm_isdst = 0; - tm->tm_gmtoff = 0; - tm->tm_zone = __utc; - return tm; -} - - -struct tm *gmtime(const time_t *t) -{ - static struct tm tm; - return gmtime_r(t, &tm); -} diff --git a/libtcgtpm/deps/libcrt/src/time/time.c b/libtcgtpm/deps/libcrt/src/time/time.c deleted file mode 100644 index 60016eefc6..0000000000 --- a/libtcgtpm/deps/libcrt/src/time/time.c +++ /dev/null @@ -1,37 +0,0 @@ -/* SPDX-License-Identifier: MIT */ - -#include -#include -#include - -// Calls the rdtsc instruction to read the current value of the processor's -// time-stamp counter (a 64-bit MSR) -clock_t clock(void) { - return rdtsc(); -} - -uint64_t secs; - -int clock_gettime(clockid_t clk_id, struct timespec *tp) { - (void) clk_id; - if (tp) { - tp->tv_nsec = rdtsc(); - tp->tv_sec = secs++; - } - return 0; -} - -// time() returns the time as the number of seconds since the Epoch -time_t time(time_t *tloc) { - (void)tloc; - time_t t = rdtsc(); - return t; -} - -int gettimeofday(struct timeval *restrict tv, void *restrict tz) -{ - if (!tv) return 0; - tv->tv_sec = clock(); - tv->tv_usec = 0; - return 0; -} diff --git a/libtcgtpm/src/lib.rs b/libtcgtpm/src/lib.rs index a5ff089f3f..f1c27b9594 100644 --- a/libtcgtpm/src/lib.rs +++ b/libtcgtpm/src/lib.rs @@ -6,9 +6,22 @@ //! This crate provides the libtcgtpm definitions used by the COCONUT-SVSM //! for the vTPM. +//! +//! # Build metadata consumed +//! +//! From `libcrt` (`links = "crt"`): +//! +//! | Env var | Usage | +//! |-----------------------|---------------------------------------------------| +//! | `DEP_CRT_INCLUDE_DIR` | C runtime headers for bindgen and TPM compilation | #![no_std] +// Ensure libcrt is linked — it provides the minimal C runtime +// that the tcgtpm C libraries depend on. +#[allow(unused_extern_crates)] +extern crate libcrt; + /// C bindings pub mod bindings { #![allow(non_upper_case_globals)] From cd9a9b542cc1092bc8815b4ec35f930daf61674f Mon Sep 17 00:00:00 2001 From: Oliver Steffen Date: Wed, 7 Oct 2026 10:01:46 +0200 Subject: [PATCH 10/13] libtcgtpm: Move cross-compile detection into build.rs Move cross-compile detection to build.rs and use cargo's HOST settings instead of handling it in the makefile (calls uname). Signed-off-by: Oliver Steffen --- libtcgtpm/Makefile | 7 +------ libtcgtpm/build.rs | 9 +++++++++ 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/libtcgtpm/Makefile b/libtcgtpm/Makefile index a2a89b4a72..1d69ec5181 100644 --- a/libtcgtpm/Makefile +++ b/libtcgtpm/Makefile @@ -1,9 +1,4 @@ -ifeq ($(shell uname -m),x86_64) -CROSS_PREFIX := -else -CROSS_PREFIX := x86_64-linux-gnu- -endif -CC := $(CROSS_PREFIX)gcc +CC ?= gcc ifdef RELEASE OPENSSL_CONFIG_TYPE = --release diff --git a/libtcgtpm/build.rs b/libtcgtpm/build.rs index fef815d50e..54d9eaeedb 100644 --- a/libtcgtpm/build.rs +++ b/libtcgtpm/build.rs @@ -16,8 +16,17 @@ fn main() { let libcrt_include_dir = std::env::var("DEP_CRT_INCLUDE_DIR").expect("DEP_CRT_INCLUDE_DIR not set"); + // Cross-compile support: when the host is not x86_64, use a cross toolchain. + let host = std::env::var("HOST").unwrap(); + let cc = if host.starts_with("x86_64") { + "gcc".to_string() + } else { + "x86_64-linux-gnu-gcc".to_string() + }; + // Build libtcgtpm. libcrt comes from the libcrt crate. let mut cmd = Command::new("make"); + cmd.arg(format!("CC={cc}")); cmd.arg(format!("LIBCRT_INCLUDE_DIR={libcrt_include_dir}")); if target_os != "none" { cmd.arg("USE_LIBCRT=0"); From 4967ea29db630afa67b8c7269841974675a6c3e0 Mon Sep 17 00:00:00 2001 From: Oliver Steffen Date: Fri, 4 Sep 2026 11:12:04 +0200 Subject: [PATCH 11/13] workspace: add cocoon-tpm OpenSSL backend integration lib Add an implementation of cocoon-tpm's OpenSSL backend integration package. It provides an OpenSSL build config (based on the libtcgtpm one), matching compiler flags to the cocoon-tpm OpenSSL backend. It depends on our libcrt crate providing a C runtime for OpenSSL. A cargo feature called "openssl" is added to select OpenSSL as the backend in cocoon-tpm. Note: After this commit the openssl and vtpm cargo feature conflict, due to duplicate libcrypto symbols at link time. This will be resolved in a later commit. Configuration options specific to the target environment are passed to the OpenSSL backend of cocoon-tpm; this includes flags for cross-compilation. The set of enabled/disabled algorithms is selected on the cocoon-tpm side and satisfies our needs. Note: The new openssl feature does not build yet, we need to implement a matching RNG in kernel/crypto. This will happen in the following commit. Signed-off-by: Oliver Steffen --- Cargo.lock | 22 +++++ Cargo.toml | 5 + .../Cargo.toml | 18 ++++ .../build.rs | 93 +++++++++++++++++++ .../src/lib.rs | 36 +++++++ .../third-party/openssl_svsm.conf | 26 ++++++ kernel/Cargo.toml | 1 + kernel/src/lib.rs | 2 +- 8 files changed, 202 insertions(+), 1 deletion(-) create mode 100644 cocoon-tpm_ossl-bare-sys-target-integration/Cargo.toml create mode 100644 cocoon-tpm_ossl-bare-sys-target-integration/build.rs create mode 100644 cocoon-tpm_ossl-bare-sys-target-integration/src/lib.rs create mode 100644 cocoon-tpm_ossl-bare-sys-target-integration/third-party/openssl_svsm.conf diff --git a/Cargo.lock b/Cargo.lock index a1798a77d6..dc385e150a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -216,6 +216,8 @@ dependencies = [ "bitflags 2.13.0", "cexpr", "clang-sys", + "log", + "prettyplease", "proc-macro2", "quote", "regex", @@ -489,6 +491,7 @@ dependencies = [ "cfb-mode", "cipher 0.4.4", "cmpa", + "cocoon-tpm-ossl-bare-sys", "cocoon-tpm-tpm2-interface", "cocoon-tpm-utils-common", "crypto-common 0.1.7", @@ -503,6 +506,25 @@ dependencies = [ "zeroize", ] +[[package]] +name = "cocoon-tpm-ossl-bare-sys" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef5bf284564051b7c149102e5ae95967f7b4cd24e895847e5734454a9a2250cb" +dependencies = [ + "bindgen", + "cc", + "cocoon-tpm-ossl-bare-sys-target-integration", + "shlex 2.0.1", +] + +[[package]] +name = "cocoon-tpm-ossl-bare-sys-target-integration" +version = "0.1.1" +dependencies = [ + "libcrt", +] + [[package]] name = "cocoon-tpm-storage" version = "0.1.5" diff --git a/Cargo.toml b/Cargo.toml index a0c872a384..be1d058fde 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -82,6 +82,7 @@ bitfield-struct = "0.13.0" bitflags = "2.6" clap = { version = "4.4.14", default-features = false } cocoon-tpm-crypto = { version = "0.1.5", default-features = false } +cocoon-tpm-ossl-bare-sys = { version = "0.1.1" } cocoon-tpm-storage = { version = "0.1.5", default-features = false } cocoon-tpm-tpm2-interface = { version = "0.1.2", default-features = false } cocoon-tpm-utils-async = { version = "0.1.4", default-features = false } @@ -172,3 +173,7 @@ unnecessary_box_returns = "warn" [workspace.metadata.scripts] vfmt = "verusfmt `find ./ -name *.verus.rs`" + +[patch.crates-io] +# cocoon-tpm OpenSSL backend integration lib for SVSM +cocoon-tpm-ossl-bare-sys-target-integration = { path = "./cocoon-tpm_ossl-bare-sys-target-integration/" } diff --git a/cocoon-tpm_ossl-bare-sys-target-integration/Cargo.toml b/cocoon-tpm_ossl-bare-sys-target-integration/Cargo.toml new file mode 100644 index 0000000000..20f5cec740 --- /dev/null +++ b/cocoon-tpm_ossl-bare-sys-target-integration/Cargo.toml @@ -0,0 +1,18 @@ +[package] +name = "cocoon-tpm-ossl-bare-sys-target-integration" +version = "0.1.1" +edition = "2024" + +license = "Apache-2.0" +description = "Cocoon TPM project - SVSM ossl-bare-sys integration helper" +homepage = "https://github.com/coconut-svsm/cocoon-tpm" +repository = "https://github.com/coconut-svsm/cocoon-tpm" +readme = "README.md" + +links = "ossl-bare-sys-target-integration" + +[lints] +workspace = true + +[dependencies] +libcrt = { workspace = true } diff --git a/cocoon-tpm_ossl-bare-sys-target-integration/build.rs b/cocoon-tpm_ossl-bare-sys-target-integration/build.rs new file mode 100644 index 0000000000..24b01f9656 --- /dev/null +++ b/cocoon-tpm_ossl-bare-sys-target-integration/build.rs @@ -0,0 +1,93 @@ +// SPDX-License-Identifier: MIT OR Apache-2.0 +// +// Copyright (c) 2026 Red Hat +// +// Author: Oliver Steffen + +use std::env; +use std::path::PathBuf; + +fn main() { + // See ossl-bare-sys' build.rs for a list and meaning of metadata variables recognized. + let src_dir = PathBuf::from(env::var("CARGO_MANIFEST_DIR").unwrap()); + + // libcrt is built by the libcrt crate. Read its include path for CPPFLAGS. + let libcrt_include_dir = env::var("DEP_CRT_INCLUDE_DIR").expect("DEP_CRT_INCLUDE_DIR not set"); + + // Use the custom SVSM OpenSSL target configuration. + let config_file = src_dir.join("third-party").join("openssl_svsm.conf"); + println!("cargo::rerun-if-changed={}", config_file.to_str().unwrap()); + println!( + "cargo::metadata=CONFIGURE_CONFIG_FILE={}", + config_file.to_str().unwrap() + ); + println!("cargo::metadata=CONFIGURE_TARGET=SVSM"); + + // SVSM is a no-threads, freestanding embedded environment. + // Only options specific to the embedded target belong here — algorithm + // selection lives in cocoon-tpm/ossl-bare-sys/build.rs. + let configure_args = [ + // Do not use assembler code. + "no-asm", + // Do not use atexit() in libcrypto builds. + "no-atexit", + // Don't automatically load all libcrypto/libssl error strings. + "no-autoerrinit", + // Don't compile in any error strings. + "no-err", + // Don't compile in filename and line number information. + "no-filenames", + // Don't build with support for Position Independent Code. + "no-pic", + // Don't use POSIX IO capabilities. + "no-posix-io", + // Exclude SSE2 code paths from assembly modules. + "no-sse2", + // Don't use anything from stdio.h. + "no-stdio", + // Don't build with support for multi-threaded applications. + "no-threads", + // Don't build with support for thread pool functionality. + "no-thread-pool", + // Use only getrandom() for CSPRNG seeding. + "--with-rand-seed=getrandom", + ]; + let mut configure_args = configure_args.join(" "); + + // Cross-compile support: when the host is not x86_64, use the cross + // toolchain for OpenSSL Configure, the shim library, and make. + let host = env::var("HOST").unwrap(); + if !host.starts_with("x86_64") { + configure_args.push_str(" --cross-compile-prefix=x86_64-linux-gnu-"); + println!("cargo::metadata=CC=x86_64-linux-gnu-gcc"); + } + + println!("cargo::metadata=CONFIGURE_ARGS={configure_args}"); + + // The SVSM conf sets CFLAGS and lib_cppflags for the OpenSSL build itself, + // but the shim library and bindgen also need the libcrt include path. + let cppflags = format!("-I{libcrt_include_dir}"); + println!("cargo::metadata=CPPFLAGS={cppflags}"); + + // The shim library must use the same code generation flags as OpenSSL for + // the SVSM target. Only code-gen flags — not -nostdinc/-nostdlib/-static + // which would break header resolution for the cc crate. + let cflags = [ + "-fPIE", + "-m64", + "-fno-stack-protector", + "-mno-red-zone", + "-ffunction-sections", + "-fdata-sections", + ]; + println!("cargo::metadata=CFLAGS={}", cflags.join(" ")); + + // Bindgen needs the libcrt headers to parse OpenSSL headers. + // When cross-compiling, also tell clang the target triple so it uses + // the correct type sizes and ABI. + let mut bindgen_cflags = cppflags.clone(); + if !host.starts_with("x86_64") { + bindgen_cflags.push_str(" --target=x86_64-unknown-none"); + } + println!("cargo::metadata=BINDGEN_CFLAGS={bindgen_cflags}"); +} diff --git a/cocoon-tpm_ossl-bare-sys-target-integration/src/lib.rs b/cocoon-tpm_ossl-bare-sys-target-integration/src/lib.rs new file mode 100644 index 0000000000..51beb7e0ca --- /dev/null +++ b/cocoon-tpm_ossl-bare-sys-target-integration/src/lib.rs @@ -0,0 +1,36 @@ +// SPDX-License-Identifier: MIT OR Apache-2.0 +// +// Copyright (c) 2026 Red Hat +// +// Author: Oliver Steffen + +//! SVSM-specific target integration for `cocoon-tpm-ossl-bare-sys`. +//! +//! This crate supplies the build configuration that +//! `cocoon-tpm-ossl-bare-sys` needs to compile OpenSSL for the SVSM +//! target. It is wired in via Cargo's `links` metadata +//! (`links = "ossl-bare-sys-target-integration"`). +//! +//! Intended to be replaced by a Cargo path/patch override when building +//! `cocoon-tpm-ossl-bare-sys` for a different target environment. +//! +//! # Build metadata consumed +//! +//! From `libcrt` (`links = "crt"`): +//! +//! | Env var | Usage | +//! |-----------------------|-------------------------------------------------| +//! | `DEP_CRT_INCLUDE_DIR` | Included in `CPPFLAGS` and `BINDGEN_CFLAGS` | +//! +//! # Build metadata provided +//! +//! | Key | Env var consumed as | Description | +//! |------------------------|----------------------------------------------------------------|-------------------------------------------------------| +//! | `CONFIGURE_CONFIG_FILE`| `DEP_OSSL_BARE_SYS_TARGET_INTEGRATION_CONFIGURE_CONFIG_FILE` | Path to the OpenSSL target configuration file | +//! | `CONFIGURE_TARGET` | `DEP_OSSL_BARE_SYS_TARGET_INTEGRATION_CONFIGURE_TARGET` | OpenSSL `Configure` target name (e.g. `SVSM`) | +//! | `CONFIGURE_ARGS` | `DEP_OSSL_BARE_SYS_TARGET_INTEGRATION_CONFIGURE_ARGS` | Extra arguments passed to OpenSSL `Configure` | +//! | `CPPFLAGS` | `DEP_OSSL_BARE_SYS_TARGET_INTEGRATION_CPPFLAGS` | C preprocessor flags (include paths) | +//! | `CFLAGS` | `DEP_OSSL_BARE_SYS_TARGET_INTEGRATION_CFLAGS` | C compiler code-generation flags | +//! | `BINDGEN_CFLAGS` | `DEP_OSSL_BARE_SYS_TARGET_INTEGRATION_BINDGEN_CFLAGS` | Extra clang flags for bindgen | + +#![no_std] diff --git a/cocoon-tpm_ossl-bare-sys-target-integration/third-party/openssl_svsm.conf b/cocoon-tpm_ossl-bare-sys-target-integration/third-party/openssl_svsm.conf new file mode 100644 index 0000000000..a763eb6a78 --- /dev/null +++ b/cocoon-tpm_ossl-bare-sys-target-integration/third-party/openssl_svsm.conf @@ -0,0 +1,26 @@ +# SPDX-License-Identifier: MIT +# +# Copyright (C) 2023 IBM Corporation +# +# Author: Claudio Carvalho + +my %targets = ( + "SVSM" => { + inherit_from => [ "BASE_unix" ], + perlasm_scheme => "elf", + CC => "gcc", + CFLAGS => add(combine(picker(default => "-Wall -ffunction-sections -fdata-sections", + debug => "-g -O0", + # When compiled with any optimization (e.g. -O1), + # the gcc generates code with instructions that are + # not supported at the SVSM level (e.g. the SSE pxor). + # That crashes the SVSM boot with an unhandled + # exception 6 (invalid opcode) usually in: + # vtpm_init()->libtpm:manufacture()->libcrypto:BN_CTX_new() + release => "-O0"), + "-fPIE -m64 -nostdinc -nostdlib -static -fno-stack-protector -mno-red-zone")), + bn_ops => "SIXTY_FOUR_BIT_LONG", + lib_cppflags => add("-DL_ENDIAN -DNO_SYSLOG -DOPENSSL_SMALL_FOOTPRINT -D_CRT_SECURE_NO_DEPRECATE -D_CRT_NONSTDC_NO_DEPRECATE -DOPENSSL_USE_USLEEP"), + sys_id => "SVSM" + }, +); diff --git a/kernel/Cargo.toml b/kernel/Cargo.toml index 9979e47db8..51774c065c 100644 --- a/kernel/Cargo.toml +++ b/kernel/Cargo.toml @@ -96,6 +96,7 @@ attest = [ attest-serial = ["attest"] default = [] +openssl = ["cocoon-tpm-crypto/openssl"] persistence = ["dep:cocoon-tpm-storage", "block", "attest"] enable-gdb = ["dep:gdbstub", "dep:gdbstub_arch"] vtpm = ["dep:libtcgtpm"] diff --git a/kernel/src/lib.rs b/kernel/src/lib.rs index 083756114e..54ccd9da53 100644 --- a/kernel/src/lib.rs +++ b/kernel/src/lib.rs @@ -29,7 +29,7 @@ pub mod block; pub mod boot_params; pub mod console; pub mod cpu; -#[cfg(feature = "vtpm")] +#[cfg(any(feature = "openssl", feature = "vtpm"))] pub mod crt; pub mod crypto; pub mod debug; From 65ab6a31c45900bf96bf60f89e16daf7528620b5 Mon Sep 17 00:00:00 2001 From: Oliver Steffen Date: Tue, 15 Sep 2026 18:00:46 +0200 Subject: [PATCH 12/13] kernel: crypto: add RNG implementation using OpenSSL The DRBG generator from cocoon-tpm crypto are not available when the OpenSSL backend is selected. Add a new RNG implementation which uses OsslRandBytes() next to the DRBG one and switch between them at build time depending on the "openssl" cargo feature. Signed-off-by: Oliver Steffen --- kernel/src/crypto/rng/mod.rs | 7 ++++++ kernel/src/crypto/rng/ossl.rs | 43 +++++++++++++++++++++++++++++++++++ 2 files changed, 50 insertions(+) create mode 100644 kernel/src/crypto/rng/ossl.rs diff --git a/kernel/src/crypto/rng/mod.rs b/kernel/src/crypto/rng/mod.rs index 11012dde3b..1c974f0ae4 100644 --- a/kernel/src/crypto/rng/mod.rs +++ b/kernel/src/crypto/rng/mod.rs @@ -14,9 +14,16 @@ use crate::utils::pool::{Pool, PoolGuard}; use cocoon_tpm_crypto::{CryptoError, rng}; +#[cfg(not(feature = "openssl"))] mod drbg; +#[cfg(not(feature = "openssl"))] use drbg::SvsmRngImpl; +#[cfg(feature = "openssl")] +mod ossl; +#[cfg(feature = "openssl")] +use ossl::SvsmRngImpl; + /// Number of [`SVSM_RNG_POOL`] slots. const SVSM_RNG_POOL_SIZE: usize = 4; diff --git a/kernel/src/crypto/rng/ossl.rs b/kernel/src/crypto/rng/ossl.rs new file mode 100644 index 0000000000..566c7a085a --- /dev/null +++ b/kernel/src/crypto/rng/ossl.rs @@ -0,0 +1,43 @@ +// SPDX-License-Identifier: MIT OR Apache-2.0 +// +// Copyright (c) 2026 Red Hat +// +// Author: Oliver Steffen + +extern crate alloc; +use alloc::boxed::Box; + +use cocoon_tpm_crypto::{ + CryptoError, CryptoPeekableIoSlicesIter, CryptoWalkableIoSlicesMutIter, + rng::{self, OsslRandBytesRng, RngGenerateError}, +}; +use cocoon_tpm_utils_common::alloc::box_try_new; + +/// OpenSSL-backed RNG wrapping `RAND_bytes()`. +pub(super) struct SvsmRngImpl { + inner: OsslRandBytesRng, +} + +impl SvsmRngImpl { + pub(super) fn new() -> Result, CryptoError> { + box_try_new(SvsmRngImpl { + inner: OsslRandBytesRng::new(), + }) + .map_err(|_| CryptoError::MemoryAllocationFailure) + } +} + +impl rng::RngCore for SvsmRngImpl { + fn generate< + 'a, + 'b, + OI: CryptoWalkableIoSlicesMutIter<'a>, + AII: CryptoPeekableIoSlicesIter<'b>, + >( + &mut self, + output: OI, + additional_input: Option, + ) -> Result<(), RngGenerateError> { + self.inner.generate(output, additional_input) + } +} From 94f162f0b93e9f296b05237acf11889b74eeba64 Mon Sep 17 00:00:00 2001 From: Oliver Steffen Date: Wed, 16 Sep 2026 13:26:47 +0200 Subject: [PATCH 13/13] libtcgtpm: use libcrypto from cocoon-tpm-ossl-bare-sys Stop building OpenSSL locally in the libtcgtpm Makefile. Instead, depend on cocoon-tpm-ossl-bare-sys which provides libcrypto.a and exports include/lib paths via cargo metadata (DEP_OSSL_*). The Makefile now expects OPENSSL_INCLUDE_DIR and OPENSSL_SRC_INCLUDE_DIR from the caller and only builds the tcgtpm libraries. Remove the OpenSSL submodule and build config. After this commit libtcgtpm can be used again. It now depends on OpenSSL via cocoon-tpm-crypto. The vtpm cargo feature enables the openssl feature automatically. The vtpm can not be built without OpenSSL. Signed-off-by: Oliver Steffen --- .gitmodules | 3 - Cargo.lock | 1 + Makefile | 12 ++- kernel/Cargo.toml | 2 +- libtcgtpm/Cargo.toml | 1 + libtcgtpm/Makefile | 144 ++----------------------------- libtcgtpm/build.rs | 19 ++-- libtcgtpm/deps/openssl | 1 - libtcgtpm/deps/openssl_svsm.conf | 26 ------ libtcgtpm/src/lib.rs | 12 ++- taplo.toml | 2 +- 11 files changed, 48 insertions(+), 175 deletions(-) delete mode 160000 libtcgtpm/deps/openssl delete mode 100644 libtcgtpm/deps/openssl_svsm.conf diff --git a/.gitmodules b/.gitmodules index 74b4f60a93..361a5560e1 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,6 +1,3 @@ -[submodule "libtcgtpm/deps/openssl"] - path = libtcgtpm/deps/openssl - url = https://github.com/openssl/openssl.git [submodule "libtcgtpm/deps/tpm-20-ref"] path = libtcgtpm/deps/tpm-20-ref url = https://github.com/TrustedComputingGroup/TPM.git diff --git a/Cargo.lock b/Cargo.lock index dc385e150a..9ef28dbbdd 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1581,6 +1581,7 @@ name = "libtcgtpm" version = "0.1.0" dependencies = [ "bindgen", + "cocoon-tpm-ossl-bare-sys", "libcrt", "prettyplease", ] diff --git a/Makefile b/Makefile index a3eaf0e8c2..3489828975 100644 --- a/Makefile +++ b/Makefile @@ -5,6 +5,9 @@ XBUILD_ARGS += -f ${FEATURES} endif FEATURES_TEST ?= vtpm,block,uefivars,secureboot,enable-console-log,attest +# Doc tests link against the host libc, so exclude features that bring in +# bare-metal C libraries (vtpm → openssl → cocoon-tpm-ossl-bare-sys). +FEATURES_DOC_TEST ?= virtio-drivers,block,vsock,uefivars,secureboot,enable-console-log,attest SVSM_ARGS_TEST += --no-default-features ifneq ($(FEATURES_TEST),) SVSM_ARGS_TEST += --features ${FEATURES_TEST} @@ -118,12 +121,17 @@ bin/coconut-test-vanadium.igvm: cargo xbuild $(XBUILD_ARGS_TEST) ./configs/test/vanadium-test-target.json test: - cargo test ${CARGO_ARGS} ${SVSM_ARGS_TEST} --package svsm + cargo test ${CARGO_ARGS} ${SVSM_ARGS_TEST} --package svsm --lib + cargo test ${CARGO_ARGS} --no-default-features --features ${FEATURES_DOC_TEST} --package svsm --doc cargo test ${CARGO_ARGS} --workspace --exclude svsm miri: MIRIFLAGS=-Zmiri-permissive-provenance \ - cargo +nightly miri test ${CARGO_ARGS} ${SVSM_ARGS_TEST} --package svsm + cargo +nightly miri test ${CARGO_ARGS} ${SVSM_ARGS_TEST} --package svsm --lib +# Doc tests link against the host libc, so exclude features that bring in +# bare-metal C libraries (vtpm → openssl → cocoon-tpm-ossl-bare-sys). + MIRIFLAGS=-Zmiri-permissive-provenance \ + cargo +nightly miri test ${CARGO_ARGS} --no-default-features --features ${FEATURES_DOC_TEST} --package svsm --doc MIRIFLAGS=-Zmiri-permissive-provenance \ cargo +nightly miri test ${CARGO_ARGS} --workspace --exclude svsm diff --git a/kernel/Cargo.toml b/kernel/Cargo.toml index 51774c065c..772c35cb4e 100644 --- a/kernel/Cargo.toml +++ b/kernel/Cargo.toml @@ -99,7 +99,7 @@ default = [] openssl = ["cocoon-tpm-crypto/openssl"] persistence = ["dep:cocoon-tpm-storage", "block", "attest"] enable-gdb = ["dep:gdbstub", "dep:gdbstub_arch"] -vtpm = ["dep:libtcgtpm"] +vtpm = ["dep:libtcgtpm", "openssl"] nosmep = [] nosmap = [] verus_all = [ diff --git a/libtcgtpm/Cargo.toml b/libtcgtpm/Cargo.toml index 0c96a7927e..bb60f7c926 100644 --- a/libtcgtpm/Cargo.toml +++ b/libtcgtpm/Cargo.toml @@ -4,6 +4,7 @@ version = "0.1.0" edition.workspace = true [dependencies] +cocoon-tpm-ossl-bare-sys = { workspace = true } libcrt = { workspace = true } [build-dependencies] diff --git a/libtcgtpm/Makefile b/libtcgtpm/Makefile index 1d69ec5181..28aea1a4af 100644 --- a/libtcgtpm/Makefile +++ b/libtcgtpm/Makefile @@ -1,18 +1,18 @@ CC ?= gcc ifdef RELEASE -OPENSSL_CONFIG_TYPE = --release TCGTPM_CFLAGS = -O3 -DDEBUG=NO else -OPENSSL_CONFIG_TYPE = --debug TCGTPM_CFLAGS = -g -O0 -DDEBUG=YES endif # Allow user to not link in libcrt USE_LIBCRT ?= 1 -# libcrt is built externally (by the libcrt crate). +# OpenSSL and libcrt are built externally (by cocoon-tpm-ossl-bare-sys +# and the libcrt crate respectively). # The following must be provided by the caller: +# OPENSSL_INCLUDE_DIR, OPENSSL_SRC_INCLUDE_DIR, OPENSSL_LIB_DIR # LIBCRT_INCLUDE_DIR ROOT_DIR := $(dir $(abspath $(lastword $(MAKEFILE_LIST)))) @@ -32,13 +32,11 @@ NUM_JOBS ?= $(shell nproc) MAKEFLAGS += -j$(NUM_JOBS) endif -OPENSSL_SRC_DIR = $(DEPS_DIR)/openssl TCGTPM_SRC_DIR = $(DEPS_DIR)/tpm-20-ref/TPMCmd -OPENSSL_BUILD_DIR = $(OUT_DIR)/openssl-build TCGTPM_BUILD_DIR = $(OUT_DIR)/tcgtpm-build -LIBCRYPTO = $(OPENSSL_BUILD_DIR)/libcrypto.a +LIBCRYPTO = $(OPENSSL_LIB_DIR)/libcrypto.a LIBTPM_TARGET = Tpm_CoreLib LIBTPM = $(TCGTPM_BUILD_DIR)/tpm/src/lib$(LIBTPM_TARGET).a @@ -52,19 +50,11 @@ LIBTPMBIGNUM = $(TCGTPM_BUILD_DIR)/tpm/cryptolibs/TpmBigNum/lib$(LIBTPMBIGNUM_TA LIBBNMATH_TARGET = Tpm_CryptoLib_Math_Ossl LIBBNMATH = $(TCGTPM_BUILD_DIR)/cryptolib_Ossl/lib$(LIBBNMATH_TARGET).a -OPENSSL_MAKEFILE = $(OPENSSL_BUILD_DIR)/Makefile TCGTPM_MAKEFILE = $(TCGTPM_BUILD_DIR)/Makefile ifeq ($(USE_LIBCRT),1) TCGTPM_CFLAGS += -static -nostdinc -fno-stack-protector -mno-sse -mno-red-zone TCGTPM_CFLAGS += -I$(LIBCRT_INCLUDE_DIR) -OPENSSL_CFLAGS = -static -nostdinc -nostdlib -fno-stack-protector -mno-red-zone -LIBCRT_INCLUDE = -I$(LIBCRT_INCLUDE_DIR) -LIBCRT_LINK = -Wl,rpath=$(LIBCRT_LIB_DIR) -lcrt -else -OPENSSL_CFLAGS = -LIBCRT_INCLUDE = -LIBCRT_LINK = endif # Avoid running jobs of this Makefile in parallel to avoid possible conflicts @@ -72,119 +62,7 @@ endif # Parallel builds are still used inside the sub-targets (-j flag) .NOTPARALLEL: -all: $(LIBCRYPTO) $(LIBBNMATH) $(LIBTPMBIGNUM) $(LIBTPM) $(LIBPLATFORM) - -# openssl -$(LIBCRYPTO): $(OPENSSL_MAKEFILE) - $(MAKE) -C $(OPENSSL_BUILD_DIR) - -$(OPENSSL_MAKEFILE): - mkdir -p $(OPENSSL_BUILD_DIR) - (cd $(OPENSSL_BUILD_DIR) && \ - perl $(OPENSSL_SRC_DIR)/Configure \ - --cross-compile-prefix=$(CROSS_PREFIX) \ - --config=$(DEPS_DIR)/openssl_svsm.conf \ - --api=1.1.1 \ - SVSM \ - disable-legacy \ - no-afalgeng \ - no-aria \ - no-asm \ - no-async \ - no-atexit \ - no-autoerrinit \ - no-autoload-config \ - no-bf \ - no-blake2 \ - no-capieng \ - no-cast \ - no-chacha \ - no-cmac \ - no-cmp \ - no-cms \ - no-ct \ - no-deprecated \ - no-des \ - no-dgram \ - no-dh \ - no-docs \ - no-dsa \ - no-dso \ - no-dtls \ - no-dtls1 \ - no-dtls1-method \ - no-dtls1_2 \ - no-dtls1_2-method \ - no-dynamic-engine \ - no-ec2m \ - no-ecdh \ - no-ecdsa \ - no-ecx \ - no-egd \ - no-engine \ - no-err \ - no-filenames \ - no-gost \ - no-http \ - no-idea \ - no-ktls \ - no-makedepend \ - no-md4 \ - no-mdc2 \ - no-ml-dsa \ - no-ml-kem \ - no-module \ - no-multiblock \ - no-nextprotoneg \ - no-ocb \ - no-ocsp \ - no-padlockeng \ - no-pic \ - no-poly1305 \ - no-posix-io \ - no-psk \ - no-quic \ - no-rc2 \ - no-rc4 \ - no-rfc3779 \ - no-rmd160 \ - no-scrypt \ - no-seed \ - no-shared \ - no-siphash \ - no-siv \ - no-sm2 \ - no-sm2-precomp \ - no-sm3 \ - no-sm4 \ - no-sock \ - no-srp \ - no-srtp \ - no-sse2 \ - no-ssl \ - no-ssl-trace \ - no-ssl3-method \ - no-static-engine \ - no-stdio \ - no-tests \ - no-thread-pool \ - no-threads \ - no-tls1 \ - no-tls1-method \ - no-tls1_1 \ - no-tls1_1-method \ - no-tls1_2 \ - no-tls1_2-method \ - no-tls1_3 \ - no-ts \ - no-ui-console \ - no-uplink \ - no-whirlpool \ - --with-rand-seed=getrandom \ - $(OPENSSL_CONFIG_TYPE) \ - $(OPENSSL_CFLAGS) \ - $(LIBCRT_INCLUDE) \ - $(LIBCRT_LINK)) +all: $(LIBBNMATH) $(LIBTPMBIGNUM) $(LIBTPM) $(LIBPLATFORM) # tcgtpm $(LIBBNMATH): $(TCGTPM_MAKEFILE) $(LIBCRYPTO) @@ -201,8 +79,8 @@ $(LIBPLATFORM): $(TCGTPM_MAKEFILE) $(LIBCRYPTO) TCGTPM_CFLAGS += -fPIE TCGTPM_CFLAGS += -DFILE_BACKED_NV=YES -DVTPM=YES -TCGTPM_CFLAGS += -I$(OPENSSL_BUILD_DIR)/include -TCGTPM_CFLAGS += -I$(OPENSSL_SRC_DIR)/include +TCGTPM_CFLAGS += -I$(OPENSSL_INCLUDE_DIR) +TCGTPM_CFLAGS += -I$(OPENSSL_SRC_INCLUDE_DIR) $(TCGTPM_MAKEFILE): $(LIBCRYPTO) mkdir -p $(TCGTPM_BUILD_DIR) @@ -213,19 +91,15 @@ $(TCGTPM_MAKEFILE): $(LIBCRYPTO) -DCMAKE_TRY_COMPILE_TARGET_TYPE=STATIC_LIBRARY \ -DCMAKE_C_FLAGS="${TCGTPM_CFLAGS}" \ -DOPENSSL_CRYPTO_LIBRARY="$(LIBCRYPTO)" \ - -DOPENSSL_INCLUDE_DIR="$(OPENSSL_BUILD_DIR)/include" \ + -DOPENSSL_INCLUDE_DIR="$(OPENSSL_INCLUDE_DIR)" \ -Duser_TpmConfiguration_Dir="$(DEPS_DIR)/TpmConfiguration" \ $(TCGTPM_SRC_DIR)) clean: - [ ! -f $(OPENSSL_MAKEFILE) ] || $(MAKE) -C $(OPENSSL_BUILD_DIR) clean [ ! -f $(TCGTPM_MAKEFILE) ] || $(MAKE) -C $(TCGTPM_BUILD_DIR) clean distclean: clean - rm -rf $(OPENSSL_BUILD_DIR) rm -rf $(TCGTPM_BUILD_DIR) -.PHONY: all clean distclean configure_openssl configure_tcgtpm libcrypto -configure_openssl: $(OPENSSL_MAKEFILE) -libcrypto: $(LIBCRYPTO) +.PHONY: all clean distclean configure_tcgtpm configure_tcgtpm: $(TCGTPM_MAKEFILE) diff --git a/libtcgtpm/build.rs b/libtcgtpm/build.rs index 54d9eaeedb..d8c38d22f1 100644 --- a/libtcgtpm/build.rs +++ b/libtcgtpm/build.rs @@ -12,6 +12,14 @@ use std::process::Stdio; fn main() { let target_os = std::env::var("CARGO_CFG_TARGET_OS").unwrap_or_default(); + // Read OpenSSL paths from cocoon-tpm-ossl-bare-sys (via cargo metadata). + let ossl_include_dir = + std::env::var("DEP_OSSL_OSSL_INCLUDE_DIR").expect("DEP_OSSL_OSSL_INCLUDE_DIR not set"); + let ossl_src_include_dir = std::env::var("DEP_OSSL_OSSL_SRC_INCLUDE_DIR") + .expect("DEP_OSSL_OSSL_SRC_INCLUDE_DIR not set"); + let ossl_lib_dir = + std::env::var("DEP_OSSL_OSSL_LIB_DIR").expect("DEP_OSSL_OSSL_LIB_DIR not set"); + // Read libcrt include path from the libcrt crate (via cargo metadata). let libcrt_include_dir = std::env::var("DEP_CRT_INCLUDE_DIR").expect("DEP_CRT_INCLUDE_DIR not set"); @@ -24,9 +32,13 @@ fn main() { "x86_64-linux-gnu-gcc".to_string() }; - // Build libtcgtpm. libcrt comes from the libcrt crate. + // Build libtcgtpm. OpenSSL (libcrypto) and libcrt come from ossl-bare-sys and libcrt crate + // respectively. let mut cmd = Command::new("make"); cmd.arg(format!("CC={cc}")); + cmd.arg(format!("OPENSSL_INCLUDE_DIR={ossl_include_dir}")); + cmd.arg(format!("OPENSSL_SRC_INCLUDE_DIR={ossl_src_include_dir}")); + cmd.arg(format!("OPENSSL_LIB_DIR={ossl_lib_dir}")); cmd.arg(format!("LIBCRT_INCLUDE_DIR={libcrt_include_dir}")); if target_os != "none" { cmd.arg("USE_LIBCRT=0"); @@ -80,10 +92,7 @@ fn main() { println!("cargo:rustc-link-search={out_dir}/tcgtpm-build/cryptolib_Ossl"); println!("cargo:rustc-link-lib=Tpm_CryptoLib_Math_Ossl"); - println!("cargo:rustc-link-search={out_dir}/openssl-build"); - println!("cargo:rustc-link-lib=crypto"); - - // libcrt is linked by the libcrt crate at link time. + // libcrypto and libcrt are provided by cocoon-tpm-ossl-bare-sys and libcrt crate respectively, at link time. // Tell cargo not to rerun the build-script unless anything in this // directory changes. diff --git a/libtcgtpm/deps/openssl b/libtcgtpm/deps/openssl deleted file mode 160000 index 67b5686b44..0000000000 --- a/libtcgtpm/deps/openssl +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 67b5686b4419b4cb8caa502711c41815f5279751 diff --git a/libtcgtpm/deps/openssl_svsm.conf b/libtcgtpm/deps/openssl_svsm.conf deleted file mode 100644 index d181066756..0000000000 --- a/libtcgtpm/deps/openssl_svsm.conf +++ /dev/null @@ -1,26 +0,0 @@ -# SPDX-License-Identifier: MIT -# -# Copyright (C) 2023 IBM Corporation -# -# Author: Claudio Carvalho - -my %targets = ( - "SVSM" => { - inherit_from => [ "BASE_unix" ], - perlasm_scheme => "elf", - CC => "gcc", - CFLAGS => add(combine(picker(default => "-Wall -ffunction-sections -fdata-sections", - debug => "-g -O0", - # When compiled with any optmization (e.g. -O1), - # the gcc generates code with instructions that are - # not supported at the SVSM level (e.g. the SSE pxor). - # That crashes the SVSM boot with an unhandled - # exception 6 (invalid opcode) usually in: - # vtpm_init()->libtpm:manufacture()->libcrypto:BN_CTX_new() - release => "-O0"), - "-fPIE -m64")), - bn_ops => "SIXTY_FOUR_BIT_LONG", - lib_cppflags => add("-DL_ENDIAN -DNO_SYSLOG -DOPENSSL_SMALL_FOOTPRINT -D_CRT_SECURE_NO_DEPRECATE -D_CRT_NONSTDC_NO_DEPRECATE -DOPENSSL_USE_USLEEP"), - sys_id => "SVSM" - }, -); diff --git a/libtcgtpm/src/lib.rs b/libtcgtpm/src/lib.rs index f1c27b9594..ac3803b1b4 100644 --- a/libtcgtpm/src/lib.rs +++ b/libtcgtpm/src/lib.rs @@ -14,12 +14,22 @@ //! | Env var | Usage | //! |-----------------------|---------------------------------------------------| //! | `DEP_CRT_INCLUDE_DIR` | C runtime headers for bindgen and TPM compilation | +//! +//! From `cocoon-tpm-ossl-bare-sys` (`links = "ossl"`): +//! +//! | Env var | Usage | +//! |---------------------------------|-----------------------------------------------| +//! | `DEP_OSSL_OSSL_INCLUDE_DIR` | Generated OpenSSL headers for TPM compilation | +//! | `DEP_OSSL_OSSL_SRC_INCLUDE_DIR` | OpenSSL source headers for TPM compilation | +//! | `DEP_OSSL_OSSL_LIB_DIR` | OpenSSL library path for TPM compilation | #![no_std] -// Ensure libcrt is linked — it provides the minimal C runtime +// Ensure these crates are linked — they provide libcrypto.a and libcrt.a // that the tcgtpm C libraries depend on. #[allow(unused_extern_crates)] +extern crate cocoon_tpm_ossl_bare_sys; +#[allow(unused_extern_crates)] extern crate libcrt; /// C bindings diff --git a/taplo.toml b/taplo.toml index 8e783331ca..37220d6005 100644 --- a/taplo.toml +++ b/taplo.toml @@ -1,5 +1,5 @@ # Exclude all git submodules -exclude = ["libtcgtpm/deps/openssl/**", "libtcgtpm/deps/tpm-20-ref/**", "packit/**"] +exclude = ["libtcgtpm/deps/tpm-20-ref/**", "packit/**"] [formatting]